make sure show actually works as well
[xxxterm.git] / whitelist.c
blob03362610feff49180375b18bcadf4173ab6dc35f
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 gchar *
25 find_domain(const gchar *s, int toplevel)
27 SoupURI *uri;
28 gchar *ret, *p;
30 if (s == NULL)
31 return (NULL);
33 uri = soup_uri_new(s);
35 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) {
36 return (NULL);
39 if (toplevel && !isdigit(uri->host[strlen(uri->host) - 1])) {
40 if ((p = strrchr(uri->host, '.')) != NULL) {
41 while(--p >= uri->host && *p != '.');
42 p++;
43 } else
44 p = uri->host;
45 } else
46 p = uri->host;
48 ret = g_strdup_printf(".%s", p);
50 soup_uri_free(uri);
52 return (ret);
55 struct domain *
56 wl_find(const gchar *search, struct domain_list *wl)
58 int i;
59 struct domain *d = NULL, dfind;
60 gchar *s = NULL;
62 if (search == NULL || wl == NULL)
63 return (NULL);
64 if (strlen(search) < 2)
65 return (NULL);
67 if (search[0] != '.')
68 s = g_strdup_printf(".%s", search);
69 else
70 s = g_strdup(search);
72 for (i = strlen(s) - 1; i >= 0; i--) {
73 if (s[i] == '.') {
74 dfind.d = &s[i];
75 d = RB_FIND(domain_list, wl, &dfind);
76 if (d)
77 goto done;
81 done:
82 if (s)
83 g_free(s);
85 return (d);
88 int
89 wl_save(struct tab *t, struct karg *args, int list)
91 char file[PATH_MAX], *lst_str = NULL;
92 FILE *f = NULL;
93 char *line = NULL, *lt = NULL, *dom;
94 size_t linelen;
95 const gchar *uri;
96 struct karg a;
97 struct domain *d;
98 GSList *cf;
99 SoupCookie *ci, *c;
101 if (t == NULL || args == NULL)
102 return (1);
104 if (runtime_settings[0] == '\0')
105 return (1);
107 switch (list) {
108 case XT_WL_JAVASCRIPT:
109 lst_str = "JavaScript";
110 break;
111 case XT_WL_COOKIE:
112 lst_str = "Cookie";
113 break;
114 case XT_WL_PLUGIN:
115 lst_str = "Plugin";
116 break;
117 default:
118 show_oops(t, "Invalid list id: %d", list);
119 return (1);
122 uri = get_uri(t);
123 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
124 if (uri == NULL || dom == NULL ||
125 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
126 show_oops(t, "Can't add domain to %s white list", lst_str);
127 goto done;
130 switch (list) {
131 case XT_WL_JAVASCRIPT:
132 lt = g_strdup_printf("js_wl=%s", dom);
133 break;
134 case XT_WL_COOKIE:
135 lt = g_strdup_printf("cookie_wl=%s", dom);
136 break;
137 case XT_WL_PLUGIN:
138 lt = g_strdup_printf("pl_wl=%s", dom);
139 break;
140 default:
141 /* can't happen */
142 show_oops(t, "Invalid list id: %d", list);
143 goto done;
146 snprintf(file, sizeof file, "%s/%s", work_dir, runtime_settings);
147 if ((f = fopen(file, "r+")) == NULL) {
148 show_oops(t, "can't open file %s");
149 goto done;
152 while (!feof(f)) {
153 line = fparseln(f, &linelen, NULL, NULL, 0);
154 if (line == NULL)
155 continue;
156 if (!strcmp(line, lt))
157 goto done;
158 free(line);
159 line = NULL;
162 fprintf(f, "%s\n", lt);
164 a.i = XT_WL_ENABLE;
165 a.i |= args->i;
166 switch (list) {
167 case XT_WL_JAVASCRIPT:
168 d = wl_find(dom, &js_wl);
169 if (!d) {
170 settings_add("js_wl", dom);
171 d = wl_find(dom, &js_wl);
173 toggle_js(t, &a);
174 break;
176 case XT_WL_COOKIE:
177 d = wl_find(dom, &c_wl);
178 if (!d) {
179 settings_add("cookie_wl", dom);
180 d = wl_find(dom, &c_wl);
182 toggle_cwl(t, &a);
184 /* find and add to persistent jar */
185 cf = soup_cookie_jar_all_cookies(s_cookiejar);
186 for (;cf; cf = cf->next) {
187 ci = cf->data;
188 if (!strcmp(dom, ci->domain) ||
189 !strcmp(&dom[1], ci->domain)) /* deal with leading . */ {
190 c = soup_cookie_copy(ci);
191 _soup_cookie_jar_add_cookie(p_cookiejar, c);
194 soup_cookies_free(cf);
195 break;
197 case XT_WL_PLUGIN:
198 d = wl_find(dom, &pl_wl);
199 if (!d) {
200 settings_add("pl_wl", dom);
201 d = wl_find(dom, &pl_wl);
203 toggle_pl(t, &a);
204 break;
205 default:
206 abort(); /* can't happen */
208 if (d)
209 d->handy = 1;
211 done:
212 if (line)
213 free(line);
214 if (dom)
215 g_free(dom);
216 if (lt)
217 g_free(lt);
218 if (f)
219 fclose(f);
221 return (0);
225 wl_show(struct tab *t, struct karg *args, char *title, struct domain_list *wl)
227 struct domain *d;
228 char *tmp, *body;
230 body = g_strdup("");
232 /* p list */
233 if (args->i & XT_WL_PERSISTENT) {
234 tmp = body;
235 body = g_strdup_printf("%s<h2>Persistent</h2>", body);
236 g_free(tmp);
237 RB_FOREACH(d, domain_list, wl) {
238 if (d->handy == 0)
239 continue;
240 tmp = body;
241 body = g_strdup_printf("%s%s<br/>", body, d->d);
242 g_free(tmp);
246 /* s list */
247 if (args->i & XT_WL_SESSION) {
248 tmp = body;
249 body = g_strdup_printf("%s<h2>Session</h2>", body);
250 g_free(tmp);
251 RB_FOREACH(d, domain_list, wl) {
252 if (d->handy == 1)
253 continue;
254 tmp = body;
255 body = g_strdup_printf("%s%s<br/>", body, d->d);
256 g_free(tmp);
260 tmp = get_html_page(title, body, "", 0);
261 g_free(body);
262 if (wl == &js_wl)
263 load_webkit_string(t, tmp, XT_URI_ABOUT_JSWL);
264 else if (wl == &c_wl)
265 load_webkit_string(t, tmp, XT_URI_ABOUT_COOKIEWL);
266 else
267 load_webkit_string(t, tmp, XT_URI_ABOUT_PLUGINWL);
268 g_free(tmp);
269 return (0);
272 void
273 wl_add(char *str, struct domain_list *wl, int handy)
275 struct domain *d;
276 int add_dot = 0;
277 char *p;
279 if (str == NULL || wl == NULL || strlen(str) < 2)
280 return;
282 DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str);
284 /* treat *.moo.com the same as .moo.com */
285 if (str[0] == '*' && str[1] == '.')
286 str = &str[1];
287 else if (str[0] == '.')
288 str = &str[0];
289 else
290 add_dot = 1;
292 /* slice off port number */
293 p = g_strrstr(str, ":");
294 if (p)
295 *p = '\0';
297 d = g_malloc(sizeof *d);
298 if (add_dot)
299 d->d = g_strdup_printf(".%s", str);
300 else
301 d->d = g_strdup(str);
302 d->handy = handy;
304 if (RB_INSERT(domain_list, wl, d))
305 goto unwind;
307 DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d);
308 return;
309 unwind:
310 if (d) {
311 if (d->d)
312 g_free(d->d);
313 g_free(d);
318 add_cookie_wl(struct settings *s, char *entry)
320 wl_add(entry, &c_wl, 1);
321 return (0);
325 add_js_wl(struct settings *s, char *entry)
327 wl_add(entry, &js_wl, 1 /* persistent */);
328 return (0);
332 add_pl_wl(struct settings *s, char *entry)
334 wl_add(entry, &pl_wl, 1 /* persistent */);
335 return (0);
339 toggle_cwl(struct tab *t, struct karg *args)
341 struct domain *d;
342 const gchar *uri;
343 char *dom = NULL;
344 int es;
346 if (args == NULL)
347 return (1);
349 uri = get_uri(t);
350 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
352 if (uri == NULL || dom == NULL ||
353 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
354 show_oops(t, "Can't toggle domain in cookie white list");
355 goto done;
357 d = wl_find(dom, &c_wl);
359 if (d == NULL)
360 es = 0;
361 else
362 es = 1;
364 if (args->i & XT_WL_TOGGLE)
365 es = !es;
366 else if ((args->i & XT_WL_ENABLE) && es != 1)
367 es = 1;
368 else if ((args->i & XT_WL_DISABLE) && es != 0)
369 es = 0;
371 if (es)
372 /* enable cookies for domain */
373 wl_add(dom, &c_wl, 0);
374 else {
375 /* disable cookies for domain */
376 if (d)
377 RB_REMOVE(domain_list, &c_wl, d);
380 if (args->i & XT_WL_RELOAD)
381 webkit_web_view_reload(t->wv);
383 done:
384 g_free(dom);
385 return (0);
389 toggle_js(struct tab *t, struct karg *args)
391 int es;
392 const gchar *uri;
393 struct domain *d;
394 char *dom = NULL;
396 if (args == NULL)
397 return (1);
399 g_object_get(G_OBJECT(t->settings),
400 "enable-scripts", &es, (char *)NULL);
401 if (args->i & XT_WL_TOGGLE)
402 es = !es;
403 else if ((args->i & XT_WL_ENABLE) && es != 1)
404 es = 1;
405 else if ((args->i & XT_WL_DISABLE) && es != 0)
406 es = 0;
407 else
408 return (1);
410 uri = get_uri(t);
411 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
413 if (uri == NULL || dom == NULL ||
414 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
415 show_oops(t, "Can't toggle domain in JavaScript white list");
416 goto done;
419 if (es) {
420 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY);
421 wl_add(dom, &js_wl, 0 /* session */);
422 } else {
423 d = wl_find(dom, &js_wl);
424 if (d)
425 RB_REMOVE(domain_list, &js_wl, d);
426 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE);
428 g_object_set(G_OBJECT(t->settings),
429 "enable-scripts", es, (char *)NULL);
430 g_object_set(G_OBJECT(t->settings),
431 "javascript-can-open-windows-automatically", es, (char *)NULL);
432 webkit_web_view_set_settings(t->wv, t->settings);
434 if (args->i & XT_WL_RELOAD)
435 webkit_web_view_reload(t->wv);
436 done:
437 if (dom)
438 g_free(dom);
439 return (0);
443 toggle_pl(struct tab *t, struct karg *args)
445 int es;
446 const gchar *uri;
447 struct domain *d;
448 char *dom = NULL;
450 if (args == NULL)
451 return (1);
453 g_object_get(G_OBJECT(t->settings),
454 "enable-plugins", &es, (char *)NULL);
455 if (args->i & XT_WL_TOGGLE)
456 es = !es;
457 else if ((args->i & XT_WL_ENABLE) && es != 1)
458 es = 1;
459 else if ((args->i & XT_WL_DISABLE) && es != 0)
460 es = 0;
461 else
462 return (1);
464 uri = get_uri(t);
465 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
467 if (uri == NULL || dom == NULL ||
468 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
469 show_oops(t, "Can't toggle domain in plugins white list");
470 goto done;
473 if (es)
474 wl_add(dom, &pl_wl, 0 /* session */);
475 else {
476 d = wl_find(dom, &pl_wl);
477 if (d)
478 RB_REMOVE(domain_list, &pl_wl, d);
480 g_object_set(G_OBJECT(t->settings),
481 "enable-plugins", es, (char *)NULL);
482 webkit_web_view_set_settings(t->wv, t->settings);
484 if (args->i & XT_WL_RELOAD)
485 webkit_web_view_reload(t->wv);
486 done:
487 if (dom)
488 g_free(dom);
489 return (0);