📄 bookmarks.c
字号:
/* Remove marked urls */ p = strchr(url, '?'); for (nb = 0; (p = strstr(p, "&url")); ++p) { if (isdigit(p[4])) { key = strtol(p + 4, NULL, 10); Bms_del(key); ++nb; } }/* -- This doesn't work because dillo erases the message upon the * receipt of the first data stream. * sprintf(msg, "Deleted %d bookmark%s!>", n, (n > 1) ? "s" : ""); if (Bmsrv_dpi_send_status_msg(sh, msg)) return 1;*/ /* Write new bookmarks file */ if (nb || ns) Bms_save(); return 0;}/* * Parse a move urls request, move and update bm file. * Return code: { 0:OK, 1:Abort } */static int Bmsrv_modify_move(SockHandler *sh, char *url){ char *p; int n, section = 0, key; /* bookmarks were loaded before */ /* get target section */ for (p = url; (p = strstr(p, "&s")); ++p) { if (isdigit(p[2])) { section = strtol(p + 2, NULL, 10); break; } } if (!p) return 1; /* move marked urls */ p = strchr(url, '?'); for (n = 0; (p = strstr(p, "&url")); ++p) { if (isdigit(p[4])) { key = strtol(p + 4, NULL, 10); Bms_move(key, section); ++n; } } /* Write new bookmarks file */ if (n) { Bms_save(); } return 0;}/* * Parse a modify request: update urls and sections, then save. * Return code: { 0:OK, 1:Abort } */static int Bmsrv_modify_update(SockHandler *sh, char *url){ char *p, *q, *title; int i, key; /* bookmarks were loaded before */ p = strchr(url, '?'); for ( ; (p = strstr(p, "s")); ++p) { if (p[-1] == '&' || p[-1] == '?' ) { for (i = 0; isdigit(p[1 + i]); ++i); if (i && p[1 + i] == '=') { /* we have a title/key to change */ key = strtol(p + 1, NULL, 10); if ((q = strchr(p + 1, '&'))) title = g_strndup(p + 2 + i, (guint)(q - (p + 2 + i))); else title = g_strdup(p + 2 + i); Unencode_str(title); Bms_update_sec_title(key, title); g_free(title); } } } p = strchr(url, '?'); for ( ; (p = strstr(p, "title")); ++p) { if (p[-1] == '&' || p[-1] == '?' ) { for (i = 0; isdigit(p[5 + i]); ++i); if (i && p[5 + i] == '=') { /* we have a title/key to change */ key = strtol(p + 5, NULL, 10); if ((q = strchr(p + 5, '&'))) title = g_strndup(p + 6 + i, (guint)(q - (p + 6 + i))); else title = g_strdup(p + 6 + i); Unencode_str(title); Bms_update_title(key, title); g_free(title); } } } /* Write new bookmarks file */ Bms_save(); return 0;}/* * Parse an "add section" request, and update the bm file. * Return code: { 0:OK, 1:Abort } */static int Bmsrv_modify_add_section(SockHandler *sh, char *url){ char *p, *title = NULL; /* bookmarks were loaded before */ /* get new section's title */ if ((p = strstr(url, "&title="))) { title = g_strdup (p + 7); if ((p = strchr(title, '&'))) *p = 0; Unencode_str(title); } else return 1; Bms_sec_add(title); g_free(title); /* Write new bookmarks file */ Bms_save(); return 0;}/* * Parse an "add url" request, and update the bm file. * Return code: { 0:OK, 1:Abort } */static int Bmsrv_modify_add_url(SockHandler *sh, char *s_url){ char *p, *q, *title, *u_title, *url; int i; static gint section = 0; /* bookmarks were loaded before */ if (sh == NULL) { /* look for section */ for (q = s_url; (q = strstr(q, "&s")); ++q) { for (i = 0; isdigit(q[2+i]); ++i); if (q[2+i] == '=') section = strtol(q + 2, NULL, 10); } return 1; } if (!(p = strstr(s_url, "&title=")) || !(q = strstr(s_url, "&url="))) return 1; title = g_strdup (p + 7); if ((p = strchr(title, '&'))) *p = 0; url = g_strdup (q + 5); if ((p = strchr(url, '&'))) *p = 0; if (strlen(title) && strlen(url)) { Unencode_str(title); Unencode_str(url); u_title = Unescape_html_str(title); Bms_add(section, url, u_title); g_free(u_title); } g_free(title); g_free(url); section = 0; /* todo: we should send an "Bookmark added" message, but the msg-after-HTML functionallity is still pending, not hard though. */ /* Write new bookmarks file */ Bms_save(); return 0;}/* * Check the parameters of a modify request, and return an error message * when it's wrong. * Return code: { 0:OK, 2:Close } */static int Bmsrv_check_modify_request(SockHandler *sh, char *url){ char *p, *msg; int n_sec, n_url; /* Count number of marked urls and sections */ Bmsrv_count_urls_and_sections(url, &n_sec, &n_url); p = strchr(url, '?'); if (strstr(p, "operation=delete&")) { if (n_url || n_sec) return 0; msg = "Delete: you must mark what to delete!"; } else if (strstr(url, "operation=move&")) { if (n_url && n_sec) return 0; else if (n_url) msg = "Move: you must mark a target section!"; else if (n_sec) msg = "Move: can not move a section (yet)."; else msg = "Move: you must mark some urls, and a target section!"; } else if (strstr(url, "operation=modify&")) { if (n_url || n_sec) return 0; msg = "Modify: you must mark what to update!"; } else if (strstr(url, "operation=modify2&")) { /* nothing to check here */ return 0; } else if (strstr(url, "operation=add_sec&")) { /* nothing to check here */ return 0; } else if (strstr(url, "operation=add_section&")) { /* nothing to check here */ return 0; } else if (strstr(url, "operation=add_url&")) { if (n_sec <= 1) return 0; msg = "Add url: only one target section is allowed!"; } else if (strstr(url, "operation=add_url2&")) { /* nothing to check here */ return 0; } else if (strstr(url, "operation=none&")) { msg = "No operation, just do nothing!"; } else { msg = "Sorry, not implemented yet."; } Bmsrv_dpi_send_status_msg(sh, msg); return 2;}/* * Parse a and process a modify request. * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_process_modify_request(SockHandler *sh, char *url){ /* check the provided parameters */ if (Bmsrv_check_modify_request(sh, url) != 0) return 2; if (strstr(url, "operation=delete&")) { if (Bmsrv_modify_delete(sh, url) == 1) return 1; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=move&")) { if (Bmsrv_modify_move(sh, url) == 1) return 1; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=modify&")) { /* make a local copy of 'url' */ Bmsrv_send_modify_update(NULL, url); MODIFY_PAGE_NUM = 3; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=modify2&")) { if (Bmsrv_modify_update(sh, url) == 1) return 1; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=add_sec&")) { /* this global variable tells which page to send (--hackish...) */ MODIFY_PAGE_NUM = 2; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=add_section&")) { if (Bmsrv_modify_add_section(sh, url) == 1) return 1; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=add_url&")) { /* this global variable tells which page to send (--hackish...) */ MODIFY_PAGE_NUM = 4; /* parse section if present */ Bmsrv_modify_add_url(NULL, url); if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } else if (strstr(url, "operation=add_url2&")) { if (Bmsrv_modify_add_url(sh, url) == 1) return 1; if (Bmsrv_send_reload_request(sh, "dpi:/bm/modify") == 1) return 1; } return 2;}/* -- Bookmarks ------------------------------------------------------------ *//* * Send the current bookmarks page (in HTML) */static int send_bm_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(""); if (sock_handler_write_str(sh, mainpage_header, 0)) return 1; /* write sections header */ if (sock_handler_write_str(sh, mainpage_sections_header, 0)) return 1; /* write sections */ for (list1 = B_secs; list1; list1 = list1->next) { sec_node = list1->data; g_string_sprintf(gstr, mainpage_sections_item, 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, mainpage_sections_footer, 0)) return 1; /* send page middle */ if (sock_handler_write_str(sh, mainpage_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, mainpage_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, mainpage_section_card_item, 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, mainpage_section_card_footer, 0)) return 1; } /* finish page */ if (sock_handler_write_str(sh, mainpage_footer, 1)) return 1; return 0;}/* -- Dpi parser ----------------------------------------------------------- *//* * Parse a data stream (dpi protocol) * Note: Buf is a zero terminated string * Return code: { 0:OK, 1:Abort, 2:Close } */static int Bmsrv_parse_buf(SockHandler *sh, char *Buf, size_t BufSize){ static char *msg1=NULL, *msg2=NULL, *msg3=NULL; char *p, *cmd, *d_cmd, *url, *title, *msg; int st; if (!msg1) { /* Initialize data for the "chat" command. */ msg1 = a_Dpip_build_cmd("cmd=%s msg=%s", "chat", "Hi browser"); msg2 = a_Dpip_build_cmd("cmd=%s msg=%s", "chat", "Is it worth?"); msg3 = a_Dpip_build_cmd("cmd=%s msg=%s", "chat", "Ok, send it"); } if (!(p = strchr(Buf, '>'))) { /* Haven't got a full tag */ g_print("Haven't got a full tag!\n"); return 1; } cmd = a_Dpip_get_attr(Buf, BufSize, "cmd"); if (cmd && strcmp(cmd, "chat") == 0) { g_free(cmd); msg = a_Dpip_get_attr(Buf, BufSize, "msg"); if (*msg == 'H') { /* "Hi server" */ if (sock_handler_write_str(sh, msg1, 1)) return 1; } else if (*msg == 'I') { /* "I want to set abookmark" */ if (sock_handler_write_str(sh, msg2, 1)) return 1; } else if (*msg == 'S') { /* "Sure" */ if (sock_handler_write_str(sh, msg3, 1)) return 1; } g_free(msg); return 0; } /* sync with the bookmarks file */ Bms_cond_load(); if (cmd && strcmp(cmd, "DpiBye") == 0) { g_print("bookmarks dpi (pid %d): Got DpiBye.\n", (gint)getpid()); exit(0); } else if (cmd && strcmp(cmd, "add_bookmark") == 0) { g_free(cmd); url = a_Dpip_get_attr(Buf, BufSize, "url"); title = a_Dpip_get_attr(Buf, BufSize, "title"); if (strlen(title) == 0) { g_free(title); title = g_strdup("(Untitled)"); } if (url && title) Bmsrv_add_bm(sh, url, title); g_free(url); g_free(title); return 2; } else if (cmd && strcmp(cmd, "open_url") == 0) { g_free(cmd); url = a_Dpip_get_attr(Buf, BufSize, "url"); if (strcmp(url, "dpi:/bm/modify") == 0) { st = Bmsrv_send_modify_answer(sh, url); return st; } else if (strncmp(url, "dpi:/bm/modify?", 15) == 0) { /* process request */ st = Bmsrv_process_modify_request(sh, url); return 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), 1) != 0) { return 1; } st = send_bm_page(sh); if (st != 0) { char *err = DOCTYPE "<HTML><body> Error on the bookmarks server...</body></html>"; if (sock_handler_write(sh, err, strlen(err), 1) != 0) { return 1; } } return 2; } return 0;}/* -- Termination handlers ----------------------------------------------- *//* * (was to delete the local namespace socket), * but this is handled by 'dpid' now. */static void cleanup(void){ /* no cleanup required */}/* * Perform any necessary cleanups upon abnormal termination */static void termination_handler(int signum){ exit(signum);}/* * -- MAIN ------------------------------------------------------------------- */int main (void) { struct sockaddr_un spun; int temp_sock_descriptor; int address_size; char *buf; int code; SockHandler *sh; /* Arrange the cleanup function for terminations via exit() */ atexit(cleanup); /* Arrange the cleanup function for abnormal terminations */ if (signal (SIGINT, termination_handler) == SIG_IGN) signal (SIGINT, SIG_IGN); if (signal (SIGHUP, termination_handler) == SIG_IGN) signal (SIGHUP, SIG_IGN); if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN); BmFile = g_strconcat(g_get_home_dir(), "/", ".dillo/bm.txt", NULL); g_print("bookmarks.dpi (v.13): accepting connections...\n"); /* some OSes may need this... */ address_size = sizeof(struct sockaddr_un); while (1) { temp_sock_descriptor = accept(STDIN_FILENO, (struct sockaddr *)&spun, &address_size); if (temp_sock_descriptor == -1) { perror("[accept]"); exit(1); } /* create the SockHandler structure */ sh = sock_handler_new(temp_sock_descriptor,temp_sock_descriptor,8*1024); while (1) { code = 1; if ((buf = sock_handler_read(sh)) != NULL) { /* Let's see what we fished... */ code = Bmsrv_parse_buf(sh, buf, strlen(buf)); } if (code == 1) exit(1); else if (code == 2) break; } sock_handler_close(sh); sock_handler_free(sh); }/*while*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -