68
char* getcontent(const char* string) {
70
const char* ptr = string;
142
int count_whitespace(const char* string) {
73
if(*ptr == '\0' || *ptr == '<') return NULL;
79
// DD ends in a newline
80
while(*ptr != '<' && *ptr != '\n') {
81
if(*ptr == '\0') return NULL;
144
while(isspace(*string)) {
86
ret = malloc(count+1);
87
memcpy(ret,string,count);
92
/* Make a state machine that turns bookmarks.html into a tree of:
109
* The state machine is necessary as we need to process line-by-line.
110
* The structure is necessary because we need to be able to easily merge a set
111
* of bookmarks and folders into the existing bookmarks.html.
114
void new_firefox_worker(void) {
115
while(fgets(line, 1024, fp) != NULL) {
119
if(strcmp(tag,"/DL") == 0) return;
120
if(strcmp(tag,"HR") == 0) ctx->next = HR;
123
void firefox_worker(FILE* fp, const char* foldername) {
127
// State machine it. ctx can be the parent tag.
128
// Write to a tree structure similar to libxml2's.
129
while(fgets(line, 1024, fp) != NULL) {
134
if(strcmp(tag,"HR") == 0)
135
printf("horizontal rule\n");
137
else if(strcmp(tag, "/DL") == 0)
140
// Either a bookmark or a folder.
141
else if(strcmp(tag, "DT") == 0) {
142
int offset = countwhitespace(line) + 4;
145
tag = readtag(line+offset);
150
if(strcmp(tag, "A") == 0) {
151
char* url = geturl(line+offset+2);
152
char* name = getcontent(line+offset+2);
154
printf("folder (%s) url: %s, name: %s\n", foldername, url, name);
156
printf("url: %s, name: %s\n", url, name);
161
else if(strcmp(tag, "H3") == 0) {
162
char* folder = getcontent(line+offset+3);
163
printf("folder: %s\n", folder);
165
if(fgets(line, 1024, fp) == NULL) return;
166
char* tag2 = readtag(line);
167
char* description = NULL;
168
if(strcmp(tag2, "DD") == 0) {
170
// FIXME: add getwhitespace to the offset
171
description = getcontent(line+1);
172
printf("description (%s): %s\n", folder, description);
178
if(fgets(line, 1024, fp) == NULL) return;
180
firefox_worker(fp, folder);
152
element* current; // To avoid having to iterate the entire list on every addition.
153
element* new_element(element** lst, item_type t, void* attributes) {
155
el = (element *)malloc(sizeof(element));
159
el->attributes = attributes;
169
element* append_element(element* parent, item_type t, void* attributes) {
171
el = (element *)malloc(sizeof(element));
175
el->attributes = attributes;
177
if(parent->children) {
178
element* ptr = parent->children;
179
while(ptr->next != NULL) {
186
parent->children = el;
191
void internet_explorer_build(const char* path, element* parent, element** list) {
203
if(chdir(path) == -1) {
204
fprintf(stderr, "Error: Could not chdir into %s\n", path);
209
while((dp = readdir(dfd)) != NULL) {
210
if((strcmp(dp->d_name,".") == 0) || (strcmp(dp->d_name,"..") == 0))
212
char* tmp = dp->d_name;
213
while(*tmp != '\0') tmp++;
214
while(tmp != dp->d_name && *tmp != '.') tmp--;
215
if(tmp != dp->d_name) {
216
if(strcmp(tmp,".url") == 0) {
217
fp = fopen(dp->d_name, "r");
218
while((read = getline(&line, &len, fp)) != -1) {
220
strncpy(utag, line, 5);
222
if(strcmp(utag,"URL=") == 0) {
223
url = malloc(strlen(line+4));
224
memcpy(url,line+4, strlen(line+4)-1);
225
url[strlen(line+4)-2] = '\0';
230
char* title = malloc(strlen(dp->d_name)+1);
231
strcpy(title, dp->d_name);
233
l = (hlink *)malloc(sizeof(hlink));
237
l->description = NULL;
241
append_element(parent, LINK, l);
243
new_element(list, LINK, l);
249
stat(dp->d_name,&statbuf);
250
if((statbuf.st_mode & S_IFMT) == S_IFDIR) {
252
char* title = malloc(strlen(dp->d_name)+1);
253
strcpy(title, dp->d_name);
256
f = (folder *)malloc(sizeof(folder));
258
f->description = NULL;
262
p = append_element(parent, FOLDER, f);
264
p = new_element(list, FOLDER, f);
266
internet_explorer_build(dp->d_name, p, list);
276
void firefox_build(FILE* fp, element* parent, element** list) {
277
// if parent is set then we will descend into parent and look at that level.
287
if((read = getline(&line, &len, fp)) == -1) break;
291
tag = read_tag(line);
295
if(strcmp(tag, "/DL") == 0) {
299
else if(strcmp(tag, "HR") == 0) {
301
append_element(parent, HR, NULL);
303
new_element(list, HR, NULL);
306
// Either a bookmark or a folder.
307
else if(strcmp(tag, "DT") == 0) {
308
int offset = count_whitespace(line)+4;
310
tag = read_tag(line + offset);
312
fprintf(stderr, "Could not find a tag after DT in line: %s\n", line + offset);
316
if(strcmp(tag, "A") == 0) {
317
char* url = getattrib(line+offset+2, HREF);
318
char* title = getcontent(line+offset+2);
319
char* icon = getattrib(line+offset+2, ICON);
320
char* feed = getattrib(line+offset+2, FEED);
321
char* description = NULL;
323
if((read = getline(&line, &len, fp)) == -1) {
324
puts("Got an EOF after an H3 tag. Corrupt file?");
327
tag = read_tag(line);
328
if(strcmp(tag, "DD") == 0) {
329
description = getcontent(line+1);
334
l = (hlink *)malloc(sizeof(hlink));
339
l->description = description;
342
append_element(parent, LINK, l);
344
new_element(list, LINK, l);
348
else if(strcmp(tag, "H3") == 0) {
349
char* title = getcontent(line+offset+3);
350
char* description = NULL;
351
if((read = getline(&line, &len, fp)) == -1) {
352
puts("Got an EOF after an H3 tag. Corrupt file?");
355
tag = read_tag(line);
358
if(strcmp(tag, "DD") == 0 || strcmp(tag, "DL") == 0) {
359
description = getcontent(line+1);
361
puts("Tag after H3 was not DD or DL.");
366
f = (folder *)malloc(sizeof(folder));
368
f->description = description;
372
p = append_element(parent, FOLDER, f);
374
p = new_element(list, FOLDER, f);
376
firefox_build(fp, p, list);
386
void firefox_format_worker(FILE* fp, const element* ptr) {
389
char* description = NULL;
394
char linkstr[64] = "\0";
398
fprintf(fp, "<HR>\n");
401
title = ((hlink *)ptr->attributes)->title;
402
url = ((hlink *)ptr->attributes)->url;
403
feed = ((hlink *)ptr->attributes)->feed;
404
description = ((hlink *)ptr->attributes)->description;
405
icon = ((hlink *)ptr->attributes)->icon;
406
strcpy(linkstr, "<DT><A HREF=\"%s\"");
409
strcat(linkstr, " FEEDURL=\"%s\"");
412
strcat(linkstr, " ICON=\"%s\"");
414
strcat(linkstr, ">%s</A>\n");
416
if(icon && feed) fprintf(fp, linkstr, url, feed, icon, title);
417
else if(icon) fprintf(fp, linkstr, url, icon, title);
418
else if(feed) fprintf(fp, linkstr, url, feed, title);
419
else fprintf(fp, linkstr, url, title);
423
fprintf(fp, "<DD>%s\n", description);
427
title = ((folder *)ptr->attributes)->title;
428
description = ((folder *)ptr->attributes)->description;
430
fprintf(fp, "<DT><H3>%s</H3>\n", title);
432
fprintf(fp, "<DD>%s\n", description);
433
fprintf(fp, "<DL><p>\n");
435
firefox_format_worker(fp, ptr->children);
436
fprintf(fp, "</DL><p>\n");
439
puts("Error: Type not A, H3, or HR.");
447
void firefox_format(const element* ptr, const char* file) {
449
const char intro[] = "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n"
450
"<!-- This is an automatically generated file.\n"
451
" It will be read and overwritten.\n"
452
" DO NOT EDIT! -->\n"
453
"<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n"
454
"<TITLE>Bookmarks</TITLE>\n"
455
"<H1>Bookmarks</H1>\n"
458
fp = fopen(file, "w");
461
firefox_format_worker(fp, ptr);
462
fprintf(fp, "</DL><p>\n");
465
fprintf(stderr, "Could not open %s for writing.\n", file);
469
void firefox_format_test(element* curr) {
473
puts("Horizontal Rule");
476
printf("Link: %s (%s)\n", ((hlink *)curr->attributes)->title,
477
((hlink *)curr->attributes)->url);
478
/* printf("Link: %s (%s)\nFeed: %s\n%s\n", ((hlink *)curr->attributes)->title,
479
((hlink *)curr->attributes)->url,
480
((hlink *)curr->attributes)->feed,
481
((hlink *)curr->attributes)->icon); */
484
printf("Folder: %s (%s)\n", ((folder *)curr->attributes)->title,
485
((folder *)curr->attributes)->description);
488
puts("Folder has children.");
489
firefox_format_test(curr->children);
490
puts("Done iterating children.");
504
void merge(element** to, element* from) {
511
if(t->type == f->type) {
518
if(strcmp(((hlink *)t->attributes)->url,
519
((hlink *)f->attributes)->url) == 0) {
524
if(strcmp(((folder *)t->attributes)->title,
525
((folder *)f->attributes)->title) == 0) {
527
if(f->children && t->children) {
528
merge(&t->children, f->children);
535
puts("Link type unknown.");
545
// Remove from its list
548
while(ptr->next != f)
553
// It was the first element in the list
558
// Append to the other list
573
void setup_import(char** fullpath, element** to_bookmarks) {
577
char* to_firefoxdir = NULL;
581
char bookmarksfile[32];
582
*bookmarksfile = '\0';
584
char random[] = "abcdefghijklmnopqrstuvwxyz0123456789"; //26
585
asprintf(&to_firefoxdir, "%s/home/%s/.mozilla/firefox", to_location, to_user);
587
// This might be dangerous.
588
asprintf(&mkdir, "mkdir -p %s", to_firefoxdir);
592
if(chdir(to_firefoxdir) == -1) {
593
fprintf(stderr, "Could not change directory to %s\n", to_firefoxdir);
599
fprintf(stderr, "Could not open directory.");
603
while((dp = readdir(dfd)) != NULL) {
604
if((strcmp(dp->d_name,".") == 0) || (strcmp(dp->d_name,"..") == 0))
606
stat(dp->d_name,&statbuf);
607
if(!S_ISDIR(statbuf.st_mode)) continue;
609
// Make sure we're looking at the default profile.
610
d_name = malloc(strlen(dp->d_name)+1);
611
strcpy(d_name,dp->d_name);
612
char* d_nameptr = d_name;
613
while(*d_nameptr != '\0') d_nameptr++;
614
while(*d_nameptr != '.' && d_nameptr != dp->d_name) d_nameptr--;
615
if(strcmp(d_nameptr,".default") == 0) {
616
strcpy(bookmarksfile, dp->d_name);
617
strcat(bookmarksfile, "/bookmarks.html");
624
if(bookmarksfile[0] != '\0') {
625
fp = fopen(bookmarksfile, "r");
627
fprintf(stderr, "Could not open file, %s\n", bookmarksfile);
630
firefox_build(fp, NULL, to_bookmarks);
632
asprintf(fullpath, "%s/%s", to_firefoxdir, bookmarksfile);
637
r = (int)((double)rand() / ((double)RAND_MAX + 1) * 26);
641
strcat(b, ".default");
643
asprintf(&path, "%s/profiles.ini", to_firefoxdir);
644
fp = fopen(path, "a");
646
fprintf(fp, "[General]\nStartWithLastProfile=1\n\n[Profile0]\n"
647
"Name=default\nIsRelative=1\nPath=%s\n\n", b);
650
asprintf(&path, "%s/%s", to_firefoxdir, b);
651
asprintf(&mkdir, "mkdir -p %s", path);
654
asprintf(fullpath, "%s/bookmarks.html", path);
188
661
void firefox_import_firefox(void) {
662
struct dirent *dp, *dp2;
665
char bookmarksfile[32] = "\0";
193
fp = fopen("/home/evan/.mozilla/firefox/j539x5mu.default/bookmarks.html", "r");
194
firefox_worker(fp, NULL);
667
element* from_bookmarks = NULL;
668
element* to_bookmarks = NULL;
670
char* from_firefoxdir = NULL;
671
char* fullpath = NULL;
674
setup_import(&fullpath, &to_bookmarks);
676
// Build a tree of the bookmarks file(s) we're importing from, then merge it
677
// with the new bookmarks tree.
678
if(os_type == LINUX) {
679
asprintf(&from_firefoxdir, "%s/home/%s/.mozilla/firefox",
680
from_location, from_user);
682
else if(os_type == WINDOWSXP) {
683
asprintf(&from_firefoxdir, "%s/Documents and Settings/%s/"
684
"Application Data/Mozilla/Firefox/Profiles", from_location,
687
if(chdir(from_firefoxdir) == -1) {
688
fprintf(stderr, "Could not change directory to %s.\n", from_firefoxdir);
691
free(from_firefoxdir);
695
while((dp = readdir(dfd)) != NULL) {
696
if((strcmp(dp->d_name,".") == 0) || (strcmp(dp->d_name,"..") == 0))
698
stat(dp->d_name,&statbuf);
699
if(!S_ISDIR(statbuf.st_mode)) continue;
701
dfd2 = opendir(dp->d_name);
703
while((dp2 = readdir(dfd2)) != NULL) {
704
if(strcmp(dp2->d_name,"bookmarks.html") == 0)
711
strcpy(bookmarksfile,dp->d_name);
712
strcat(bookmarksfile,"/bookmarks.html");
713
fp = fopen(bookmarksfile,"r");
715
fprintf(stderr, "Could not open file, %s.", bookmarksfile);
718
// TODO: get rid of current.
720
firefox_build(fp, NULL, &from_bookmarks);
723
merge(&to_bookmarks, from_bookmarks);
725
to_bookmarks = from_bookmarks;
731
// Now we translate the tree into a bookmarks.html file.
732
firefox_format(to_bookmarks, fullpath);
736
void firefox_import_internetexplorer(void) {
737
char* from_iedir = NULL;
738
element* to_bookmarks = NULL;
739
element* from_bookmarks = NULL;
740
char* fullpath = NULL;
742
setup_import(&fullpath, &to_bookmarks);
744
asprintf(&from_iedir, "%s/Documents and Settings/%s/Favorites", from_location, from_user);
746
internet_explorer_build(from_iedir, NULL, &from_bookmarks);
748
merge(&to_bookmarks, from_bookmarks);
750
to_bookmarks = from_bookmarks;
752
firefox_format(to_bookmarks, fullpath);
756
// vim:ai:et:sts=4:tw=80:sw=4: