diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | about.c | 116 | ||||
-rw-r--r-- | settings.c | 1314 | ||||
-rw-r--r-- | whitelist.c | 427 | ||||
-rw-r--r-- | xxxterm.c | 1875 | ||||
-rw-r--r-- | xxxterm.h | 166 |
6 files changed, 2027 insertions, 1873 deletions
diff --git a/Makefile b/Makefile index 9e5c31b..0036495 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ BINDIR=${PREFIX}/bin PROG=xxxterm MAN=xxxterm.1 -SRCS= inspector.c marco.c about.c xxxterm.c +SRCS= inspector.c marco.c about.c whitelist.c settings.c xxxterm.c CFLAGS+= -O2 DEBUG= -ggdb3 LDADD= -lutil -lgcrypt diff --git a/about.c b/about.c index 65d0ae1..d4a7a28 100644 --- a/about.c +++ b/about.c @@ -402,6 +402,75 @@ cookie_show_wl(struct tab *t, struct karg *args) return (0); } +int +js_show_wl(struct tab *t, struct karg *args) +{ + args->i = XT_SHOW | XT_WL_PERSISTENT | XT_WL_SESSION; + wl_show(t, args, "JavaScript White List", &js_wl); + + return (0); +} + +int +cookie_cmd(struct tab *t, struct karg *args) +{ + if (args->i & XT_SHOW) + wl_show(t, args, "Cookie White List", &c_wl); + else if (args->i & XT_WL_TOGGLE) { + args->i |= XT_WL_RELOAD; + toggle_cwl(t, args); + } else if (args->i & XT_SAVE) { + args->i |= XT_WL_RELOAD; + wl_save(t, args, XT_WL_COOKIE); + } else if (args->i & XT_DELETE) + show_oops(t, "'cookie delete' currently unimplemented"); + + return (0); +} + +int +js_cmd(struct tab *t, struct karg *args) +{ + if (args->i & XT_SHOW) + wl_show(t, args, "JavaScript White List", &js_wl); + else if (args->i & XT_SAVE) { + args->i |= XT_WL_RELOAD; + wl_save(t, args, XT_WL_JAVASCRIPT); + } else if (args->i & XT_WL_TOGGLE) { + args->i |= XT_WL_RELOAD; + toggle_js(t, args); + } else if (args->i & XT_DELETE) + show_oops(t, "'js delete' currently unimplemented"); + + return (0); +} + +int +pl_show_wl(struct tab *t, struct karg *args) +{ + args->i = XT_SHOW | XT_WL_PERSISTENT | XT_WL_SESSION; + wl_show(t, args, "Plugin White List", &pl_wl); + + return (0); +} + +int +pl_cmd(struct tab *t, struct karg *args) +{ + if (args->i & XT_SHOW) + wl_show(t, args, "Plugin White List", &pl_wl); + else if (args->i & XT_SAVE) { + args->i |= XT_WL_RELOAD; + wl_save(t, args, XT_WL_PLUGIN); + } else if (args->i & XT_WL_TOGGLE) { + args->i |= XT_WL_RELOAD; + toggle_pl(t, args); + } else if (args->i & XT_DELETE) + show_oops(t, "'plugin delete' currently unimplemented"); + + return (0); +} + /* * cancel, remove, etc. downloads */ @@ -1322,3 +1391,50 @@ xtp_page_dl(struct tab *t, struct karg *args) return (0); } +int +startpage(struct tab *t, struct karg *args) +{ + char *page, *body, *b; + struct sp *s; + + if (t == NULL) + show_oops(NULL, "startpage invalid parameters"); + + body = g_strdup_printf("<b>Startup Exception(s):</b><p>"); + + TAILQ_FOREACH(s, &spl, entry) { + b = body; + body = g_strdup_printf("%s%s<br>", body, s->line); + g_free(b); + } + + page = get_html_page("Startup Exception", body, "", 0); + g_free(body); + + load_webkit_string(t, page, XT_URI_ABOUT_STARTPAGE); + g_free(page); + + return (0); +} + +void +startpage_add(const char *fmt, ...) +{ + va_list ap; + char *msg; + struct sp *s; + + if (fmt == NULL) + return; + + va_start(ap, fmt); + if (vasprintf(&msg, fmt, ap) == -1) + errx(1, "startpage_add failed"); + va_end(ap); + + s = g_malloc0(sizeof *s); + s->line = msg; + + TAILQ_INSERT_TAIL(&spl, s, entry); +} + diff --git a/settings.c b/settings.c new file mode 100644 index 0000000..8ff3ad9 --- /dev/null +++ b/settings.c @@ -0,0 +1,1314 @@ +/* + * Copyright (c) 2010, 2011 Marco Peereboom <marco@peereboom.us> + * Copyright (c) 2011 Stevan Andjelkovic <stevan@student.chalmers.se> + * Copyright (c) 2010, 2011 Edd Barrett <vext01@gmail.com> + * Copyright (c) 2011 Todd T. Fries <todd@fries.net> + * Copyright (c) 2011 Raphael Graf <r@undefined.ch> + * Copyright (c) 2011 Michal Mazurek <akfaew@jasminek.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xxxterm.h" + +/* globals */ +SoupURI *proxy_uri = NULL; +PangoFontDescription *cmd_font; +PangoFontDescription *oops_font; +PangoFontDescription *statusbar_font; +PangoFontDescription *tabbar_font; + +/* settings that require restart */ +int tabless = 0; /* allow only 1 tab */ +int enable_socket = 0; +int single_instance = 0; /* only allow one xxxterm to run */ +int fancy_bar = 1; /* fancy toolbar */ +int browser_mode = XT_BM_NORMAL; +int enable_localstorage = 1; +char *statusbar_elems = NULL; + +/* runtime settings */ +int show_tabs = 1; /* show tabs on notebook */ +int tab_style = XT_TABS_NORMAL; /* tab bar style */ +int show_url = 1; /* show url toolbar on notebook */ +int show_statusbar = 0; /* vimperator style status bar */ +int ctrl_click_focus = 0; /* ctrl click gets focus */ +int cookies_enabled = 1; /* enable cookies */ +int read_only_cookies = 0; /* enable to not write cookies */ +int enable_scripts = 1; +int enable_plugins = 1; +gfloat default_zoom_level = 1.0; +char default_script[PATH_MAX]; +int window_height = 768; +int window_width = 1024; +int icon_size = 2; /* 1 = smallest, 2+ = bigger */ +int refresh_interval = 10; /* download refresh interval */ +int enable_plugin_whitelist = 0; +int enable_cookie_whitelist = 0; +int enable_js_whitelist = 0; +int session_timeout = 3600; /* cookie session timeout */ +int cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; +char *ssl_ca_file = NULL; +char *resource_dir = NULL; +gboolean ssl_strict_certs = FALSE; +int append_next = 1; /* append tab after current tab */ +char *home = NULL; +char *search_string = NULL; +char *http_proxy = NULL; +char download_dir[PATH_MAX]; +char runtime_settings[PATH_MAX]; /* override of settings */ +int allow_volatile_cookies = 0; +int save_global_history = 0; /* save global history to disk */ +char *user_agent = NULL; +int save_rejected_cookies = 0; +int session_autosave = 0; +int guess_search = 0; +int dns_prefetch = FALSE; +gint max_connections = 25; +gint max_host_connections = 5; +gint enable_spell_checking = 0; +char *spell_check_languages = NULL; +int xterm_workaround = 0; +char *url_regex = NULL; +int history_autosave = 0; +char search_file[PATH_MAX]; +char command_file[PATH_MAX]; +char *encoding = NULL; +int autofocus_onload = 0; + +char *cmd_font_name = NULL; +char *oops_font_name = NULL; +char *statusbar_font_name = NULL; +char *tabbar_font_name = NULL; + +char *get_download_dir(struct settings *); +char *get_default_script(struct settings *); +char *get_runtime_dir(struct settings *); +char *get_tab_style(struct settings *); +char *get_work_dir(struct settings *); + +int add_cookie_wl(struct settings *, char *); +int add_js_wl(struct settings *, char *); +int add_pl_wl(struct settings *, char *); +int add_mime_type(struct settings *, char *); +int add_alias(struct settings *, char *); +int add_kb(struct settings *, char *); + +int set_download_dir(struct settings *, char *); +int set_default_script(struct settings *, char *); +int set_runtime_dir(struct settings *, char *); +int set_tab_style(struct settings *, char *); +int set_work_dir(struct settings *, char *); + +void walk_mime_type(struct settings *, void (*)(struct settings *, + char *, void *), void *); +void walk_alias(struct settings *, void (*)(struct settings *, + char *, void *), void *); +void walk_cookie_wl(struct settings *, void (*)(struct settings *, + char *, void *), void *); +void walk_js_wl(struct settings *, void (*)(struct settings *, + char *, void *), void *); +void walk_pl_wl(struct settings *, void (*)(struct settings *, + char *, void *), void *); +void walk_kb(struct settings *, void (*)(struct settings *, char *, + void *), void *); + +int +set_http_proxy(char *proxy) +{ + SoupURI *uri; + + if (proxy == NULL) + return (1); + + /* see if we need to clear it instead */ + if (strlen(proxy) == 0) { + setup_proxy(NULL); + return (0); + } + + uri = soup_uri_new(proxy); + if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) + return (1); + + setup_proxy(proxy); + + soup_uri_free(uri); + + return (0); +} + +struct special { + int (*set)(struct settings *, char *); + char *(*get)(struct settings *); + void (*walk)(struct settings *, + void (*cb)(struct settings *, char *, void *), + void *); +}; + +struct special s_browser_mode = { + set_browser_mode, + get_browser_mode, + NULL +}; + +struct special s_cookie = { + set_cookie_policy, + get_cookie_policy, + NULL +}; + +struct special s_alias = { + add_alias, + NULL, + walk_alias +}; + +struct special s_mime = { + add_mime_type, + NULL, + walk_mime_type +}; + +struct special s_js = { + add_js_wl, + NULL, + walk_js_wl +}; + +struct special s_pl = { + add_pl_wl, + NULL, + walk_pl_wl +}; + +struct special s_kb = { + add_kb, + NULL, + walk_kb +}; + +struct special s_cookie_wl = { + add_cookie_wl, + NULL, + walk_cookie_wl +}; + +struct special s_default_script = { + set_default_script, + get_default_script, + NULL +}; + +struct special s_download_dir = { + set_download_dir, + get_download_dir, + NULL +}; + +struct special s_work_dir = { + set_work_dir, + get_work_dir, + NULL +}; + +struct special s_tab_style = { + set_tab_style, + get_tab_style, + NULL +}; + +struct settings rs[] = { + { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL }, + { "append_next", XT_S_INT, 0, &append_next, NULL, NULL }, + { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL }, + { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode }, + { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie }, + { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL }, + { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL }, + { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level }, + { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script }, + { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir }, + { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL }, + { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL }, + { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL }, + { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL }, + { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL }, + { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL }, + { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL }, + { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL }, + { "encoding", XT_S_STR, 0, NULL, &encoding, NULL }, + { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL }, + { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL }, + { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL }, + { "home", XT_S_STR, 0, NULL, &home, NULL }, + { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy }, + { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL }, + { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL }, + { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL }, + { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL }, + { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL }, + { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL }, + { "search_string", XT_S_STR, 0, NULL, &search_string, NULL }, + { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL }, + { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL }, + { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL }, + { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL }, + { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL }, + { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL }, + { "show_url", XT_S_INT, 0, &show_url, NULL, NULL }, + { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL }, + { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL }, + { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL }, + { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL }, + { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL }, + { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style }, + { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL }, + { "user_agent", XT_S_STR, 0, NULL, &user_agent, NULL }, + { "window_height", XT_S_INT, 0, &window_height, NULL, NULL }, + { "window_width", XT_S_INT, 0, &window_width, NULL, NULL }, + { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir }, + { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL }, + + /* font settings */ + { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL }, + { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL }, + { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL }, + { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL }, + + /* runtime settings */ + { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias }, + { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl }, + { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js }, + { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb }, + { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime }, + { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl }, +}; + +size_t +get_settings_size(void) +{ + return (LENGTH(rs)); +} + +char * +get_setting_name(int i) +{ + if (i > LENGTH(rs)) + return (NULL); + return (rs[i].name); +} + +char * +get_as_string(struct settings *s) +{ + char *r = NULL; + + if (s == NULL) + return (NULL); + + if (s->s) { + if (s->s->get) + r = s->s->get(s); + else + warnx("get_as_string skip %s\n", s->name); + } else if (s->type == XT_S_INT) + r = g_strdup_printf("%d", *s->ival); + else if (s->type == XT_S_STR) + r = g_strdup(*s->sval); + else if (s->type == XT_S_FLOAT) + r = g_strdup_printf("%f", *s->fval); + else + r = g_strdup_printf("INVALID TYPE"); + + return (r); +} + +void +settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + int i; + char *s; + + for (i = 0; i < LENGTH(rs); i++) { + if (rs[i].s && rs[i].s->walk) + rs[i].s->walk(&rs[i], cb, cb_args); + else { + s = get_as_string(&rs[i]); + cb(&rs[i], s, cb_args); + g_free(s); + } + } +} + +int +set_browser_mode(struct settings *s, char *val) +{ + if (!strcmp(val, "whitelist")) { + browser_mode = XT_BM_WHITELIST; + allow_volatile_cookies = 0; + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + cookies_enabled = 1; + enable_cookie_whitelist = 1; + enable_plugin_whitelist = 1; + enable_plugins = 0; + read_only_cookies = 0; + save_rejected_cookies = 0; + session_timeout = 3600; + enable_scripts = 0; + enable_js_whitelist = 1; + enable_localstorage = 0; + } else if (!strcmp(val, "normal")) { + browser_mode = XT_BM_NORMAL; + allow_volatile_cookies = 0; + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + cookies_enabled = 1; + enable_cookie_whitelist = 0; + enable_plugin_whitelist = 0; + enable_plugins = 1; + read_only_cookies = 0; + save_rejected_cookies = 0; + session_timeout = 3600; + enable_scripts = 1; + enable_js_whitelist = 0; + enable_localstorage = 1; + } else if (!strcmp(val, "kiosk")) { + browser_mode = XT_BM_KIOSK; + allow_volatile_cookies = 0; + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + cookies_enabled = 1; + enable_cookie_whitelist = 0; + enable_plugin_whitelist = 0; + enable_plugins = 1; + read_only_cookies = 0; + save_rejected_cookies = 0; + session_timeout = 3600; + enable_scripts = 1; + enable_js_whitelist = 0; + enable_localstorage = 1; + show_tabs = 0; + tabless = 1; + } else + return (1); + + return (0); +} + +char * +get_browser_mode(struct settings *s) +{ + char *r = NULL; + + if (browser_mode == XT_BM_WHITELIST) + r = g_strdup("whitelist"); + else if (browser_mode == XT_BM_NORMAL) + r = g_strdup("normal"); + else if (browser_mode == XT_BM_KIOSK) + r = g_strdup("kiosk"); + else + return (NULL); + + return (r); +} + +int +set_cookie_policy(struct settings *s, char *val) +{ + if (!strcmp(val, "no3rdparty")) + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; + else if (!strcmp(val, "accept")) + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; + else if (!strcmp(val, "reject")) + cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER; + else + return (1); + + return (0); +} + +char * +get_cookie_policy(struct settings *s) +{ + char *r = NULL; + + if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY) + r = g_strdup("no3rdparty"); + else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS) + r = g_strdup("accept"); + else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER) + r = g_strdup("reject"); + else + return (NULL); + + return (r); +} + +char * +get_default_script(struct settings *s) +{ + if (default_script[0] == '\0') + return (0); + return (g_strdup(default_script)); +} + +int +set_default_script(struct settings *s, char *val) +{ + if (val[0] == '~') + snprintf(default_script, sizeof default_script, "%s/%s", + pwd->pw_dir, &val[1]); + else + strlcpy(default_script, val, sizeof default_script); + + return (0); +} + +char * +get_download_dir(struct settings *s) +{ + if (download_dir[0] == '\0') + return (0); + return (g_strdup(download_dir)); +} + +int +set_download_dir(struct settings *s, char *val) +{ + if (val[0] == '~') + snprintf(download_dir, sizeof download_dir, "%s/%s", + pwd->pw_dir, &val[1]); + else + strlcpy(download_dir, val, sizeof download_dir); + + return (0); +} + +int +add_alias(struct settings *s, char *line) +{ + char *l, *alias; + struct alias *a = NULL; + + if (s == NULL || line == NULL) { + show_oops(NULL, "add_alias invalid parameters"); + return (1); + } + + l = line; + a = g_malloc(sizeof(*a)); + + if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) { + show_oops(NULL, "add_alias: incomplete alias definition"); + goto bad; + } + if (strlen(alias) == 0 || strlen(l) == 0) { + show_oops(NULL, "add_alias: invalid alias definition"); + goto bad; + } + + a->a_name = g_strdup(alias); + a->a_uri = g_strdup(l); + + DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri); + + TAILQ_INSERT_TAIL(&aliases, a, entry); + + return (0); +bad: + if (a) + g_free(a); + return (1); +} + +void +walk_alias(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct alias *a; + char *str; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_alias invalid parameters"); + return; + } + + TAILQ_FOREACH(a, &aliases, entry) { + str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri); + cb(s, str, cb_args); + g_free(str); + } +} + +int +add_mime_type(struct settings *s, char *line) +{ + char *mime_type; + char *l; + struct mime_type *m = NULL; + int downloadfirst = 0; + + /* XXX this could be smarter */ + + if (line == NULL || strlen(line) == 0) { + show_oops(NULL, "add_mime_type invalid parameters"); + return (1); + } + + l = line; + if (*l == '@') { + downloadfirst = 1; + l++; + } + m = g_malloc(sizeof(*m)); + + if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) { + show_oops(NULL, "add_mime_type: invalid mime_type"); + goto bad; + } + if (mime_type[strlen(mime_type) - 1] == '*') { + mime_type[strlen(mime_type) - 1] = '\0'; + m->mt_default = 1; + } else + m->mt_default = 0; + + if (strlen(mime_type) == 0 || strlen(l) == 0) { + show_oops(NULL, "add_mime_type: invalid mime_type"); + goto bad; + } + + m->mt_type = g_strdup(mime_type); + m->mt_action = g_strdup(l); + m->mt_download = downloadfirst; + + DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n", + m->mt_type, m->mt_action, m->mt_default); + + TAILQ_INSERT_TAIL(&mtl, m, entry); + + return (0); +bad: + if (m) + g_free(m); + return (1); +} + +void +walk_mime_type(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct mime_type *m; + char *str; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_mime_type invalid parameters"); + return; + } + + TAILQ_FOREACH(m, &mtl, entry) { + str = g_strdup_printf("%s%s --> %s", + m->mt_type, + m->mt_default ? "*" : "", + m->mt_action); + cb(s, str, cb_args); + g_free(str); + } +} + +/* inherent to GTK not all keys will be caught at all times */ +/* XXX sort key bindings */ +struct key_binding keys[] = { + { "command_mode", 0, 0, GDK_Escape }, + { "insert_mode", 0, 0, GDK_i }, + { "cookiejar", MOD1, 0, GDK_j }, + { "downloadmgr", MOD1, 0, GDK_d }, + { "history", MOD1, 0, GDK_h }, + { "print", CTRL, 0, GDK_p }, + { "search", 0, 0, GDK_slash }, + { "searchb", 0, 0, GDK_question }, + { "statustoggle", CTRL, 0, GDK_n }, + { "command", 0, 0, GDK_colon }, + { "qa", CTRL, 0, GDK_q }, + { "restart", MOD1, 0, GDK_q }, + { "js toggle", CTRL, 0, GDK_j }, + { "cookie toggle", MOD1, 0, GDK_c }, + { "togglesrc", CTRL, 0, GDK_s }, + { "yankuri", 0, 0, GDK_y }, + { "pasteuricur", 0, 0, GDK_p }, + { "pasteurinew", 0, 0, GDK_P }, + { "toplevel toggle", 0, 0, GDK_F4 }, + { "help", 0, 0, GDK_F1 }, + { "run_script", MOD1, 0, GDK_r }, + + /* search */ + { "searchnext", 0, 0, GDK_n }, + { "searchprevious", 0, 0, GDK_N }, + + /* focus */ + { "focusaddress", 0, 0, GDK_F6 }, + { "focussearch", 0, 0, GDK_F7 }, + + /* hinting */ + { "hinting", 0, 0, GDK_f }, + { "hinting", 0, 0, GDK_period }, + { "hinting_newtab", SHFT, 0, GDK_F }, + { "hinting_newtab", 0, 0, GDK_comma }, + + /* custom stylesheet */ + { "userstyle", 0, 0, GDK_s }, + + /* navigation */ + { "goback", 0, 0, GDK_BackSpace }, + { "goback", MOD1, 0, GDK_Left }, + { "goforward", SHFT, 0, GDK_BackSpace }, + { "goforward", MOD1, 0, GDK_Right }, + { "reload", 0, 0, GDK_F5 }, + { "reload", CTRL, 0, GDK_r }, + { "reload", CTRL, 0, GDK_l }, + { "favorites", MOD1, 1, GDK_f }, + + /* vertical movement */ + { "scrolldown", 0, 0, GDK_j }, + { "scrolldown", 0, 0, GDK_Down }, + { "scrollup", 0, 0, GDK_Up }, + { "scrollup", 0, 0, GDK_k }, + { "scrollbottom", 0, 0, GDK_G }, + { "scrollbottom", 0, 0, GDK_End }, + { "scrolltop", 0, 0, GDK_Home }, + { "scrollpagedown", 0, 0, GDK_space }, + { "scrollpagedown", CTRL, 0, GDK_f }, + { "scrollhalfdown", CTRL, 0, GDK_d }, + { "scrollpagedown", 0, 0, GDK_Page_Down }, + { "scrollpageup", 0, 0, GDK_Page_Up }, + { "scrollpageup", CTRL, 0, GDK_b }, + { "scrollhalfup", CTRL, 0, GDK_u }, + /* horizontal movement */ + { "scrollright", 0, 0, GDK_l }, + { "scrollright", 0, 0, GDK_Right }, + { "scrollleft", 0, 0, GDK_Left }, + { "scrollleft", 0, 0, GDK_h }, + { "scrollfarright", 0, 0, GDK_dollar }, + { "scrollfarleft", 0, 0, GDK_0 }, + + /* tabs */ + { "tabnew", CTRL, 0, GDK_t }, + { "999tabnew", CTRL, 0, GDK_T }, + { "tabclose", CTRL, 1, GDK_w }, + { "tabundoclose", 0, 0, GDK_U }, + { "tabnext 1", CTRL, 0, GDK_1 }, + { "tabnext 2", CTRL, 0, GDK_2 }, + { "tabnext 3", CTRL, 0, GDK_3 }, + { "tabnext 4", CTRL, 0, GDK_4 }, + { "tabnext 5", CTRL, 0, GDK_5 }, + { "tabnext 6", CTRL, 0, GDK_6 }, + { "tabnext 7", CTRL, 0, GDK_7 }, + { "tabnext 8", CTRL, 0, GDK_8 }, + { "tabnext 9", CTRL, 0, GDK_9 }, + { "tabfirst", CTRL, 0, GDK_less }, + { "tablast", CTRL, 0, GDK_greater }, + { "tabprevious", CTRL, 0, GDK_Left }, + { "tabnext", CTRL, 0, GDK_Right }, + { "focusout", CTRL, 0, GDK_minus }, + { "focusin", CTRL, 0, GDK_plus }, + { "focusin", CTRL, 0, GDK_equal }, + { "focusreset", CTRL, 0, GDK_0 }, + + /* command aliases (handy when -S flag is used) */ + { "promptopen", 0, 0, GDK_F9 }, + { "promptopencurrent", 0, 0, GDK_F10 }, + { "prompttabnew", 0, 0, GDK_F11 }, + { "prompttabnewcurrent",0, 0, GDK_F12 }, +}; + +void +walk_kb(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct key_binding *k; + char str[1024]; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_kb invalid parameters"); + return; + } + + TAILQ_FOREACH(k, &kbl, entry) { + if (k->cmd == NULL) + continue; + str[0] = '\0'; + + /* sanity */ + if (gdk_keyval_name(k->key) == NULL) + continue; + + strlcat(str, k->cmd, sizeof str); + strlcat(str, ",", sizeof str); + + if (k->mask & GDK_SHIFT_MASK) + strlcat(str, "S-", sizeof str); + if (k->mask & GDK_CONTROL_MASK) + strlcat(str, "C-", sizeof str); + if (k->mask & GDK_MOD1_MASK) + strlcat(str, "M1-", sizeof str); + if (k->mask & GDK_MOD2_MASK) + strlcat(str, "M2-", sizeof str); + if (k->mask & GDK_MOD3_MASK) + strlcat(str, "M3-", sizeof str); + if (k->mask & GDK_MOD4_MASK) + strlcat(str, "M4-", sizeof str); + if (k->mask & GDK_MOD5_MASK) + strlcat(str, "M5-", sizeof str); + + strlcat(str, gdk_keyval_name(k->key), sizeof str); + cb(s, str, cb_args); + } +} + +void +init_keybindings(void) +{ + int i; + struct key_binding *k; + + for (i = 0; i < LENGTH(keys); i++) { + k = g_malloc0(sizeof *k); + k->cmd = keys[i].cmd; + k->mask = keys[i].mask; + k->use_in_entry = keys[i].use_in_entry; + k->key = keys[i].key; + TAILQ_INSERT_HEAD(&kbl, k, entry); + + DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n", + k->cmd ? k->cmd : "unnamed key"); + } +} + +void +keybinding_clearall(void) +{ + struct key_binding *k, *next; + + for (k = TAILQ_FIRST(&kbl); k; k = next) { + next = TAILQ_NEXT(k, entry); + if (k->cmd == NULL) + continue; + + DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n", + k->cmd ? k->cmd : "unnamed key"); + TAILQ_REMOVE(&kbl, k, entry); + g_free(k); + } +} + +int +keybinding_add(char *cmd, char *key, int use_in_entry) +{ + struct key_binding *k; + guint keyval, mask = 0; + int i; + + DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key); + + /* Keys which are to be used in entry have been prefixed with an + * exclamation mark. */ + if (use_in_entry) + key++; + + /* find modifier keys */ + if (strstr(key, "S-")) + mask |= GDK_SHIFT_MASK; + if (strstr(key, "C-")) + mask |= GDK_CONTROL_MASK; + if (strstr(key, "M1-")) + mask |= GDK_MOD1_MASK; + if (strstr(key, "M2-")) + mask |= GDK_MOD2_MASK; + if (strstr(key, "M3-")) + mask |= GDK_MOD3_MASK; + if (strstr(key, "M4-")) + mask |= GDK_MOD4_MASK; + if (strstr(key, "M5-")) + mask |= GDK_MOD5_MASK; + + /* find keyname */ + for (i = strlen(key) - 1; i > 0; i--) + if (key[i] == '-') + key = &key[i + 1]; + + /* validate keyname */ + keyval = gdk_keyval_from_name(key); + if (keyval == GDK_VoidSymbol) { + warnx("invalid keybinding name %s", key); + return (1); + } + /* must run this test too, gtk+ doesn't handle 10 for example */ + if (gdk_keyval_name(keyval) == NULL) { + warnx("invalid keybinding name %s", key); + return (1); + } + + /* Remove eventual dupes. */ + TAILQ_FOREACH(k, &kbl, entry) + if (k->key == keyval && k->mask == mask) { + TAILQ_REMOVE(&kbl, k, entry); + g_free(k); + break; + } + + /* add keyname */ + k = g_malloc0(sizeof *k); + k->cmd = g_strdup(cmd); + k->mask = mask; + k->use_in_entry = use_in_entry; + k->key = keyval; + + DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n", + k->cmd, + k->mask, + k->use_in_entry, + k->key); + DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n", + k->cmd, gdk_keyval_name(keyval)); + + TAILQ_INSERT_HEAD(&kbl, k, entry); + + return (0); +} + +int +add_kb(struct settings *s, char *entry) +{ + char *kb, *key; + + DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry); + + /* clearall is special */ + if (!strcmp(entry, "clearall")) { + keybinding_clearall(); + return (0); + } + + kb = strstr(entry, ","); + if (kb == NULL) + return (1); + *kb = '\0'; + key = kb + 1; + + return (keybinding_add(entry, key, key[0] == '!')); +} + +void +setup_proxy(char *uri) +{ + if (proxy_uri) { + g_object_set(session, "proxy_uri", NULL, (char *)NULL); + soup_uri_free(proxy_uri); + proxy_uri = NULL; + } + if (http_proxy) { + if (http_proxy != uri) { + g_free(http_proxy); + http_proxy = NULL; + } + } + + if (uri) { + http_proxy = g_strdup(uri); + DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri); + proxy_uri = soup_uri_new(http_proxy); + if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri))) + g_object_set(session, "proxy-uri", proxy_uri, + (char *)NULL); + } +} + +char * +get_tab_style(struct settings *s) +{ + if (tab_style == XT_TABS_NORMAL) + return (g_strdup("normal")); + else + return (g_strdup("compact")); +} + +int +set_tab_style(struct settings *s, char *val) +{ + if (!strcmp(val, "normal")) + tab_style = XT_TABS_NORMAL; + else if (!strcmp(val, "compact")) + tab_style = XT_TABS_COMPACT; + else + return (1); + + return (0); +} + +char * +get_work_dir(struct settings *s) +{ + if (work_dir[0] == '\0') + return (0); + return (g_strdup(work_dir)); +} + +int +set_work_dir(struct settings *s, char *val) +{ + if (val[0] == '~') + snprintf(work_dir, sizeof work_dir, "%s/%s", + pwd->pw_dir, &val[1]); + else + strlcpy(work_dir, val, sizeof work_dir); + + return (0); +} + +void +walk_cookie_wl(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct domain *d; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_cookie_wl invalid parameters"); + return; + } + + RB_FOREACH_REVERSE(d, domain_list, &c_wl) + cb(s, d->d, cb_args); +} + +void +walk_js_wl(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct domain *d; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_js_wl invalid parameters"); + return; + } + + RB_FOREACH_REVERSE(d, domain_list, &js_wl) + cb(s, d->d, cb_args); +} + +void +walk_pl_wl(struct settings *s, + void (*cb)(struct settings *, char *, void *), void *cb_args) +{ + struct domain *d; + + if (s == NULL || cb == NULL) { + show_oops(NULL, "walk_pl_wl invalid parameters"); + return; + } + + RB_FOREACH_REVERSE(d, domain_list, &pl_wl) + cb(s, d->d, cb_args); +} + +int +settings_add(char *var, char *val) +{ + int i, rv, *p; + gfloat *f; + char **s; + + /* get settings */ + for (i = 0, rv = 0; i < LENGTH(rs); i++) { + if (strcmp(var, rs[i].name)) + continue; + + if (rs[i].s) { + if (rs[i].s->set(&rs[i], val)) + errx(1, "invalid value for %s: %s", var, val); + rv = 1; + break; + } else + switch (rs[i].type) { + case XT_S_INT: + p = rs[i].ival; + *p = atoi(val); + rv = 1; + break; + case XT_S_STR: + s = rs[i].sval; + if (s == NULL) + errx(1, "invalid sval for %s", + rs[i].name); + if (*s) + g_free(*s); + *s = g_strdup(val); + rv = 1; + break; + case XT_S_FLOAT: + f = rs[i].fval; + *f = atof(val); + rv = 1; + break; + case XT_S_INVALID: + default: + errx(1, "invalid type for %s", var); + } + break; + } + return (rv); +} + +#define WS "\n= \t" +void +config_parse(char *filename, int runtime) +{ + FILE *config, *f; + char *line, *cp, *var, *val; + size_t len, lineno = 0; + int handled; + char file[PATH_MAX]; + struct stat sb; + + DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename); + + if (filename == NULL) + return; + + if (runtime && runtime_settings[0] != '\0') { + snprintf(file, sizeof file, "%s/%s", + work_dir, runtime_settings); + if (stat(file, &sb)) { + warnx("runtime file doesn't exist, creating it"); + if ((f = fopen(file, "w")) == NULL) + err(1, "runtime"); + fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n"); + fclose(f); + } + } else + strlcpy(file, filename, sizeof file); + + if ((config = fopen(file, "r")) == NULL) { + warn("config_parse: cannot open %s", filename); + return; + } + + for (;;) { + if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) + if (feof(config) || ferror(config)) + break; + + cp = line; + cp += (long)strspn(cp, WS); + if (cp[0] == '\0') { + /* empty line */ + free(line); + continue; + } + + if ((var = strsep(&cp, WS)) == NULL || cp == NULL) + startpage_add("invalid configuration file entry: %s", + line); + else { + cp += (long)strspn(cp, WS); + + if ((val = strsep(&cp, "\0")) == NULL) + break; + + DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n", + var, val); + handled = settings_add(var, val); + + if (handled == 0) + startpage_add("invalid configuration file entry" + ": %s=%s", var, val); + } + + free(line); + } + + fclose(config); +} + +struct settings_args { + char **body; + int i; +}; + +void +print_setting(struct settings *s, char *val, void *cb_args) +{ + char *tmp, *color; + struct settings_args *sa = cb_args; + + if (sa == NULL) + return; + + if (s->flags & XT_SF_RUNTIME) + color = "#22cc22"; + else + color = "#cccccc"; + + tmp = *sa->body; + *sa->body = g_strdup_printf( + "%s\n<tr>" + "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>" + "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>", + *sa->body, + color, + s->name, + color, + val + ); + g_free(tmp); + sa->i++; +} + +int +set_show(struct tab *t, struct karg *args) +{ + char *body, *page, *tmp; + int i = 1; + struct settings_args sa; + + bzero(&sa, sizeof sa); + sa.body = &body; + + /* body */ + body = g_strdup_printf("<div align='center'><table><tr>" + "<th align='left'>Setting</th>" + "<th align='left'>Value</th></tr>\n"); + + settings_walk(print_setting, &sa); + i = sa.i; + + /* small message if there are none */ + if (i == 1) { + tmp = body; + body = g_strdup_printf("%s\n<tr><td style='text-align:center'" + "colspan='2'>No settings</td></tr>\n", body); + g_free(tmp); + } + + tmp = body; + body = g_strdup_printf("%s</table></div>", body); + g_free(tmp); + + page = get_html_page("Settings", body, "", 0); + + g_free(body); + + load_webkit_string(t, page, XT_URI_ABOUT_SET); + + g_free(page); + + return (XT_CB_PASSTHROUGH); +} + +int +set(struct tab *t, struct karg *args) +{ + char *p, *val; + int i; + + if (args == NULL || args->s == NULL) + return (set_show(t, args)); + + /* strip spaces */ + p = g_strstrip(args->s); + + if (strlen(p) == 0) + return (set_show(t, args)); + + /* we got some sort of string */ + val = g_strrstr(p, "="); + if (val) { + *val++ = '\0'; + val = g_strchomp(val); + p = g_strchomp(p); + + for (i = 0; i < get_settings_size(); i++) { + if (strcmp(rs[i].name, p)) + continue; + + if (rs[i].activate) { + if (rs[i].activate(val)) + show_oops(t, "%s invalid value %s", + p, val); + else + show_oops(t, ":set %s = %s", p, val); + goto done; + } else { + show_oops(t, "not a runtime option: %s", p); + goto done; + } + } + show_oops(t, "unknown option: %s", p); + } else { + p = g_strchomp(p); + + for (i = 0; i < get_settings_size(); i++) { + if (strcmp(rs[i].name, p)) + continue; + + /* XXX this could use some cleanup */ + switch (rs[i].type) { + case XT_S_INT: + if (rs[i].ival) + show_oops(t, "%s = %d", + rs[i].name, *rs[i].ival); + else if (rs[i].s && rs[i].s->get) + show_oops(t, "%s = %s", + rs[i].name, + rs[i].s->get(&rs[i])); + else if (rs[i].s && rs[i].s->get == NULL) + show_oops(t, "%s = ...", rs[i].name); + else + show_oops(t, "%s = ", rs[i].name); + break; + case XT_S_FLOAT: + if (rs[i].fval) + show_oops(t, "%s = %f", + rs[i].name, *rs[i].fval); + else if (rs[i].s && rs[i].s->get) + show_oops(t, "%s = %s", + rs[i].name, + rs[i].s->get(&rs[i])); + else if (rs[i].s && rs[i].s->get == NULL) + show_oops(t, "%s = ...", rs[i].name); + else + show_oops(t, "%s = ", rs[i].name); + break; + case XT_S_STR: + if (rs[i].sval && *rs[i].sval) + show_oops(t, "%s = %s", + rs[i].name, *rs[i].sval); + else if (rs[i].s && rs[i].s->get) + show_oops(t, "%s = %s", + rs[i].name, + rs[i].s->get(&rs[i])); + else if (rs[i].s && rs[i].s->get == NULL) + show_oops(t, "%s = ...", rs[i].name); + else + show_oops(t, "%s = ", rs[i].name); + break; + default: + show_oops(t, "unknown type for %s", rs[i].name); + goto done; + } + + goto done; + } + show_oops(t, "unknown option: %s", p); + } +done: + return (XT_CB_PASSTHROUGH); +} + diff --git a/whitelist.c b/whitelist.c new file mode 100644 index 0000000..3eba38c --- /dev/null +++ b/whitelist.c @@ -0,0 +1,427 @@ +/* + * Copyright (c) 2010, 2011 Marco Peereboom <marco@peereboom.us> + * Copyright (c) 2011 Stevan Andjelkovic <stevan@student.chalmers.se> + * Copyright (c) 2010, 2011 Edd Barrett <vext01@gmail.com> + * Copyright (c) 2011 Todd T. Fries <todd@fries.net> + * Copyright (c) 2011 Raphael Graf <r@undefined.ch> + * Copyright (c) 2011 Michal Mazurek <akfaew@jasminek.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xxxterm.h" + +gchar * +find_domain(const gchar *s, int toplevel) +{ + SoupURI *uri; + gchar *ret, *p; + + if (s == NULL) + return (NULL); + + uri = soup_uri_new(s); + + if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) { + return (NULL); + } + + if (toplevel && !isdigit(uri->host[strlen(uri->host) - 1])) { + if ((p = strrchr(uri->host, '.')) != NULL) { + while(--p >= uri->host && *p != '.'); + p++; + } else + p = uri->host; + } else + p = uri->host; + + ret = g_strdup_printf(".%s", p); + + soup_uri_free(uri); + + return (ret); +} + +struct domain * +wl_find(const gchar *search, struct domain_list *wl) +{ + int i; + struct domain *d = NULL, dfind; + gchar *s = NULL; + + if (search == NULL || wl == NULL) + return (NULL); + if (strlen(search) < 2) + return (NULL); + + if (search[0] != '.') + s = g_strdup_printf(".%s", search); + else + s = g_strdup(search); + + for (i = strlen(s) - 1; i >= 0; i--) { + if (s[i] == '.') { + dfind.d = &s[i]; + d = RB_FIND(domain_list, wl, &dfind); + if (d) + goto done; + } + } + +done: + if (s) + g_free(s); + + return (d); +} + +int +wl_save(struct tab *t, struct karg *args, int list) +{ + char file[PATH_MAX], *lst_str = NULL; + FILE *f; + char *line = NULL, *lt = NULL, *dom = NULL; + size_t linelen; + const gchar *uri; + struct karg a; + struct domain *d; + GSList *cf; + SoupCookie *ci, *c; + + if (t == NULL || args == NULL) + return (1); + + if (runtime_settings[0] == '\0') + return (1); + + snprintf(file, sizeof file, "%s/%s", work_dir, runtime_settings); + if ((f = fopen(file, "r+")) == NULL) + return (1); + + switch (list) { + case XT_WL_JAVASCRIPT: + lst_str = "JavaScript"; + lt = g_strdup_printf("js_wl=%s", dom); + break; + case XT_WL_COOKIE: + lst_str = "Cookie"; + lt = g_strdup_printf("cookie_wl=%s", dom); + break; + case XT_WL_PLUGIN: + lst_str = "Plugin"; + lt = g_strdup_printf("pl_wl=%s", dom); + break; + default: + show_oops(t, "Invalid list id: %d", list); + return (1); + } + + uri = get_uri(t); + dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); + if (uri == NULL || dom == NULL || + webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { + show_oops(t, "Can't add domain to %s white list", lst_str); + goto done; + } + + while (!feof(f)) { + line = fparseln(f, &linelen, NULL, NULL, 0); + if (line == NULL) + continue; + if (!strcmp(line, lt)) + goto done; + free(line); + line = NULL; + } + + fprintf(f, "%s\n", lt); + + a.i = XT_WL_ENABLE; + a.i |= args->i; + switch (list) { + case XT_WL_JAVASCRIPT: + d = wl_find(dom, &js_wl); + if (!d) { + settings_add("js_wl", dom); + d = wl_find(dom, &js_wl); + } + toggle_js(t, &a); + break; + + case XT_WL_COOKIE: + d = wl_find(dom, &c_wl); + if (!d) { + settings_add("cookie_wl", dom); + d = wl_find(dom, &c_wl); + } + toggle_cwl(t, &a); + + /* find and add to persistent jar */ + cf = soup_cookie_jar_all_cookies(s_cookiejar); + for (;cf; cf = cf->next) { + ci = cf->data; + if (!strcmp(dom, ci->domain) || + !strcmp(&dom[1], ci->domain)) /* deal with leading . */ { + c = soup_cookie_copy(ci); + _soup_cookie_jar_add_cookie(p_cookiejar, c); + } + } + soup_cookies_free(cf); + break; + + case XT_WL_PLUGIN: + d = wl_find(dom, &pl_wl); + if (!d) { + settings_add("pl_wl", dom); + d = wl_find(dom, &pl_wl); + } + toggle_pl(t, &a); + break; + default: + abort(); /* can't happen */ + } + if (d) + d->handy = 1; + +done: + if (line) + free(line); + if (dom) + g_free(dom); + if (lt) + g_free(lt); + fclose(f); + + return (0); +} + +void +wl_add(char *str, struct domain_list *wl, int handy) +{ + struct domain *d; + int add_dot = 0; + char *p; + + if (str == NULL || wl == NULL || strlen(str) < 2) + return; + + DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str); + + /* treat *.moo.com the same as .moo.com */ + if (str[0] == '*' && str[1] == '.') + str = &str[1]; + else if (str[0] == '.') + str = &str[0]; + else + add_dot = 1; + + /* slice off port number */ + p = g_strrstr(str, ":"); + if (p) + *p = '\0'; + + d = g_malloc(sizeof *d); + if (add_dot) + d->d = g_strdup_printf(".%s", str); + else + d->d = g_strdup(str); + d->handy = handy; + + if (RB_INSERT(domain_list, wl, d)) + goto unwind; + + DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d); + return; +unwind: + if (d) { + if (d->d) + g_free(d->d); + g_free(d); + } +} + +int +add_cookie_wl(struct settings *s, char *entry) +{ + wl_add(entry, &c_wl, 1); + return (0); +} + +int +add_js_wl(struct settings *s, char *entry) +{ + wl_add(entry, &js_wl, 1 /* persistent */); + return (0); +} + +int +add_pl_wl(struct settings *s, char *entry) +{ + wl_add(entry, &pl_wl, 1 /* persistent */); + return (0); +} + +int +toggle_cwl(struct tab *t, struct karg *args) +{ + struct domain *d; + const gchar *uri; + char *dom = NULL; + int es; + + if (args == NULL) + return (1); + + uri = get_uri(t); + dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); + + if (uri == NULL || dom == NULL || + webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { + show_oops(t, "Can't toggle domain in cookie white list"); + goto done; + } + d = wl_find(dom, &c_wl); + + if (d == NULL) + es = 0; + else + es = 1; + + if (args->i & XT_WL_TOGGLE) + es = !es; + else if ((args->i & XT_WL_ENABLE) && es != 1) + es = 1; + else if ((args->i & XT_WL_DISABLE) && es != 0) + es = 0; + + if (es) + /* enable cookies for domain */ + wl_add(dom, &c_wl, 0); + else { + /* disable cookies for domain */ + if (d) + RB_REMOVE(domain_list, &c_wl, d); + } + + if (args->i & XT_WL_RELOAD) + webkit_web_view_reload(t->wv); + +done: + g_free(dom); + return (0); +} + +int +toggle_js(struct tab *t, struct karg *args) +{ + int es; + const gchar *uri; + struct domain *d; + char *dom = NULL; + + if (args == NULL) + return (1); + + g_object_get(G_OBJECT(t->settings), + "enable-scripts", &es, (char *)NULL); + if (args->i & XT_WL_TOGGLE) + es = !es; + else if ((args->i & XT_WL_ENABLE) && es != 1) + es = 1; + else if ((args->i & XT_WL_DISABLE) && es != 0) + es = 0; + else + return (1); + + uri = get_uri(t); + dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); + + if (uri == NULL || dom == NULL || + webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { + show_oops(t, "Can't toggle domain in JavaScript white list"); + goto done; + } + + if (es) { + button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY); + wl_add(dom, &js_wl, 0 /* session */); + } else { + d = wl_find(dom, &js_wl); + if (d) + RB_REMOVE(domain_list, &js_wl, d); + button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE); + } + g_object_set(G_OBJECT(t->settings), + "enable-scripts", es, (char *)NULL); + g_object_set(G_OBJECT(t->settings), + "javascript-can-open-windows-automatically", es, (char *)NULL); + webkit_web_view_set_settings(t->wv, t->settings); + + if (args->i & XT_WL_RELOAD) + webkit_web_view_reload(t->wv); +done: + if (dom) + g_free(dom); + return (0); +} + +int +toggle_pl(struct tab *t, struct karg *args) +{ + int es; + const gchar *uri; + struct domain *d; + char *dom = NULL; + + if (args == NULL) + return (1); + + g_object_get(G_OBJECT(t->settings), + "enable-plugins", &es, (char *)NULL); + if (args->i & XT_WL_TOGGLE) + es = !es; + else if ((args->i & XT_WL_ENABLE) && es != 1) + es = 1; + else if ((args->i & XT_WL_DISABLE) && es != 0) + es = 0; + else + return (1); + + uri = get_uri(t); + dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); + + if (uri == NULL || dom == NULL || + webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { + show_oops(t, "Can't toggle domain in plugins white list"); + goto done; + } + + if (es) + wl_add(dom, &pl_wl, 0 /* session */); + else { + d = wl_find(dom, &pl_wl); + if (d) + RB_REMOVE(domain_list, &pl_wl, d); + } + g_object_set(G_OBJECT(t->settings), + "enable-plugins", es, (char *)NULL); + webkit_web_view_set_settings(t->wv, t->settings); + + if (args->i & XT_WL_RELOAD) + webkit_web_view_reload(t->wv); +done: + if (dom) + g_free(dom); + return (0); +} + diff --git a/xxxterm.c b/xxxterm.c index 194f5fd..b885e1c 100644 --- a/xxxterm.c +++ b/xxxterm.c @@ -76,12 +76,6 @@ struct undo { }; TAILQ_HEAD(undo_tailq, undo); -struct sp { - char *line; - TAILQ_ENTRY(sp) entry; -}; -TAILQ_HEAD(sp_list, sp); - struct command_entry { char *line; TAILQ_ENTRY(command_entry) entry; @@ -202,10 +196,6 @@ TAILQ_HEAD(command_list, command_entry); #define XT_SES_DONOTHING (0) #define XT_SES_CLOSETABS (1) -#define XT_BM_NORMAL (0) -#define XT_BM_WHITELIST (1) -#define XT_BM_KIOSK (2) - #define XT_PREFIX (1<<0) #define XT_USERARG (1<<1) #define XT_URLARG (1<<2) @@ -218,142 +208,14 @@ TAILQ_HEAD(command_list, command_entry); #define XT_MODE_INSERT (0) #define XT_MODE_COMMAND (1) -#define XT_TABS_NORMAL 0 -#define XT_TABS_COMPACT 1 - #define XT_BUFCMD_SZ (8) #define XT_EJS_SHOW (1<<0) -/* mime types */ -struct mime_type { - char *mt_type; - char *mt_action; - int mt_default; - int mt_download; - TAILQ_ENTRY(mime_type) entry; -}; -TAILQ_HEAD(mime_type_list, mime_type); - -/* uri aliases */ -struct alias { - char *a_name; - char *a_uri; - TAILQ_ENTRY(alias) entry; -}; -TAILQ_HEAD(alias_list, alias); - -/* settings that require restart */ -int tabless = 0; /* allow only 1 tab */ -int enable_socket = 0; -int single_instance = 0; /* only allow one xxxterm to run */ -int fancy_bar = 1; /* fancy toolbar */ -int browser_mode = XT_BM_NORMAL; -int enable_localstorage = 1; -char *statusbar_elems = NULL; - -/* runtime settings */ -int show_tabs = 1; /* show tabs on notebook */ -int tab_style = XT_TABS_NORMAL; /* tab bar style */ -int show_url = 1; /* show url toolbar on notebook */ -int show_statusbar = 0; /* vimperator style status bar */ -int ctrl_click_focus = 0; /* ctrl click gets focus */ -int cookies_enabled = 1; /* enable cookies */ -int read_only_cookies = 0; /* enable to not write cookies */ -int enable_scripts = 1; -int enable_plugins = 1; -gfloat default_zoom_level = 1.0; -char default_script[PATH_MAX]; -int window_height = 768; -int window_width = 1024; -int icon_size = 2; /* 1 = smallest, 2+ = bigger */ -int refresh_interval = 10; /* download refresh interval */ -int enable_plugin_whitelist = 0; -int enable_cookie_whitelist = 0; -int enable_js_whitelist = 0; -int session_timeout = 3600; /* cookie session timeout */ -int cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; -char *ssl_ca_file = NULL; -char *resource_dir = NULL; -gboolean ssl_strict_certs = FALSE; -int append_next = 1; /* append tab after current tab */ -char *home = NULL; -char *search_string = NULL; -char *http_proxy = NULL; -char download_dir[PATH_MAX]; -char runtime_settings[PATH_MAX]; /* override of settings */ -int allow_volatile_cookies = 0; -int save_global_history = 0; /* save global history to disk */ -char *user_agent = NULL; -int save_rejected_cookies = 0; -int session_autosave = 0; -int guess_search = 0; -int dns_prefetch = FALSE; -gint max_connections = 25; -gint max_host_connections = 5; -gint enable_spell_checking = 0; -char *spell_check_languages = NULL; -int xterm_workaround = 0; -char *url_regex = NULL; -int history_autosave = 0; -char search_file[PATH_MAX]; -char command_file[PATH_MAX]; -char *encoding = NULL; -int autofocus_onload = 0; - -char *cmd_font_name = NULL; -char *oops_font_name = NULL; -char *statusbar_font_name = NULL; -char *tabbar_font_name = NULL; -PangoFontDescription *cmd_font; -PangoFontDescription *oops_font; -PangoFontDescription *statusbar_font; -PangoFontDescription *tabbar_font; -char *qmarks[XT_NOMARKS]; - -int btn_down; /* M1 down in any wv */ -regex_t url_re; /* guess_search regex */ - -struct settings; -struct key_binding; -int set_browser_mode(struct settings *, char *); -int set_cookie_policy(struct settings *, char *); -int set_download_dir(struct settings *, char *); -int set_default_script(struct settings *, char *); -int set_runtime_dir(struct settings *, char *); -int set_tab_style(struct settings *, char *); -int set_work_dir(struct settings *, char *); -int add_alias(struct settings *, char *); -int add_mime_type(struct settings *, char *); -int add_cookie_wl(struct settings *, char *); -int add_js_wl(struct settings *, char *); -int add_pl_wl(struct settings *, char *); -int add_kb(struct settings *, char *); -void button_set_stockid(GtkWidget *, char *); GtkWidget * create_button(char *, char *, int); -char *get_browser_mode(struct settings *); -char *get_cookie_policy(struct settings *); -char *get_download_dir(struct settings *); -char *get_default_script(struct settings *); -char *get_runtime_dir(struct settings *); -char *get_tab_style(struct settings *); -char *get_work_dir(struct settings *); void startpage_add(const char *, ...); -void walk_alias(struct settings *, void (*)(struct settings *, - char *, void *), void *); -void walk_cookie_wl(struct settings *, void (*)(struct settings *, - char *, void *), void *); -void walk_js_wl(struct settings *, void (*)(struct settings *, - char *, void *), void *); -void walk_pl_wl(struct settings *, void (*)(struct settings *, - char *, void *), void *); -void walk_kb(struct settings *, void (*)(struct settings *, char *, - void *), void *); -void walk_mime_type(struct settings *, void (*)(struct settings *, - char *, void *), void *); - void recalc_tabs(void); void recolor_compact_tabs(void); void set_current_tab(int page_num); @@ -362,168 +224,6 @@ void marks_clear(struct tab *t); int set_http_proxy(char *); -struct special { - int (*set)(struct settings *, char *); - char *(*get)(struct settings *); - void (*walk)(struct settings *, - void (*cb)(struct settings *, char *, void *), - void *); -}; - -struct special s_browser_mode = { - set_browser_mode, - get_browser_mode, - NULL -}; - -struct special s_cookie = { - set_cookie_policy, - get_cookie_policy, - NULL -}; - -struct special s_alias = { - add_alias, - NULL, - walk_alias -}; - -struct special s_mime = { - add_mime_type, - NULL, - walk_mime_type -}; - -struct special s_js = { - add_js_wl, - NULL, - walk_js_wl -}; - -struct special s_pl = { - add_pl_wl, - NULL, - walk_pl_wl -}; - -struct special s_kb = { - add_kb, - NULL, - walk_kb -}; - -struct special s_cookie_wl = { - add_cookie_wl, - NULL, - walk_cookie_wl -}; - -struct special s_default_script = { - set_default_script, - get_default_script, - NULL -}; - -struct special s_download_dir = { - set_download_dir, - get_download_dir, - NULL -}; - -struct special s_work_dir = { - set_work_dir, - get_work_dir, - NULL -}; - -struct special s_tab_style = { - set_tab_style, - get_tab_style, - NULL -}; - -struct settings { - char *name; - int type; -#define XT_S_INVALID (0) -#define XT_S_INT (1) -#define XT_S_STR (2) -#define XT_S_FLOAT (3) - uint32_t flags; -#define XT_SF_RESTART (1<<0) -#define XT_SF_RUNTIME (1<<1) - int *ival; - char **sval; - struct special *s; - gfloat *fval; - int (*activate)(char *); -} rs[] = { - { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL }, - { "append_next", XT_S_INT, 0, &append_next, NULL, NULL }, - { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL }, - { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode }, - { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie }, - { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL }, - { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL }, - { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level }, - { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script }, - { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir }, - { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL }, - { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL }, - { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL }, - { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL }, - { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL }, - { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL }, - { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL }, - { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL }, - { "encoding", XT_S_STR, 0, NULL, &encoding, NULL }, - { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL }, - { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL }, - { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL }, - { "home", XT_S_STR, 0, NULL, &home, NULL }, - { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy }, - { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL }, - { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL }, - { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL }, - { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL }, - { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL }, - { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL }, - { "search_string", XT_S_STR, 0, NULL, &search_string, NULL }, - { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL }, - { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL }, - { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL }, - { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL }, - { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL }, - { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL }, - { "show_url", XT_S_INT, 0, &show_url, NULL, NULL }, - { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL }, - { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL }, - { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL }, - { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL }, - { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL }, - { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style }, - { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL }, - { "user_agent", XT_S_STR, 0, NULL, &user_agent, NULL }, - { "window_height", XT_S_INT, 0, &window_height, NULL, NULL }, - { "window_width", XT_S_INT, 0, &window_width, NULL, NULL }, - { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir }, - { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL }, - - /* font settings */ - { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL }, - { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL }, - { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL }, - { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL }, - - /* runtime settings */ - { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias }, - { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl }, - { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js }, - { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb }, - { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime }, - { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl }, -}; - /* globals */ extern char *__progname; char **start_argv; @@ -554,6 +254,10 @@ char named_session[PATH_MAX]; GtkListStore *completion_model; GtkListStore *buffers_store; +char *qmarks[XT_NOMARKS]; +int btn_down; /* M1 down in any wv */ +regex_t url_re; /* guess_search regex */ + /* starts from 1 to catch atoi() failures when calling xtp_handle_dl() */ int next_download_id = 1; @@ -936,196 +640,11 @@ show_oops(struct tab *at, const char *fmt, ...) free(msg); } -char * -get_as_string(struct settings *s) -{ - char *r = NULL; - - if (s == NULL) - return (NULL); - - if (s->s) { - if (s->s->get) - r = s->s->get(s); - else - warnx("get_as_string skip %s\n", s->name); - } else if (s->type == XT_S_INT) - r = g_strdup_printf("%d", *s->ival); - else if (s->type == XT_S_STR) - r = g_strdup(*s->sval); - else if (s->type == XT_S_FLOAT) - r = g_strdup_printf("%f", *s->fval); - else - r = g_strdup_printf("INVALID TYPE"); - - return (r); -} - -void -settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - int i; - char *s; - - for (i = 0; i < LENGTH(rs); i++) { - if (rs[i].s && rs[i].s->walk) - rs[i].s->walk(&rs[i], cb, cb_args); - else { - s = get_as_string(&rs[i]); - cb(&rs[i], s, cb_args); - g_free(s); - } - } -} - -int -set_browser_mode(struct settings *s, char *val) -{ - if (!strcmp(val, "whitelist")) { - browser_mode = XT_BM_WHITELIST; - allow_volatile_cookies = 0; - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; - cookies_enabled = 1; - enable_cookie_whitelist = 1; - enable_plugin_whitelist = 1; - enable_plugins = 0; - read_only_cookies = 0; - save_rejected_cookies = 0; - session_timeout = 3600; - enable_scripts = 0; - enable_js_whitelist = 1; - enable_localstorage = 0; - } else if (!strcmp(val, "normal")) { - browser_mode = XT_BM_NORMAL; - allow_volatile_cookies = 0; - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; - cookies_enabled = 1; - enable_cookie_whitelist = 0; - enable_plugin_whitelist = 0; - enable_plugins = 1; - read_only_cookies = 0; - save_rejected_cookies = 0; - session_timeout = 3600; - enable_scripts = 1; - enable_js_whitelist = 0; - enable_localstorage = 1; - } else if (!strcmp(val, "kiosk")) { - browser_mode = XT_BM_KIOSK; - allow_volatile_cookies = 0; - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; - cookies_enabled = 1; - enable_cookie_whitelist = 0; - enable_plugin_whitelist = 0; - enable_plugins = 1; - read_only_cookies = 0; - save_rejected_cookies = 0; - session_timeout = 3600; - enable_scripts = 1; - enable_js_whitelist = 0; - enable_localstorage = 1; - show_tabs = 0; - tabless = 1; - } else - return (1); - - return (0); -} - -char * -get_browser_mode(struct settings *s) -{ - char *r = NULL; - - if (browser_mode == XT_BM_WHITELIST) - r = g_strdup("whitelist"); - else if (browser_mode == XT_BM_NORMAL) - r = g_strdup("normal"); - else if (browser_mode == XT_BM_KIOSK) - r = g_strdup("kiosk"); - else - return (NULL); - - return (r); -} - -int -set_cookie_policy(struct settings *s, char *val) -{ - if (!strcmp(val, "no3rdparty")) - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY; - else if (!strcmp(val, "accept")) - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS; - else if (!strcmp(val, "reject")) - cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER; - else - return (1); - - return (0); -} - -char * -get_cookie_policy(struct settings *s) -{ - char *r = NULL; - - if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY) - r = g_strdup("no3rdparty"); - else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS) - r = g_strdup("accept"); - else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER) - r = g_strdup("reject"); - else - return (NULL); - - return (r); -} - -char * -get_default_script(struct settings *s) -{ - if (default_script[0] == '\0') - return (0); - return (g_strdup(default_script)); -} - -int -set_default_script(struct settings *s, char *val) -{ - if (val[0] == '~') - snprintf(default_script, sizeof default_script, "%s/%s", - pwd->pw_dir, &val[1]); - else - strlcpy(default_script, val, sizeof default_script); - - return (0); -} - -char * -get_download_dir(struct settings *s) -{ - if (download_dir[0] == '\0') - return (0); - return (g_strdup(download_dir)); -} - -int -set_download_dir(struct settings *s, char *val) -{ - if (val[0] == '~') - snprintf(download_dir, sizeof download_dir, "%s/%s", - pwd->pw_dir, &val[1]); - else - strlcpy(download_dir, val, sizeof download_dir); - - return (0); -} - char work_dir[PATH_MAX]; char certs_dir[PATH_MAX]; char cache_dir[PATH_MAX]; char sessions_dir[PATH_MAX]; char cookie_file[PATH_MAX]; -SoupURI *proxy_uri = NULL; SoupSession *session; SoupCookieJar *s_cookiejar; SoupCookieJar *p_cookiejar; @@ -1156,48 +675,6 @@ domain_rb_cmp(struct domain *d1, struct domain *d2) } RB_GENERATE(domain_list, domain, entry, domain_rb_cmp); -char * -get_work_dir(struct settings *s) -{ - if (work_dir[0] == '\0') - return (0); - return (g_strdup(work_dir)); -} - -int -set_work_dir(struct settings *s, char *val) -{ - if (val[0] == '~') - snprintf(work_dir, sizeof work_dir, "%s/%s", - pwd->pw_dir, &val[1]); - else - strlcpy(work_dir, val, sizeof work_dir); - - return (0); -} - -char * -get_tab_style(struct settings *s) -{ - if (tab_style == XT_TABS_NORMAL) - return (g_strdup("normal")); - else - return (g_strdup("compact")); -} - -int -set_tab_style(struct settings *s, char *val) -{ - if (!strcmp(val, "normal")) - tab_style = XT_TABS_NORMAL; - else if (!strcmp(val, "compact")) - tab_style = XT_TABS_COMPACT; - else - return (1); - - return (0); -} - int download_rb_cmp(struct download *e1, struct download *e2) { @@ -1246,25 +723,6 @@ print_cookie(char *msg, SoupCookie *c) DNPRINTF(XT_D_COOKIE, "====================================\n"); } -void -walk_alias(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct alias *a; - char *str; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_alias invalid parameters"); - return; - } - - TAILQ_FOREACH(a, &aliases, entry) { - str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri); - cb(s, str, cb_args); - g_free(str); - } -} - char * match_alias(char *url_in) { @@ -1430,96 +888,6 @@ notitle: return set; } -int -add_alias(struct settings *s, char *line) -{ - char *l, *alias; - struct alias *a = NULL; - - if (s == NULL || line == NULL) { - show_oops(NULL, "add_alias invalid parameters"); - return (1); - } - - l = line; - a = g_malloc(sizeof(*a)); - - if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) { - show_oops(NULL, "add_alias: incomplete alias definition"); - goto bad; - } - if (strlen(alias) == 0 || strlen(l) == 0) { - show_oops(NULL, "add_alias: invalid alias definition"); - goto bad; - } - - a->a_name = g_strdup(alias); - a->a_uri = g_strdup(l); - - DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri); - - TAILQ_INSERT_TAIL(&aliases, a, entry); - - return (0); -bad: - if (a) - g_free(a); - return (1); -} - -int -add_mime_type(struct settings *s, char *line) -{ - char *mime_type; - char *l; - struct mime_type *m = NULL; - int downloadfirst = 0; - - /* XXX this could be smarter */ - - if (line == NULL || strlen(line) == 0) { - show_oops(NULL, "add_mime_type invalid parameters"); - return (1); - } - - l = line; - if (*l == '@') { - downloadfirst = 1; - l++; - } - m = g_malloc(sizeof(*m)); - - if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) { - show_oops(NULL, "add_mime_type: invalid mime_type"); - goto bad; - } - if (mime_type[strlen(mime_type) - 1] == '*') { - mime_type[strlen(mime_type) - 1] = '\0'; - m->mt_default = 1; - } else - m->mt_default = 0; - - if (strlen(mime_type) == 0 || strlen(l) == 0) { - show_oops(NULL, "add_mime_type: invalid mime_type"); - goto bad; - } - - m->mt_type = g_strdup(mime_type); - m->mt_action = g_strdup(l); - m->mt_download = downloadfirst; - - DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n", - m->mt_type, m->mt_action, m->mt_default); - - TAILQ_INSERT_TAIL(&mtl, m, entry); - - return (0); -bad: - if (m) - g_free(m); - return (1); -} - struct mime_type * find_mime_type(char *mime_type) { @@ -1542,172 +910,6 @@ find_mime_type(char *mime_type) return (rv); } -void -walk_mime_type(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct mime_type *m; - char *str; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_mime_type invalid parameters"); - return; - } - - TAILQ_FOREACH(m, &mtl, entry) { - str = g_strdup_printf("%s%s --> %s", - m->mt_type, - m->mt_default ? "*" : "", - m->mt_action); - cb(s, str, cb_args); - g_free(str); - } -} - -void -wl_add(char *str, struct domain_list *wl, int handy) -{ - struct domain *d; - int add_dot = 0; - char *p; - - if (str == NULL || wl == NULL || strlen(str) < 2) - return; - - DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str); - - /* treat *.moo.com the same as .moo.com */ - if (str[0] == '*' && str[1] == '.') - str = &str[1]; - else if (str[0] == '.') - str = &str[0]; - else - add_dot = 1; - - /* slice off port number */ - p = g_strrstr(str, ":"); - if (p) - *p = '\0'; - - d = g_malloc(sizeof *d); - if (add_dot) - d->d = g_strdup_printf(".%s", str); - else - d->d = g_strdup(str); - d->handy = handy; - - if (RB_INSERT(domain_list, wl, d)) - goto unwind; - - DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d); - return; -unwind: - if (d) { - if (d->d) - g_free(d->d); - g_free(d); - } -} - -int -add_cookie_wl(struct settings *s, char *entry) -{ - wl_add(entry, &c_wl, 1); - return (0); -} - -void -walk_cookie_wl(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct domain *d; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_cookie_wl invalid parameters"); - return; - } - - RB_FOREACH_REVERSE(d, domain_list, &c_wl) - cb(s, d->d, cb_args); -} - -void -walk_js_wl(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct domain *d; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_js_wl invalid parameters"); - return; - } - - RB_FOREACH_REVERSE(d, domain_list, &js_wl) - cb(s, d->d, cb_args); -} - -int -add_js_wl(struct settings *s, char *entry) -{ - wl_add(entry, &js_wl, 1 /* persistent */); - return (0); -} - -void -walk_pl_wl(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct domain *d; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_pl_wl invalid parameters"); - return; - } - - RB_FOREACH_REVERSE(d, domain_list, &pl_wl) - cb(s, d->d, cb_args); -} - -int -add_pl_wl(struct settings *s, char *entry) -{ - wl_add(entry, &pl_wl, 1 /* persistent */); - return (0); -} - -struct domain * -wl_find(const gchar *search, struct domain_list *wl) -{ - int i; - struct domain *d = NULL, dfind; - gchar *s = NULL; - - if (search == NULL || wl == NULL) - return (NULL); - if (strlen(search) < 2) - return (NULL); - - if (search[0] != '.') - s = g_strdup_printf(".%s", search); - else - s = g_strdup(search); - - for (i = strlen(s) - 1; i >= 0; i--) { - if (s[i] == '.') { - dfind.d = &s[i]; - d = RB_FIND(domain_list, wl, &dfind); - if (d) - goto done; - } - } - -done: - if (s) - g_free(s); - - return (d); -} - struct domain * wl_find_uri(const gchar *s, struct domain_list *wl) { @@ -1739,125 +941,6 @@ wl_find_uri(const gchar *s, struct domain_list *wl) return (NULL); } -int -settings_add(char *var, char *val) -{ - int i, rv, *p; - gfloat *f; - char **s; - - /* get settings */ - for (i = 0, rv = 0; i < LENGTH(rs); i++) { - if (strcmp(var, rs[i].name)) - continue; - - if (rs[i].s) { - if (rs[i].s->set(&rs[i], val)) - errx(1, "invalid value for %s: %s", var, val); - rv = 1; - break; - } else - switch (rs[i].type) { - case XT_S_INT: - p = rs[i].ival; - *p = atoi(val); - rv = 1; - break; - case XT_S_STR: - s = rs[i].sval; - if (s == NULL) - errx(1, "invalid sval for %s", - rs[i].name); - if (*s) - g_free(*s); - *s = g_strdup(val); - rv = 1; - break; - case XT_S_FLOAT: - f = rs[i].fval; - *f = atof(val); - rv = 1; - break; - case XT_S_INVALID: - default: - errx(1, "invalid type for %s", var); - } - break; - } - return (rv); -} - -#define WS "\n= \t" -void -config_parse(char *filename, int runtime) -{ - FILE *config, *f; - char *line, *cp, *var, *val; - size_t len, lineno = 0; - int handled; - char file[PATH_MAX]; - struct stat sb; - - DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename); - - if (filename == NULL) - return; - - if (runtime && runtime_settings[0] != '\0') { - snprintf(file, sizeof file, "%s/%s", - work_dir, runtime_settings); - if (stat(file, &sb)) { - warnx("runtime file doesn't exist, creating it"); - if ((f = fopen(file, "w")) == NULL) - err(1, "runtime"); - fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n"); - fclose(f); - } - } else - strlcpy(file, filename, sizeof file); - - if ((config = fopen(file, "r")) == NULL) { - warn("config_parse: cannot open %s", filename); - return; - } - - for (;;) { - if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) - if (feof(config) || ferror(config)) - break; - - cp = line; - cp += (long)strspn(cp, WS); - if (cp[0] == '\0') { - /* empty line */ - free(line); - continue; - } - - if ((var = strsep(&cp, WS)) == NULL || cp == NULL) - startpage_add("invalid configuration file entry: %s", - line); - else { - cp += (long)strspn(cp, WS); - - if ((val = strsep(&cp, "\0")) == NULL) - break; - - DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n", - var, val); - handled = settings_add(var, val); - - if (handled == 0) - startpage_add("invalid configuration file entry" - ": %s=%s", var, val); - } - - free(line); - } - - fclose(config); -} - char * js_ref_to_string(JSContextRef context, JSValueRef ref) { @@ -2376,191 +1459,6 @@ done: return (0); } -gchar * -find_domain(const gchar *s, int toplevel) -{ - SoupURI *uri; - gchar *ret, *p; - - if (s == NULL) - return (NULL); - - uri = soup_uri_new(s); - - if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) { - return (NULL); - } - - if (toplevel && !isdigit(uri->host[strlen(uri->host) - 1])) { - if ((p = strrchr(uri->host, '.')) != NULL) { - while(--p >= uri->host && *p != '.'); - p++; - } else - p = uri->host; - } else - p = uri->host; - - ret = g_strdup_printf(".%s", p); - - soup_uri_free(uri); - - return (ret); -} - -int -toggle_cwl(struct tab *t, struct karg *args) -{ - struct domain *d; - const gchar *uri; - char *dom = NULL; - int es; - - if (args == NULL) - return (1); - - uri = get_uri(t); - dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); - - if (uri == NULL || dom == NULL || - webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { - show_oops(t, "Can't toggle domain in cookie white list"); - goto done; - } - d = wl_find(dom, &c_wl); - - if (d == NULL) - es = 0; - else - es = 1; - - if (args->i & XT_WL_TOGGLE) - es = !es; - else if ((args->i & XT_WL_ENABLE) && es != 1) - es = 1; - else if ((args->i & XT_WL_DISABLE) && es != 0) - es = 0; - - if (es) - /* enable cookies for domain */ - wl_add(dom, &c_wl, 0); - else { - /* disable cookies for domain */ - if (d) - RB_REMOVE(domain_list, &c_wl, d); - } - - if (args->i & XT_WL_RELOAD) - webkit_web_view_reload(t->wv); - -done: - g_free(dom); - return (0); -} - -int -toggle_js(struct tab *t, struct karg *args) -{ - int es; - const gchar *uri; - struct domain *d; - char *dom = NULL; - - if (args == NULL) - return (1); - - g_object_get(G_OBJECT(t->settings), - "enable-scripts", &es, (char *)NULL); - if (args->i & XT_WL_TOGGLE) - es = !es; - else if ((args->i & XT_WL_ENABLE) && es != 1) - es = 1; - else if ((args->i & XT_WL_DISABLE) && es != 0) - es = 0; - else - return (1); - - uri = get_uri(t); - dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); - - if (uri == NULL || dom == NULL || - webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { - show_oops(t, "Can't toggle domain in JavaScript white list"); - goto done; - } - - if (es) { - button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY); - wl_add(dom, &js_wl, 0 /* session */); - } else { - d = wl_find(dom, &js_wl); - if (d) - RB_REMOVE(domain_list, &js_wl, d); - button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE); - } - g_object_set(G_OBJECT(t->settings), - "enable-scripts", es, (char *)NULL); - g_object_set(G_OBJECT(t->settings), - "javascript-can-open-windows-automatically", es, (char *)NULL); - webkit_web_view_set_settings(t->wv, t->settings); - - if (args->i & XT_WL_RELOAD) - webkit_web_view_reload(t->wv); -done: - if (dom) - g_free(dom); - return (0); -} - -int -toggle_pl(struct tab *t, struct karg *args) -{ - int es; - const gchar *uri; - struct domain *d; - char *dom = NULL; - - if (args == NULL) - return (1); - - g_object_get(G_OBJECT(t->settings), - "enable-plugins", &es, (char *)NULL); - if (args->i & XT_WL_TOGGLE) - es = !es; - else if ((args->i & XT_WL_ENABLE) && es != 1) - es = 1; - else if ((args->i & XT_WL_DISABLE) && es != 0) - es = 0; - else - return (1); - - uri = get_uri(t); - dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); - - if (uri == NULL || dom == NULL || - webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { - show_oops(t, "Can't toggle domain in plugins white list"); - goto done; - } - - if (es) - wl_add(dom, &pl_wl, 0 /* session */); - else { - d = wl_find(dom, &pl_wl); - if (d) - RB_REMOVE(domain_list, &pl_wl, d); - } - g_object_set(G_OBJECT(t->settings), - "enable-plugins", es, (char *)NULL); - webkit_web_view_set_settings(t->wv, t->settings); - - if (args->i & XT_WL_RELOAD) - webkit_web_view_reload(t->wv); -done: - if (dom) - g_free(dom); - return (0); -} - void js_toggle_cb(GtkWidget *w, struct tab *t) { @@ -2629,53 +1527,6 @@ focus(struct tab *t, struct karg *args) } int -startpage(struct tab *t, struct karg *args) -{ - char *page, *body, *b; - struct sp *s; - - if (t == NULL) - show_oops(NULL, "startpage invalid parameters"); - - body = g_strdup_printf("<b>Startup Exception(s):</b><p>"); - - TAILQ_FOREACH(s, &spl, entry) { - b = body; - body = g_strdup_printf("%s%s<br>", body, s->line); - g_free(b); - } - - page = get_html_page("Startup Exception", body, "", 0); - g_free(body); - - load_webkit_string(t, page, XT_URI_ABOUT_STARTPAGE); - g_free(page); - - return (0); -} - -void -startpage_add(const char *fmt, ...) -{ - va_list ap; - char *msg; - struct sp *s; - - if (fmt == NULL) - return; - - va_start(ap, fmt); - if (vasprintf(&msg, fmt, ap) == -1) - errx(1, "startpage_add failed"); - va_end(ap); - - s = g_malloc0(sizeof *s); - s->line = msg; - - TAILQ_INSERT_TAIL(&spl, s, entry); -} - -int connect_socket_from_uri(const gchar *uri, const gchar **error_str, char *domain, size_t domain_sz) { @@ -3162,199 +2013,6 @@ wl_show(struct tab *t, struct karg *args, char *title, struct domain_list *wl) return (0); } -#define XT_WL_INVALID (0) -#define XT_WL_JAVASCRIPT (1) -#define XT_WL_COOKIE (2) -#define XT_WL_PLUGIN (3) -int -wl_save(struct tab *t, struct karg *args, int list) -{ - char file[PATH_MAX], *lst_str = NULL; - FILE *f; - char *line = NULL, *lt = NULL, *dom = NULL; - size_t linelen; - const gchar *uri; - struct karg a; - struct domain *d; - GSList *cf; - SoupCookie *ci, *c; - - if (t == NULL || args == NULL) - return (1); - - if (runtime_settings[0] == '\0') - return (1); - - snprintf(file, sizeof file, "%s/%s", work_dir, runtime_settings); - if ((f = fopen(file, "r+")) == NULL) - return (1); - - switch (list) { - case XT_WL_JAVASCRIPT: - lst_str = "JavaScript"; - lt = g_strdup_printf("js_wl=%s", dom); - break; - case XT_WL_COOKIE: - lst_str = "Cookie"; - lt = g_strdup_printf("cookie_wl=%s", dom); - break; - case XT_WL_PLUGIN: - lst_str = "Plugin"; - lt = g_strdup_printf("pl_wl=%s", dom); - break; - default: - show_oops(t, "Invalid list id: %d", list); - return (1); - } - - uri = get_uri(t); - dom = find_domain(uri, args->i & XT_WL_TOPLEVEL); - if (uri == NULL || dom == NULL || - webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) { - show_oops(t, "Can't add domain to %s white list", lst_str); - goto done; - } - - while (!feof(f)) { - line = fparseln(f, &linelen, NULL, NULL, 0); - if (line == NULL) - continue; - if (!strcmp(line, lt)) - goto done; - free(line); - line = NULL; - } - - fprintf(f, "%s\n", lt); - - a.i = XT_WL_ENABLE; - a.i |= args->i; - switch (list) { - case XT_WL_JAVASCRIPT: - d = wl_find(dom, &js_wl); - if (!d) { - settings_add("js_wl", dom); - d = wl_find(dom, &js_wl); - } - toggle_js(t, &a); - break; - - case XT_WL_COOKIE: - d = wl_find(dom, &c_wl); - if (!d) { - settings_add("cookie_wl", dom); - d = wl_find(dom, &c_wl); - } - toggle_cwl(t, &a); - - /* find and add to persistent jar */ - cf = soup_cookie_jar_all_cookies(s_cookiejar); - for (;cf; cf = cf->next) { - ci = cf->data; - if (!strcmp(dom, ci->domain) || - !strcmp(&dom[1], ci->domain)) /* deal with leading . */ { - c = soup_cookie_copy(ci); - _soup_cookie_jar_add_cookie(p_cookiejar, c); - } - } - soup_cookies_free(cf); - break; - - case XT_WL_PLUGIN: - d = wl_find(dom, &pl_wl); - if (!d) { - settings_add("pl_wl", dom); - d = wl_find(dom, &pl_wl); - } - toggle_pl(t, &a); - break; - default: - abort(); /* can't happen */ - } - if (d) - d->handy = 1; - -done: - if (line) - free(line); - if (dom) - g_free(dom); - if (lt) - g_free(lt); - fclose(f); - - return (0); -} - -int -js_show_wl(struct tab *t, struct karg *args) -{ - args->i = XT_SHOW | XT_WL_PERSISTENT | XT_WL_SESSION; - wl_show(t, args, "JavaScript White List", &js_wl); - - return (0); -} - -int -cookie_cmd(struct tab *t, struct karg *args) -{ - if (args->i & XT_SHOW) - wl_show(t, args, "Cookie White List", &c_wl); - else if (args->i & XT_WL_TOGGLE) { - args->i |= XT_WL_RELOAD; - toggle_cwl(t, args); - } else if (args->i & XT_SAVE) { - args->i |= XT_WL_RELOAD; - wl_save(t, args, XT_WL_COOKIE); - } else if (args->i & XT_DELETE) - show_oops(t, "'cookie delete' currently unimplemented"); - - return (0); -} - -int -js_cmd(struct tab *t, struct karg *args) -{ - if (args->i & XT_SHOW) - wl_show(t, args, "JavaScript White List", &js_wl); - else if (args->i & XT_SAVE) { - args->i |= XT_WL_RELOAD; - wl_save(t, args, XT_WL_JAVASCRIPT); - } else if (args->i & XT_WL_TOGGLE) { - args->i |= XT_WL_RELOAD; - toggle_js(t, args); - } else if (args->i & XT_DELETE) - show_oops(t, "'js delete' currently unimplemented"); - - return (0); -} - -int -pl_show_wl(struct tab *t, struct karg *args) -{ - args->i = XT_SHOW | XT_WL_PERSISTENT | XT_WL_SESSION; - wl_show(t, args, "Plugin White List", &pl_wl); - - return (0); -} - -int -pl_cmd(struct tab *t, struct karg *args) -{ - if (args->i & XT_SHOW) - wl_show(t, args, "Plugin White List", &pl_wl); - else if (args->i & XT_SAVE) { - args->i |= XT_WL_RELOAD; - wl_save(t, args, XT_WL_PLUGIN); - } else if (args->i & XT_WL_TOGGLE) { - args->i |= XT_WL_RELOAD; - toggle_pl(t, args); - } else if (args->i & XT_DELETE) - show_oops(t, "'plugin delete' currently unimplemented"); - - return (0); -} - int toplevel_cmd(struct tab *t, struct karg *args) { @@ -4029,181 +2687,6 @@ search(struct tab *t, struct karg *args) return (XT_CB_HANDLED); } -struct settings_args { - char **body; - int i; -}; - -void -print_setting(struct settings *s, char *val, void *cb_args) -{ - char *tmp, *color; - struct settings_args *sa = cb_args; - - if (sa == NULL) - return; - - if (s->flags & XT_SF_RUNTIME) - color = "#22cc22"; - else - color = "#cccccc"; - - tmp = *sa->body; - *sa->body = g_strdup_printf( - "%s\n<tr>" - "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>" - "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>", - *sa->body, - color, - s->name, - color, - val - ); - g_free(tmp); - sa->i++; -} - -int -set_show(struct tab *t, struct karg *args) -{ - char *body, *page, *tmp; - int i = 1; - struct settings_args sa; - - bzero(&sa, sizeof sa); - sa.body = &body; - - /* body */ - body = g_strdup_printf("<div align='center'><table><tr>" - "<th align='left'>Setting</th>" - "<th align='left'>Value</th></tr>\n"); - - settings_walk(print_setting, &sa); - i = sa.i; - - /* small message if there are none */ - if (i == 1) { - tmp = body; - body = g_strdup_printf("%s\n<tr><td style='text-align:center'" - "colspan='2'>No settings</td></tr>\n", body); - g_free(tmp); - } - - tmp = body; - body = g_strdup_printf("%s</table></div>", body); - g_free(tmp); - - page = get_html_page("Settings", body, "", 0); - - g_free(body); - - load_webkit_string(t, page, XT_URI_ABOUT_SET); - - g_free(page); - - return (XT_CB_PASSTHROUGH); -} - -int -set(struct tab *t, struct karg *args) -{ - char *p, *val; - int i; - - if (args == NULL || args->s == NULL) - return (set_show(t, args)); - - /* strip spaces */ - p = g_strstrip(args->s); - - if (strlen(p) == 0) - return (set_show(t, args)); - - /* we got some sort of string */ - val = g_strrstr(p, "="); - if (val) { - *val++ = '\0'; - val = g_strchomp(val); - p = g_strchomp(p); - - for (i = 0; i < LENGTH(rs); i++) { - if (strcmp(rs[i].name, p)) - continue; - - if (rs[i].activate) { - if (rs[i].activate(val)) - show_oops(t, "%s invalid value %s", - p, val); - else - show_oops(t, ":set %s = %s", p, val); - goto done; - } else { - show_oops(t, "not a runtime option: %s", p); - goto done; - } - } - show_oops(t, "unknown option: %s", p); - } else { - p = g_strchomp(p); - - for (i = 0; i < LENGTH(rs); i++) { - if (strcmp(rs[i].name, p)) - continue; - - /* XXX this could use some cleanup */ - switch (rs[i].type) { - case XT_S_INT: - if (rs[i].ival) - show_oops(t, "%s = %d", - rs[i].name, *rs[i].ival); - else if (rs[i].s && rs[i].s->get) - show_oops(t, "%s = %s", - rs[i].name, - rs[i].s->get(&rs[i])); - else if (rs[i].s && rs[i].s->get == NULL) - show_oops(t, "%s = ...", rs[i].name); - else - show_oops(t, "%s = ", rs[i].name); - break; - case XT_S_FLOAT: - if (rs[i].fval) - show_oops(t, "%s = %f", - rs[i].name, *rs[i].fval); - else if (rs[i].s && rs[i].s->get) - show_oops(t, "%s = %s", - rs[i].name, - rs[i].s->get(&rs[i])); - else if (rs[i].s && rs[i].s->get == NULL) - show_oops(t, "%s = ...", rs[i].name); - else - show_oops(t, "%s = ", rs[i].name); - break; - case XT_S_STR: - if (rs[i].sval && *rs[i].sval) - show_oops(t, "%s = %s", - rs[i].name, *rs[i].sval); - else if (rs[i].s && rs[i].s->get) - show_oops(t, "%s = %s", - rs[i].name, - rs[i].s->get(&rs[i])); - else if (rs[i].s && rs[i].s->get == NULL) - show_oops(t, "%s = ...", rs[i].name); - else - show_oops(t, "%s = ", rs[i].name); - break; - default: - show_oops(t, "unknown type for %s", rs[i].name); - goto done; - } - - goto done; - } - show_oops(t, "unknown option: %s", p); - } -done: - return (XT_CB_PASSTHROUGH); -} - int session_save(struct tab *t, char *filename) { @@ -4488,299 +2971,6 @@ restart(struct tab *t, struct karg *args) return (0); } -#define CTRL GDK_CONTROL_MASK -#define MOD1 GDK_MOD1_MASK -#define SHFT GDK_SHIFT_MASK - -/* inherent to GTK not all keys will be caught at all times */ -/* XXX sort key bindings */ -struct key_binding { - char *cmd; - guint mask; - guint use_in_entry; - guint key; - TAILQ_ENTRY(key_binding) entry; /* in bss so no need to init */ -} keys[] = { - { "command_mode", 0, 0, GDK_Escape }, - { "insert_mode", 0, 0, GDK_i }, - { "cookiejar", MOD1, 0, GDK_j }, - { "downloadmgr", MOD1, 0, GDK_d }, - { "history", MOD1, 0, GDK_h }, - { "print", CTRL, 0, GDK_p }, - { "search", 0, 0, GDK_slash }, - { "searchb", 0, 0, GDK_question }, - { "statustoggle", CTRL, 0, GDK_n }, - { "command", 0, 0, GDK_colon }, - { "qa", CTRL, 0, GDK_q }, - { "restart", MOD1, 0, GDK_q }, - { "js toggle", CTRL, 0, GDK_j }, - { "cookie toggle", MOD1, 0, GDK_c }, - { "togglesrc", CTRL, 0, GDK_s }, - { "yankuri", 0, 0, GDK_y }, - { "pasteuricur", 0, 0, GDK_p }, - { "pasteurinew", 0, 0, GDK_P }, - { "toplevel toggle", 0, 0, GDK_F4 }, - { "help", 0, 0, GDK_F1 }, - { "run_script", MOD1, 0, GDK_r }, - - /* search */ - { "searchnext", 0, 0, GDK_n }, - { "searchprevious", 0, 0, GDK_N }, - - /* focus */ - { "focusaddress", 0, 0, GDK_F6 }, - { "focussearch", 0, 0, GDK_F7 }, - - /* hinting */ - { "hinting", 0, 0, GDK_f }, - { "hinting", 0, 0, GDK_period }, - { "hinting_newtab", SHFT, 0, GDK_F }, - { "hinting_newtab", 0, 0, GDK_comma }, - - /* custom stylesheet */ - { "userstyle", 0, 0, GDK_s }, - - /* navigation */ - { "goback", 0, 0, GDK_BackSpace }, - { "goback", MOD1, 0, GDK_Left }, - { "goforward", SHFT, 0, GDK_BackSpace }, - { "goforward", MOD1, 0, GDK_Right }, - { "reload", 0, 0, GDK_F5 }, - { "reload", CTRL, 0, GDK_r }, - { "reload", CTRL, 0, GDK_l }, - { "favorites", MOD1, 1, GDK_f }, - - /* vertical movement */ - { "scrolldown", 0, 0, GDK_j }, - { "scrolldown", 0, 0, GDK_Down }, - { "scrollup", 0, 0, GDK_Up }, - { "scrollup", 0, 0, GDK_k }, - { "scrollbottom", 0, 0, GDK_G }, - { "scrollbottom", 0, 0, GDK_End }, - { "scrolltop", 0, 0, GDK_Home }, - { "scrollpagedown", 0, 0, GDK_space }, - { "scrollpagedown", CTRL, 0, GDK_f }, - { "scrollhalfdown", CTRL, 0, GDK_d }, - { "scrollpagedown", 0, 0, GDK_Page_Down }, - { "scrollpageup", 0, 0, GDK_Page_Up }, - { "scrollpageup", CTRL, 0, GDK_b }, - { "scrollhalfup", CTRL, 0, GDK_u }, - /* horizontal movement */ - { "scrollright", 0, 0, GDK_l }, - { "scrollright", 0, 0, GDK_Right }, - { "scrollleft", 0, 0, GDK_Left }, - { "scrollleft", 0, 0, GDK_h }, - { "scrollfarright", 0, 0, GDK_dollar }, - { "scrollfarleft", 0, 0, GDK_0 }, - - /* tabs */ - { "tabnew", CTRL, 0, GDK_t }, - { "999tabnew", CTRL, 0, GDK_T }, - { "tabclose", CTRL, 1, GDK_w }, - { "tabundoclose", 0, 0, GDK_U }, - { "tabnext 1", CTRL, 0, GDK_1 }, - { "tabnext 2", CTRL, 0, GDK_2 }, - { "tabnext 3", CTRL, 0, GDK_3 }, - { "tabnext 4", CTRL, 0, GDK_4 }, - { "tabnext 5", CTRL, 0, GDK_5 }, - { "tabnext 6", CTRL, 0, GDK_6 }, - { "tabnext 7", CTRL, 0, GDK_7 }, - { "tabnext 8", CTRL, 0, GDK_8 }, - { "tabnext 9", CTRL, 0, GDK_9 }, - { "tabfirst", CTRL, 0, GDK_less }, - { "tablast", CTRL, 0, GDK_greater }, - { "tabprevious", CTRL, 0, GDK_Left }, - { "tabnext", CTRL, 0, GDK_Right }, - { "focusout", CTRL, 0, GDK_minus }, - { "focusin", CTRL, 0, GDK_plus }, - { "focusin", CTRL, 0, GDK_equal }, - { "focusreset", CTRL, 0, GDK_0 }, - - /* command aliases (handy when -S flag is used) */ - { "promptopen", 0, 0, GDK_F9 }, - { "promptopencurrent", 0, 0, GDK_F10 }, - { "prompttabnew", 0, 0, GDK_F11 }, - { "prompttabnewcurrent",0, 0, GDK_F12 }, -}; -TAILQ_HEAD(keybinding_list, key_binding); - -void -walk_kb(struct settings *s, - void (*cb)(struct settings *, char *, void *), void *cb_args) -{ - struct key_binding *k; - char str[1024]; - - if (s == NULL || cb == NULL) { - show_oops(NULL, "walk_kb invalid parameters"); - return; - } - - TAILQ_FOREACH(k, &kbl, entry) { - if (k->cmd == NULL) - continue; - str[0] = '\0'; - - /* sanity */ - if (gdk_keyval_name(k->key) == NULL) - continue; - - strlcat(str, k->cmd, sizeof str); - strlcat(str, ",", sizeof str); - - if (k->mask & GDK_SHIFT_MASK) - strlcat(str, "S-", sizeof str); - if (k->mask & GDK_CONTROL_MASK) - strlcat(str, "C-", sizeof str); - if (k->mask & GDK_MOD1_MASK) - strlcat(str, "M1-", sizeof str); - if (k->mask & GDK_MOD2_MASK) - strlcat(str, "M2-", sizeof str); - if (k->mask & GDK_MOD3_MASK) - strlcat(str, "M3-", sizeof str); - if (k->mask & GDK_MOD4_MASK) - strlcat(str, "M4-", sizeof str); - if (k->mask & GDK_MOD5_MASK) - strlcat(str, "M5-", sizeof str); - - strlcat(str, gdk_keyval_name(k->key), sizeof str); - cb(s, str, cb_args); - } -} - -void -init_keybindings(void) -{ - int i; - struct key_binding *k; - - for (i = 0; i < LENGTH(keys); i++) { - k = g_malloc0(sizeof *k); - k->cmd = keys[i].cmd; - k->mask = keys[i].mask; - k->use_in_entry = keys[i].use_in_entry; - k->key = keys[i].key; - TAILQ_INSERT_HEAD(&kbl, k, entry); - - DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n", - k->cmd ? k->cmd : "unnamed key"); - } -} - -void -keybinding_clearall(void) -{ - struct key_binding *k, *next; - - for (k = TAILQ_FIRST(&kbl); k; k = next) { - next = TAILQ_NEXT(k, entry); - if (k->cmd == NULL) - continue; - - DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n", - k->cmd ? k->cmd : "unnamed key"); - TAILQ_REMOVE(&kbl, k, entry); - g_free(k); - } -} - -int -keybinding_add(char *cmd, char *key, int use_in_entry) -{ - struct key_binding *k; - guint keyval, mask = 0; - int i; - - DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key); - - /* Keys which are to be used in entry have been prefixed with an - * exclamation mark. */ - if (use_in_entry) - key++; - - /* find modifier keys */ - if (strstr(key, "S-")) - mask |= GDK_SHIFT_MASK; - if (strstr(key, "C-")) - mask |= GDK_CONTROL_MASK; - if (strstr(key, "M1-")) - mask |= GDK_MOD1_MASK; - if (strstr(key, "M2-")) - mask |= GDK_MOD2_MASK; - if (strstr(key, "M3-")) - mask |= GDK_MOD3_MASK; - if (strstr(key, "M4-")) - mask |= GDK_MOD4_MASK; - if (strstr(key, "M5-")) - mask |= GDK_MOD5_MASK; - - /* find keyname */ - for (i = strlen(key) - 1; i > 0; i--) - if (key[i] == '-') - key = &key[i + 1]; - - /* validate keyname */ - keyval = gdk_keyval_from_name(key); - if (keyval == GDK_VoidSymbol) { - warnx("invalid keybinding name %s", key); - return (1); - } - /* must run this test too, gtk+ doesn't handle 10 for example */ - if (gdk_keyval_name(keyval) == NULL) { - warnx("invalid keybinding name %s", key); - return (1); - } - - /* Remove eventual dupes. */ - TAILQ_FOREACH(k, &kbl, entry) - if (k->key == keyval && k->mask == mask) { - TAILQ_REMOVE(&kbl, k, entry); - g_free(k); - break; - } - - /* add keyname */ - k = g_malloc0(sizeof *k); - k->cmd = g_strdup(cmd); - k->mask = mask; - k->use_in_entry = use_in_entry; - k->key = keyval; - - DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n", - k->cmd, - k->mask, - k->use_in_entry, - k->key); - DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n", - k->cmd, gdk_keyval_name(keyval)); - - TAILQ_INSERT_HEAD(&kbl, k, entry); - - return (0); -} - -int -add_kb(struct settings *s, char *entry) -{ - char *kb, *key; - - DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry); - - /* clearall is special */ - if (!strcmp(entry, "clearall")) { - keybinding_clearall(); - return (0); - } - - kb = strstr(entry, ","); - if (kb == NULL) - return (1); - *kb = '\0'; - key = kb + 1; - - return (keybinding_add(entry, key, key[0] == '!')); -} - struct cmd { char *cmd; int level; @@ -6740,9 +4930,10 @@ cmd_getlist(int id, char *key) cmd_status.len = c; return; } else if (cmds[id].type & XT_SETARG) { - for (i = 0; i < LENGTH(rs); i++) - if(!strncmp(key, rs[i].name, strlen(key))) - cmd_status.list[c++] = rs[i].name; + for (i = 0; i < get_settings_size(); i++) + if(!strncmp(key, get_setting_name(i), + strlen(key))) + cmd_status.list[c++] = get_setting_name(i); cmd_status.len = c; return; } @@ -8628,56 +6819,6 @@ setup_cookies(void) soup_session_add_feature(session, (SoupSessionFeature*)s_cookiejar); } -void -setup_proxy(char *uri) -{ - if (proxy_uri) { - g_object_set(session, "proxy_uri", NULL, (char *)NULL); - soup_uri_free(proxy_uri); - proxy_uri = NULL; - } - if (http_proxy) { - if (http_proxy != uri) { - g_free(http_proxy); - http_proxy = NULL; - } - } - - if (uri) { - http_proxy = g_strdup(uri); - DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri); - proxy_uri = soup_uri_new(http_proxy); - if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri))) - g_object_set(session, "proxy-uri", proxy_uri, - (char *)NULL); - } -} - -int -set_http_proxy(char *proxy) -{ - SoupURI *uri; - - if (proxy == NULL) - return (1); - - /* see if we need to clear it instead */ - if (strlen(proxy) == 0) { - setup_proxy(NULL); - return (0); - } - - uri = soup_uri_new(proxy); - if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) - return (1); - - setup_proxy(proxy); - - soup_uri_free(uri); - - return (0); -} - int send_cmd_to_socket(char *cmd) { diff --git a/xxxterm.h b/xxxterm.h index 7dd3b90..4c6bde9 100644 --- a/xxxterm.h +++ b/xxxterm.h @@ -268,6 +268,7 @@ const gchar *get_uri(struct tab *); const gchar *get_title(struct tab *, bool); void load_webkit_string(struct tab *, const char *, gchar *); +void button_set_stockid(GtkWidget *, char *); /* cookies */ int remove_cookie(int); @@ -307,6 +308,12 @@ struct about_type { int (*func)(struct tab *, struct karg *); }; +struct sp { + char *line; + TAILQ_ENTRY(sp) entry; +}; +TAILQ_HEAD(sp_list, sp); + int blank(struct tab *, struct karg *); int help(struct tab *, struct karg *); int about(struct tab *, struct karg *); @@ -326,6 +333,10 @@ void update_history_tabs(struct tab *); void update_download_tabs(struct tab *); void xtp_generate_keys(void); size_t about_list_size(void); +int cookie_cmd(struct tab *, struct karg *); +int js_cmd(struct tab *, struct karg *); +int pl_cmd(struct tab *, struct karg *); +void startpage_add(const char *, ...); /* * xtp tab meanings @@ -352,6 +363,11 @@ size_t about_list_size(void); #define XT_SAVE (1<<10) #define XT_OPEN (1<<11) +#define XT_WL_INVALID (0) +#define XT_WL_JAVASCRIPT (1) +#define XT_WL_COOKIE (2) +#define XT_WL_PLUGIN (3) + struct domain { RB_ENTRY(domain) entry; gchar *d; @@ -363,21 +379,152 @@ RB_PROTOTYPE(domain_list, domain, entry, domain_rb_cmp); int wl_show(struct tab *, struct karg *, char *, struct domain_list *); +/* uri aliases */ +struct alias { + char *a_name; + char *a_uri; + TAILQ_ENTRY(alias) entry; +}; +TAILQ_HEAD(alias_list, alias); + +/* mime types */ +struct mime_type { + char *mt_type; + char *mt_action; + int mt_default; + int mt_download; + TAILQ_ENTRY(mime_type) entry; +}; +TAILQ_HEAD(mime_type_list, mime_type); + +struct domain * wl_find(const gchar *, struct domain_list *); +int wl_save(struct tab *, struct karg *, int); +int toggle_cwl(struct tab *, struct karg *); +int toggle_js(struct tab *, struct karg *); +int toggle_pl(struct tab *, struct karg *); + /* settings */ -extern char *encoding; -extern char *resource_dir; -extern int save_rejected_cookies; -extern int refresh_interval; -extern char *ssl_ca_file; +#define XT_BM_NORMAL (0) +#define XT_BM_WHITELIST (1) +#define XT_BM_KIOSK (2) + +#define XT_TABS_NORMAL (0) +#define XT_TABS_COMPACT (1) + +#define CTRL GDK_CONTROL_MASK +#define MOD1 GDK_MOD1_MASK +#define SHFT GDK_SHIFT_MASK + +struct key_binding { + char *cmd; + guint mask; + guint use_in_entry; + guint key; + TAILQ_ENTRY(key_binding) entry; /* in bss so no need to init */ +}; +TAILQ_HEAD(keybinding_list, key_binding); + +struct settings { + char *name; + int type; +#define XT_S_INVALID (0) +#define XT_S_INT (1) +#define XT_S_STR (2) +#define XT_S_FLOAT (3) + uint32_t flags; +#define XT_SF_RESTART (1<<0) +#define XT_SF_RUNTIME (1<<1) + int *ival; + char **sval; + struct special *s; + gfloat *fval; + int (*activate)(char *); +}; + +int set(struct tab *, struct karg *); +size_t get_settings_size(void); +int settings_add(char *, char *); +void setup_proxy(char *); +int set_browser_mode(struct settings *, char *); +int set_cookie_policy(struct settings *, char *); +char *get_browser_mode(struct settings *); +char *get_cookie_policy(struct settings *); +void init_keybindings(void); +void config_parse(char *, int); +char *get_setting_name(int); + +extern int tabless; +extern int enable_socket; +extern int single_instance; +extern int fancy_bar; +extern int browser_mode; +extern int enable_localstorage; +extern char *statusbar_elems; + +extern int show_tabs; +extern int tab_style; +extern int show_url; +extern int show_statusbar; +extern int ctrl_click_focus; +extern int cookies_enabled; +extern int read_only_cookies; +extern int enable_scripts; +extern int enable_plugins; +extern gfloat default_zoom_level; +extern char default_script[PATH_MAX]; +extern int window_height; +extern int window_width; +extern int icon_size; +extern int refresh_interval; +extern int enable_plugin_whitelist; +extern int enable_cookie_whitelist; +extern int enable_js_whitelist; +extern int session_timeout; +extern int cookie_policy; +extern char *ssl_ca_file; +extern char *resource_dir; +extern gboolean ssl_strict_certs; +extern int append_next; +extern char *home; +extern char *search_string; +extern char *http_proxy; +extern char download_dir[PATH_MAX]; +extern char runtime_settings[PATH_MAX]; +extern int allow_volatile_cookies; +extern int save_global_history; +extern char *user_agent; +extern int save_rejected_cookies; +extern int session_autosave; +extern int guess_search; +extern int dns_prefetch; +extern gint max_connections; +extern gint max_host_connections; +extern gint enable_spell_checking; +extern char *spell_check_languages; +extern int xterm_workaround; +extern char *url_regex; +extern int history_autosave; +extern char search_file[PATH_MAX]; +extern char command_file[PATH_MAX]; +extern char *encoding; +extern int autofocus_onload; +extern char *cmd_font_name; +extern char *oops_font_name; +extern char *statusbar_font_name; +extern char *tabbar_font_name; /* globals */ extern char *version; extern char *icons[]; extern char rc_fname[PATH_MAX]; extern char work_dir[PATH_MAX]; +extern struct passwd *pwd; long long unsigned int blocked_cookies; extern SoupCookieJar *s_cookiejar; extern SoupCookieJar *p_cookiejar; +extern SoupSession *session; + +extern void (*_soup_cookie_jar_add_cookie)(SoupCookieJar *, SoupCookie *); extern struct history_list hl; extern struct download_list downloads; @@ -386,3 +533,12 @@ extern struct about_type about_list[]; extern struct domain_list c_wl; extern struct domain_list js_wl; extern struct domain_list pl_wl; +extern struct alias_list aliases; +extern struct mime_type_list mtl; +extern struct keybinding_list kbl; +extern struct sp_list spl; + +extern PangoFontDescription *cmd_font; +extern PangoFontDescription *oops_font; +extern PangoFontDescription *statusbar_font; +extern PangoFontDescription *tabbar_font; |