📄 bookmarks.c
字号:
e += 5; } else { *p = (isdigit(e[1]) ? (e[1] - '0') : (e[1] - 'A' + 10)) * 16 + (isdigit(e[2]) ? (e[2] - '0') : (e[2] - 'A' + 10)); e += 2; } } else { *p = *e; } } *p = 0;}/* * Read a line of text up to the newline character, store it into a newly * allocated string and return it. */char *Get_line(FILE *stream){ int size = 64; int ch, i; char *buf; buf = g_new(char, size); for (i = 0; (ch = fgetc(stream)) != EOF; ++i) { if (i + 1 == size) { size *= 2; buf = g_realloc(buf, size); } if ((buf[i] = ch) == '\n' && ++i) break; } buf[i] = 0; if (i > 0) { buf = g_realloc(buf, i + 1); } else { g_free(buf); buf = NULL; } return buf;}/* * Send a sized data stream to client. */int send_data_chunk(int OutFD, char *Data, size_t DataSize){ if (send(OutFD, Data, DataSize, 0) == -1) { perror("[send_data_chunk]"); return 1; } //sleep(1); return 0;}/* * Send a data string to client. */int send_data_string(int OutFD, char *str){ return send_data_chunk(OutFD, str, strlen(str));}/* * Send a short message to dillo's status bar. */int Bmsrv_dpi_send_status_msg(int OutFD, char *str){ int st; GString *gstr = g_string_new(""); gchar *sstr = Stuff_chars(str, "'\""); g_string_sprintf(gstr, "<dpi cmd='send_status_message' msg='%s'>", sstr); st = send_data_chunk(OutFD, gstr->str, gstr->len); g_string_free(gstr, TRUE); g_free(sstr); return st;}/* -- ADT for bookmarks ---------------------------------------------------- *//* * Compare function for searching a bookmark by its key */static gint Bms_key_cmp(gconstpointer node, gconstpointer key){ return ( GPOINTER_TO_INT(key) != ((BmRec *)node)->key );}/* * Compare function for searching a bookmark by section */static gint Bms_bysec_cmp(gconstpointer node, gconstpointer key){ return ( GPOINTER_TO_INT(key) != ((BmRec *)node)->section );}/* * Compare function for searching a section by its number */static gint Bms_sec_cmp(gconstpointer node, gconstpointer key){ return ( GPOINTER_TO_INT(key) != ((BmSec *)node)->section );}/* * Return the Bm record by key */static BmRec *Bms_get(gint key){ GSList *list; list = g_slist_find_custom(B_bms, GINT_TO_POINTER(key), Bms_key_cmp); return (list) ? list->data : NULL;}/* * Return the Section record by key */static BmSec *Bms_get_sec(gint key){ GSList *list; list = g_slist_find_custom(B_secs, GINT_TO_POINTER(key), Bms_sec_cmp); return (list) ? list->data : NULL;}/* * Add a bookmark */void Bms_add(gint section, char *url, char *title){ BmRec *node; node = g_new(BmRec, 1); node->key = ++bm_key; node->section = section; node->url = g_strdup(url); node->title = g_strdup(title); B_bms = g_slist_append(B_bms, node);}/* * Add a section */void Bms_sec_add(char *title){ BmSec *node; node = g_new(BmSec, 1); node->section = sec_key++; node->title = g_strdup(title); B_secs = g_slist_append(B_secs, node);}/* * Delete a bookmark by its key */void Bms_del(gint key){ GSList *list; BmRec *node; list = g_slist_find_custom(B_bms, GINT_TO_POINTER(key), Bms_key_cmp); if (list) { node = list->data; g_free(node->title); g_free(node->url); g_free(list->data); B_bms = g_slist_remove(B_bms, list->data); } if (B_bms == NULL) bm_key = 0;}/* * Delete a section and its bookmarks by section number */void Bms_sec_del(gint section){ GSList *list; BmSec *sec_node; BmRec *bm_node; list = g_slist_find_custom(B_secs, GINT_TO_POINTER(section), Bms_sec_cmp); if (list) { sec_node = list->data; g_free(sec_node->title); g_free(list->data); B_secs = g_slist_remove(B_secs, list->data); /* iterate B_bms and remove those that match the section */ while ((list = g_slist_find_custom(B_bms, GINT_TO_POINTER(section), Bms_bysec_cmp))) { bm_node = list->data; Bms_del(bm_node->key); } } if (B_secs == NULL) sec_key = 0;}/* * Move a bookmark to another section */void Bms_move(gint key, gint target_section){ GSList *list; list = g_slist_find_custom(B_bms, GINT_TO_POINTER(key), Bms_key_cmp); if (list) { BmRec *node = list->data; node->section = target_section; }}/* * Update a bookmark title by key */void Bms_update_title(gint key, gchar *n_title){ GSList *list; list = g_slist_find_custom(B_bms, GINT_TO_POINTER(key), Bms_key_cmp); if (list) { BmRec *node = list->data; if (strcmp(node->title, n_title)) { g_free(node->title); node->title = g_strdup(n_title); } }}/* * Update a section title by key */void Bms_update_sec_title(gint key, gchar *n_title){ GSList *list; list = g_slist_find_custom(B_secs, GINT_TO_POINTER(key), Bms_sec_cmp); if (list) { BmSec *node = list->data; if (strcmp(node->title, n_title)) { g_free(node->title); node->title = g_strdup(n_title); } }}/* * Free all the bookmarks data (bookmarks and sections) */void Bms_free(){ BmRec *bm_node; BmSec *sec_node; /* free B_bms */ while (B_bms) { bm_node = B_bms->data; Bms_del(bm_node->key); } /* free B_secs */ while (B_secs) { sec_node = B_secs->data; Bms_sec_del(sec_node->section); }}/* * Enforce increasing correlative section numbers with no jumps. */void Bms_normalize(){ BmRec *bm_node; BmSec *sec_node; GSList *list1, *list2; gint n; /* we need at least one section */ if (!B_secs) Bms_sec_add("Unclassified"); /* make correlative section numbers */ n = 0; for (list1 = B_secs; list1; list1 = list1->next) { sec_node = list1->data; sec_node->o_sec = sec_node->section; sec_node->section = n++; } /* iterate B_secs and make the changes in B_bms */ for (list1 = B_secs; list1; list1 = list1->next) { sec_node = list1->data; if (sec_node->section != sec_node->o_sec) { /* update section numbers */ for (list2 = B_bms; list2; list2 = list2->next) { bm_node = list2->data; if (bm_node->section == sec_node->o_sec) bm_node->section = sec_node->section; } } }}/* -- Load bookmarks file -------------------------------------------------- *//* * If there's no "bm.txt", create one from "bookmarks.html". */void Bms_check_import(){ gchar *OldBmFile; char *cmd1 = "echo \":s0: Unclassified\" > %s"; char *cmd2 = "grep -i \"href\" %s | " "sed -e 's/<li><A HREF=\"/s0 /' -e 's/\">/ /' -e 's/<.*$//' >> %s"; GString *gstr = g_string_new(""); if (access(BmFile, F_OK) != 0) { OldBmFile = g_strconcat(g_get_home_dir(), "/", ".dillo/bookmarks.html", NULL); if (access(OldBmFile, F_OK) == 0) { g_string_sprintf(gstr, cmd1, BmFile); system(gstr->str); g_string_sprintf(gstr, cmd2, OldBmFile, BmFile); system(gstr->str); g_string_free(gstr, TRUE); g_free(OldBmFile); } }}/* * Load bookmarks data from a file */int Bms_load(){ FILE *BmTxt; char *buf, *p, *url, *title; int section; struct stat TimeStamp; /* clear current bookmarks */ Bms_free(); /* open bm file */ if (!(BmTxt = fopen(BmFile, "r"))) { perror("[fopen]"); return 1; } /* load bm file into memory */ while ((buf = Get_line(BmTxt)) != NULL) { if (buf[0] == 's') { /* get section, url and title */ section = strtol(buf + 1, NULL, 10); p = strchr(buf, ' '); *p = 0; url = ++p; p = strchr(p, ' '); *p = 0; title = ++p; p = strchr(p, '\n'); *p = 0; Bms_add(section, url, title); //g_print("Section: %d Url: %s Title: %s\n", section, url, title); } else if (buf[0] == ':' && buf[1] == 's') { // section = strtol(buf + 2, NULL, 10); p = strchr(buf + 2, ' '); title = ++p; p = strchr(p, '\n'); *p = 0; Bms_sec_add(title); } else { g_print("Syntax error in bookmarks file:\n %s", buf); } g_free(buf); } fclose(BmTxt); /* keep track of the timestamp */ stat(BmFile, &TimeStamp); BmFileTimeStamp = TimeStamp.st_mtime; return 0;}/* * Load bookmarks data if: * - file timestamp is newer than ours or * - we haven't loaded anything yet :) */int Bms_cond_load(){ int st = 0; struct stat TimeStamp; if (stat(BmFile, &TimeStamp) != 0) { /* try to import... */ Bms_check_import(); if (stat(BmFile, &TimeStamp) != 0) TimeStamp.st_mtime = 0; } if (!BmFileTimeStamp || !B_bms || !B_secs || BmFileTimeStamp < TimeStamp.st_mtime) { Bms_load(); st = 1; } //g_print("\n >>> %s\n\n", st ? "LOADED" : "KEPT"); return st;}/* -- Save bookmarks file -------------------------------------------------- *//* * Update the bookmarks file from memory contents * Return code: { 0:OK, 1:Abort } */int Bms_save(){ FILE *BmTxt; BmRec *bm_node; BmSec *sec_node; GSList *list, *list2; GString *gstr = g_string_new(""); struct stat BmStat; /* make a safety backup */ if (stat(BmFile, &BmStat) == 0 && BmStat.st_size > 256) { gchar *BmFileBak = g_strconcat(BmFile, ".bak", NULL); rename(BmFile, BmFileBak); g_free(BmFileBak); } /* open bm file */ if (!(BmTxt = fopen(BmFile, "w"))) { perror("[fopen]"); return 1; } /* normalize */ Bms_normalize(); /* save sections */ for (list = B_secs; list; list = list->next) { sec_node = list->data; g_string_sprintf(gstr, ":s%d: %s\n", sec_node->section, sec_node->title); fwrite(gstr->str, gstr->len, 1, BmTxt); } /* save bookmarks (section url title) */ for (list = B_secs; list; list = list->next) { sec_node = list->data; for (list2 = B_bms; list2; list2 = list2->next) { bm_node = list2->data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -