📄 bookmarks.c
字号:
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 */static 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 */static 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; g_free(node->title); node->title = Escape_html_str(n_title); }}/* * Update a section title by key */static 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; g_free(node->title); node->title = Escape_html_str(n_title); }}/* * Free all the bookmarks data (bookmarks and sections) */static void Bms_free(void){ 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. */static void Bms_normalize(void){ 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". */static void Bms_check_import(void){ 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 */static int Bms_load(void){ FILE *BmTxt; char *buf, *p, *url, *title, *u_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; u_title = Unescape_html_str(title); Bms_add(section, url, u_title); g_free(u_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 :) */static int Bms_cond_load(void){ 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; } return st;}/* -- Save bookmarks file -------------------------------------------------- *//* * Update the bookmarks file from memory contents * Return code: { 0:OK, 1:Abort } */static int Bms_save(void){ FILE *BmTxt; BmRec *bm_node; BmSec *sec_node; GSList *list, *list2; struct stat BmStat; gchar *u_title; GString *gstr = g_string_new(""); /* 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; u_title = Unescape_html_str(sec_node->title); g_string_sprintf(gstr, ":s%d: %s\n", sec_node->section, u_title); fwrite(gstr->str, (size_t)gstr->len, 1, BmTxt); g_free(u_title); } /* 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; if (bm_node->section == sec_node->section) { u_title = Unescape_html_str(bm_node->title); g_string_sprintf(gstr, "s%d %s %s\n", bm_node->section, bm_node->url, u_title); fwrite(gstr->str, (size_t)gstr->len, 1, BmTxt); g_free(u_title); } } } g_string_free(gstr, TRUE); fclose(BmTxt); /* keep track of the timestamp */ stat(BmFile, &BmStat); BmFileTimeStamp = BmStat.st_mtime; return 0;}/* -- Add bookmark --------------------------------------------------------- *//* * Add a new bookmark to DB :) */static int Bmsrv_add_bm(SockHandler *sh, char *url, char *title){ char *u_title; char *msg="Added bookmark!"; int section = 0; /* Add in memory */ u_title = Unescape_html_str(title); Bms_add(section, url, u_title); g_free(u_title); /* Write to file */ Bms_save(); if (Bmsrv_dpi_send_status_msg(sh, msg)) return 1; return 0;}/* -- Modify --------------------------------------------------------------- *//* * Count how many sections and urls were marked in a request */static void Bmsrv_count_urls_and_sections(char *url, gint *n_sec, gint *n_url){ char *p, *q; int i; /* Check marked urls and sections */ *n_sec = *n_url = 0; if ((p = strchr(url, '?'))) { for (q = p; (q = strstr(q, "&url")); ++q) { for (i = 0; isdigit(q[4+i]); ++i); *n_url += (q[4+i] == '=') ? 1 : 0; } for (q = p; (q = strstr(q, "&s")); ++q) { for (i = 0; isdigit(q[2+i]); ++i); *n_sec += (q[2+i] == '=') ? 1 : 0; } }}/* * Send a dpi reload request * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_reload_request(SockHandler *sh, char *url){ gint st; char *d_cmd; d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "reload_request", url); st = sock_handler_write_str(sh, d_cmd, 1) ? 1 : 0; g_free(d_cmd); return st;}/* * Send the HTML for the modify page * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_modify_page(SockHandler *sh){ static GString *gstr = NULL; gchar *l_title; GSList *list1, *list2; BmSec *sec_node; BmRec *bm_node; if (!gstr) gstr = g_string_new(""); /* send modify page header */ if (sock_handler_write_str(sh, modifypage_header, 0)) return 1; /* write sections header */ if (sock_handler_write_str(sh, modifypage_sections_header, 0)) return 1; /* write sections */ for (list1 = B_secs; list1; list1 = list1->next) { sec_node = list1->data; g_string_sprintf(gstr, modifypage_sections_item, sec_node->section, sec_node->section, sec_node->title); if (sock_handler_write_str(sh, gstr->str, 0)) return 1; } /* write sections footer */ if (sock_handler_write_str(sh, modifypage_sections_footer, 0)) return 1; /* send page middle */ if (sock_handler_write_str(sh, modifypage_middle1, 0)) return 1; /* send bookmark cards */ for (list1 = B_secs; list1; list1 = list1->next) { sec_node = list1->data; /* send card header */ l_title = make_one_line_str(sec_node->title); g_string_sprintf(gstr, modifypage_section_card_header, sec_node->section, l_title); g_free(l_title); if (sock_handler_write_str(sh, gstr->str, 0)) return 1; /* send section's bookmarks */ for (list2 = B_bms; list2; list2 = list2->next) { bm_node = list2->data; if (bm_node->section == sec_node->section) { g_string_sprintf(gstr, modifypage_section_card_item, bm_node->key, bm_node->url, bm_node->title); if (sock_handler_write_str(sh, gstr->str, 0)) return 1; } } /* send card footer */ if (sock_handler_write_str(sh, modifypage_section_card_footer, 0)) return 1; } /* finish page */ if (sock_handler_write_str(sh, modifypage_footer, 1)) return 1; return 2;}/* * Send the HTML for the modify page for "add section" * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_modify_page_add_section(SockHandler *sh){ /* send modify page2 */ if (sock_handler_write_str(sh, modifypage_add_section_page, 1)) return 1; return 2;}/* * Send the HTML for the modify page for "add url" * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_modify_page_add_url(SockHandler *sh){ if (sock_handler_write_str(sh, modifypage_add_url, 1)) return 1; return 2;}/* * Parse a modify urls request and either: * - make a local copy of the url * or * - send the modify page for the marked urls and sections * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_modify_update(SockHandler *sh, char *url){ static char *url1 = NULL; static GString *gstr = NULL; char *p, *q; int i, key, n_sec, n_url; BmRec *bm_node; BmSec *sec_node; /* bookmarks were loaded before */ if (!gstr) gstr = g_string_new(""); if (sh == NULL) { /* just copy url */ g_free(url1); url1 = g_strdup(url); return 0; } /* send HTML here */ if (sock_handler_write_str(sh, modifypage_update_header, 0)) return 1; /* Count number of marked urls and sections */ Bmsrv_count_urls_and_sections(url1, &n_sec, &n_url); if (n_sec) { g_string_sprintf(gstr, modifypage_update_title, "Update sections:"); sock_handler_write_str(sh, gstr->str, 0); sock_handler_write_str(sh, modifypage_update_item_header, 0); /* send items here */ p = strchr(url1, '?'); for (q = p; (q = strstr(q, "&s")); ++q) { for (i = 0; isdigit(q[2+i]); ++i); if (q[2+i] == '=') { key = strtol(q + 2, NULL, 10); if ((sec_node = Bms_get_sec(key))) { g_string_sprintf(gstr, modifypage_update_item2, sec_node->section, sec_node->title); sock_handler_write_str(sh, gstr->str, 0); } } } sock_handler_write_str(sh, modifypage_update_item_footer, 0); } if (n_url) { g_string_sprintf(gstr, modifypage_update_title, "Update titles:"); sock_handler_write_str(sh, gstr->str, 0); sock_handler_write_str(sh, modifypage_update_item_header, 0); /* send items here */ p = strchr(url1, '?'); for (q = p; (q = strstr(q, "&url")); ++q) { for (i = 0; isdigit(q[4+i]); ++i); if (q[4+i] == '=') { key = strtol(q + 4, NULL, 10); bm_node = Bms_get(key); g_string_sprintf(gstr, modifypage_update_item, bm_node->key, bm_node->title, bm_node->url); sock_handler_write_str(sh, gstr->str, 0); } } sock_handler_write_str(sh, modifypage_update_item_footer, 0); } sock_handler_write_str(sh, modifypage_update_footer, 1); return 2;}/* * Make the modify-page and send it back * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_send_modify_answer(SockHandler *sh, char *url){ char *d_cmd; int st; d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", url); st = sock_handler_write_str(sh, d_cmd, 1); g_free(d_cmd); if (st != 0) return 1; /* Send HTTP header */ if (sock_handler_write(sh, Header, strlen(Header), 0) != 0) { return 1; } if (MODIFY_PAGE_NUM == 2) { MODIFY_PAGE_NUM = 1; return Bmsrv_send_modify_page_add_section(sh); } else if (MODIFY_PAGE_NUM == 3) { MODIFY_PAGE_NUM = 1; return Bmsrv_send_modify_update(sh, NULL); } else if (MODIFY_PAGE_NUM == 4) { MODIFY_PAGE_NUM = 1; return Bmsrv_send_modify_page_add_url(sh); } else { return Bmsrv_send_modify_page(sh); }}/* Operations *//* * Parse a delete bms request, delete them, and update bm file. * Return code: { 0:OK, 1:Abort } */static int Bmsrv_modify_delete(SockHandler *sh, char *url){ gchar *p; gint nb, ns, key; /* bookmarks were loaded before */ /* Remove marked sections */ p = strchr(url, '?'); for (ns = 0; (p = strstr(p, "&s")); ++p) { if (isdigit(p[2])) { key = strtol(p + 2, NULL, 10); Bms_sec_del(key); ++ns; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -