Add a favedit command and remove rm links from :fav
[xombrero.git] / whitelist.c
blob819fb7a2b76b254048acf2c2ba5fa23e4d8d4840
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>
8 * Copyright (c) 2012 Josh Rickmar <jrick@devio.us>
10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies.
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #include <xombrero.h>
25 gchar *
26 find_domain(const gchar *s, int flags)
28 SoupURI *uri;
29 gchar *ret, *p;
31 if (s == NULL)
32 return (NULL);
34 uri = soup_uri_new(s);
36 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri))
37 return (NULL);
39 if (flags & XT_WL_TOPLEVEL &&
40 !isdigit(uri->host[strlen(uri->host) - 1]))
41 p = tld_get_suffix(uri->host);
42 else
43 p = uri->host;
45 if (flags & XT_WL_TOPLEVEL)
46 ret = g_strdup_printf(".%s", p);
47 else /* assume FQDN */
48 ret = g_strdup(p);
50 soup_uri_free(uri);
52 return (ret);
55 struct domain *
56 wl_find(const gchar *s, struct domain_list *wl)
58 struct domain *d = NULL, dfind;
59 int i;
61 if (s == NULL || wl == NULL)
62 return (NULL);
63 if (strlen(s) < 2)
64 return (NULL);
66 for (i = strlen(s) - 1; i >= 0; --i) {
67 if (i == 0 || (s[i] == '.')) {
68 dfind.d = (gchar *)&s[i];
69 d = RB_FIND(domain_list, wl, &dfind);
70 if (d)
71 goto done;
72 if (i == 0 && s[i] != '.') {
73 dfind.d = g_strdup_printf(".%s", s);
74 d = RB_FIND(domain_list, wl, &dfind);
75 g_free(dfind.d);
76 if (d)
77 goto done;
82 done:
83 return (d);
86 int
87 wl_save(struct tab *t, struct karg *args, int list)
89 char file[PATH_MAX], *lst_str = NULL;
90 FILE *f = NULL;
91 char *line = NULL, *lt = NULL, *dom;
92 size_t linelen;
93 const gchar *uri;
94 struct karg a;
95 struct domain *d;
96 GSList *cf;
97 SoupCookie *ci, *c;
99 if (t == NULL || args == NULL)
100 return (1);
102 if (runtime_settings[0] == '\0')
103 return (1);
105 switch (list) {
106 case XT_WL_JAVASCRIPT:
107 lst_str = "JavaScript";
108 break;
109 case XT_WL_COOKIE:
110 lst_str = "Cookie";
111 break;
112 case XT_WL_PLUGIN:
113 lst_str = "Plugin";
114 break;
115 case XT_WL_HTTPS:
116 lst_str = "HTTPS";
117 break;
118 default:
119 show_oops(t, "Invalid list id: %d", list);
120 return (1);
123 uri = get_uri(t);
124 dom = find_domain(uri, args->i);
125 if (uri == NULL || dom == NULL ||
126 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
127 show_oops(t, "Can't add domain to %s white list", lst_str);
128 goto done;
131 switch (list) {
132 case XT_WL_JAVASCRIPT:
133 lt = g_strdup_printf("js_wl=%s", dom);
134 break;
135 case XT_WL_COOKIE:
136 lt = g_strdup_printf("cookie_wl=%s", dom);
137 break;
138 case XT_WL_PLUGIN:
139 lt = g_strdup_printf("pl_wl=%s", dom);
140 break;
141 case XT_WL_HTTPS:
142 lt = g_strdup_printf("force_https=%s", dom);
143 break;
144 default:
145 /* can't happen */
146 show_oops(t, "Invalid list id: %d", list);
147 goto done;
150 snprintf(file, sizeof file, "%s" PS "%s", work_dir, runtime_settings);
151 if ((f = fopen(file, "r+")) == NULL) {
152 show_oops(t, "can't open file %s");
153 goto done;
156 while (!feof(f)) {
157 line = fparseln(f, &linelen, NULL, NULL, 0);
158 if (line == NULL)
159 continue;
160 if (!strcmp(line, lt))
161 goto done;
162 free(line);
163 line = NULL;
166 fprintf(f, "%s\n", lt);
168 a.i = XT_WL_ENABLE;
169 a.i |= args->i;
170 switch (list) {
171 case XT_WL_JAVASCRIPT:
172 d = wl_find(dom, &js_wl);
173 if (!d) {
174 settings_add("js_wl", dom);
175 d = wl_find(dom, &js_wl);
177 toggle_js(t, &a);
178 break;
180 case XT_WL_COOKIE:
181 d = wl_find(dom, &c_wl);
182 if (!d) {
183 settings_add("cookie_wl", dom);
184 d = wl_find(dom, &c_wl);
186 toggle_cwl(t, &a);
188 /* find and add to persistent jar */
189 cf = soup_cookie_jar_all_cookies(s_cookiejar);
190 for (;cf; cf = cf->next) {
191 ci = cf->data;
192 if (!strcmp(dom, ci->domain) ||
193 !strcmp(&dom[1], ci->domain)) /* deal with leading . */ {
194 c = soup_cookie_copy(ci);
195 _soup_cookie_jar_add_cookie(p_cookiejar, c);
198 soup_cookies_free(cf);
199 break;
201 case XT_WL_PLUGIN:
202 d = wl_find(dom, &pl_wl);
203 if (!d) {
204 settings_add("pl_wl", dom);
205 d = wl_find(dom, &pl_wl);
207 toggle_pl(t, &a);
208 break;
209 case XT_WL_HTTPS:
210 d = wl_find(dom, &force_https);
211 if (!d) {
212 settings_add("force_https", dom);
213 d = wl_find(dom, &force_https);
215 toggle_force_https(t, &a);
216 break;
217 default:
218 abort(); /* can't happen */
220 if (d)
221 d->handy = 1;
223 done:
224 if (line)
225 free(line);
226 if (dom)
227 g_free(dom);
228 if (lt)
229 g_free(lt);
230 if (f)
231 fclose(f);
233 return (0);
237 wl_show(struct tab *t, struct karg *args, char *title, struct domain_list *wl)
239 struct domain *d;
240 char *tmp, *body;
242 body = g_strdup("");
244 /* p list */
245 if (args->i & XT_WL_PERSISTENT) {
246 tmp = body;
247 body = g_strdup_printf("%s<h2>Persistent</h2>", body);
248 g_free(tmp);
249 RB_FOREACH(d, domain_list, wl) {
250 if (d->handy == 0)
251 continue;
252 tmp = body;
253 body = g_strdup_printf("%s%s<br/>", body, d->d);
254 g_free(tmp);
258 /* s list */
259 if (args->i & XT_WL_SESSION) {
260 tmp = body;
261 body = g_strdup_printf("%s<h2>Session</h2>", body);
262 g_free(tmp);
263 RB_FOREACH(d, domain_list, wl) {
264 if (d->handy == 1)
265 continue;
266 tmp = body;
267 body = g_strdup_printf("%s%s<br/>", body, d->d);
268 g_free(tmp);
272 tmp = get_html_page(title, body, "", 0);
273 g_free(body);
274 if (wl == &js_wl)
275 load_webkit_string(t, tmp, XT_URI_ABOUT_JSWL);
276 else if (wl == &c_wl)
277 load_webkit_string(t, tmp, XT_URI_ABOUT_COOKIEWL);
278 else if (wl == &pl_wl)
279 load_webkit_string(t, tmp, XT_URI_ABOUT_PLUGINWL);
280 else if (wl == &force_https)
281 load_webkit_string(t, tmp, XT_URI_ABOUT_HTTPS);
282 g_free(tmp);
283 return (0);
286 void
287 wl_add(const char *str, struct domain_list *wl, int flags)
289 struct domain *d;
290 int add_dot = 0;
291 char *p;
293 if (str == NULL || wl == NULL || strlen(str) < 2)
294 return;
296 DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str);
298 /* treat *.moo.com the same as .moo.com */
299 if (str[0] == '*' && str[1] == '.')
300 str = &str[1];
301 else if (str[0] != '.' && (flags & XT_WL_TOPLEVEL))
302 add_dot = 1;
304 /* slice off port number */
305 p = g_strrstr(str, ":");
306 if (p)
307 *p = '\0';
309 d = g_malloc(sizeof *d);
310 if (add_dot)
311 d->d = g_strdup_printf(".%s", str);
312 else
313 d->d = g_strdup(str);
314 d->handy = (flags & XT_WL_PERSISTENT) ? 1 : 0;
316 if (RB_INSERT(domain_list, wl, d))
317 goto unwind;
319 DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d);
320 return;
321 unwind:
322 if (d) {
323 if (d->d)
324 g_free(d->d);
325 g_free(d);
330 add_cookie_wl(struct settings *s, char *entry)
332 wl_add(entry, &c_wl, XT_WL_PERSISTENT);
333 return (0);
337 add_js_wl(struct settings *s, char *entry)
339 wl_add(entry, &js_wl, XT_WL_PERSISTENT);
340 return (0);
344 add_pl_wl(struct settings *s, char *entry)
346 wl_add(entry, &pl_wl, XT_WL_PERSISTENT);
347 return (0);
351 toggle_cwl(struct tab *t, struct karg *args)
353 struct domain *d;
354 const gchar *uri;
355 char *dom = NULL;
356 int es;
358 if (args == NULL)
359 return (1);
361 uri = get_uri(t);
362 dom = find_domain(uri, args->i);
364 if (uri == NULL || dom == NULL ||
365 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
366 show_oops(t, "Can't toggle domain in cookie white list");
367 goto done;
369 d = wl_find(dom, &c_wl);
371 if (d == NULL)
372 es = 0;
373 else
374 es = 1;
376 if (args->i & XT_WL_TOGGLE)
377 es = !es;
378 else if ((args->i & XT_WL_ENABLE) && es != 1)
379 es = 1;
380 else if ((args->i & XT_WL_DISABLE) && es != 0)
381 es = 0;
383 if (es) {
384 /* enable cookies for domain */
385 args->i |= !XT_WL_PERSISTENT;
386 wl_add(dom, &c_wl, args->i);
387 } else {
388 /* disable cookies for domain */
389 if (d)
390 RB_REMOVE(domain_list, &c_wl, d);
393 if (args->i & XT_WL_RELOAD)
394 webkit_web_view_reload(t->wv);
396 done:
397 g_free(dom);
398 return (0);
402 toggle_js(struct tab *t, struct karg *args)
404 int es;
405 const gchar *uri;
406 struct domain *d;
407 char *dom = NULL;
409 if (args == NULL)
410 return (1);
412 g_object_get(G_OBJECT(t->settings),
413 "enable-scripts", &es, (char *)NULL);
414 if (args->i & XT_WL_TOGGLE)
415 es = !es;
416 else if ((args->i & XT_WL_ENABLE) && es != 1)
417 es = 1;
418 else if ((args->i & XT_WL_DISABLE) && es != 0)
419 es = 0;
420 else
421 return (1);
423 uri = get_uri(t);
424 dom = find_domain(uri, args->i);
426 if (uri == NULL || dom == NULL ||
427 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
428 show_oops(t, "Can't toggle domain in JavaScript white list");
429 goto done;
432 if (es) {
433 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY);
434 args->i |= !XT_WL_PERSISTENT;
435 wl_add(dom, &js_wl, args->i);
436 } else {
437 d = wl_find(dom, &js_wl);
438 if (d)
439 RB_REMOVE(domain_list, &js_wl, d);
440 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE);
442 g_object_set(G_OBJECT(t->settings),
443 "enable-scripts", es, (char *)NULL);
444 g_object_set(G_OBJECT(t->settings),
445 "javascript-can-open-windows-automatically", es, (char *)NULL);
446 webkit_web_view_set_settings(t->wv, t->settings);
448 if (args->i & XT_WL_RELOAD)
449 webkit_web_view_reload(t->wv);
450 done:
451 if (dom)
452 g_free(dom);
453 return (0);
457 toggle_pl(struct tab *t, struct karg *args)
459 int es;
460 const gchar *uri;
461 struct domain *d;
462 char *dom = NULL;
464 if (args == NULL)
465 return (1);
467 g_object_get(G_OBJECT(t->settings),
468 "enable-plugins", &es, (char *)NULL);
469 if (args->i & XT_WL_TOGGLE)
470 es = !es;
471 else if ((args->i & XT_WL_ENABLE) && es != 1)
472 es = 1;
473 else if ((args->i & XT_WL_DISABLE) && es != 0)
474 es = 0;
475 else
476 return (1);
478 uri = get_uri(t);
479 dom = find_domain(uri, args->i);
481 if (uri == NULL || dom == NULL ||
482 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
483 show_oops(t, "Can't toggle domain in plugins white list");
484 goto done;
487 if (es) {
488 args->i |= !XT_WL_PERSISTENT;
489 wl_add(dom, &pl_wl, args->i);
490 } else {
491 d = wl_find(dom, &pl_wl);
492 if (d)
493 RB_REMOVE(domain_list, &pl_wl, d);
495 g_object_set(G_OBJECT(t->settings),
496 "enable-plugins", es, (char *)NULL);
497 webkit_web_view_set_settings(t->wv, t->settings);
499 if (args->i & XT_WL_RELOAD)
500 webkit_web_view_reload(t->wv);
501 done:
502 if (dom)
503 g_free(dom);
504 return (0);
508 toggle_force_https(struct tab *t, struct karg *args)
510 int es;
511 const gchar *uri;
512 struct domain *d;
513 char *dom = NULL;
515 if (args == NULL)
516 return (1);
518 uri = get_uri(t);
519 dom = find_domain(uri, args->i);
521 if (uri == NULL || dom == NULL ||
522 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
523 show_oops(t, "Can't toggle domain in https force list");
524 goto done;
526 d = wl_find(dom, &force_https);
528 if (d == NULL)
529 es = 0;
530 else
531 es = 1;
533 if (args->i & XT_WL_TOGGLE)
534 es = !es;
535 else if ((args->i & XT_WL_ENABLE) && es != 1)
536 es = 1;
537 else if ((args->i & XT_WL_DISABLE) && es != 0)
538 es = 0;
540 uri = get_uri(t);
541 dom = find_domain(uri, args->i);
543 if (es) {
544 args->i |= !XT_WL_PERSISTENT;
545 wl_add(dom, &force_https, args->i);
546 } else {
547 d = wl_find(dom, &force_https);
548 if (d)
549 RB_REMOVE(domain_list, &force_https, d);
552 if (args->i & XT_WL_RELOAD)
553 webkit_web_view_reload(t->wv);
554 done:
555 if (dom)
556 g_free(dom);
557 return (0);