also fixup PS over here
[xombrero.git] / whitelist.c
blob1f1263a66ed2cacfdc768f76a18e51b0dd8ea89e
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 p = tld_get_suffix(uri->host);
41 } else
42 p = uri->host;
44 ret = g_strdup_printf(".%s", p);
46 soup_uri_free(uri);
48 return (ret);
51 struct domain *
52 wl_find(const gchar *search, struct domain_list *wl)
54 int i;
55 struct domain *d = NULL, dfind;
56 gchar *s = NULL;
58 if (search == NULL || wl == NULL)
59 return (NULL);
60 if (strlen(search) < 2)
61 return (NULL);
63 if (search[0] != '.')
64 s = g_strdup_printf(".%s", search);
65 else
66 s = g_strdup(search);
68 for (i = strlen(s) - 1; i >= 0; i--) {
69 if (s[i] == '.') {
70 dfind.d = &s[i];
71 d = RB_FIND(domain_list, wl, &dfind);
72 if (d)
73 goto done;
77 done:
78 if (s)
79 g_free(s);
81 return (d);
84 int
85 wl_save(struct tab *t, struct karg *args, int list)
87 char file[PATH_MAX], *lst_str = NULL;
88 FILE *f = NULL;
89 char *line = NULL, *lt = NULL, *dom;
90 size_t linelen;
91 const gchar *uri;
92 struct karg a;
93 struct domain *d;
94 GSList *cf;
95 SoupCookie *ci, *c;
97 if (t == NULL || args == NULL)
98 return (1);
100 if (runtime_settings[0] == '\0')
101 return (1);
103 switch (list) {
104 case XT_WL_JAVASCRIPT:
105 lst_str = "JavaScript";
106 break;
107 case XT_WL_COOKIE:
108 lst_str = "Cookie";
109 break;
110 case XT_WL_PLUGIN:
111 lst_str = "Plugin";
112 break;
113 default:
114 show_oops(t, "Invalid list id: %d", list);
115 return (1);
118 uri = get_uri(t);
119 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
120 if (uri == NULL || dom == NULL ||
121 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
122 show_oops(t, "Can't add domain to %s white list", lst_str);
123 goto done;
126 switch (list) {
127 case XT_WL_JAVASCRIPT:
128 lt = g_strdup_printf("js_wl=%s", dom);
129 break;
130 case XT_WL_COOKIE:
131 lt = g_strdup_printf("cookie_wl=%s", dom);
132 break;
133 case XT_WL_PLUGIN:
134 lt = g_strdup_printf("pl_wl=%s", dom);
135 break;
136 default:
137 /* can't happen */
138 show_oops(t, "Invalid list id: %d", list);
139 goto done;
142 snprintf(file, sizeof file, "%s" PS "%s", work_dir, runtime_settings);
143 if ((f = fopen(file, "r+")) == NULL) {
144 show_oops(t, "can't open file %s");
145 goto done;
148 while (!feof(f)) {
149 line = fparseln(f, &linelen, NULL, NULL, 0);
150 if (line == NULL)
151 continue;
152 if (!strcmp(line, lt))
153 goto done;
154 free(line);
155 line = NULL;
158 fprintf(f, "%s\n", lt);
160 a.i = XT_WL_ENABLE;
161 a.i |= args->i;
162 switch (list) {
163 case XT_WL_JAVASCRIPT:
164 d = wl_find(dom, &js_wl);
165 if (!d) {
166 settings_add("js_wl", dom);
167 d = wl_find(dom, &js_wl);
169 toggle_js(t, &a);
170 break;
172 case XT_WL_COOKIE:
173 d = wl_find(dom, &c_wl);
174 if (!d) {
175 settings_add("cookie_wl", dom);
176 d = wl_find(dom, &c_wl);
178 toggle_cwl(t, &a);
180 /* find and add to persistent jar */
181 cf = soup_cookie_jar_all_cookies(s_cookiejar);
182 for (;cf; cf = cf->next) {
183 ci = cf->data;
184 if (!strcmp(dom, ci->domain) ||
185 !strcmp(&dom[1], ci->domain)) /* deal with leading . */ {
186 c = soup_cookie_copy(ci);
187 _soup_cookie_jar_add_cookie(p_cookiejar, c);
190 soup_cookies_free(cf);
191 break;
193 case XT_WL_PLUGIN:
194 d = wl_find(dom, &pl_wl);
195 if (!d) {
196 settings_add("pl_wl", dom);
197 d = wl_find(dom, &pl_wl);
199 toggle_pl(t, &a);
200 break;
201 default:
202 abort(); /* can't happen */
204 if (d)
205 d->handy = 1;
207 done:
208 if (line)
209 free(line);
210 if (dom)
211 g_free(dom);
212 if (lt)
213 g_free(lt);
214 if (f)
215 fclose(f);
217 return (0);
221 wl_show(struct tab *t, struct karg *args, char *title, struct domain_list *wl)
223 struct domain *d;
224 char *tmp, *body;
226 body = g_strdup("");
228 /* p list */
229 if (args->i & XT_WL_PERSISTENT) {
230 tmp = body;
231 body = g_strdup_printf("%s<h2>Persistent</h2>", body);
232 g_free(tmp);
233 RB_FOREACH(d, domain_list, wl) {
234 if (d->handy == 0)
235 continue;
236 tmp = body;
237 body = g_strdup_printf("%s%s<br/>", body, d->d);
238 g_free(tmp);
242 /* s list */
243 if (args->i & XT_WL_SESSION) {
244 tmp = body;
245 body = g_strdup_printf("%s<h2>Session</h2>", body);
246 g_free(tmp);
247 RB_FOREACH(d, domain_list, wl) {
248 if (d->handy == 1)
249 continue;
250 tmp = body;
251 body = g_strdup_printf("%s%s<br/>", body, d->d);
252 g_free(tmp);
256 tmp = get_html_page(title, body, "", 0);
257 g_free(body);
258 if (wl == &js_wl)
259 load_webkit_string(t, tmp, XT_URI_ABOUT_JSWL);
260 else if (wl == &c_wl)
261 load_webkit_string(t, tmp, XT_URI_ABOUT_COOKIEWL);
262 else
263 load_webkit_string(t, tmp, XT_URI_ABOUT_PLUGINWL);
264 g_free(tmp);
265 return (0);
268 void
269 wl_add(char *str, struct domain_list *wl, int handy)
271 struct domain *d;
272 int add_dot = 0;
273 char *p;
275 if (str == NULL || wl == NULL || strlen(str) < 2)
276 return;
278 DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str);
280 /* treat *.moo.com the same as .moo.com */
281 if (str[0] == '*' && str[1] == '.')
282 str = &str[1];
283 else if (str[0] == '.')
284 str = &str[0];
285 else
286 add_dot = 1;
288 /* slice off port number */
289 p = g_strrstr(str, ":");
290 if (p)
291 *p = '\0';
293 d = g_malloc(sizeof *d);
294 if (add_dot)
295 d->d = g_strdup_printf(".%s", str);
296 else
297 d->d = g_strdup(str);
298 d->handy = handy;
300 if (RB_INSERT(domain_list, wl, d))
301 goto unwind;
303 DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d);
304 return;
305 unwind:
306 if (d) {
307 if (d->d)
308 g_free(d->d);
309 g_free(d);
314 add_cookie_wl(struct settings *s, char *entry)
316 wl_add(entry, &c_wl, 1);
317 return (0);
321 add_js_wl(struct settings *s, char *entry)
323 wl_add(entry, &js_wl, 1 /* persistent */);
324 return (0);
328 add_pl_wl(struct settings *s, char *entry)
330 wl_add(entry, &pl_wl, 1 /* persistent */);
331 return (0);
335 toggle_cwl(struct tab *t, struct karg *args)
337 struct domain *d;
338 const gchar *uri;
339 char *dom = NULL;
340 int es;
342 if (args == NULL)
343 return (1);
345 uri = get_uri(t);
346 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
348 if (uri == NULL || dom == NULL ||
349 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
350 show_oops(t, "Can't toggle domain in cookie white list");
351 goto done;
353 d = wl_find(dom, &c_wl);
355 if (d == NULL)
356 es = 0;
357 else
358 es = 1;
360 if (args->i & XT_WL_TOGGLE)
361 es = !es;
362 else if ((args->i & XT_WL_ENABLE) && es != 1)
363 es = 1;
364 else if ((args->i & XT_WL_DISABLE) && es != 0)
365 es = 0;
367 if (es)
368 /* enable cookies for domain */
369 wl_add(dom, &c_wl, 0);
370 else {
371 /* disable cookies for domain */
372 if (d)
373 RB_REMOVE(domain_list, &c_wl, d);
376 if (args->i & XT_WL_RELOAD)
377 webkit_web_view_reload(t->wv);
379 done:
380 g_free(dom);
381 return (0);
385 toggle_js(struct tab *t, struct karg *args)
387 int es;
388 const gchar *uri;
389 struct domain *d;
390 char *dom = NULL;
392 if (args == NULL)
393 return (1);
395 g_object_get(G_OBJECT(t->settings),
396 "enable-scripts", &es, (char *)NULL);
397 if (args->i & XT_WL_TOGGLE)
398 es = !es;
399 else if ((args->i & XT_WL_ENABLE) && es != 1)
400 es = 1;
401 else if ((args->i & XT_WL_DISABLE) && es != 0)
402 es = 0;
403 else
404 return (1);
406 uri = get_uri(t);
407 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
409 if (uri == NULL || dom == NULL ||
410 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
411 show_oops(t, "Can't toggle domain in JavaScript white list");
412 goto done;
415 if (es) {
416 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY);
417 wl_add(dom, &js_wl, 0 /* session */);
418 } else {
419 d = wl_find(dom, &js_wl);
420 if (d)
421 RB_REMOVE(domain_list, &js_wl, d);
422 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE);
424 g_object_set(G_OBJECT(t->settings),
425 "enable-scripts", es, (char *)NULL);
426 g_object_set(G_OBJECT(t->settings),
427 "javascript-can-open-windows-automatically", es, (char *)NULL);
428 webkit_web_view_set_settings(t->wv, t->settings);
430 if (args->i & XT_WL_RELOAD)
431 webkit_web_view_reload(t->wv);
432 done:
433 if (dom)
434 g_free(dom);
435 return (0);
439 toggle_pl(struct tab *t, struct karg *args)
441 int es;
442 const gchar *uri;
443 struct domain *d;
444 char *dom = NULL;
446 if (args == NULL)
447 return (1);
449 g_object_get(G_OBJECT(t->settings),
450 "enable-plugins", &es, (char *)NULL);
451 if (args->i & XT_WL_TOGGLE)
452 es = !es;
453 else if ((args->i & XT_WL_ENABLE) && es != 1)
454 es = 1;
455 else if ((args->i & XT_WL_DISABLE) && es != 0)
456 es = 0;
457 else
458 return (1);
460 uri = get_uri(t);
461 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
463 if (uri == NULL || dom == NULL ||
464 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
465 show_oops(t, "Can't toggle domain in plugins white list");
466 goto done;
469 if (es)
470 wl_add(dom, &pl_wl, 0 /* session */);
471 else {
472 d = wl_find(dom, &pl_wl);
473 if (d)
474 RB_REMOVE(domain_list, &pl_wl, d);
476 g_object_set(G_OBJECT(t->settings),
477 "enable-plugins", es, (char *)NULL);
478 webkit_web_view_set_settings(t->wv, t->settings);
480 if (args->i & XT_WL_RELOAD)
481 webkit_web_view_reload(t->wv);
482 done:
483 if (dom)
484 g_free(dom);
485 return (0);