Remove encoding as a runtime setting for now
[xxxterm.git] / settings.c
blobf98fa7700809056da8bb66ccd3b220a93cef24b8
1 /*
2 * Copyright (c) 2010, 2011 Marco Peereboom <marco@peereboom.us>
3 * Copyright (c) 2011 Stevan Andjelkovic <stevan@student.chalmers.se>
4 * Copyright (c) 2010, 2011 Edd Barrett <vext01@gmail.com>
5 * Copyright (c) 2011 Todd T. Fries <todd@fries.net>
6 * Copyright (c) 2011 Raphael Graf <r@undefined.ch>
7 * Copyright (c) 2011 Michal Mazurek <akfaew@jasminek.net>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include <xxxterm.h>
24 /* globals */
25 SoupURI *proxy_uri = NULL;
26 PangoFontDescription *cmd_font;
27 PangoFontDescription *oops_font;
28 PangoFontDescription *statusbar_font;
29 PangoFontDescription *tabbar_font;
30 extern regex_t url_re;
32 /* settings that require restart */
33 int tabless = 0; /* allow only 1 tab */
34 int enable_socket = 0;
35 int single_instance = 0; /* only allow one xxxterm to run */
36 int fancy_bar = 1; /* fancy toolbar */
37 int browser_mode = XT_BM_NORMAL;
38 int gui_mode = XT_GM_CLASSIC;
39 int enable_localstorage = 1;
40 char *statusbar_elems = NULL;
42 /* runtime settings */
43 int show_tabs = 1; /* show tabs on notebook */
44 int tab_style = XT_TABS_NORMAL; /* tab bar style */
45 int show_url = 1; /* show url toolbar on notebook */
46 int show_statusbar = 0; /* vimperator style status bar */
47 int ctrl_click_focus = 0; /* ctrl click gets focus */
48 int cookies_enabled = 1; /* enable cookies */
49 int read_only_cookies = 0; /* enable to not write cookies */
50 int enable_scripts = 1;
51 int enable_plugins = 1;
52 gfloat default_zoom_level = 1.0;
53 char default_script[PATH_MAX];
54 int window_height = 768;
55 int window_width = 1024;
56 int window_maximize = 0;
57 int icon_size = 2; /* 1 = smallest, 2+ = bigger */
58 int refresh_interval = 10; /* download refresh interval */
59 int enable_plugin_whitelist = 0;
60 int enable_cookie_whitelist = 0;
61 int enable_js_whitelist = 0;
62 int session_timeout = 3600; /* cookie session timeout */
63 int cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
64 char *ssl_ca_file = NULL;
65 char *resource_dir = NULL;
66 gboolean ssl_strict_certs = FALSE;
67 gboolean enable_strict_transport = TRUE;
68 int append_next = 1; /* append tab after current tab */
69 char *home = NULL;
70 char *search_string = NULL;
71 char *http_proxy = NULL;
72 char download_dir[PATH_MAX];
73 int download_mode = XT_DM_START;
74 char runtime_settings[PATH_MAX]; /* override of settings */
75 int allow_volatile_cookies = 0;
76 int color_visited_uris = 1;
77 int save_global_history = 0; /* save global history to disk */
78 struct user_agent *user_agent = NULL;
79 int save_rejected_cookies = 0;
80 int session_autosave = 0;
81 int guess_search = 0;
82 int dns_prefetch = FALSE;
83 gint max_connections = 25;
84 gint max_host_connections = 5;
85 gint enable_spell_checking = 0;
86 char *spell_check_languages = NULL;
87 int xterm_workaround = 0;
88 char *url_regex = NULL;
89 int history_autosave = 0;
90 char search_file[PATH_MAX];
91 char command_file[PATH_MAX];
92 char *encoding = NULL;
93 int autofocus_onload = 0;
94 int enable_js_autorun = 1;
95 int edit_mode = XT_EM_HYBRID;
96 int userstyle_global = 0;
97 int auto_load_images = 1;
98 int enable_autoscroll = 0;
99 int enable_favicon_entry = 1;
100 int enable_favicon_tabs = 0;
101 char *external_editor = NULL;
102 int referer_mode = XT_REFERER_ALWAYS;
103 char *referer_custom = NULL;
105 char *cmd_font_name = NULL;
106 char *oops_font_name = NULL;
107 char *statusbar_font_name = NULL;
108 char *tabbar_font_name = NULL;
110 char *get_download_dir(struct settings *);
111 char *get_default_script(struct settings *);
112 char *get_runtime_dir(struct settings *);
113 char *get_tab_style(struct settings *);
114 char *get_edit_mode(struct settings *);
115 char *get_download_mode(struct settings *);
116 char *get_work_dir(struct settings *);
117 char *get_referer(struct settings *);
119 int add_cookie_wl(struct settings *, char *);
120 int add_js_wl(struct settings *, char *);
121 int add_pl_wl(struct settings *, char *);
122 int add_mime_type(struct settings *, char *);
123 int add_alias(struct settings *, char *);
124 int add_kb(struct settings *, char *);
125 int add_ua(struct settings *, char *);
127 int set_append_next(char *);
128 int set_cmd_font(char *);
129 int set_color_visited_uris(char *);
130 int set_cookie_policy_rt(char *);
131 int set_cookies_enabled(char *);
132 int set_ctrl_click_focus(char *);
133 int set_home(char *);
134 int set_download_dir(struct settings *, char *);
135 int set_default_script(struct settings *, char *);
136 int set_default_script_rt(char *);
137 int set_default_zoom_level(char *);
138 int set_enable_cookie_whitelist(char *);
139 int set_enable_js_autorun(char *);
140 int set_enable_js_whitelist(char *);
141 int set_enable_localstorage(char *);
142 int set_enable_plugins(char *);
143 int set_enable_plugin_whitelist(char *);
144 int set_enable_scripts(char *);
145 int set_enable_spell_checking(char *);
146 int set_enable_strict_transport(char *);
147 int set_encoding_rt(char *);
148 int set_runtime_dir(struct settings *, char *);
149 int set_tabbar_font(char *value);
150 int set_tab_style(struct settings *, char *);
151 int set_tab_style_rt(char *);
152 int set_edit_mode(struct settings *, char *);
153 int set_work_dir(struct settings *, char *);
154 int set_auto_load_images(char *);
155 int set_enable_autoscroll(char *);
156 int set_enable_favicon_entry(char *);
157 int set_enable_favicon_tabs(char *);
158 int set_guess_search(char *);
159 int set_download_mode(struct settings *, char *);
160 int set_download_mode_rt(char *);
161 int set_oops_font(char *);
162 int set_read_only_cookies(char *);
163 int set_referer(struct settings *, char *);
164 int set_referer_rt(char *);
165 int set_refresh_interval(char *);
166 int set_search_string(char *s);
167 int set_session_autosave(char *);
168 int set_session_timeout(char *);
169 int set_show_statusbar(char *);
170 int set_show_tabs(char *);
171 int set_show_url(char *);
172 int set_spell_check_languages(char *);
173 int set_ssl_ca_file_rt(char *);
174 int set_ssl_strict_certs(char *);
175 int set_statusbar_font(char *);
176 int set_url_regex(char *);
177 int set_userstyle_global(char *);
178 int set_external_editor(char *);
179 int set_xterm_workaround(char *);
181 void walk_mime_type(struct settings *, void (*)(struct settings *,
182 char *, void *), void *);
183 void walk_alias(struct settings *, void (*)(struct settings *,
184 char *, void *), void *);
185 void walk_cookie_wl(struct settings *, void (*)(struct settings *,
186 char *, void *), void *);
187 void walk_js_wl(struct settings *, void (*)(struct settings *,
188 char *, void *), void *);
189 void walk_pl_wl(struct settings *, void (*)(struct settings *,
190 char *, void *), void *);
191 void walk_kb(struct settings *, void (*)(struct settings *, char *,
192 void *), void *);
193 void walk_ua(struct settings *, void (*)(struct settings *, char *,
194 void *), void *);
197 set_http_proxy(char *proxy)
199 SoupURI *uri;
201 if (proxy == NULL)
202 return (1);
204 /* see if we need to clear it instead */
205 if (strlen(proxy) == 0) {
206 setup_proxy(NULL);
207 return (0);
210 uri = soup_uri_new(proxy);
211 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
212 return (1);
214 setup_proxy(proxy);
216 soup_uri_free(uri);
218 return (0);
221 struct special {
222 int (*set)(struct settings *, char *);
223 char *(*get)(struct settings *);
224 void (*walk)(struct settings *,
225 void (*cb)(struct settings *, char *, void *),
226 void *);
229 struct special s_browser_mode = {
230 set_browser_mode,
231 get_browser_mode,
232 NULL
235 struct special s_gui_mode = {
236 set_gui_mode,
237 get_gui_mode,
238 NULL
241 struct special s_cookie = {
242 set_cookie_policy,
243 get_cookie_policy,
244 NULL
247 struct special s_alias = {
248 add_alias,
249 NULL,
250 walk_alias
253 struct special s_mime = {
254 add_mime_type,
255 NULL,
256 walk_mime_type
259 struct special s_js = {
260 add_js_wl,
261 NULL,
262 walk_js_wl
265 struct special s_pl = {
266 add_pl_wl,
267 NULL,
268 walk_pl_wl
271 struct special s_kb = {
272 add_kb,
273 NULL,
274 walk_kb
277 struct special s_cookie_wl = {
278 add_cookie_wl,
279 NULL,
280 walk_cookie_wl
283 struct special s_default_script = {
284 set_default_script,
285 get_default_script,
286 NULL
289 struct special s_download_dir = {
290 set_download_dir,
291 get_download_dir,
292 NULL
295 struct special s_work_dir = {
296 set_work_dir,
297 get_work_dir,
298 NULL
301 struct special s_tab_style = {
302 set_tab_style,
303 get_tab_style,
304 NULL
307 struct special s_edit_mode = {
308 set_edit_mode,
309 get_edit_mode,
310 NULL
313 struct special s_download_mode = {
314 set_download_mode,
315 get_download_mode,
316 NULL
319 struct special s_ua = {
320 add_ua,
321 NULL,
322 walk_ua
325 struct special s_referer = {
326 set_referer,
327 get_referer,
328 NULL
331 struct settings rs[] = {
332 { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL, NULL, NULL},
333 { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL, NULL, NULL },
334 { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode, NULL, NULL },
335 { "gui_mode", XT_S_INT, 0, NULL, NULL,&s_gui_mode, NULL, NULL },
336 { "color_visited_uris", XT_S_INT, 0, &color_visited_uris , NULL, NULL, NULL, set_color_visited_uris },
337 { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie, NULL, set_cookie_policy_rt },
338 { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL, NULL, set_cookies_enabled },
339 { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL, NULL, set_ctrl_click_focus },
340 { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level, set_default_zoom_level },
341 { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script, NULL, set_default_script_rt },
342 { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir, NULL, NULL },
343 { "download_mode", XT_S_STR, 0, NULL, NULL,&s_download_mode, NULL, set_download_mode_rt },
344 { "edit_mode", XT_S_STR, 0, NULL, NULL,&s_edit_mode, NULL, NULL},
345 { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL, NULL, set_enable_cookie_whitelist },
346 { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL, NULL, set_enable_js_whitelist },
347 { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL, NULL, set_enable_plugin_whitelist },
348 { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL, NULL, set_enable_localstorage },
349 { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL, NULL, set_enable_plugins },
350 { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL, NULL, set_enable_scripts },
351 { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL, NULL, NULL },
352 { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL, NULL, set_enable_spell_checking },
353 { "encoding", XT_S_STR, 0, NULL, &encoding, NULL, NULL, NULL },
354 { "external_editor", XT_S_STR,0, NULL, &external_editor, NULL, NULL, set_external_editor },
355 { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL, NULL, NULL },
356 { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL, NULL, set_guess_search },
357 { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL, NULL, NULL },
358 { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy },
359 { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL, NULL, NULL },
360 { "enable_js_autorun", XT_S_INT, 0, &enable_js_autorun, NULL, NULL, NULL, set_enable_js_autorun },
361 { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL, NULL, NULL },
362 { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL, NULL, NULL },
363 { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL, NULL, set_read_only_cookies },
364 { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL, NULL, set_refresh_interval },
365 { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL, NULL, NULL },
366 { "search_string", XT_S_STR, 0, NULL, &search_string, NULL, NULL, set_search_string },
367 { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL, NULL, NULL },
368 { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL, NULL, NULL },
369 { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL, NULL, set_session_timeout },
370 { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL, NULL, set_session_autosave },
371 { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL, NULL, NULL },
372 { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL, NULL, set_show_tabs },
373 { "show_url", XT_S_INT, 0, &show_url, NULL, NULL, NULL, set_show_url },
374 { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL, NULL, set_show_statusbar },
375 { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL, NULL, set_spell_check_languages },
376 { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL, NULL, set_ssl_ca_file_rt },
377 { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL, NULL, set_ssl_strict_certs },
378 { "enable_strict_transport", XT_S_INT, 0, &enable_strict_transport, NULL, NULL, NULL, set_enable_strict_transport },
379 { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL, NULL, NULL },
380 { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style, NULL, set_tab_style_rt },
381 { "userstyle_global", XT_S_INT, 0, &userstyle_global, NULL, NULL, NULL, set_userstyle_global },
382 { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL, NULL, set_url_regex },
383 { "window_height", XT_S_INT, 0, &window_height, NULL, NULL, NULL, NULL },
384 { "window_width", XT_S_INT, 0, &window_width, NULL, NULL, NULL, NULL },
385 { "window_maximize", XT_S_INT, 0, &window_maximize, NULL, NULL, NULL, NULL },
386 { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir, NULL, NULL },
387 { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL, NULL, set_xterm_workaround },
388 { "auto_load_images", XT_S_INT, 0, &auto_load_images, NULL, NULL, NULL, set_auto_load_images },
389 { "enable_favicon_entry", XT_S_INT, 0, &enable_favicon_entry, NULL, NULL, NULL, set_enable_favicon_entry },
390 { "enable_favicon_tabs", XT_S_INT, 0, &enable_favicon_tabs, NULL, NULL, NULL, set_enable_favicon_tabs },
391 { "referer", XT_S_STR, 0, NULL, NULL,&s_referer, NULL, set_referer_rt },
393 /* font settings */
394 { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL, NULL, set_cmd_font },
395 { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL, NULL, set_oops_font },
396 { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL, NULL, set_statusbar_font },
397 { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL, NULL, set_tabbar_font },
399 /* runtime settings */
400 { "append_next", XT_S_INT, 0, &append_next, NULL, NULL, NULL, set_append_next },
401 { "enable_autoscroll", XT_S_INT, 0, &enable_autoscroll, NULL, NULL, NULL, set_enable_autoscroll },
402 { "home", XT_S_STR, 0, NULL, &home, NULL, NULL, set_home },
404 /* special settings */
405 { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias, NULL, NULL },
406 { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl, NULL, NULL },
407 { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js, NULL, NULL },
408 { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
409 { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
410 { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
411 { "user_agent", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
415 set_default_zoom_level(char *value)
417 struct karg args = {0};
418 struct tab *t;
420 if (value == NULL || strlen(value) == 0)
421 return (-1);
422 default_zoom_level = g_strtod(value, NULL);
423 args.i = 100; /* adjust = 100 percent for no additional adjustment */
424 TAILQ_FOREACH(t, &tabs, entry)
425 resizetab(t, &args);
426 return (0);
430 set_cookies_enabled(char *value)
432 int tmp;
433 const char *errstr;
435 tmp = strtonum(value, 0, 1, &errstr);
436 if (errstr)
437 return (-1);
438 cookies_enabled = tmp;
439 return (0);
443 set_append_next(char *value)
445 int tmp;
446 const char *errstr;
448 tmp = strtonum(value, 0, 1, &errstr);
449 if (errstr)
450 return (-1);
451 append_next = tmp;
452 return (0);
456 set_cmd_font(char *value)
458 struct tab *t;
460 if (value == NULL || strlen(value))
461 return (-1);
462 if (cmd_font_name)
463 g_free(cmd_font_name);
464 if (cmd_font)
465 pango_font_description_free(cmd_font);
466 cmd_font_name = g_strdup(value);
467 cmd_font = pango_font_description_from_string(cmd_font_name);
468 TAILQ_FOREACH(t, &tabs, entry)
469 gtk_widget_modify_font(GTK_WIDGET(t->cmd), cmd_font);
470 return (0);
474 set_oops_font(char *value)
476 struct tab *t;
478 if (value == NULL || strlen(value) == 0)
479 return (-1);
480 if (oops_font_name)
481 g_free(oops_font_name);
482 if (oops_font)
483 pango_font_description_free(oops_font);
484 oops_font_name = g_strdup(value);
485 oops_font = pango_font_description_from_string(oops_font_name);
486 TAILQ_FOREACH(t, &tabs, entry)
487 gtk_widget_modify_font(GTK_WIDGET(t->oops), oops_font);
488 return (0);
492 set_statusbar_font(char *value)
494 struct tab *t;
496 if (value == NULL || strlen(value) == 0)
497 return (-1);
498 if (statusbar_font_name)
499 g_free(statusbar_font_name);
500 if (statusbar_font)
501 pango_font_description_free(statusbar_font);
502 statusbar_font_name = g_strdup(value);
503 statusbar_font = pango_font_description_from_string(
504 statusbar_font_name);
505 TAILQ_FOREACH(t, &tabs, entry) {
506 gtk_widget_modify_font(GTK_WIDGET(t->sbe.statusbar),
507 statusbar_font);
508 gtk_widget_modify_font(GTK_WIDGET(t->sbe.buffercmd),
509 statusbar_font);
510 gtk_widget_modify_font(GTK_WIDGET(t->sbe.zoom),
511 statusbar_font);
512 gtk_widget_modify_font(GTK_WIDGET(t->sbe.position),
513 statusbar_font);
515 return (0);
519 set_tabbar_font(char *value)
521 struct tab *t;
523 if (value == NULL || strlen(value) == 0)
524 return (-1);
525 if (tabbar_font_name)
526 g_free(tabbar_font_name);
527 if (tabbar_font)
528 pango_font_description_free(tabbar_font);
529 tabbar_font_name = g_strdup(value);
530 tabbar_font = pango_font_description_from_string(tabbar_font_name);
531 TAILQ_FOREACH(t, &tabs, entry)
532 gtk_widget_modify_font(GTK_WIDGET(t->tab_elems.label),
533 tabbar_font);
534 return (0);
538 set_color_visited_uris(char *value)
540 int tmp;
541 const char *errstr;
543 tmp = strtonum(value, 0, 1, &errstr);
544 if (errstr)
545 return (-1);
546 color_visited_uris = tmp;
547 return (0);
551 set_home(char *value)
553 if (value == NULL || strlen(value) == 0)
554 return (-1);
555 if (home)
556 g_free(home);
557 home = g_strdup(value);
558 return (0);
562 set_search_string(char *value)
564 if (value == NULL || strlen(value) == 0)
565 return (-1);
566 if (search_string)
567 g_free(search_string);
568 search_string = g_strdup(value);
569 return (0);
572 size_t
573 get_settings_size(void)
575 return (LENGTH(rs));
578 char *
579 get_setting_name(int i)
581 if (i > LENGTH(rs))
582 return (NULL);
583 return (rs[i].name);
586 char *
587 get_as_string(struct settings *s)
589 char *r = NULL;
591 if (s == NULL)
592 return (NULL);
594 if (s->s) {
595 if (s->s->get)
596 r = s->s->get(s);
597 else
598 warnx("get_as_string skip %s\n", s->name);
599 } else if (s->type == XT_S_INT)
600 r = g_strdup_printf("%d", *s->ival);
601 else if (s->type == XT_S_STR)
602 r = g_strdup(*s->sval);
603 else if (s->type == XT_S_FLOAT)
604 r = g_strdup_printf("%f", *s->fval);
605 else
606 r = g_strdup_printf("INVALID TYPE");
608 return (r);
611 void
612 settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args)
614 int i;
615 char *s;
617 for (i = 0; i < LENGTH(rs); i++) {
618 if (rs[i].s && rs[i].s->walk)
619 rs[i].s->walk(&rs[i], cb, cb_args);
620 else {
621 s = get_as_string(&rs[i]);
622 cb(&rs[i], s, cb_args);
623 g_free(s);
629 set_browser_mode(struct settings *s, char *val)
631 if (!strcmp(val, "whitelist")) {
632 browser_mode = XT_BM_WHITELIST;
633 allow_volatile_cookies = 0;
634 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
635 cookies_enabled = 1;
636 enable_cookie_whitelist = 1;
637 enable_plugin_whitelist = 1;
638 enable_plugins = 0;
639 read_only_cookies = 0;
640 save_rejected_cookies = 0;
641 session_timeout = 3600;
642 enable_scripts = 0;
643 enable_js_whitelist = 1;
644 enable_localstorage = 0;
645 referer_mode = XT_REFERER_SAME_DOMAIN;
646 } else if (!strcmp(val, "normal")) {
647 browser_mode = XT_BM_NORMAL;
648 allow_volatile_cookies = 0;
649 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
650 cookies_enabled = 1;
651 enable_cookie_whitelist = 0;
652 enable_plugin_whitelist = 0;
653 enable_plugins = 1;
654 read_only_cookies = 0;
655 save_rejected_cookies = 0;
656 session_timeout = 3600;
657 enable_scripts = 1;
658 enable_js_whitelist = 0;
659 enable_localstorage = 1;
660 referer_mode = XT_REFERER_ALWAYS;
661 } else if (!strcmp(val, "kiosk")) {
662 browser_mode = XT_BM_KIOSK;
663 allow_volatile_cookies = 0;
664 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
665 cookies_enabled = 1;
666 enable_cookie_whitelist = 0;
667 enable_plugin_whitelist = 0;
668 enable_plugins = 1;
669 read_only_cookies = 0;
670 save_rejected_cookies = 0;
671 session_timeout = 3600;
672 enable_scripts = 1;
673 enable_js_whitelist = 0;
674 enable_localstorage = 1;
675 referer_mode = XT_REFERER_ALWAYS;
676 show_tabs = 0;
677 tabless = 1;
678 } else
679 return (1);
681 return (0);
684 char *
685 get_browser_mode(struct settings *s)
687 char *r = NULL;
689 if (browser_mode == XT_BM_WHITELIST)
690 r = g_strdup("whitelist");
691 else if (browser_mode == XT_BM_NORMAL)
692 r = g_strdup("normal");
693 else if (browser_mode == XT_BM_KIOSK)
694 r = g_strdup("kiosk");
695 else
696 return (NULL);
698 return (r);
702 set_gui_mode(struct settings *s, char *val)
704 if (!strcmp(val, "classic")) {
705 fancy_bar = 1;
706 show_tabs = 1;
707 tab_style = XT_TABS_NORMAL;
708 show_url = 1;
709 show_statusbar = 0;
710 } else if (!strcmp(val, "minimal")) {
711 fancy_bar = 0;
712 show_tabs = 1;
713 tab_style = XT_TABS_COMPACT;
714 show_url = 0;
715 show_statusbar = 1;
716 } else
717 return (1);
719 return (0);
722 char *
723 get_gui_mode(struct settings *s)
725 char *r = NULL;
727 if (gui_mode == XT_GM_CLASSIC)
728 r = g_strdup("classic");
729 else if (browser_mode == XT_GM_MINIMAL)
730 r = g_strdup("minimal");
731 else
732 return (NULL);
734 return (r);
738 set_cookie_policy(struct settings *s, char *val)
740 if (!strcmp(val, "no3rdparty"))
741 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
742 else if (!strcmp(val, "accept"))
743 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
744 else if (!strcmp(val, "reject"))
745 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
746 else
747 return (1);
749 return (0);
753 set_cookie_policy_rt(char *value)
755 if (set_cookie_policy(NULL, value))
756 return (-1);
757 g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY,
758 cookie_policy, (void *)NULL);
759 return (0);
762 char *
763 get_cookie_policy(struct settings *s)
765 char *r = NULL;
767 if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY)
768 r = g_strdup("no3rdparty");
769 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
770 r = g_strdup("accept");
771 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
772 r = g_strdup("reject");
773 else
774 return (NULL);
776 return (r);
779 char *
780 get_default_script(struct settings *s)
782 if (default_script[0] == '\0')
783 return (0);
784 return (g_strdup(default_script));
788 set_default_script(struct settings *s, char *val)
790 if (val[0] == '~')
791 snprintf(default_script, sizeof default_script, "%s" PS "%s",
792 pwd->pw_dir, &val[1]);
793 else
794 strlcpy(default_script, val, sizeof default_script);
796 return (0);
800 set_default_script_rt(char *value)
802 if (value == NULL || strlen(value) == 0)
803 return (-1);
804 return (set_default_script(NULL, value));
807 char *
808 get_download_dir(struct settings *s)
810 if (download_dir[0] == '\0')
811 return (0);
812 return (g_strdup(download_dir));
816 set_download_dir(struct settings *s, char *val)
818 if (val[0] == '~')
819 snprintf(download_dir, sizeof download_dir, "%s" PS "%s",
820 pwd->pw_dir, &val[1]);
821 else
822 strlcpy(download_dir, val, sizeof download_dir);
824 return (0);
828 add_alias(struct settings *s, char *line)
830 char *l, *alias;
831 struct alias *a = NULL;
833 if (s == NULL || line == NULL) {
834 show_oops(NULL, "add_alias invalid parameters");
835 return (1);
838 l = line;
839 a = g_malloc(sizeof(*a));
841 if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) {
842 show_oops(NULL, "add_alias: incomplete alias definition");
843 goto bad;
845 if (strlen(alias) == 0 || strlen(l) == 0) {
846 show_oops(NULL, "add_alias: invalid alias definition");
847 goto bad;
850 a->a_name = g_strdup(alias);
851 a->a_uri = g_strdup(l);
853 DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri);
855 TAILQ_INSERT_TAIL(&aliases, a, entry);
857 return (0);
858 bad:
859 if (a)
860 g_free(a);
861 return (1);
864 void
865 walk_alias(struct settings *s,
866 void (*cb)(struct settings *, char *, void *), void *cb_args)
868 struct alias *a;
869 char *str;
871 if (s == NULL || cb == NULL) {
872 show_oops(NULL, "walk_alias invalid parameters");
873 return;
876 TAILQ_FOREACH(a, &aliases, entry) {
877 str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri);
878 cb(s, str, cb_args);
879 g_free(str);
884 add_mime_type(struct settings *s, char *line)
886 char *mime_type;
887 char *l;
888 struct mime_type *m = NULL;
889 int downloadfirst = 0;
891 /* XXX this could be smarter */
893 if (line == NULL || strlen(line) == 0) {
894 show_oops(NULL, "add_mime_type invalid parameters");
895 return (1);
898 l = line;
899 if (*l == '@') {
900 downloadfirst = 1;
901 l++;
903 m = g_malloc(sizeof(*m));
905 if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) {
906 show_oops(NULL, "add_mime_type: invalid mime_type");
907 goto bad;
909 if (mime_type[strlen(mime_type) - 1] == '*') {
910 mime_type[strlen(mime_type) - 1] = '\0';
911 m->mt_default = 1;
912 } else
913 m->mt_default = 0;
915 if (strlen(mime_type) == 0 || strlen(l) == 0) {
916 show_oops(NULL, "add_mime_type: invalid mime_type");
917 goto bad;
920 m->mt_type = g_strdup(mime_type);
921 m->mt_action = g_strdup(l);
922 m->mt_download = downloadfirst;
924 DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n",
925 m->mt_type, m->mt_action, m->mt_default);
927 TAILQ_INSERT_TAIL(&mtl, m, entry);
929 return (0);
930 bad:
931 if (m)
932 g_free(m);
933 return (1);
936 void
937 walk_mime_type(struct settings *s,
938 void (*cb)(struct settings *, char *, void *), void *cb_args)
940 struct mime_type *m;
941 char *str;
943 if (s == NULL || cb == NULL) {
944 show_oops(NULL, "walk_mime_type invalid parameters");
945 return;
948 TAILQ_FOREACH(m, &mtl, entry) {
949 str = g_strdup_printf("%s%s --> %s",
950 m->mt_type,
951 m->mt_default ? "*" : "",
952 m->mt_action);
953 cb(s, str, cb_args);
954 g_free(str);
958 /* inherent to GTK not all keys will be caught at all times */
959 /* XXX sort key bindings */
960 struct key_binding keys[] = {
961 { "command_mode", 0, 1, GDK_Escape },
962 { "insert_mode", 0, 0, GDK_i },
963 { "cookiejar", MOD1, 1, GDK_j },
964 { "downloadmgr", MOD1, 1, GDK_d },
965 { "history", MOD1, 1, GDK_h },
966 { "print", CTRL, 1, GDK_p },
967 { "search", 0, 0, GDK_slash },
968 { "searchb", 0, 0, GDK_question },
969 { "statustoggle", CTRL, 1, GDK_n },
970 { "command", 0, 0, GDK_colon },
971 { "qa", CTRL, 1, GDK_q },
972 { "restart", MOD1, 1, GDK_q },
973 { "js toggle", CTRL, 1, GDK_j },
974 { "plugin toggle", MOD1, 1, GDK_p },
975 { "cookie toggle", MOD1, 1, GDK_c },
976 { "togglesrc", CTRL, 1, GDK_s },
977 { "yankuri", 0, 0, GDK_y },
978 { "pasteuricur", 0, 0, GDK_p },
979 { "pasteurinew", 0, 0, GDK_P },
980 { "toplevel toggle", 0, 1, GDK_F4 },
981 { "help", 0, 1, GDK_F1 },
982 { "run_script", MOD1, 1, GDK_r },
983 { "proxy toggle", 0, 1, GDK_F2 },
984 { "editelement", CTRL, 1, GDK_i },
985 { "passthrough", CTRL, 1, GDK_z },
986 { "modurl", CTRL, 1, GDK_Return },
988 /* search */
989 { "searchnext", 0, 0, GDK_n },
990 { "searchprevious", 0, 0, GDK_N },
992 /* focus */
993 { "focusaddress", 0, 1, GDK_F6 },
994 { "focussearch", 0, 1, GDK_F7 },
996 /* hinting */
997 { "hinting", 0, 0, GDK_f },
998 { "hinting", 0, 0, GDK_period },
999 { "hinting_newtab", SHFT, 0, GDK_F },
1000 { "hinting_newtab", 0, 0, GDK_comma },
1002 /* custom stylesheet */
1003 { "userstyle", 0, 0, GDK_s },
1004 { "userstyle_global", SHFT, 0, GDK_S },
1006 /* navigation */
1007 { "goback", 0, 0, GDK_BackSpace },
1008 { "goback", MOD1, 1, GDK_Left },
1009 { "goforward", SHFT, 1, GDK_BackSpace },
1010 { "goforward", MOD1, 1, GDK_Right },
1011 { "reload", 0, 1, GDK_F5 },
1012 { "reload", CTRL, 1, GDK_r },
1013 { "reload", CTRL, 1, GDK_l },
1014 { "favorites", MOD1, 1, GDK_f },
1016 /* vertical movement */
1017 { "scrolldown", 0, 0, GDK_j },
1018 { "scrolldown", 0, 0, GDK_Down },
1019 { "scrollup", 0, 0, GDK_Up },
1020 { "scrollup", 0, 0, GDK_k },
1021 { "scrollbottom", 0, 0, GDK_G },
1022 { "scrollbottom", 0, 0, GDK_End },
1023 { "scrolltop", 0, 0, GDK_Home },
1024 { "scrollpagedown", 0, 0, GDK_space },
1025 { "scrollpagedown", CTRL, 1, GDK_f },
1026 { "scrollhalfdown", CTRL, 1, GDK_d },
1027 { "scrollpagedown", 0, 0, GDK_Page_Down },
1028 { "scrollpageup", 0, 0, GDK_Page_Up },
1029 { "scrollpageup", CTRL, 1, GDK_b },
1030 { "scrollhalfup", CTRL, 1, GDK_u },
1031 /* horizontal movement */
1032 { "scrollright", 0, 0, GDK_l },
1033 { "scrollright", 0, 0, GDK_Right },
1034 { "scrollleft", 0, 0, GDK_Left },
1035 { "scrollleft", 0, 0, GDK_h },
1036 { "scrollfarright", 0, 0, GDK_dollar },
1037 { "scrollfarleft", 0, 0, GDK_0 },
1039 /* tabs */
1040 { "tabnew", CTRL, 1, GDK_t },
1041 { "999tabnew", CTRL, 1, GDK_T },
1042 { "tabclose", CTRL, 1, GDK_w },
1043 { "tabundoclose", 0, 0, GDK_U },
1044 { "tabnext 1", CTRL, 1, GDK_1 },
1045 { "tabnext 2", CTRL, 1, GDK_2 },
1046 { "tabnext 3", CTRL, 1, GDK_3 },
1047 { "tabnext 4", CTRL, 1, GDK_4 },
1048 { "tabnext 5", CTRL, 1, GDK_5 },
1049 { "tabnext 6", CTRL, 1, GDK_6 },
1050 { "tabnext 7", CTRL, 1, GDK_7 },
1051 { "tabnext 8", CTRL, 1, GDK_8 },
1052 { "tabnext 9", CTRL, 1, GDK_9 },
1053 { "tabfirst", CTRL, 1, GDK_less },
1054 { "tablast", CTRL, 1, GDK_greater },
1055 { "tabprevious", CTRL, 1, GDK_Left },
1056 { "tabnext", CTRL, 1, GDK_Right },
1057 { "focusout", CTRL, 1, GDK_minus },
1058 { "focusin", CTRL, 1, GDK_plus },
1059 { "focusin", CTRL, 1, GDK_equal },
1060 { "focusreset", CTRL, 1, GDK_0 },
1062 /* command aliases (handy when -S flag is used) */
1063 { "promptopen", 0, 1, GDK_F9 },
1064 { "promptopencurrent", 0, 1, GDK_F10 },
1065 { "prompttabnew", 0, 1, GDK_F11 },
1066 { "prompttabnewcurrent",0, 1, GDK_F12 },
1069 void
1070 walk_kb(struct settings *s,
1071 void (*cb)(struct settings *, char *, void *), void *cb_args)
1073 struct key_binding *k;
1074 char str[1024];
1076 if (s == NULL || cb == NULL) {
1077 show_oops(NULL, "walk_kb invalid parameters");
1078 return;
1081 TAILQ_FOREACH(k, &kbl, entry) {
1082 if (k->cmd == NULL)
1083 continue;
1084 str[0] = '\0';
1086 /* sanity */
1087 if (gdk_keyval_name(k->key) == NULL)
1088 continue;
1090 strlcat(str, k->cmd, sizeof str);
1091 strlcat(str, ",", sizeof str);
1093 if (k->mask & GDK_SHIFT_MASK)
1094 strlcat(str, "S-", sizeof str);
1095 if (k->mask & GDK_CONTROL_MASK)
1096 strlcat(str, "C-", sizeof str);
1097 if (k->mask & GDK_MOD1_MASK)
1098 strlcat(str, "M1-", sizeof str);
1099 if (k->mask & GDK_MOD2_MASK)
1100 strlcat(str, "M2-", sizeof str);
1101 if (k->mask & GDK_MOD3_MASK)
1102 strlcat(str, "M3-", sizeof str);
1103 if (k->mask & GDK_MOD4_MASK)
1104 strlcat(str, "M4-", sizeof str);
1105 if (k->mask & GDK_MOD5_MASK)
1106 strlcat(str, "M5-", sizeof str);
1108 strlcat(str, gdk_keyval_name(k->key), sizeof str);
1109 cb(s, str, cb_args);
1113 void
1114 init_keybindings(void)
1116 int i;
1117 struct key_binding *k;
1119 for (i = 0; i < LENGTH(keys); i++) {
1120 k = g_malloc0(sizeof *k);
1121 k->cmd = keys[i].cmd;
1122 k->mask = keys[i].mask;
1123 k->use_in_entry = keys[i].use_in_entry;
1124 k->key = keys[i].key;
1125 TAILQ_INSERT_HEAD(&kbl, k, entry);
1127 DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n",
1128 k->cmd ? k->cmd : "unnamed key");
1132 void
1133 keybinding_clearall(void)
1135 struct key_binding *k, *next;
1137 for (k = TAILQ_FIRST(&kbl); k; k = next) {
1138 next = TAILQ_NEXT(k, entry);
1139 if (k->cmd == NULL)
1140 continue;
1142 DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n",
1143 k->cmd ? k->cmd : "unnamed key");
1144 TAILQ_REMOVE(&kbl, k, entry);
1145 g_free(k);
1150 keybinding_add(char *cmd, char *key, int use_in_entry)
1152 struct key_binding *k;
1153 guint keyval, mask = 0;
1154 int i;
1156 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key);
1158 /* Keys which are to be used in entry have been prefixed with an
1159 * exclamation mark. */
1160 if (use_in_entry)
1161 key++;
1163 /* find modifier keys */
1164 if (strstr(key, "S-"))
1165 mask |= GDK_SHIFT_MASK;
1166 if (strstr(key, "C-"))
1167 mask |= GDK_CONTROL_MASK;
1168 if (strstr(key, "M1-"))
1169 mask |= GDK_MOD1_MASK;
1170 if (strstr(key, "M2-"))
1171 mask |= GDK_MOD2_MASK;
1172 if (strstr(key, "M3-"))
1173 mask |= GDK_MOD3_MASK;
1174 if (strstr(key, "M4-"))
1175 mask |= GDK_MOD4_MASK;
1176 if (strstr(key, "M5-"))
1177 mask |= GDK_MOD5_MASK;
1179 /* find keyname */
1180 for (i = strlen(key) - 1; i > 0; i--)
1181 if (key[i] == '-')
1182 key = &key[i + 1];
1184 /* validate keyname */
1185 keyval = gdk_keyval_from_name(key);
1186 if (keyval == GDK_VoidSymbol) {
1187 warnx("invalid keybinding name %s", key);
1188 return (1);
1190 /* must run this test too, gtk+ doesn't handle 10 for example */
1191 if (gdk_keyval_name(keyval) == NULL) {
1192 warnx("invalid keybinding name %s", key);
1193 return (1);
1196 /* Remove eventual dupes. */
1197 TAILQ_FOREACH(k, &kbl, entry)
1198 if (k->key == keyval && k->mask == mask) {
1199 TAILQ_REMOVE(&kbl, k, entry);
1200 g_free(k);
1201 break;
1204 /* add keyname */
1205 k = g_malloc0(sizeof *k);
1206 k->cmd = g_strdup(cmd);
1207 k->mask = mask;
1208 k->use_in_entry = use_in_entry;
1209 k->key = keyval;
1211 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n",
1212 k->cmd,
1213 k->mask,
1214 k->use_in_entry,
1215 k->key);
1216 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n",
1217 k->cmd, gdk_keyval_name(keyval));
1219 TAILQ_INSERT_HEAD(&kbl, k, entry);
1221 return (0);
1225 add_kb(struct settings *s, char *entry)
1227 char *kb, *key;
1229 DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry);
1231 /* clearall is special */
1232 if (!strcmp(entry, "clearall")) {
1233 keybinding_clearall();
1234 return (0);
1237 kb = strstr(entry, ",");
1238 if (kb == NULL)
1239 return (1);
1240 *kb = '\0';
1241 key = kb + 1;
1243 return (keybinding_add(entry, key, key[0] == '!'));
1247 add_ua(struct settings *s, char *value)
1249 struct user_agent *ua;
1251 ua = g_malloc0(sizeof *ua);
1252 ua->value = g_strdup(value);
1254 TAILQ_INSERT_HEAD(&ua_list, ua, entry);
1256 /* use the last added user agent */
1257 user_agent = TAILQ_FIRST(&ua_list);
1258 user_agent_count++;
1260 return (0);
1264 void
1265 walk_ua(struct settings *s,
1266 void (*cb)(struct settings *, char *, void *), void *cb_args)
1268 struct user_agent *ua;
1270 if (s == NULL || cb == NULL) {
1271 show_oops(NULL, "walk_ua invalid parameters");
1272 return;
1275 TAILQ_FOREACH(ua, &ua_list, entry)
1276 cb(s, ua->value, cb_args);
1280 set_auto_load_images(char *value)
1282 struct tab *t;
1283 int tmp;
1284 const char *errstr;
1286 tmp = strtonum(value, 0, 1, &errstr);
1287 if (errstr)
1288 return (-1);
1289 auto_load_images = tmp;
1290 TAILQ_FOREACH(t, &tabs, entry) {
1291 g_object_set(G_OBJECT(t->settings),
1292 "auto-load-images", auto_load_images, (char *)NULL);
1293 webkit_web_view_set_settings(t->wv, t->settings);
1295 return (0);
1299 set_ctrl_click_focus(char *value)
1301 int tmp;
1302 const char *errstr;
1304 tmp = strtonum(value, 0, 1, &errstr);
1305 if (errstr)
1306 return (-1);
1307 ctrl_click_focus = tmp;
1308 return (0);
1312 set_enable_autoscroll(char *value)
1314 int tmp;
1315 const char *errstr;
1317 tmp = strtonum(value, 0, 1, &errstr);
1318 if (errstr)
1319 return (-1);
1320 enable_autoscroll = tmp;
1321 return (0);
1325 set_enable_cookie_whitelist(char *value)
1327 int tmp;
1328 const char *errstr;
1330 tmp = strtonum(value, 0, 1, &errstr);
1331 if (errstr)
1332 return (-1);
1333 enable_cookie_whitelist = tmp;
1334 return (0);
1338 set_enable_js_autorun(char *value)
1340 int tmp;
1341 const char *errstr;
1343 tmp = strtonum(value, 0, 1, &errstr);
1344 if (errstr)
1345 return (-1);
1346 enable_js_autorun = tmp;
1347 return (0);
1351 set_enable_js_whitelist(char *value)
1353 int tmp;
1354 const char *errstr;
1356 tmp = strtonum(value, 0, 1, &errstr);
1357 if (errstr)
1358 return (-1);
1359 enable_js_whitelist = tmp;
1360 return (0);
1364 set_enable_favicon_entry(char *value)
1366 int tmp;
1367 const char *errstr;
1369 tmp = strtonum(value, 0, 1, &errstr);
1370 if (errstr)
1371 return (-1);
1372 enable_favicon_entry = tmp;
1373 return (0);
1377 set_enable_favicon_tabs(char *value)
1379 int tmp;
1380 const char *errstr;
1382 tmp = strtonum(value, 0, 1, &errstr);
1383 if (errstr)
1384 return (-1);
1385 enable_favicon_tabs = tmp;
1386 return (0);
1390 set_enable_localstorage(char *value)
1392 struct tab *t;
1393 int tmp;
1394 const char *errstr;
1396 tmp = strtonum(value, 0, 1, &errstr);
1397 if (errstr)
1398 return (-1);
1399 enable_localstorage = tmp;
1400 TAILQ_FOREACH(t, &tabs, entry) {
1401 g_object_set(G_OBJECT(t->settings),
1402 "enable-html5-local-storage", enable_localstorage,
1403 (char *)NULL);
1405 return (0);
1409 set_enable_plugins(char *value)
1411 struct tab *t;
1412 int tmp;
1413 const char *errstr;
1415 tmp = strtonum(value, 0, 1, &errstr);
1416 if (errstr)
1417 return (-1);
1418 enable_plugins = tmp;
1419 TAILQ_FOREACH(t, &tabs, entry)
1420 g_object_set(G_OBJECT(t->settings), "enable-plugins",
1421 enable_plugins, (char *)NULL);
1422 return (0);
1426 set_enable_plugin_whitelist(char *value)
1428 int tmp;
1429 const char *errstr;
1431 tmp = strtonum(value, 0, 1, &errstr);
1432 if (errstr)
1433 return (-1);
1434 enable_plugin_whitelist = tmp;
1435 return (0);
1439 set_enable_scripts(char *value)
1441 struct tab *t;
1442 int tmp;
1443 const char *errstr;
1445 tmp = strtonum(value, 0, 1, &errstr);
1446 if (errstr)
1447 return (-1);
1448 enable_scripts = tmp;
1449 TAILQ_FOREACH(t, &tabs, entry)
1450 g_object_set(G_OBJECT(t->settings), "enable-scripts",
1451 enable_scripts, (char *)NULL);
1452 return (0);
1456 set_enable_spell_checking(char *value)
1458 struct tab *t;
1459 int tmp;
1460 const char *errstr;
1462 tmp = strtonum(value, 0, 1, &errstr);
1463 if (errstr)
1464 return (-1);
1465 enable_spell_checking = tmp;
1466 TAILQ_FOREACH(t, &tabs, entry)
1467 g_object_set(G_OBJECT(t->settings), "enable_spell_checking",
1468 enable_spell_checking, (char *)NULL);
1469 return (0);
1473 set_enable_strict_transport(char *value)
1475 int tmp;
1476 const char *errstr;
1478 tmp = strtonum(value, 0, 1, &errstr);
1479 if (errstr)
1480 return (-1);
1481 enable_strict_transport = tmp;
1482 return (0);
1485 #if 0
1487 * XXX: this is currently broken. Need to figure out what to do with
1488 * this. Problemm is set_encoding will refresh the tab it's run on, so
1489 * we can either put a big fat warning in the manpage and refresh every
1490 * single open tab with the new encoding or scrap it as a runtime
1491 * setting.
1494 set_encoding_rt(char *value)
1496 struct karg args = {0};
1498 if (value == NULL || strlen(value) == 0)
1499 return (-1);
1500 if (encoding)
1501 g_free(encoding);
1502 encoding = g_strdup(value);
1503 args.s = encoding;
1504 set_encoding(get_current_tab(), &args);
1505 return (0);
1507 #endif
1510 set_guess_search(char *value)
1512 int tmp;
1513 const char *errstr;
1515 tmp = strtonum(value, 0, 1, &errstr);
1516 if (errstr)
1517 return (-1);
1518 guess_search = tmp;
1519 return (0);
1523 set_read_only_cookies(char *value)
1525 int tmp;
1526 const char *errstr;
1528 tmp = strtonum(value, 0, 1, &errstr);
1529 if (errstr)
1530 return (-1);
1531 read_only_cookies = tmp;
1532 g_object_set(G_OBJECT(p_cookiejar), SOUP_COOKIE_JAR_READ_ONLY,
1533 read_only_cookies, (void *)NULL);
1534 return (0);
1537 char *
1538 get_referer(struct settings *s)
1540 if (referer_mode == XT_REFERER_ALWAYS)
1541 return (g_strdup("always"));
1542 if (referer_mode == XT_REFERER_NEVER)
1543 return (g_strdup("never"));
1544 if (referer_mode == XT_REFERER_SAME_DOMAIN)
1545 return (g_strdup("same-domain"));
1546 if (referer_mode == XT_REFERER_SAME_FQDN)
1547 return (g_strdup("same-fqdn"));
1548 if (referer_mode == XT_REFERER_CUSTOM)
1549 return (g_strdup(referer_custom));
1550 return (NULL);
1554 set_referer(struct settings *s, char *value)
1556 if (referer_custom)
1557 g_free(referer_custom);
1559 if (!strcmp(value, "always"))
1560 referer_mode = XT_REFERER_ALWAYS;
1561 else if (!strcmp(value, "never"))
1562 referer_mode = XT_REFERER_NEVER;
1563 else if (!strcmp(value, "same-domain"))
1564 referer_mode = XT_REFERER_SAME_DOMAIN;
1565 else if (!strcmp(value, "same-fqdn"))
1566 referer_mode = XT_REFERER_SAME_FQDN;
1567 else if (!valid_url_type(value)) {
1568 referer_mode = XT_REFERER_CUSTOM;
1569 referer_custom = g_strdup(value);
1570 } else {
1571 /* we've already free'd the custom referer */
1572 if (referer_mode == XT_REFERER_CUSTOM)
1573 referer_mode = XT_REFERER_NEVER;
1574 return (1);
1577 return (0);
1581 set_referer_rt(char *value)
1583 if (value == NULL || strlen(value) == 0)
1584 return (-1);
1585 return (set_referer(NULL, value));
1589 set_refresh_interval(char *value)
1591 int tmp;
1592 const char *errstr;
1594 tmp = strtonum(value, 0, INT_MAX, &errstr);
1595 if (errstr)
1596 return (-1);
1597 refresh_interval = tmp;
1598 return (0);
1602 set_session_autosave(char *value)
1604 int tmp;
1605 const char *errstr;
1607 tmp = strtonum(value, 0, 1, &errstr);
1608 if (errstr)
1609 return (-1);
1610 session_autosave = tmp;
1611 return (0);
1615 set_session_timeout(char *value)
1617 int tmp;
1618 const char *errstr;
1620 tmp = strtonum(value, 0, INT_MAX, &errstr);
1621 if (errstr)
1622 return (-1);
1623 session_timeout = tmp;
1624 return (0);
1628 set_show_statusbar(char *value)
1630 int tmp;
1631 const char *errstr;
1633 tmp = strtonum(value, 0, 1, &errstr);
1634 if (errstr)
1635 return (-1);
1636 show_statusbar = tmp;
1637 statusbar_set_visibility();
1638 return (0);
1642 set_show_tabs(char *value)
1644 struct karg args = {0};
1645 int val;
1646 const char *errstr;
1648 val = strtonum(value, 0, 1, &errstr);
1649 if (errstr)
1650 return (-1);
1651 args.i = val ? XT_TAB_SHOW : XT_TAB_HIDE;
1652 tabaction(get_current_tab(), &args);
1653 return (0);
1657 set_show_url(char *value)
1659 struct karg args = {0};
1660 int val;
1661 const char *errstr;
1663 val = strtonum(value, 0, 1, &errstr);
1664 if (errstr)
1665 return (-1);
1666 args.i = val ? XT_URL_SHOW : XT_URL_HIDE;
1667 urlaction(get_current_tab(), &args);
1668 return (0);
1672 set_spell_check_languages(char *value)
1674 struct tab *t;
1676 if (value == NULL || strlen(value) == 0)
1677 return (-1);
1678 if (spell_check_languages)
1679 g_free(spell_check_languages);
1680 spell_check_languages = g_strdup(value);
1681 TAILQ_FOREACH(t, &tabs, entry)
1682 g_object_set(G_OBJECT(t->settings), "spell_checking_languages",
1683 spell_check_languages, (char *)NULL);
1684 return (0);
1688 check_valid_file(char *name)
1690 struct stat sb;
1692 if (name == NULL || stat(name, &sb))
1693 return (-1);
1694 return (0);
1698 set_ssl_ca_file_rt(char *value)
1700 if (value == NULL || strlen(value) == 0)
1701 return (-1);
1702 if (set_ssl_ca_file(value))
1703 return (-1);
1704 return (0);
1708 set_ssl_strict_certs(char *value)
1710 int tmp;
1711 const char *errstr;
1713 tmp = strtonum(value, 0, 1, &errstr);
1714 if (errstr)
1715 return (-1);
1716 ssl_strict_certs = tmp;
1717 set_ssl_ca_file(ssl_ca_file);
1718 return (0);
1722 set_external_editor(char *editor)
1724 if (external_editor)
1725 g_free(external_editor);
1727 external_editor = g_strdup(editor);
1729 return (0);
1732 void
1733 setup_proxy(char *uri)
1735 if (proxy_uri) {
1736 g_object_set(session, "proxy_uri", NULL, (char *)NULL);
1737 soup_uri_free(proxy_uri);
1738 proxy_uri = NULL;
1740 if (http_proxy) {
1741 if (http_proxy != uri) {
1742 g_free(http_proxy);
1743 http_proxy = NULL;
1747 if (uri) {
1748 http_proxy = g_strdup(uri);
1749 DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri);
1750 proxy_uri = soup_uri_new(http_proxy);
1751 if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri)))
1752 g_object_set(session, "proxy-uri", proxy_uri,
1753 (char *)NULL);
1757 char *
1758 get_tab_style(struct settings *s)
1760 if (tab_style == XT_TABS_NORMAL)
1761 return (g_strdup("normal"));
1762 else
1763 return (g_strdup("compact"));
1767 set_tab_style(struct settings *s, char *val)
1769 if (!strcmp(val, "normal"))
1770 tab_style = XT_TABS_NORMAL;
1771 else if (!strcmp(val, "compact"))
1772 tab_style = XT_TABS_COMPACT;
1773 else
1774 return (1);
1776 return (0);
1780 set_tab_style_rt(char *value)
1782 struct karg args = {0};
1783 int old_tab_style;
1785 old_tab_style = tab_style;
1786 if (set_tab_style(NULL, value))
1787 return (-1);
1788 if (old_tab_style != tab_style) {
1789 tab_style = old_tab_style;
1790 args.i = XT_TAB_NEXTSTYLE;
1791 tabaction(get_current_tab(), &args);
1793 return (0);
1797 set_url_regex(char *value)
1799 if (regcomp(&url_re, value, REG_EXTENDED | REG_NOSUB))
1800 return (-1);
1801 if (url_regex)
1802 g_free(url_regex);
1803 url_regex = g_strdup(value);
1804 return (0);
1808 set_userstyle_global(char *value)
1810 struct karg args = {0};
1811 int tmp, old_style;
1812 const char *errstr;
1814 old_style = userstyle_global;
1815 tmp = strtonum(value, 0, 1, &errstr);
1816 if (errstr)
1817 return (-1);
1818 if (tmp != old_style) {
1819 args.i = XT_STYLE_GLOBAL;
1820 userstyle(get_current_tab(), &args);
1822 return (0);
1825 char *
1826 get_edit_mode(struct settings *s)
1828 if (edit_mode == XT_EM_HYBRID)
1829 return (g_strdup("hybrid"));
1830 else
1831 return (g_strdup("vi"));
1835 set_edit_mode(struct settings *s, char *val)
1837 if (!strcmp(val, "hybrid"))
1838 edit_mode = XT_EM_HYBRID;
1839 else if (!strcmp(val, "vi"))
1840 edit_mode = XT_EM_VI;
1841 else
1842 return (1);
1844 return (0);
1847 char *
1848 get_download_mode(struct settings *s)
1850 switch (download_mode) {
1851 case XT_DM_START:
1852 return (g_strdup("start"));
1853 break;
1854 case XT_DM_ASK:
1855 return (g_strdup("ask"));
1856 break;
1857 case XT_DM_ADD:
1858 return (g_strdup("add"));
1859 break;
1861 return (g_strdup("unknown"));
1865 set_download_mode(struct settings *s, char *val)
1867 if (!strcmp(val, "start"))
1868 download_mode = XT_DM_START;
1869 else if (!strcmp(val, "ask"))
1870 download_mode = XT_DM_ASK;
1871 else if (!strcmp(val, "add"))
1872 download_mode = XT_DM_ADD;
1873 else
1874 return (1);
1876 return (0);
1880 set_download_mode_rt(char *val)
1882 if (val == NULL || strlen(val) == 0)
1883 return (-1);
1884 return (set_download_mode(NULL, val));
1887 char *
1888 get_work_dir(struct settings *s)
1890 if (work_dir[0] == '\0')
1891 return (0);
1892 return (g_strdup(work_dir));
1896 set_work_dir(struct settings *s, char *val)
1898 if (val[0] == '~')
1899 snprintf(work_dir, sizeof work_dir, "%s" PS "%s",
1900 pwd->pw_dir, &val[1]);
1901 else
1902 strlcpy(work_dir, val, sizeof work_dir);
1904 return (0);
1908 set_xterm_workaround(char *value)
1910 int tmp;
1911 const char *errstr;
1913 tmp = strtonum(value, 0, 1, &errstr);
1914 if (errstr)
1915 return (-1);
1916 xterm_workaround = tmp;
1917 return (0);
1920 void
1921 walk_cookie_wl(struct settings *s,
1922 void (*cb)(struct settings *, char *, void *), void *cb_args)
1924 struct domain *d;
1926 if (s == NULL || cb == NULL) {
1927 show_oops(NULL, "walk_cookie_wl invalid parameters");
1928 return;
1931 RB_FOREACH_REVERSE(d, domain_list, &c_wl)
1932 cb(s, d->d, cb_args);
1935 void
1936 walk_js_wl(struct settings *s,
1937 void (*cb)(struct settings *, char *, void *), void *cb_args)
1939 struct domain *d;
1941 if (s == NULL || cb == NULL) {
1942 show_oops(NULL, "walk_js_wl invalid parameters");
1943 return;
1946 RB_FOREACH_REVERSE(d, domain_list, &js_wl)
1947 cb(s, d->d, cb_args);
1950 void
1951 walk_pl_wl(struct settings *s,
1952 void (*cb)(struct settings *, char *, void *), void *cb_args)
1954 struct domain *d;
1956 if (s == NULL || cb == NULL) {
1957 show_oops(NULL, "walk_pl_wl invalid parameters");
1958 return;
1961 RB_FOREACH_REVERSE(d, domain_list, &pl_wl)
1962 cb(s, d->d, cb_args);
1966 settings_add(char *var, char *val)
1968 int i, rv, *p;
1969 gfloat *f;
1970 char **s;
1972 /* get settings */
1973 for (i = 0, rv = 0; i < LENGTH(rs); i++) {
1974 if (strcmp(var, rs[i].name))
1975 continue;
1977 if (rs[i].s) {
1978 if (rs[i].s->set(&rs[i], val))
1979 errx(1, "invalid value for %s: %s", var, val);
1980 rv = 1;
1981 break;
1982 } else
1983 switch (rs[i].type) {
1984 case XT_S_INT:
1985 p = rs[i].ival;
1986 *p = atoi(val);
1987 rv = 1;
1988 break;
1989 case XT_S_STR:
1990 s = rs[i].sval;
1991 if (s == NULL)
1992 errx(1, "invalid sval for %s",
1993 rs[i].name);
1994 if (*s)
1995 g_free(*s);
1996 *s = g_strdup(val);
1997 rv = 1;
1998 break;
1999 case XT_S_FLOAT:
2000 f = rs[i].fval;
2001 *f = atof(val);
2002 rv = 1;
2003 break;
2004 case XT_S_INVALID:
2005 default:
2006 errx(1, "invalid type for %s", var);
2008 break;
2010 return (rv);
2013 #define WS "\n= \t"
2014 void
2015 config_parse(char *filename, int runtime)
2017 FILE *config, *f;
2018 char *line, *cp, *var, *val;
2019 size_t len, lineno = 0;
2020 int handled;
2021 char file[PATH_MAX];
2022 struct stat sb;
2024 DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename);
2026 if (filename == NULL)
2027 return;
2029 if (runtime && runtime_settings[0] != '\0') {
2030 snprintf(file, sizeof file, "%s" PS "%s",
2031 work_dir, runtime_settings);
2032 if (stat(file, &sb)) {
2033 warnx("runtime file doesn't exist, creating it");
2034 if ((f = fopen(file, "w")) == NULL)
2035 err(1, "runtime");
2036 fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n");
2037 fclose(f);
2039 } else
2040 strlcpy(file, filename, sizeof file);
2042 if ((config = fopen(file, "r")) == NULL) {
2043 warn("config_parse: cannot open %s", filename);
2044 return;
2047 for (;;) {
2048 if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
2049 if (feof(config) || ferror(config))
2050 break;
2052 cp = line;
2053 cp += (long)strspn(cp, WS);
2054 if (cp[0] == '\0') {
2055 /* empty line */
2056 free(line);
2057 continue;
2060 if ((var = strsep(&cp, WS)) == NULL || cp == NULL)
2061 startpage_add("invalid configuration file entry: %s",
2062 line);
2063 else {
2064 cp += (long)strspn(cp, WS);
2066 if ((val = strsep(&cp, "\0")) == NULL)
2067 break;
2069 DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n",
2070 var, val);
2071 handled = settings_add(var, val);
2073 if (handled == 0)
2074 startpage_add("invalid configuration file entry"
2075 ": %s=%s", var, val);
2078 free(line);
2081 fclose(config);
2084 struct settings_args {
2085 char **body;
2086 int i;
2089 void
2090 print_setting(struct settings *s, char *val, void *cb_args)
2092 char *tmp, *color;
2093 struct settings_args *sa = cb_args;
2095 if (sa == NULL)
2096 return;
2098 if (s->flags & XT_SF_RUNTIME)
2099 color = "#22cc22";
2100 else
2101 color = "#cccccc";
2103 tmp = *sa->body;
2104 *sa->body = g_strdup_printf(
2105 "%s\n<tr>"
2106 "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>"
2107 "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>",
2108 *sa->body,
2109 color,
2110 s->name,
2111 color,
2114 g_free(tmp);
2115 sa->i++;
2119 set_show(struct tab *t, struct karg *args)
2121 char *body, *page, *tmp;
2122 int i = 1;
2123 struct settings_args sa;
2125 bzero(&sa, sizeof sa);
2126 sa.body = &body;
2128 /* body */
2129 body = g_strdup_printf("<div align='center'><table><tr>"
2130 "<th align='left'>Setting</th>"
2131 "<th align='left'>Value</th></tr>\n");
2133 settings_walk(print_setting, &sa);
2134 i = sa.i;
2136 /* small message if there are none */
2137 if (i == 1) {
2138 tmp = body;
2139 body = g_strdup_printf("%s\n<tr><td style='text-align:center'"
2140 "colspan='2'>No settings</td></tr>\n", body);
2141 g_free(tmp);
2144 tmp = body;
2145 body = g_strdup_printf("%s</table></div>", body);
2146 g_free(tmp);
2148 page = get_html_page("Settings", body, "", 0);
2150 g_free(body);
2152 load_webkit_string(t, page, XT_URI_ABOUT_SET);
2154 g_free(page);
2156 return (XT_CB_PASSTHROUGH);
2160 set(struct tab *t, struct karg *args)
2162 char *p, *val;
2163 int i;
2165 if (args == NULL || args->s == NULL)
2166 return (set_show(t, args));
2168 /* strip spaces */
2169 p = g_strstrip(args->s);
2171 if (strlen(p) == 0)
2172 return (set_show(t, args));
2174 /* we got some sort of string */
2175 val = g_strstr_len(p, strlen(p), "=");
2176 if (val) {
2177 *val++ = '\0';
2178 val = g_strstrip(val);
2179 p = g_strchomp(p);
2181 for (i = 0; i < get_settings_size(); i++) {
2182 if (strcmp(rs[i].name, p))
2183 continue;
2185 if (rs[i].activate) {
2186 if (rs[i].activate(val))
2187 show_oops(t, "%s invalid value %s",
2188 p, val);
2189 else
2190 show_oops(t, ":set %s = %s", p, val);
2191 goto done;
2192 } else {
2193 show_oops(t, "not a runtime option: %s", p);
2194 goto done;
2197 show_oops(t, "unknown option: %s", p);
2198 } else {
2199 p = g_strchomp(p);
2201 for (i = 0; i < get_settings_size(); i++) {
2202 if (strcmp(rs[i].name, p))
2203 continue;
2205 /* XXX this could use some cleanup */
2206 switch (rs[i].type) {
2207 case XT_S_INT:
2208 if (rs[i].ival)
2209 show_oops(t, "%s = %d",
2210 rs[i].name, *rs[i].ival);
2211 else if (rs[i].s && rs[i].s->get)
2212 show_oops(t, "%s = %s",
2213 rs[i].name,
2214 rs[i].s->get(&rs[i]));
2215 else if (rs[i].s && rs[i].s->get == NULL)
2216 show_oops(t, "%s = ...", rs[i].name);
2217 else
2218 show_oops(t, "%s = ", rs[i].name);
2219 break;
2220 case XT_S_FLOAT:
2221 if (rs[i].fval)
2222 show_oops(t, "%s = %f",
2223 rs[i].name, *rs[i].fval);
2224 else if (rs[i].s && rs[i].s->get)
2225 show_oops(t, "%s = %s",
2226 rs[i].name,
2227 rs[i].s->get(&rs[i]));
2228 else if (rs[i].s && rs[i].s->get == NULL)
2229 show_oops(t, "%s = ...", rs[i].name);
2230 else
2231 show_oops(t, "%s = ", rs[i].name);
2232 break;
2233 case XT_S_STR:
2234 if (rs[i].sval && *rs[i].sval)
2235 show_oops(t, "%s = %s",
2236 rs[i].name, *rs[i].sval);
2237 else if (rs[i].s && rs[i].s->get)
2238 show_oops(t, "%s = %s",
2239 rs[i].name,
2240 rs[i].s->get(&rs[i]));
2241 else if (rs[i].s && rs[i].s->get == NULL)
2242 show_oops(t, "%s = ...", rs[i].name);
2243 else
2244 show_oops(t, "%s = ", rs[i].name);
2245 break;
2246 default:
2247 show_oops(t, "unknown type for %s", rs[i].name);
2248 goto done;
2251 goto done;
2253 show_oops(t, "unknown option: %s", p);
2255 done:
2256 return (XT_CB_PASSTHROUGH);