1 /**
2  * vimb - a webkit based vim like browser.
3  *
4  * Copyright (C) 2012-2018 Daniel Carl
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://www.gnu.org/licenses/.
18  */
19 
20 #include <string.h>
21 
22 #include "main.h"
23 #include "handler.h"
24 #include "util.h"
25 
26 extern struct Vimb vb;
27 
28 struct handler {
29     GHashTable *table;  /* holds the protocol handlers */
30 };
31 
32 static char *handler_lookup(Handler *h, const char *uri);
33 
handler_new(void)34 Handler *handler_new(void)
35 {
36     Handler *h = g_new(Handler, 1);
37     h->table   = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
38 
39     return h;
40 }
41 
handler_free(Handler * h)42 void handler_free(Handler *h)
43 {
44     if (h->table) {
45         g_hash_table_destroy(h->table);
46         h->table = NULL;
47     }
48     g_free(h);
49 }
50 
handler_add(Handler * h,const char * key,const char * cmd)51 gboolean handler_add(Handler *h, const char *key, const char *cmd)
52 {
53     g_hash_table_insert(h->table, g_strdup(key), g_strdup(cmd));
54 
55     return TRUE;
56 }
57 
handler_remove(Handler * h,const char * key)58 gboolean handler_remove(Handler *h, const char *key)
59 {
60     return g_hash_table_remove(h->table, key);
61 }
62 
handler_handle_uri(Handler * h,const char * uri)63 gboolean handler_handle_uri(Handler *h, const char *uri)
64 {
65     char *handler, *cmd;
66     GError *error = NULL;
67     gboolean res;
68 
69     if (!(handler = handler_lookup(h, uri))) {
70         return FALSE;
71     }
72 
73     cmd = g_strdup_printf(handler, uri);
74     if (!g_spawn_command_line_async(cmd, &error)) {
75         g_warning("Can't run '%s': %s", cmd, error->message);
76         g_clear_error(&error);
77         res = FALSE;
78     } else {
79         res = TRUE;
80     }
81 
82     g_free(cmd);
83     return res;
84 }
85 
handler_fill_completion(Handler * h,GtkListStore * store,const char * input)86 gboolean handler_fill_completion(Handler *h, GtkListStore *store, const char *input)
87 {
88     GList *src     = g_hash_table_get_keys(h->table);
89     gboolean found = util_fill_completion(store, input, src);
90     g_list_free(src);
91 
92     return found;
93 }
94 
handler_lookup(Handler * h,const char * uri)95 static char *handler_lookup(Handler *h, const char *uri)
96 {
97     char *p, *schema, *handler = NULL;
98 
99     if ((p = strchr(uri, ':'))) {
100         schema  = g_strndup(uri, p - uri);
101         handler = g_hash_table_lookup(h->table, schema);
102         g_free(schema);
103     }
104 
105     return handler;
106 }
107