📄 bookmarks.c
字号:
/* * Bookmarks server (chat version). * * NOTE: this code illustrates how to make a dpi-program. * * Copyright 2002-2006 Jorge Arellano Cid <jcid@dillo.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *//* Todo: this server is not assembling the received packets. * This means it currently expects dillo to send full dpi tags * within the socket; if that fails, everything stops. * This is not hard to fix, mainly is a matter of expecting the * final '>' of a tag. */#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <ctype.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/un.h>#include <time.h>#include <netdb.h>#include <fcntl.h>#include <signal.h>#include "../dpip/dpip.h"#include "dpiutil.h"#include <glib.h>/* This one is tricky, some sources state it should include the byte * for the terminating NULL, and others say it shouldn't. */# define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + strlen ((ptr)->sun_path))#define DOCTYPE \ "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"/* * Notes on character escaping: * - Basically things are saved unescaped and escaped when in memory. * - &<>"' are escaped in titles and sections and saved unescaped. * - ' is escaped as %27 in URLs and saved escaped. */typedef struct { gint key; gint section; gchar *url; gchar *title;} BmRec;typedef struct { gint section; gchar *title; gint o_sec; /* private, for normalization */} BmSec;/* * Local data */static char *Header = "Content-type: text/html\n\n";static char *BmFile = NULL;static time_t BmFileTimeStamp = 0;static GSList *B_bms = NULL;static gint bm_key = 0;static GSList *B_secs = NULL;static gint sec_key = 0;static int MODIFY_PAGE_NUM = 1;/* * Forward declarations *//* -- HTML templates ------------------------------------------------------- */char *mainpage_header =DOCTYPE"<html>\n""<head>\n""<title>Bookmarks</title>\n""</head>\n""<body bgcolor='#778899' link='black' vlink='brown'>\n""<table border='1' cellpadding='0' width='100%'>\n"" <tr><td>\n"" <table width='100%' bgcolor='#b4b4b4'>\n"" <tr>\n"" <td> Bookmarks::</td>\n"" <td width='100%' align='right'>\n"" [<a href='dpi:/bm/modify'>modify</a>]\n"" </td></tr>\n"" </table></td></tr>\n""</table>\n""<br>\n";char *modifypage_header =DOCTYPE"<html>\n""<head>\n""<title>Bookmarks</title>\n""</head>\n""<body bgcolor='#778899' link='black' vlink='brown'>\n""<table border='1' cellpadding='0' width='100%'>\n"" <tr><td>\n"" <table width='100%' bgcolor='#b4b4b4'>\n"" <tr>\n"" <td> Bookmarks :: modify</td></tr>\n"" </table></td></tr> \n""</table> \n""\n""<form>\n""<table width='100%' border='1' cellpadding='0'>\n"" <tr><td>\n"" <table width='100%' bgcolor='teal'>\n"" <tr>\n"" <td><b>Select an operation </b></td>\n"" <td><select name='operation'>\n"" <option value='none' selected>--\n"" <option value='delete'>Delete\n"" <option value='move'>Move\n"" <option value='modify'>Modify\n"" <option value='add_sec'>Add Section\n"" <option value='add_url'>Add URL\n"" </select></td>\n"" <td><b>, mark its operands, and </b></td>\n"" <td><input type='submit' name='submit' value='submit.'></td>\n"" <td width='100%'></td>\n"" </tr>\n"" </table></td></tr>\n""</table>\n";char *mainpage_sections_header ="<table border='1' cellpadding='0' cellspacing='20' width='100%'>\n"" <tr valign='top'>\n"" <td>\n"" <table bgcolor='#b4b4b4' border='2' cellpadding='4' cellspacing='1'>\n"" <tr><td>\n"" <table width='100%' bgcolor='#b4b4b4'>\n"" <tr><td><small>Sections:</small></td></tr></table></td></tr>\n";char *modifypage_sections_header ="<table border='1' cellpadding='0' cellspacing='20' width='100%'>\n"" <tr valign='top'>\n"" <td>\n"" <table bgcolor='#b4b4b4' border='1'>\n"" <tr><td>\n"" <table width='100%' bgcolor='#b4b4b4'>\n"" <tr><td><small>Sections:</small></td></tr></table></td></tr>\n";char *mainpage_sections_item =" <tr><td align='center'>\n"" <a href='#s%d'>%s</a></td></tr>\n";char *modifypage_sections_item =" <tr><td>\n"" <table width='100%%' bgcolor='#b4b4b4'cellspacing='0' cellpadding='0'>\n"" <tr align='center'>"" <td width='1%%'><input type='checkbox' name='s%d'></td>\n"" <td><a href='#s%d'>%s</a></td></tr></table></td></tr>\n";char *mainpage_sections_footer =" </table>\n";char *modifypage_sections_footer =" </table>\n";char *mainpage_middle1 =" </td>\n"" <td width='100%'>\n";char *modifypage_middle1 =" </td>\n"" <td width='100%'>\n";char *mainpage_section_card_header =" <a name='s%d'></a>\n"" <table bgcolor='#bfbfbf' width='100%%' cellspacing='2'>\n"" <tr>\n"" <td bgcolor='#bf0c0c'><font color='white'><b>\n"" %s </b></font></td>\n"" <td bgcolor='white' width='100%%'> </td></tr>\n";char *modifypage_section_card_header =" <a name='s%d'></a>\n"" <table bgcolor='#bfbfbf' width='100%%' cellspacing='2'>\n"" <tr>\n"" <td bgcolor='#bf0c0c'><font color='white'><b>\n"" %s </b></font></td>\n"" <td bgcolor='white' width='100%%'> </td></tr>\n";char *mainpage_section_card_item =" <tr><td colspan='2'>\n"" <a href='%s'>%s</a> </td></tr>\n";char *modifypage_section_card_item =" <tr>\n"" <td colspan='2'><input type='checkbox' name='url%d'>\n"" <a href='%s'>%s</a></td></tr>\n";char *mainpage_section_card_footer =" </table>\n"" <hr>\n";char *modifypage_section_card_footer =" </table>\n"" <hr>\n";char *mainpage_footer =" </td>\n"" </tr>\n""</table>\n""</body>\n""</html>\n";char *modifypage_footer =" </td>\n"" </tr>\n""</table>\n""</form>\n""</body>\n""</html>\n";/* ------------------------------------------------------------------------- */char *modifypage_add_section_page =DOCTYPE"<html>\n""<head>\n""<title>Bookmarks</title>\n""</head>\n""<body bgcolor='#778899' link='black' vlink='brown'>\n""<table border='1' cellpadding='0' width='100%'>\n"" <tr><td colspan='2'>\n"" <table bgcolor='#b4b4b4' width='100%'>\n"" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: add section\n"" </td></tr></table></td></tr>\n""</table>\n""<br>\n""<form>\n"" <input type='hidden' name='operation' value='add_section'>\n""<table border='1' width='100%'>\n"" <tr>\n"" <td bgcolor='olive'><b>New section:</b></td>\n"" <td bgcolor='white' width='100%'></td></tr>\n""</table>\n""<table width='100%' cellpadding='10'>\n""<tr><td>\n"" <table width='100%' bgcolor='teal'>\n"" <tr>\n"" <td>Title:</td>\n"" <td><input type='text' name='title' size='64'></td></tr>\n"" </table>\n"" </td></tr>\n""</table>\n""<table width='100%' cellpadding='4' border='0'>\n""<tr><td bgcolor='#a0a0a0'>\n"" <input type='submit' name='submit' value='submit.'></td></tr>\n""</table>\n""</form>\n""</body>\n""</html>\n""\n";/* ------------------------------------------------------------------------- */char *modifypage_update_header =DOCTYPE"<html>\n""<head>\n""<title>Bookmarks</title>\n""</head>\n""<body bgcolor='#778899' link='black' vlink='brown'>\n""<table border='1' cellpadding='0' width='100%'>\n"" <tr><td colspan='2'>\n"" <table bgcolor='#b4b4b4' width='100%'>\n"" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: update\n"" </td></tr></table></td></tr>\n""</table>\n""<br>\n""<form>\n""<input type='hidden' name='operation' value='modify2'>\n";char *modifypage_update_title ="<table border='1' width='100%%'>\n"" <tr>\n"" <td bgcolor='olive'><b>%s</b></td>\n"" <td bgcolor='white' width='100%%'></td></tr>\n""</table>\n";char *modifypage_update_item_header ="<table width='100%' cellpadding='10'>\n";char *modifypage_update_item ="<tr><td>\n"" <table width='100%%' bgcolor='teal'>\n"" <tr>\n"" <td>Title:</td>\n"" <td><input type='text' name='title%d' size='64'\n"" value='%s'></td></tr>\n"" <tr>\n"" <td>URL:</td>\n"" <td>%s</td></tr>\n"" </table>\n"" </td></tr>\n";char *modifypage_update_item2 ="<tr><td>\n"" <table width='100%%' bgcolor='teal'>\n"" <tr>\n"" <td>Title:</td>\n"" <td><input type='text' name='s%d' size='64'\n"" value='%s'></td></tr>\n"" </table>\n"" </td></tr>\n";char *modifypage_update_item_footer ="</table>\n";char *modifypage_update_footer ="<table width='100%' cellpadding='4' border='0'>\n""<tr><td bgcolor='#a0a0a0'>\n"" <input type='submit' name='submit' value='submit.'></td></tr>\n""</table>\n""</form>\n""</body>\n""</html>\n";/* ------------------------------------------------------------------------- */char *modifypage_add_url =DOCTYPE"<html>\n""<head>\n""<title>Bookmarks</title>\n""</head>\n""<body bgcolor='#778899' link='black' vlink='brown'>\n""<table border='1' cellpadding='0' width='100%'>\n"" <tr><td colspan='2'>\n"" <table bgcolor='#b4b4b4' width='100%'>\n"" <tr><td bgcolor='#b4b4b4'> Modify bookmarks:: add url\n"" </td></tr></table></td></tr>\n""</table>\n""<br>\n""<form>\n""<input type='hidden' name='operation' value='add_url2'>\n""<table border='1' width='100%'>\n"" <tr>\n"" <td bgcolor='olive'><b>Add url:</b></td>\n"" <td bgcolor='white' width='100%'></td></tr>\n""</table>\n""<table width='100%' cellpadding='10'>\n""<tr><td>\n"" <table width='100%' bgcolor='teal'>\n"" <tr>\n"" <td>Title:</td>\n"" <td><input type='text' name='title' size='64'></td></tr>\n"" <tr>\n"" <td>URL:</td>\n"" <td><input type='text' name='url' size='64'></td></tr>\n"" </table>\n"" </td></tr>\n""</table>\n""<table width='100%' cellpadding='4' border='0'>\n""<tr><td bgcolor='#a0a0a0'>\n"" <input type='submit' name='submit' value='submit.'></td></tr>\n""</table>\n""</form>\n""</body>\n""</html>\n";/* ------------------------------------------------------------------------- *//* * Return a new string with spaces changed with */static char *make_one_line_str(char *str){ char *new_str; int i, j, n; for (i = 0, n = 0; str[i]; ++i) if (str[i] == ' ') ++n; new_str = g_new(char, strlen(str) + 6*n + 1); new_str[0] = 0; for (i = 0, j = 0; str[i]; ++i) { if (str[i] == ' ') { strcpy(new_str + j, " "); j += 6; } else { new_str[j] = str[i]; new_str[++j] = 0; } } return new_str;}/* * Given an urlencoded string, return it to the original version. */static void Unencode_str(char *e_str){ char *p, *e; for (p = e = e_str; *e; e++, p++) { if (*e == '+') { *p = ' '; } else if (*e == '%') { if (g_strncasecmp(e, "%0D%0A", 6) == 0) { *p = '\n'; 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. */static char *Get_line(FILE *stream){ guint i, size = 64; int ch; 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 short message to dillo's status bar. */static int Bmsrv_dpi_send_status_msg(SockHandler *sh, char *str){ int st; char *d_cmd; d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_status_message", str); st = sock_handler_write_str(sh, d_cmd, 1); g_free(d_cmd); 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 */static 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 = Escape_uri_str(url, "'"); node->title = Escape_html_str(title); B_bms = g_slist_append(B_bms, node);}/* * Add a section */static void Bms_sec_add(char *title){ BmSec *node; node = g_new(BmSec, 1); node->section = sec_key++; node->title = Escape_html_str(title); B_secs = g_slist_append(B_secs, node);}/* * Delete a bookmark by its key */static 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 */static void Bms_sec_del(gint section){ GSList *list; BmSec *sec_node; BmRec *bm_node;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -