Add a setting to read additional config files from any other config
[xxxterm.git] / settings.c
blobb0d773e39e9c635091d27dc3d954099855708db4
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;
104 int download_notifications = 0;
105 char *include_config = NULL;
107 char *cmd_font_name = NULL;
108 char *oops_font_name = NULL;
109 char *statusbar_font_name = NULL;
110 char *tabbar_font_name = NULL;
112 char *get_download_dir(struct settings *);
113 char *get_default_script(struct settings *);
114 char *get_runtime_dir(struct settings *);
115 char *get_tab_style(struct settings *);
116 char *get_edit_mode(struct settings *);
117 char *get_download_mode(struct settings *);
118 char *get_work_dir(struct settings *);
119 char *get_referer(struct settings *);
121 int add_cookie_wl(struct settings *, char *);
122 int add_js_wl(struct settings *, char *);
123 int add_pl_wl(struct settings *, char *);
124 int add_mime_type(struct settings *, char *);
125 int add_alias(struct settings *, char *);
126 int add_kb(struct settings *, char *);
127 int add_ua(struct settings *, char *);
129 int set_append_next(char *);
130 int set_cmd_font(char *);
131 int set_color_visited_uris(char *);
132 int set_cookie_policy_rt(char *);
133 int set_cookies_enabled(char *);
134 int set_ctrl_click_focus(char *);
135 int set_home(char *);
136 int set_download_dir(struct settings *, char *);
137 int set_download_notifications(char *);
138 int set_default_script(struct settings *, char *);
139 int set_default_script_rt(char *);
140 int set_default_zoom_level(char *);
141 int set_enable_cookie_whitelist(char *);
142 int set_enable_js_autorun(char *);
143 int set_enable_js_whitelist(char *);
144 int set_enable_localstorage(char *);
145 int set_enable_plugins(char *);
146 int set_enable_plugin_whitelist(char *);
147 int set_enable_scripts(char *);
148 int set_enable_spell_checking(char *);
149 int set_enable_strict_transport(char *);
150 int set_encoding_rt(char *);
151 int set_runtime_dir(struct settings *, char *);
152 int set_tabbar_font(char *value);
153 int set_tab_style(struct settings *, char *);
154 int set_tab_style_rt(char *);
155 int set_edit_mode(struct settings *, char *);
156 int set_work_dir(struct settings *, char *);
157 int set_auto_load_images(char *);
158 int set_enable_autoscroll(char *);
159 int set_enable_favicon_entry(char *);
160 int set_enable_favicon_tabs(char *);
161 int set_guess_search(char *);
162 int set_download_mode(struct settings *, char *);
163 int set_download_mode_rt(char *);
164 int set_oops_font(char *);
165 int set_read_only_cookies(char *);
166 int set_referer(struct settings *, char *);
167 int set_referer_rt(char *);
168 int set_refresh_interval(char *);
169 int set_search_string(char *s);
170 int set_session_autosave(char *);
171 int set_session_timeout(char *);
172 int set_show_statusbar(char *);
173 int set_show_tabs(char *);
174 int set_show_url(char *);
175 int set_spell_check_languages(char *);
176 int set_ssl_ca_file_rt(char *);
177 int set_ssl_strict_certs(char *);
178 int set_statusbar_font(char *);
179 int set_url_regex(char *);
180 int set_userstyle_global(char *);
181 int set_external_editor(char *);
182 int set_xterm_workaround(char *);
184 void walk_mime_type(struct settings *, void (*)(struct settings *,
185 char *, void *), void *);
186 void walk_alias(struct settings *, void (*)(struct settings *,
187 char *, void *), void *);
188 void walk_cookie_wl(struct settings *, void (*)(struct settings *,
189 char *, void *), void *);
190 void walk_js_wl(struct settings *, void (*)(struct settings *,
191 char *, void *), void *);
192 void walk_pl_wl(struct settings *, void (*)(struct settings *,
193 char *, void *), void *);
194 void walk_kb(struct settings *, void (*)(struct settings *, char *,
195 void *), void *);
196 void walk_ua(struct settings *, void (*)(struct settings *, char *,
197 void *), void *);
200 set_http_proxy(char *proxy)
202 SoupURI *uri;
204 if (proxy == NULL)
205 return (1);
207 /* see if we need to clear it instead */
208 if (strlen(proxy) == 0) {
209 setup_proxy(NULL);
210 return (0);
213 uri = soup_uri_new(proxy);
214 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
215 return (1);
217 setup_proxy(proxy);
219 soup_uri_free(uri);
221 return (0);
224 struct special {
225 int (*set)(struct settings *, char *);
226 char *(*get)(struct settings *);
227 void (*walk)(struct settings *,
228 void (*cb)(struct settings *, char *, void *),
229 void *);
232 struct special s_browser_mode = {
233 set_browser_mode,
234 get_browser_mode,
235 NULL
238 struct special s_gui_mode = {
239 set_gui_mode,
240 get_gui_mode,
241 NULL
244 struct special s_cookie = {
245 set_cookie_policy,
246 get_cookie_policy,
247 NULL
250 struct special s_alias = {
251 add_alias,
252 NULL,
253 walk_alias
256 struct special s_mime = {
257 add_mime_type,
258 NULL,
259 walk_mime_type
262 struct special s_js = {
263 add_js_wl,
264 NULL,
265 walk_js_wl
268 struct special s_pl = {
269 add_pl_wl,
270 NULL,
271 walk_pl_wl
274 struct special s_kb = {
275 add_kb,
276 NULL,
277 walk_kb
280 struct special s_cookie_wl = {
281 add_cookie_wl,
282 NULL,
283 walk_cookie_wl
286 struct special s_default_script = {
287 set_default_script,
288 get_default_script,
289 NULL
292 struct special s_download_dir = {
293 set_download_dir,
294 get_download_dir,
295 NULL
298 struct special s_work_dir = {
299 set_work_dir,
300 get_work_dir,
301 NULL
304 struct special s_tab_style = {
305 set_tab_style,
306 get_tab_style,
307 NULL
310 struct special s_edit_mode = {
311 set_edit_mode,
312 get_edit_mode,
313 NULL
316 struct special s_download_mode = {
317 set_download_mode,
318 get_download_mode,
319 NULL
322 struct special s_ua = {
323 add_ua,
324 NULL,
325 walk_ua
328 struct special s_referer = {
329 set_referer,
330 get_referer,
331 NULL
334 struct settings rs[] = {
335 { "allow_volatile_cookies", XT_S_INT, 0, &allow_volatile_cookies, NULL, NULL, NULL, NULL},
336 { "autofocus_onload", XT_S_INT, 0, &autofocus_onload, NULL, NULL, NULL, NULL },
337 { "browser_mode", XT_S_INT, 0, NULL, NULL,&s_browser_mode, NULL, NULL },
338 { "gui_mode", XT_S_INT, 0, NULL, NULL,&s_gui_mode, NULL, NULL },
339 { "color_visited_uris", XT_S_INT, 0, &color_visited_uris , NULL, NULL, NULL, set_color_visited_uris },
340 { "cookie_policy", XT_S_INT, 0, NULL, NULL,&s_cookie, NULL, set_cookie_policy_rt },
341 { "cookies_enabled", XT_S_INT, 0, &cookies_enabled, NULL, NULL, NULL, set_cookies_enabled },
342 { "ctrl_click_focus", XT_S_INT, 0, &ctrl_click_focus, NULL, NULL, NULL, set_ctrl_click_focus },
343 { "default_zoom_level", XT_S_FLOAT, 0, NULL, NULL, NULL, &default_zoom_level, set_default_zoom_level },
344 { "default_script", XT_S_STR, 0, NULL, NULL,&s_default_script, NULL, set_default_script_rt },
345 { "download_dir", XT_S_STR, 0, NULL, NULL,&s_download_dir, NULL, NULL },
346 { "download_mode", XT_S_STR, 0, NULL, NULL,&s_download_mode, NULL, set_download_mode_rt },
347 { "edit_mode", XT_S_STR, 0, NULL, NULL,&s_edit_mode, NULL, NULL},
348 { "enable_cookie_whitelist", XT_S_INT, 0, &enable_cookie_whitelist, NULL, NULL, NULL, set_enable_cookie_whitelist },
349 { "enable_js_whitelist", XT_S_INT, 0, &enable_js_whitelist, NULL, NULL, NULL, set_enable_js_whitelist },
350 { "enable_plugin_whitelist", XT_S_INT, 0, &enable_plugin_whitelist, NULL, NULL, NULL, set_enable_plugin_whitelist },
351 { "enable_localstorage", XT_S_INT, 0, &enable_localstorage, NULL, NULL, NULL, set_enable_localstorage },
352 { "enable_plugins", XT_S_INT, 0, &enable_plugins, NULL, NULL, NULL, set_enable_plugins },
353 { "enable_scripts", XT_S_INT, 0, &enable_scripts, NULL, NULL, NULL, set_enable_scripts },
354 { "enable_socket", XT_S_INT, XT_SF_RESTART,&enable_socket, NULL, NULL, NULL, NULL },
355 { "enable_spell_checking", XT_S_INT, 0, &enable_spell_checking, NULL, NULL, NULL, set_enable_spell_checking },
356 { "encoding", XT_S_STR, 0, NULL, &encoding, NULL, NULL, NULL },
357 { "external_editor", XT_S_STR,0, NULL, &external_editor, NULL, NULL, set_external_editor },
358 { "fancy_bar", XT_S_INT, XT_SF_RESTART,&fancy_bar, NULL, NULL, NULL, NULL },
359 { "guess_search", XT_S_INT, 0, &guess_search, NULL, NULL, NULL, set_guess_search },
360 { "history_autosave", XT_S_INT, 0, &history_autosave, NULL, NULL, NULL, NULL },
361 { "http_proxy", XT_S_STR, 0, NULL, &http_proxy, NULL, NULL, set_http_proxy },
362 { "icon_size", XT_S_INT, 0, &icon_size, NULL, NULL, NULL, NULL },
363 { "enable_js_autorun", XT_S_INT, 0, &enable_js_autorun, NULL, NULL, NULL, set_enable_js_autorun },
364 { "max_connections", XT_S_INT, XT_SF_RESTART,&max_connections, NULL, NULL, NULL, NULL },
365 { "max_host_connections", XT_S_INT, XT_SF_RESTART,&max_host_connections, NULL, NULL, NULL, NULL },
366 { "read_only_cookies", XT_S_INT, 0, &read_only_cookies, NULL, NULL, NULL, set_read_only_cookies },
367 { "refresh_interval", XT_S_INT, 0, &refresh_interval, NULL, NULL, NULL, set_refresh_interval },
368 { "resource_dir", XT_S_STR, 0, NULL, &resource_dir, NULL, NULL, NULL },
369 { "search_string", XT_S_STR, 0, NULL, &search_string, NULL, NULL, set_search_string },
370 { "save_global_history", XT_S_INT, XT_SF_RESTART,&save_global_history, NULL, NULL, NULL, NULL },
371 { "save_rejected_cookies", XT_S_INT, XT_SF_RESTART,&save_rejected_cookies, NULL, NULL, NULL, NULL },
372 { "session_timeout", XT_S_INT, 0, &session_timeout, NULL, NULL, NULL, set_session_timeout },
373 { "session_autosave", XT_S_INT, 0, &session_autosave, NULL, NULL, NULL, set_session_autosave },
374 { "single_instance", XT_S_INT, XT_SF_RESTART,&single_instance, NULL, NULL, NULL, NULL },
375 { "show_tabs", XT_S_INT, 0, &show_tabs, NULL, NULL, NULL, set_show_tabs },
376 { "show_url", XT_S_INT, 0, &show_url, NULL, NULL, NULL, set_show_url },
377 { "show_statusbar", XT_S_INT, 0, &show_statusbar, NULL, NULL, NULL, set_show_statusbar },
378 { "spell_check_languages", XT_S_STR, 0, NULL, &spell_check_languages, NULL, NULL, set_spell_check_languages },
379 { "ssl_ca_file", XT_S_STR, 0, NULL, &ssl_ca_file, NULL, NULL, set_ssl_ca_file_rt },
380 { "ssl_strict_certs", XT_S_INT, 0, &ssl_strict_certs, NULL, NULL, NULL, set_ssl_strict_certs },
381 { "enable_strict_transport", XT_S_INT, 0, &enable_strict_transport, NULL, NULL, NULL, set_enable_strict_transport },
382 { "statusbar_elems", XT_S_STR, 0, NULL, &statusbar_elems, NULL, NULL, NULL },
383 { "tab_style", XT_S_STR, 0, NULL, NULL,&s_tab_style, NULL, set_tab_style_rt },
384 { "userstyle_global", XT_S_INT, 0, &userstyle_global, NULL, NULL, NULL, set_userstyle_global },
385 { "url_regex", XT_S_STR, 0, NULL, &url_regex, NULL, NULL, set_url_regex },
386 { "window_height", XT_S_INT, 0, &window_height, NULL, NULL, NULL, NULL },
387 { "window_width", XT_S_INT, 0, &window_width, NULL, NULL, NULL, NULL },
388 { "window_maximize", XT_S_INT, 0, &window_maximize, NULL, NULL, NULL, NULL },
389 { "work_dir", XT_S_STR, 0, NULL, NULL,&s_work_dir, NULL, NULL },
390 { "xterm_workaround", XT_S_INT, 0, &xterm_workaround, NULL, NULL, NULL, set_xterm_workaround },
391 { "auto_load_images", XT_S_INT, 0, &auto_load_images, NULL, NULL, NULL, set_auto_load_images },
392 { "enable_favicon_entry", XT_S_INT, 0, &enable_favicon_entry, NULL, NULL, NULL, set_enable_favicon_entry },
393 { "enable_favicon_tabs", XT_S_INT, 0, &enable_favicon_tabs, NULL, NULL, NULL, set_enable_favicon_tabs },
394 { "referer", XT_S_STR, 0, NULL, NULL,&s_referer, NULL, set_referer_rt },
395 { "download_notifications", XT_S_INT, 0, &download_notifications, NULL, NULL, NULL, set_download_notifications },
396 { "include_config", XT_S_STR, 0, NULL, &include_config, NULL, NULL, NULL },
398 /* font settings */
399 { "cmd_font", XT_S_STR, 0, NULL, &cmd_font_name, NULL, NULL, set_cmd_font },
400 { "oops_font", XT_S_STR, 0, NULL, &oops_font_name, NULL, NULL, set_oops_font },
401 { "statusbar_font", XT_S_STR, 0, NULL, &statusbar_font_name, NULL, NULL, set_statusbar_font },
402 { "tabbar_font", XT_S_STR, 0, NULL, &tabbar_font_name, NULL, NULL, set_tabbar_font },
404 /* runtime settings */
405 { "append_next", XT_S_INT, 0, &append_next, NULL, NULL, NULL, set_append_next },
406 { "enable_autoscroll", XT_S_INT, 0, &enable_autoscroll, NULL, NULL, NULL, set_enable_autoscroll },
407 { "home", XT_S_STR, 0, NULL, &home, NULL, NULL, set_home },
409 /* special settings */
410 { "alias", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_alias, NULL, NULL },
411 { "cookie_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_cookie_wl, NULL, NULL },
412 { "js_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_js, NULL, NULL },
413 { "keybinding", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
414 { "mime_type", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
415 { "pl_wl", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
416 { "user_agent", XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
420 set_default_zoom_level(char *value)
422 struct karg args = {0};
423 struct tab *t;
425 if (value == NULL || strlen(value) == 0)
426 return (-1);
427 default_zoom_level = g_strtod(value, NULL);
428 args.i = 100; /* adjust = 100 percent for no additional adjustment */
429 TAILQ_FOREACH(t, &tabs, entry)
430 resizetab(t, &args);
431 return (0);
435 set_cookies_enabled(char *value)
437 int tmp;
438 const char *errstr;
440 tmp = strtonum(value, 0, 1, &errstr);
441 if (errstr)
442 return (-1);
443 cookies_enabled = tmp;
444 return (0);
448 set_append_next(char *value)
450 int tmp;
451 const char *errstr;
453 tmp = strtonum(value, 0, 1, &errstr);
454 if (errstr)
455 return (-1);
456 append_next = tmp;
457 return (0);
461 set_cmd_font(char *value)
463 struct tab *t;
465 if (value == NULL || strlen(value))
466 return (-1);
467 if (cmd_font_name)
468 g_free(cmd_font_name);
469 if (cmd_font)
470 pango_font_description_free(cmd_font);
471 cmd_font_name = g_strdup(value);
472 cmd_font = pango_font_description_from_string(cmd_font_name);
473 TAILQ_FOREACH(t, &tabs, entry)
474 gtk_widget_modify_font(GTK_WIDGET(t->cmd), cmd_font);
475 return (0);
479 set_oops_font(char *value)
481 struct tab *t;
483 if (value == NULL || strlen(value) == 0)
484 return (-1);
485 if (oops_font_name)
486 g_free(oops_font_name);
487 if (oops_font)
488 pango_font_description_free(oops_font);
489 oops_font_name = g_strdup(value);
490 oops_font = pango_font_description_from_string(oops_font_name);
491 TAILQ_FOREACH(t, &tabs, entry)
492 gtk_widget_modify_font(GTK_WIDGET(t->oops), oops_font);
493 return (0);
497 set_statusbar_font(char *value)
499 struct tab *t;
501 if (value == NULL || strlen(value) == 0)
502 return (-1);
503 if (statusbar_font_name)
504 g_free(statusbar_font_name);
505 if (statusbar_font)
506 pango_font_description_free(statusbar_font);
507 statusbar_font_name = g_strdup(value);
508 statusbar_font = pango_font_description_from_string(
509 statusbar_font_name);
510 TAILQ_FOREACH(t, &tabs, entry) {
511 gtk_widget_modify_font(GTK_WIDGET(t->sbe.statusbar),
512 statusbar_font);
513 gtk_widget_modify_font(GTK_WIDGET(t->sbe.buffercmd),
514 statusbar_font);
515 gtk_widget_modify_font(GTK_WIDGET(t->sbe.zoom),
516 statusbar_font);
517 gtk_widget_modify_font(GTK_WIDGET(t->sbe.position),
518 statusbar_font);
520 return (0);
524 set_tabbar_font(char *value)
526 struct tab *t;
528 if (value == NULL || strlen(value) == 0)
529 return (-1);
530 if (tabbar_font_name)
531 g_free(tabbar_font_name);
532 if (tabbar_font)
533 pango_font_description_free(tabbar_font);
534 tabbar_font_name = g_strdup(value);
535 tabbar_font = pango_font_description_from_string(tabbar_font_name);
536 TAILQ_FOREACH(t, &tabs, entry)
537 gtk_widget_modify_font(GTK_WIDGET(t->tab_elems.label),
538 tabbar_font);
539 return (0);
543 set_color_visited_uris(char *value)
545 int tmp;
546 const char *errstr;
548 tmp = strtonum(value, 0, 1, &errstr);
549 if (errstr)
550 return (-1);
551 color_visited_uris = tmp;
552 return (0);
556 set_home(char *value)
558 if (value == NULL || strlen(value) == 0)
559 return (-1);
560 if (home)
561 g_free(home);
562 home = g_strdup(value);
563 return (0);
567 set_search_string(char *value)
569 if (value == NULL || strlen(value) == 0)
570 return (-1);
571 if (search_string)
572 g_free(search_string);
573 search_string = g_strdup(value);
574 return (0);
577 size_t
578 get_settings_size(void)
580 return (LENGTH(rs));
583 char *
584 get_setting_name(int i)
586 if (i > LENGTH(rs))
587 return (NULL);
588 return (rs[i].name);
591 char *
592 get_as_string(struct settings *s)
594 char *r = NULL;
596 if (s == NULL)
597 return (NULL);
599 if (s->s) {
600 if (s->s->get)
601 r = s->s->get(s);
602 else
603 warnx("get_as_string skip %s\n", s->name);
604 } else if (s->type == XT_S_INT)
605 r = g_strdup_printf("%d", *s->ival);
606 else if (s->type == XT_S_STR)
607 r = g_strdup(*s->sval);
608 else if (s->type == XT_S_FLOAT)
609 r = g_strdup_printf("%f", *s->fval);
610 else
611 r = g_strdup_printf("INVALID TYPE");
613 return (r);
616 void
617 settings_walk(void (*cb)(struct settings *, char *, void *), void *cb_args)
619 int i;
620 char *s;
622 for (i = 0; i < LENGTH(rs); i++) {
623 if (rs[i].s && rs[i].s->walk)
624 rs[i].s->walk(&rs[i], cb, cb_args);
625 else {
626 s = get_as_string(&rs[i]);
627 cb(&rs[i], s, cb_args);
628 g_free(s);
634 set_browser_mode(struct settings *s, char *val)
636 if (!strcmp(val, "whitelist")) {
637 browser_mode = XT_BM_WHITELIST;
638 allow_volatile_cookies = 0;
639 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
640 cookies_enabled = 1;
641 enable_cookie_whitelist = 1;
642 enable_plugin_whitelist = 1;
643 enable_plugins = 0;
644 read_only_cookies = 0;
645 save_rejected_cookies = 0;
646 session_timeout = 3600;
647 enable_scripts = 0;
648 enable_js_whitelist = 1;
649 enable_localstorage = 0;
650 referer_mode = XT_REFERER_SAME_DOMAIN;
651 } else if (!strcmp(val, "normal")) {
652 browser_mode = XT_BM_NORMAL;
653 allow_volatile_cookies = 0;
654 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
655 cookies_enabled = 1;
656 enable_cookie_whitelist = 0;
657 enable_plugin_whitelist = 0;
658 enable_plugins = 1;
659 read_only_cookies = 0;
660 save_rejected_cookies = 0;
661 session_timeout = 3600;
662 enable_scripts = 1;
663 enable_js_whitelist = 0;
664 enable_localstorage = 1;
665 referer_mode = XT_REFERER_ALWAYS;
666 } else if (!strcmp(val, "kiosk")) {
667 browser_mode = XT_BM_KIOSK;
668 allow_volatile_cookies = 0;
669 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
670 cookies_enabled = 1;
671 enable_cookie_whitelist = 0;
672 enable_plugin_whitelist = 0;
673 enable_plugins = 1;
674 read_only_cookies = 0;
675 save_rejected_cookies = 0;
676 session_timeout = 3600;
677 enable_scripts = 1;
678 enable_js_whitelist = 0;
679 enable_localstorage = 1;
680 referer_mode = XT_REFERER_ALWAYS;
681 show_tabs = 0;
682 tabless = 1;
683 } else
684 return (1);
686 return (0);
689 char *
690 get_browser_mode(struct settings *s)
692 char *r = NULL;
694 if (browser_mode == XT_BM_WHITELIST)
695 r = g_strdup("whitelist");
696 else if (browser_mode == XT_BM_NORMAL)
697 r = g_strdup("normal");
698 else if (browser_mode == XT_BM_KIOSK)
699 r = g_strdup("kiosk");
700 else
701 return (NULL);
703 return (r);
707 set_gui_mode(struct settings *s, char *val)
709 if (!strcmp(val, "classic")) {
710 fancy_bar = 1;
711 show_tabs = 1;
712 tab_style = XT_TABS_NORMAL;
713 show_url = 1;
714 show_statusbar = 0;
715 } else if (!strcmp(val, "minimal")) {
716 fancy_bar = 0;
717 show_tabs = 1;
718 tab_style = XT_TABS_COMPACT;
719 show_url = 0;
720 show_statusbar = 1;
721 } else
722 return (1);
724 return (0);
727 char *
728 get_gui_mode(struct settings *s)
730 char *r = NULL;
732 if (gui_mode == XT_GM_CLASSIC)
733 r = g_strdup("classic");
734 else if (browser_mode == XT_GM_MINIMAL)
735 r = g_strdup("minimal");
736 else
737 return (NULL);
739 return (r);
743 set_cookie_policy(struct settings *s, char *val)
745 if (!strcmp(val, "no3rdparty"))
746 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY;
747 else if (!strcmp(val, "accept"))
748 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
749 else if (!strcmp(val, "reject"))
750 cookie_policy = SOUP_COOKIE_JAR_ACCEPT_NEVER;
751 else
752 return (1);
754 return (0);
758 set_cookie_policy_rt(char *value)
760 if (set_cookie_policy(NULL, value))
761 return (-1);
762 g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY,
763 cookie_policy, (void *)NULL);
764 return (0);
767 char *
768 get_cookie_policy(struct settings *s)
770 char *r = NULL;
772 if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY)
773 r = g_strdup("no3rdparty");
774 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
775 r = g_strdup("accept");
776 else if (cookie_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
777 r = g_strdup("reject");
778 else
779 return (NULL);
781 return (r);
784 char *
785 get_default_script(struct settings *s)
787 if (default_script[0] == '\0')
788 return (0);
789 return (g_strdup(default_script));
793 set_default_script(struct settings *s, char *val)
795 if (val[0] == '~')
796 snprintf(default_script, sizeof default_script, "%s" PS "%s",
797 pwd->pw_dir, &val[1]);
798 else
799 strlcpy(default_script, val, sizeof default_script);
801 return (0);
805 set_default_script_rt(char *value)
807 if (value == NULL || strlen(value) == 0)
808 return (-1);
809 return (set_default_script(NULL, value));
812 char *
813 get_download_dir(struct settings *s)
815 if (download_dir[0] == '\0')
816 return (0);
817 return (g_strdup(download_dir));
821 set_download_dir(struct settings *s, char *val)
823 if (val[0] == '~')
824 snprintf(download_dir, sizeof download_dir, "%s" PS "%s",
825 pwd->pw_dir, &val[1]);
826 else
827 strlcpy(download_dir, val, sizeof download_dir);
829 return (0);
833 add_alias(struct settings *s, char *line)
835 char *l, *alias;
836 struct alias *a = NULL;
838 if (s == NULL || line == NULL) {
839 show_oops(NULL, "add_alias invalid parameters");
840 return (1);
843 l = line;
844 a = g_malloc(sizeof(*a));
846 if ((alias = strsep(&l, " \t,")) == NULL || l == NULL) {
847 show_oops(NULL, "add_alias: incomplete alias definition");
848 goto bad;
850 if (strlen(alias) == 0 || strlen(l) == 0) {
851 show_oops(NULL, "add_alias: invalid alias definition");
852 goto bad;
855 a->a_name = g_strdup(alias);
856 a->a_uri = g_strdup(l);
858 DNPRINTF(XT_D_CONFIG, "add_alias: %s for %s\n", a->a_name, a->a_uri);
860 TAILQ_INSERT_TAIL(&aliases, a, entry);
862 return (0);
863 bad:
864 if (a)
865 g_free(a);
866 return (1);
869 void
870 walk_alias(struct settings *s,
871 void (*cb)(struct settings *, char *, void *), void *cb_args)
873 struct alias *a;
874 char *str;
876 if (s == NULL || cb == NULL) {
877 show_oops(NULL, "walk_alias invalid parameters");
878 return;
881 TAILQ_FOREACH(a, &aliases, entry) {
882 str = g_strdup_printf("%s --> %s", a->a_name, a->a_uri);
883 cb(s, str, cb_args);
884 g_free(str);
889 add_mime_type(struct settings *s, char *line)
891 char *mime_type;
892 char *l;
893 struct mime_type *m = NULL;
894 int downloadfirst = 0;
896 /* XXX this could be smarter */
898 if (line == NULL || strlen(line) == 0) {
899 show_oops(NULL, "add_mime_type invalid parameters");
900 return (1);
903 l = line;
904 if (*l == '@') {
905 downloadfirst = 1;
906 l++;
908 m = g_malloc(sizeof(*m));
910 if ((mime_type = strsep(&l, " \t,")) == NULL || l == NULL) {
911 show_oops(NULL, "add_mime_type: invalid mime_type");
912 goto bad;
914 if (mime_type[strlen(mime_type) - 1] == '*') {
915 mime_type[strlen(mime_type) - 1] = '\0';
916 m->mt_default = 1;
917 } else
918 m->mt_default = 0;
920 if (strlen(mime_type) == 0 || strlen(l) == 0) {
921 show_oops(NULL, "add_mime_type: invalid mime_type");
922 goto bad;
925 m->mt_type = g_strdup(mime_type);
926 m->mt_action = g_strdup(l);
927 m->mt_download = downloadfirst;
929 DNPRINTF(XT_D_CONFIG, "add_mime_type: type %s action %s default %d\n",
930 m->mt_type, m->mt_action, m->mt_default);
932 TAILQ_INSERT_TAIL(&mtl, m, entry);
934 return (0);
935 bad:
936 if (m)
937 g_free(m);
938 return (1);
941 void
942 walk_mime_type(struct settings *s,
943 void (*cb)(struct settings *, char *, void *), void *cb_args)
945 struct mime_type *m;
946 char *str;
948 if (s == NULL || cb == NULL) {
949 show_oops(NULL, "walk_mime_type invalid parameters");
950 return;
953 TAILQ_FOREACH(m, &mtl, entry) {
954 str = g_strdup_printf("%s%s --> %s",
955 m->mt_type,
956 m->mt_default ? "*" : "",
957 m->mt_action);
958 cb(s, str, cb_args);
959 g_free(str);
963 /* inherent to GTK not all keys will be caught at all times */
964 /* XXX sort key bindings */
965 struct key_binding keys[] = {
966 { "command_mode", 0, 1, GDK_Escape },
967 { "insert_mode", 0, 0, GDK_i },
968 { "cookiejar", MOD1, 1, GDK_j },
969 { "downloadmgr", MOD1, 1, GDK_d },
970 { "history", MOD1, 1, GDK_h },
971 { "print", CTRL, 1, GDK_p },
972 { "search", 0, 0, GDK_slash },
973 { "searchb", 0, 0, GDK_question },
974 { "statustoggle", CTRL, 1, GDK_n },
975 { "command", 0, 0, GDK_colon },
976 { "qa", CTRL, 1, GDK_q },
977 { "restart", MOD1, 1, GDK_q },
978 { "js toggle", CTRL, 1, GDK_j },
979 { "plugin toggle", MOD1, 1, GDK_p },
980 { "cookie toggle", MOD1, 1, GDK_c },
981 { "togglesrc", CTRL, 1, GDK_s },
982 { "yankuri", 0, 0, GDK_y },
983 { "pasteuricur", 0, 0, GDK_p },
984 { "pasteurinew", 0, 0, GDK_P },
985 { "toplevel toggle", 0, 1, GDK_F4 },
986 { "help", 0, 1, GDK_F1 },
987 { "run_script", MOD1, 1, GDK_r },
988 { "proxy toggle", 0, 1, GDK_F2 },
989 { "editelement", CTRL, 1, GDK_i },
990 { "passthrough", CTRL, 1, GDK_z },
991 { "modurl", CTRL, 1, GDK_Return },
993 /* search */
994 { "searchnext", 0, 0, GDK_n },
995 { "searchprevious", 0, 0, GDK_N },
997 /* focus */
998 { "focusaddress", 0, 1, GDK_F6 },
999 { "focussearch", 0, 1, GDK_F7 },
1001 /* hinting */
1002 { "hinting", 0, 0, GDK_f },
1003 { "hinting", 0, 0, GDK_period },
1004 { "hinting_newtab", SHFT, 0, GDK_F },
1005 { "hinting_newtab", 0, 0, GDK_comma },
1007 /* custom stylesheet */
1008 { "userstyle", 0, 0, GDK_s },
1009 { "userstyle_global", SHFT, 0, GDK_S },
1011 /* navigation */
1012 { "goback", 0, 0, GDK_BackSpace },
1013 { "goback", MOD1, 1, GDK_Left },
1014 { "goforward", SHFT, 1, GDK_BackSpace },
1015 { "goforward", MOD1, 1, GDK_Right },
1016 { "reload", 0, 1, GDK_F5 },
1017 { "reload", CTRL, 1, GDK_r },
1018 { "reload", CTRL, 1, GDK_l },
1019 { "favorites", MOD1, 1, GDK_f },
1021 /* vertical movement */
1022 { "scrolldown", 0, 0, GDK_j },
1023 { "scrolldown", 0, 0, GDK_Down },
1024 { "scrollup", 0, 0, GDK_Up },
1025 { "scrollup", 0, 0, GDK_k },
1026 { "scrollbottom", 0, 0, GDK_G },
1027 { "scrollbottom", 0, 0, GDK_End },
1028 { "scrolltop", 0, 0, GDK_Home },
1029 { "scrollpagedown", 0, 0, GDK_space },
1030 { "scrollpagedown", CTRL, 1, GDK_f },
1031 { "scrollhalfdown", CTRL, 1, GDK_d },
1032 { "scrollpagedown", 0, 0, GDK_Page_Down },
1033 { "scrollpageup", 0, 0, GDK_Page_Up },
1034 { "scrollpageup", CTRL, 1, GDK_b },
1035 { "scrollhalfup", CTRL, 1, GDK_u },
1036 /* horizontal movement */
1037 { "scrollright", 0, 0, GDK_l },
1038 { "scrollright", 0, 0, GDK_Right },
1039 { "scrollleft", 0, 0, GDK_Left },
1040 { "scrollleft", 0, 0, GDK_h },
1041 { "scrollfarright", 0, 0, GDK_dollar },
1042 { "scrollfarleft", 0, 0, GDK_0 },
1044 /* tabs */
1045 { "tabnew", CTRL, 1, GDK_t },
1046 { "999tabnew", CTRL, 1, GDK_T },
1047 { "tabclose", CTRL, 1, GDK_w },
1048 { "tabundoclose", 0, 0, GDK_U },
1049 { "tabnext 1", CTRL, 1, GDK_1 },
1050 { "tabnext 2", CTRL, 1, GDK_2 },
1051 { "tabnext 3", CTRL, 1, GDK_3 },
1052 { "tabnext 4", CTRL, 1, GDK_4 },
1053 { "tabnext 5", CTRL, 1, GDK_5 },
1054 { "tabnext 6", CTRL, 1, GDK_6 },
1055 { "tabnext 7", CTRL, 1, GDK_7 },
1056 { "tabnext 8", CTRL, 1, GDK_8 },
1057 { "tabnext 9", CTRL, 1, GDK_9 },
1058 { "tabfirst", CTRL, 1, GDK_less },
1059 { "tablast", CTRL, 1, GDK_greater },
1060 { "tabprevious", CTRL, 1, GDK_Left },
1061 { "tabnext", CTRL, 1, GDK_Right },
1062 { "focusout", CTRL, 1, GDK_minus },
1063 { "focusin", CTRL, 1, GDK_plus },
1064 { "focusin", CTRL, 1, GDK_equal },
1065 { "focusreset", CTRL, 1, GDK_0 },
1067 /* command aliases (handy when -S flag is used) */
1068 { "promptopen", 0, 1, GDK_F9 },
1069 { "promptopencurrent", 0, 1, GDK_F10 },
1070 { "prompttabnew", 0, 1, GDK_F11 },
1071 { "prompttabnewcurrent",0, 1, GDK_F12 },
1074 void
1075 walk_kb(struct settings *s,
1076 void (*cb)(struct settings *, char *, void *), void *cb_args)
1078 struct key_binding *k;
1079 char str[1024];
1081 if (s == NULL || cb == NULL) {
1082 show_oops(NULL, "walk_kb invalid parameters");
1083 return;
1086 TAILQ_FOREACH(k, &kbl, entry) {
1087 if (k->cmd == NULL)
1088 continue;
1089 str[0] = '\0';
1091 /* sanity */
1092 if (gdk_keyval_name(k->key) == NULL)
1093 continue;
1095 strlcat(str, k->cmd, sizeof str);
1096 strlcat(str, ",", sizeof str);
1098 if (k->mask & GDK_SHIFT_MASK)
1099 strlcat(str, "S-", sizeof str);
1100 if (k->mask & GDK_CONTROL_MASK)
1101 strlcat(str, "C-", sizeof str);
1102 if (k->mask & GDK_MOD1_MASK)
1103 strlcat(str, "M1-", sizeof str);
1104 if (k->mask & GDK_MOD2_MASK)
1105 strlcat(str, "M2-", sizeof str);
1106 if (k->mask & GDK_MOD3_MASK)
1107 strlcat(str, "M3-", sizeof str);
1108 if (k->mask & GDK_MOD4_MASK)
1109 strlcat(str, "M4-", sizeof str);
1110 if (k->mask & GDK_MOD5_MASK)
1111 strlcat(str, "M5-", sizeof str);
1113 strlcat(str, gdk_keyval_name(k->key), sizeof str);
1114 cb(s, str, cb_args);
1118 void
1119 init_keybindings(void)
1121 int i;
1122 struct key_binding *k;
1124 for (i = 0; i < LENGTH(keys); i++) {
1125 k = g_malloc0(sizeof *k);
1126 k->cmd = keys[i].cmd;
1127 k->mask = keys[i].mask;
1128 k->use_in_entry = keys[i].use_in_entry;
1129 k->key = keys[i].key;
1130 TAILQ_INSERT_HEAD(&kbl, k, entry);
1132 DNPRINTF(XT_D_KEYBINDING, "init_keybindings: added: %s\n",
1133 k->cmd ? k->cmd : "unnamed key");
1137 void
1138 keybinding_clearall(void)
1140 struct key_binding *k, *next;
1142 for (k = TAILQ_FIRST(&kbl); k; k = next) {
1143 next = TAILQ_NEXT(k, entry);
1144 if (k->cmd == NULL)
1145 continue;
1147 DNPRINTF(XT_D_KEYBINDING, "keybinding_clearall: %s\n",
1148 k->cmd ? k->cmd : "unnamed key");
1149 TAILQ_REMOVE(&kbl, k, entry);
1150 g_free(k);
1155 keybinding_add(char *cmd, char *key, int use_in_entry)
1157 struct key_binding *k;
1158 guint keyval, mask = 0;
1159 int i;
1161 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s %s\n", cmd, key);
1163 /* Keys which are to be used in entry have been prefixed with an
1164 * exclamation mark. */
1165 if (use_in_entry)
1166 key++;
1168 /* find modifier keys */
1169 if (strstr(key, "S-"))
1170 mask |= GDK_SHIFT_MASK;
1171 if (strstr(key, "C-"))
1172 mask |= GDK_CONTROL_MASK;
1173 if (strstr(key, "M1-"))
1174 mask |= GDK_MOD1_MASK;
1175 if (strstr(key, "M2-"))
1176 mask |= GDK_MOD2_MASK;
1177 if (strstr(key, "M3-"))
1178 mask |= GDK_MOD3_MASK;
1179 if (strstr(key, "M4-"))
1180 mask |= GDK_MOD4_MASK;
1181 if (strstr(key, "M5-"))
1182 mask |= GDK_MOD5_MASK;
1184 /* find keyname */
1185 for (i = strlen(key) - 1; i > 0; i--)
1186 if (key[i] == '-')
1187 key = &key[i + 1];
1189 /* validate keyname */
1190 keyval = gdk_keyval_from_name(key);
1191 if (keyval == GDK_VoidSymbol) {
1192 warnx("invalid keybinding name %s", key);
1193 return (1);
1195 /* must run this test too, gtk+ doesn't handle 10 for example */
1196 if (gdk_keyval_name(keyval) == NULL) {
1197 warnx("invalid keybinding name %s", key);
1198 return (1);
1201 /* Remove eventual dupes. */
1202 TAILQ_FOREACH(k, &kbl, entry)
1203 if (k->key == keyval && k->mask == mask) {
1204 TAILQ_REMOVE(&kbl, k, entry);
1205 g_free(k);
1206 break;
1209 /* add keyname */
1210 k = g_malloc0(sizeof *k);
1211 k->cmd = g_strdup(cmd);
1212 k->mask = mask;
1213 k->use_in_entry = use_in_entry;
1214 k->key = keyval;
1216 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: %s 0x%x %d 0x%x\n",
1217 k->cmd,
1218 k->mask,
1219 k->use_in_entry,
1220 k->key);
1221 DNPRINTF(XT_D_KEYBINDING, "keybinding_add: adding: %s %s\n",
1222 k->cmd, gdk_keyval_name(keyval));
1224 TAILQ_INSERT_HEAD(&kbl, k, entry);
1226 return (0);
1230 add_kb(struct settings *s, char *entry)
1232 char *kb, *key;
1234 DNPRINTF(XT_D_KEYBINDING, "add_kb: %s\n", entry);
1236 /* clearall is special */
1237 if (!strcmp(entry, "clearall")) {
1238 keybinding_clearall();
1239 return (0);
1242 kb = strstr(entry, ",");
1243 if (kb == NULL)
1244 return (1);
1245 *kb = '\0';
1246 key = kb + 1;
1248 return (keybinding_add(entry, key, key[0] == '!'));
1252 add_ua(struct settings *s, char *value)
1254 struct user_agent *ua;
1256 ua = g_malloc0(sizeof *ua);
1257 ua->value = g_strdup(value);
1259 TAILQ_INSERT_HEAD(&ua_list, ua, entry);
1261 /* use the last added user agent */
1262 user_agent = TAILQ_FIRST(&ua_list);
1263 user_agent_count++;
1265 return (0);
1269 void
1270 walk_ua(struct settings *s,
1271 void (*cb)(struct settings *, char *, void *), void *cb_args)
1273 struct user_agent *ua;
1275 if (s == NULL || cb == NULL) {
1276 show_oops(NULL, "walk_ua invalid parameters");
1277 return;
1280 TAILQ_FOREACH(ua, &ua_list, entry)
1281 cb(s, ua->value, cb_args);
1285 set_auto_load_images(char *value)
1287 struct tab *t;
1288 int tmp;
1289 const char *errstr;
1291 tmp = strtonum(value, 0, 1, &errstr);
1292 if (errstr)
1293 return (-1);
1294 auto_load_images = tmp;
1295 TAILQ_FOREACH(t, &tabs, entry) {
1296 g_object_set(G_OBJECT(t->settings),
1297 "auto-load-images", auto_load_images, (char *)NULL);
1298 webkit_web_view_set_settings(t->wv, t->settings);
1300 return (0);
1304 set_ctrl_click_focus(char *value)
1306 int tmp;
1307 const char *errstr;
1309 tmp = strtonum(value, 0, 1, &errstr);
1310 if (errstr)
1311 return (-1);
1312 ctrl_click_focus = tmp;
1313 return (0);
1317 set_download_notifications(char *value)
1319 int tmp;
1320 const char *errstr;
1322 tmp = strtonum(value, 0, 1, &errstr);
1323 if (errstr)
1324 return (-1);
1325 download_notifications = tmp;
1326 return (0);
1330 set_enable_autoscroll(char *value)
1332 int tmp;
1333 const char *errstr;
1335 tmp = strtonum(value, 0, 1, &errstr);
1336 if (errstr)
1337 return (-1);
1338 enable_autoscroll = tmp;
1339 return (0);
1343 set_enable_cookie_whitelist(char *value)
1345 int tmp;
1346 const char *errstr;
1348 tmp = strtonum(value, 0, 1, &errstr);
1349 if (errstr)
1350 return (-1);
1351 enable_cookie_whitelist = tmp;
1352 return (0);
1356 set_enable_js_autorun(char *value)
1358 int tmp;
1359 const char *errstr;
1361 tmp = strtonum(value, 0, 1, &errstr);
1362 if (errstr)
1363 return (-1);
1364 enable_js_autorun = tmp;
1365 return (0);
1369 set_enable_js_whitelist(char *value)
1371 int tmp;
1372 const char *errstr;
1374 tmp = strtonum(value, 0, 1, &errstr);
1375 if (errstr)
1376 return (-1);
1377 enable_js_whitelist = tmp;
1378 return (0);
1382 set_enable_favicon_entry(char *value)
1384 int tmp;
1385 const char *errstr;
1387 tmp = strtonum(value, 0, 1, &errstr);
1388 if (errstr)
1389 return (-1);
1390 enable_favicon_entry = tmp;
1391 return (0);
1395 set_enable_favicon_tabs(char *value)
1397 int tmp;
1398 const char *errstr;
1400 tmp = strtonum(value, 0, 1, &errstr);
1401 if (errstr)
1402 return (-1);
1403 enable_favicon_tabs = tmp;
1404 return (0);
1408 set_enable_localstorage(char *value)
1410 struct tab *t;
1411 int tmp;
1412 const char *errstr;
1414 tmp = strtonum(value, 0, 1, &errstr);
1415 if (errstr)
1416 return (-1);
1417 enable_localstorage = tmp;
1418 TAILQ_FOREACH(t, &tabs, entry) {
1419 g_object_set(G_OBJECT(t->settings),
1420 "enable-html5-local-storage", enable_localstorage,
1421 (char *)NULL);
1423 return (0);
1427 set_enable_plugins(char *value)
1429 struct tab *t;
1430 int tmp;
1431 const char *errstr;
1433 tmp = strtonum(value, 0, 1, &errstr);
1434 if (errstr)
1435 return (-1);
1436 enable_plugins = tmp;
1437 TAILQ_FOREACH(t, &tabs, entry)
1438 g_object_set(G_OBJECT(t->settings), "enable-plugins",
1439 enable_plugins, (char *)NULL);
1440 return (0);
1444 set_enable_plugin_whitelist(char *value)
1446 int tmp;
1447 const char *errstr;
1449 tmp = strtonum(value, 0, 1, &errstr);
1450 if (errstr)
1451 return (-1);
1452 enable_plugin_whitelist = tmp;
1453 return (0);
1457 set_enable_scripts(char *value)
1459 struct tab *t;
1460 int tmp;
1461 const char *errstr;
1463 tmp = strtonum(value, 0, 1, &errstr);
1464 if (errstr)
1465 return (-1);
1466 enable_scripts = tmp;
1467 TAILQ_FOREACH(t, &tabs, entry)
1468 g_object_set(G_OBJECT(t->settings), "enable-scripts",
1469 enable_scripts, (char *)NULL);
1470 return (0);
1474 set_enable_spell_checking(char *value)
1476 struct tab *t;
1477 int tmp;
1478 const char *errstr;
1480 tmp = strtonum(value, 0, 1, &errstr);
1481 if (errstr)
1482 return (-1);
1483 enable_spell_checking = tmp;
1484 TAILQ_FOREACH(t, &tabs, entry)
1485 g_object_set(G_OBJECT(t->settings), "enable_spell_checking",
1486 enable_spell_checking, (char *)NULL);
1487 return (0);
1491 set_enable_strict_transport(char *value)
1493 int tmp;
1494 const char *errstr;
1496 tmp = strtonum(value, 0, 1, &errstr);
1497 if (errstr)
1498 return (-1);
1499 enable_strict_transport = tmp;
1500 return (0);
1503 #if 0
1505 * XXX: this is currently broken. Need to figure out what to do with
1506 * this. Problemm is set_encoding will refresh the tab it's run on, so
1507 * we can either put a big fat warning in the manpage and refresh every
1508 * single open tab with the new encoding or scrap it as a runtime
1509 * setting.
1512 set_encoding_rt(char *value)
1514 struct karg args = {0};
1516 if (value == NULL || strlen(value) == 0)
1517 return (-1);
1518 if (encoding)
1519 g_free(encoding);
1520 encoding = g_strdup(value);
1521 args.s = encoding;
1522 set_encoding(get_current_tab(), &args);
1523 return (0);
1525 #endif
1528 set_guess_search(char *value)
1530 int tmp;
1531 const char *errstr;
1533 tmp = strtonum(value, 0, 1, &errstr);
1534 if (errstr)
1535 return (-1);
1536 guess_search = tmp;
1537 return (0);
1541 set_read_only_cookies(char *value)
1543 int tmp;
1544 const char *errstr;
1546 tmp = strtonum(value, 0, 1, &errstr);
1547 if (errstr)
1548 return (-1);
1549 read_only_cookies = tmp;
1550 g_object_set(G_OBJECT(p_cookiejar), SOUP_COOKIE_JAR_READ_ONLY,
1551 read_only_cookies, (void *)NULL);
1552 return (0);
1555 char *
1556 get_referer(struct settings *s)
1558 if (referer_mode == XT_REFERER_ALWAYS)
1559 return (g_strdup("always"));
1560 if (referer_mode == XT_REFERER_NEVER)
1561 return (g_strdup("never"));
1562 if (referer_mode == XT_REFERER_SAME_DOMAIN)
1563 return (g_strdup("same-domain"));
1564 if (referer_mode == XT_REFERER_SAME_FQDN)
1565 return (g_strdup("same-fqdn"));
1566 if (referer_mode == XT_REFERER_CUSTOM)
1567 return (g_strdup(referer_custom));
1568 return (NULL);
1572 set_referer(struct settings *s, char *value)
1574 if (referer_custom)
1575 g_free(referer_custom);
1577 if (!strcmp(value, "always"))
1578 referer_mode = XT_REFERER_ALWAYS;
1579 else if (!strcmp(value, "never"))
1580 referer_mode = XT_REFERER_NEVER;
1581 else if (!strcmp(value, "same-domain"))
1582 referer_mode = XT_REFERER_SAME_DOMAIN;
1583 else if (!strcmp(value, "same-fqdn"))
1584 referer_mode = XT_REFERER_SAME_FQDN;
1585 else if (!valid_url_type(value)) {
1586 referer_mode = XT_REFERER_CUSTOM;
1587 referer_custom = g_strdup(value);
1588 } else {
1589 /* we've already free'd the custom referer */
1590 if (referer_mode == XT_REFERER_CUSTOM)
1591 referer_mode = XT_REFERER_NEVER;
1592 return (1);
1595 return (0);
1599 set_referer_rt(char *value)
1601 if (value == NULL || strlen(value) == 0)
1602 return (-1);
1603 return (set_referer(NULL, value));
1607 set_refresh_interval(char *value)
1609 int tmp;
1610 const char *errstr;
1612 tmp = strtonum(value, 0, INT_MAX, &errstr);
1613 if (errstr)
1614 return (-1);
1615 refresh_interval = tmp;
1616 return (0);
1620 set_session_autosave(char *value)
1622 int tmp;
1623 const char *errstr;
1625 tmp = strtonum(value, 0, 1, &errstr);
1626 if (errstr)
1627 return (-1);
1628 session_autosave = tmp;
1629 return (0);
1633 set_session_timeout(char *value)
1635 int tmp;
1636 const char *errstr;
1638 tmp = strtonum(value, 0, INT_MAX, &errstr);
1639 if (errstr)
1640 return (-1);
1641 session_timeout = tmp;
1642 return (0);
1646 set_show_statusbar(char *value)
1648 int tmp;
1649 const char *errstr;
1651 tmp = strtonum(value, 0, 1, &errstr);
1652 if (errstr)
1653 return (-1);
1654 show_statusbar = tmp;
1655 statusbar_set_visibility();
1656 return (0);
1660 set_show_tabs(char *value)
1662 struct karg args = {0};
1663 int val;
1664 const char *errstr;
1666 val = strtonum(value, 0, 1, &errstr);
1667 if (errstr)
1668 return (-1);
1669 args.i = val ? XT_TAB_SHOW : XT_TAB_HIDE;
1670 tabaction(get_current_tab(), &args);
1671 return (0);
1675 set_show_url(char *value)
1677 struct karg args = {0};
1678 int val;
1679 const char *errstr;
1681 val = strtonum(value, 0, 1, &errstr);
1682 if (errstr)
1683 return (-1);
1684 args.i = val ? XT_URL_SHOW : XT_URL_HIDE;
1685 urlaction(get_current_tab(), &args);
1686 return (0);
1690 set_spell_check_languages(char *value)
1692 struct tab *t;
1694 if (value == NULL || strlen(value) == 0)
1695 return (-1);
1696 if (spell_check_languages)
1697 g_free(spell_check_languages);
1698 spell_check_languages = g_strdup(value);
1699 TAILQ_FOREACH(t, &tabs, entry)
1700 g_object_set(G_OBJECT(t->settings), "spell_checking_languages",
1701 spell_check_languages, (char *)NULL);
1702 return (0);
1706 check_valid_file(char *name)
1708 struct stat sb;
1710 if (name == NULL || stat(name, &sb))
1711 return (-1);
1712 return (0);
1716 set_ssl_ca_file_rt(char *value)
1718 if (value == NULL || strlen(value) == 0)
1719 return (-1);
1720 if (set_ssl_ca_file(value))
1721 return (-1);
1722 return (0);
1726 set_ssl_strict_certs(char *value)
1728 int tmp;
1729 const char *errstr;
1731 tmp = strtonum(value, 0, 1, &errstr);
1732 if (errstr)
1733 return (-1);
1734 ssl_strict_certs = tmp;
1735 set_ssl_ca_file(ssl_ca_file);
1736 return (0);
1740 set_external_editor(char *editor)
1742 if (external_editor)
1743 g_free(external_editor);
1745 external_editor = g_strdup(editor);
1747 return (0);
1750 void
1751 setup_proxy(char *uri)
1753 if (proxy_uri) {
1754 g_object_set(session, "proxy_uri", NULL, (char *)NULL);
1755 soup_uri_free(proxy_uri);
1756 proxy_uri = NULL;
1758 if (http_proxy) {
1759 if (http_proxy != uri) {
1760 g_free(http_proxy);
1761 http_proxy = NULL;
1765 if (uri) {
1766 http_proxy = g_strdup(uri);
1767 DNPRINTF(XT_D_CONFIG, "setup_proxy: %s\n", uri);
1768 proxy_uri = soup_uri_new(http_proxy);
1769 if (!(proxy_uri == NULL || !SOUP_URI_VALID_FOR_HTTP(proxy_uri)))
1770 g_object_set(session, "proxy-uri", proxy_uri,
1771 (char *)NULL);
1775 char *
1776 get_tab_style(struct settings *s)
1778 if (tab_style == XT_TABS_NORMAL)
1779 return (g_strdup("normal"));
1780 else
1781 return (g_strdup("compact"));
1785 set_tab_style(struct settings *s, char *val)
1787 if (!strcmp(val, "normal"))
1788 tab_style = XT_TABS_NORMAL;
1789 else if (!strcmp(val, "compact"))
1790 tab_style = XT_TABS_COMPACT;
1791 else
1792 return (1);
1794 return (0);
1798 set_tab_style_rt(char *value)
1800 struct karg args = {0};
1801 int old_tab_style;
1803 old_tab_style = tab_style;
1804 if (set_tab_style(NULL, value))
1805 return (-1);
1806 if (old_tab_style != tab_style) {
1807 tab_style = old_tab_style;
1808 args.i = XT_TAB_NEXTSTYLE;
1809 tabaction(get_current_tab(), &args);
1811 return (0);
1815 set_url_regex(char *value)
1817 if (regcomp(&url_re, value, REG_EXTENDED | REG_NOSUB))
1818 return (-1);
1819 if (url_regex)
1820 g_free(url_regex);
1821 url_regex = g_strdup(value);
1822 return (0);
1826 set_userstyle_global(char *value)
1828 struct karg args = {0};
1829 int tmp, old_style;
1830 const char *errstr;
1832 old_style = userstyle_global;
1833 tmp = strtonum(value, 0, 1, &errstr);
1834 if (errstr)
1835 return (-1);
1836 if (tmp != old_style) {
1837 args.i = XT_STYLE_GLOBAL;
1838 userstyle(get_current_tab(), &args);
1840 return (0);
1843 char *
1844 get_edit_mode(struct settings *s)
1846 if (edit_mode == XT_EM_HYBRID)
1847 return (g_strdup("hybrid"));
1848 else
1849 return (g_strdup("vi"));
1853 set_edit_mode(struct settings *s, char *val)
1855 if (!strcmp(val, "hybrid"))
1856 edit_mode = XT_EM_HYBRID;
1857 else if (!strcmp(val, "vi"))
1858 edit_mode = XT_EM_VI;
1859 else
1860 return (1);
1862 return (0);
1865 char *
1866 get_download_mode(struct settings *s)
1868 switch (download_mode) {
1869 case XT_DM_START:
1870 return (g_strdup("start"));
1871 break;
1872 case XT_DM_ASK:
1873 return (g_strdup("ask"));
1874 break;
1875 case XT_DM_ADD:
1876 return (g_strdup("add"));
1877 break;
1879 return (g_strdup("unknown"));
1883 set_download_mode(struct settings *s, char *val)
1885 if (!strcmp(val, "start"))
1886 download_mode = XT_DM_START;
1887 else if (!strcmp(val, "ask"))
1888 download_mode = XT_DM_ASK;
1889 else if (!strcmp(val, "add"))
1890 download_mode = XT_DM_ADD;
1891 else
1892 return (1);
1894 return (0);
1898 set_download_mode_rt(char *val)
1900 if (val == NULL || strlen(val) == 0)
1901 return (-1);
1902 return (set_download_mode(NULL, val));
1905 char *
1906 get_work_dir(struct settings *s)
1908 if (work_dir[0] == '\0')
1909 return (0);
1910 return (g_strdup(work_dir));
1914 set_work_dir(struct settings *s, char *val)
1916 if (val[0] == '~')
1917 snprintf(work_dir, sizeof work_dir, "%s" PS "%s",
1918 pwd->pw_dir, &val[1]);
1919 else
1920 strlcpy(work_dir, val, sizeof work_dir);
1922 return (0);
1926 set_xterm_workaround(char *value)
1928 int tmp;
1929 const char *errstr;
1931 tmp = strtonum(value, 0, 1, &errstr);
1932 if (errstr)
1933 return (-1);
1934 xterm_workaround = tmp;
1935 return (0);
1938 void
1939 walk_cookie_wl(struct settings *s,
1940 void (*cb)(struct settings *, char *, void *), void *cb_args)
1942 struct domain *d;
1944 if (s == NULL || cb == NULL) {
1945 show_oops(NULL, "walk_cookie_wl invalid parameters");
1946 return;
1949 RB_FOREACH_REVERSE(d, domain_list, &c_wl)
1950 cb(s, d->d, cb_args);
1953 void
1954 walk_js_wl(struct settings *s,
1955 void (*cb)(struct settings *, char *, void *), void *cb_args)
1957 struct domain *d;
1959 if (s == NULL || cb == NULL) {
1960 show_oops(NULL, "walk_js_wl invalid parameters");
1961 return;
1964 RB_FOREACH_REVERSE(d, domain_list, &js_wl)
1965 cb(s, d->d, cb_args);
1968 void
1969 walk_pl_wl(struct settings *s,
1970 void (*cb)(struct settings *, char *, void *), void *cb_args)
1972 struct domain *d;
1974 if (s == NULL || cb == NULL) {
1975 show_oops(NULL, "walk_pl_wl invalid parameters");
1976 return;
1979 RB_FOREACH_REVERSE(d, domain_list, &pl_wl)
1980 cb(s, d->d, cb_args);
1984 settings_add(char *var, char *val)
1986 int i, rv, *p;
1987 gfloat *f;
1988 char c[PATH_MAX], **s;
1990 /* get settings */
1991 for (i = 0, rv = 0; i < LENGTH(rs); i++) {
1992 if (strcmp(var, rs[i].name))
1993 continue;
1995 if (!strcmp(var, "include_config")) {
1996 if (val[0] == '~')
1997 snprintf(c, PATH_MAX, "%s" PS "%s", pwd->pw_dir,
1998 &val[1]);
1999 else
2000 strlcpy(c, val, PATH_MAX);
2001 config_parse(c, 0);
2002 rv = 1;
2003 break;
2006 if (rs[i].s) {
2007 if (rs[i].s->set(&rs[i], val))
2008 errx(1, "invalid value for %s: %s", var, val);
2009 rv = 1;
2010 break;
2011 } else
2012 switch (rs[i].type) {
2013 case XT_S_INT:
2014 p = rs[i].ival;
2015 *p = atoi(val);
2016 rv = 1;
2017 break;
2018 case XT_S_STR:
2019 s = rs[i].sval;
2020 if (s == NULL)
2021 errx(1, "invalid sval for %s",
2022 rs[i].name);
2023 if (*s)
2024 g_free(*s);
2025 *s = g_strdup(val);
2026 rv = 1;
2027 break;
2028 case XT_S_FLOAT:
2029 f = rs[i].fval;
2030 *f = atof(val);
2031 rv = 1;
2032 break;
2033 case XT_S_INVALID:
2034 default:
2035 errx(1, "invalid type for %s", var);
2037 break;
2039 return (rv);
2042 #define WS "\n= \t"
2043 void
2044 config_parse(char *filename, int runtime)
2046 FILE *config, *f;
2047 char *line, *cp, *var, *val;
2048 size_t len, lineno = 0;
2049 int handled;
2050 char file[PATH_MAX];
2051 struct stat sb;
2053 DNPRINTF(XT_D_CONFIG, "config_parse: filename %s\n", filename);
2055 if (filename == NULL)
2056 return;
2058 if (runtime && runtime_settings[0] != '\0') {
2059 snprintf(file, sizeof file, "%s" PS "%s",
2060 work_dir, runtime_settings);
2061 if (stat(file, &sb)) {
2062 warnx("runtime file doesn't exist, creating it");
2063 if ((f = fopen(file, "w")) == NULL)
2064 err(1, "runtime");
2065 fprintf(f, "# AUTO GENERATED, DO NOT EDIT\n");
2066 fclose(f);
2068 } else
2069 strlcpy(file, filename, sizeof file);
2071 if ((config = fopen(file, "r")) == NULL) {
2072 warn("config_parse: cannot open %s", filename);
2073 return;
2076 for (;;) {
2077 if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL)
2078 if (feof(config) || ferror(config))
2079 break;
2081 cp = line;
2082 cp += (long)strspn(cp, WS);
2083 if (cp[0] == '\0') {
2084 /* empty line */
2085 free(line);
2086 continue;
2089 if ((var = strsep(&cp, WS)) == NULL || cp == NULL)
2090 startpage_add("invalid configuration file entry: %s",
2091 line);
2092 else {
2093 cp += (long)strspn(cp, WS);
2095 if ((val = strsep(&cp, "\0")) == NULL)
2096 break;
2098 DNPRINTF(XT_D_CONFIG, "config_parse: %s=%s\n",
2099 var, val);
2100 handled = settings_add(var, val);
2102 if (handled == 0)
2103 startpage_add("invalid configuration file entry"
2104 ": %s=%s", var, val);
2107 free(line);
2110 fclose(config);
2113 struct settings_args {
2114 char **body;
2115 int i;
2118 void
2119 print_setting(struct settings *s, char *val, void *cb_args)
2121 char *tmp, *color;
2122 struct settings_args *sa = cb_args;
2124 if (sa == NULL)
2125 return;
2127 if (s->flags & XT_SF_RUNTIME)
2128 color = "#22cc22";
2129 else
2130 color = "#cccccc";
2132 tmp = *sa->body;
2133 *sa->body = g_strdup_printf(
2134 "%s\n<tr>"
2135 "<td style='background-color: %s; width: 10%%;word-break:break-all'>%s</td>"
2136 "<td style='background-color: %s; width: 20%%;word-break:break-all'>%s</td>",
2137 *sa->body,
2138 color,
2139 s->name,
2140 color,
2143 g_free(tmp);
2144 sa->i++;
2148 set_show(struct tab *t, struct karg *args)
2150 char *body, *page, *tmp;
2151 int i = 1;
2152 struct settings_args sa;
2154 bzero(&sa, sizeof sa);
2155 sa.body = &body;
2157 /* body */
2158 body = g_strdup_printf("<div align='center'><table><tr>"
2159 "<th align='left'>Setting</th>"
2160 "<th align='left'>Value</th></tr>\n");
2162 settings_walk(print_setting, &sa);
2163 i = sa.i;
2165 /* small message if there are none */
2166 if (i == 1) {
2167 tmp = body;
2168 body = g_strdup_printf("%s\n<tr><td style='text-align:center'"
2169 "colspan='2'>No settings</td></tr>\n", body);
2170 g_free(tmp);
2173 tmp = body;
2174 body = g_strdup_printf("%s</table></div>", body);
2175 g_free(tmp);
2177 page = get_html_page("Settings", body, "", 0);
2179 g_free(body);
2181 load_webkit_string(t, page, XT_URI_ABOUT_SET);
2183 g_free(page);
2185 return (XT_CB_PASSTHROUGH);
2189 set(struct tab *t, struct karg *args)
2191 char *p, *val;
2192 int i;
2194 if (args == NULL || args->s == NULL)
2195 return (set_show(t, args));
2197 /* strip spaces */
2198 p = g_strstrip(args->s);
2200 if (strlen(p) == 0)
2201 return (set_show(t, args));
2203 /* we got some sort of string */
2204 val = g_strstr_len(p, strlen(p), "=");
2205 if (val) {
2206 *val++ = '\0';
2207 val = g_strstrip(val);
2208 p = g_strchomp(p);
2210 for (i = 0; i < get_settings_size(); i++) {
2211 if (strcmp(rs[i].name, p))
2212 continue;
2214 if (rs[i].activate) {
2215 if (rs[i].activate(val))
2216 show_oops(t, "%s invalid value %s",
2217 p, val);
2218 else
2219 show_oops(t, ":set %s = %s", p, val);
2220 goto done;
2221 } else {
2222 show_oops(t, "not a runtime option: %s", p);
2223 goto done;
2226 show_oops(t, "unknown option: %s", p);
2227 } else {
2228 p = g_strchomp(p);
2230 for (i = 0; i < get_settings_size(); i++) {
2231 if (strcmp(rs[i].name, p))
2232 continue;
2234 /* XXX this could use some cleanup */
2235 switch (rs[i].type) {
2236 case XT_S_INT:
2237 if (rs[i].ival)
2238 show_oops(t, "%s = %d",
2239 rs[i].name, *rs[i].ival);
2240 else if (rs[i].s && rs[i].s->get)
2241 show_oops(t, "%s = %s",
2242 rs[i].name,
2243 rs[i].s->get(&rs[i]));
2244 else if (rs[i].s && rs[i].s->get == NULL)
2245 show_oops(t, "%s = ...", rs[i].name);
2246 else
2247 show_oops(t, "%s = ", rs[i].name);
2248 break;
2249 case XT_S_FLOAT:
2250 if (rs[i].fval)
2251 show_oops(t, "%s = %f",
2252 rs[i].name, *rs[i].fval);
2253 else if (rs[i].s && rs[i].s->get)
2254 show_oops(t, "%s = %s",
2255 rs[i].name,
2256 rs[i].s->get(&rs[i]));
2257 else if (rs[i].s && rs[i].s->get == NULL)
2258 show_oops(t, "%s = ...", rs[i].name);
2259 else
2260 show_oops(t, "%s = ", rs[i].name);
2261 break;
2262 case XT_S_STR:
2263 if (rs[i].sval && *rs[i].sval)
2264 show_oops(t, "%s = %s",
2265 rs[i].name, *rs[i].sval);
2266 else if (rs[i].s && rs[i].s->get)
2267 show_oops(t, "%s = %s",
2268 rs[i].name,
2269 rs[i].s->get(&rs[i]));
2270 else if (rs[i].s && rs[i].s->get == NULL)
2271 show_oops(t, "%s = ...", rs[i].name);
2272 else
2273 show_oops(t, "%s = ", rs[i].name);
2274 break;
2275 default:
2276 show_oops(t, "unknown type for %s", rs[i].name);
2277 goto done;
2280 goto done;
2282 show_oops(t, "unknown option: %s", p);
2284 done:
2285 return (XT_CB_PASSTHROUGH);