about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJosh Rickmar <jrick@devio.us>2012-06-01 17:15:52 -0400
committerJosh Rickmar <jrick@devio.us>2012-06-01 17:15:52 -0400
commit1df03fd0b17313e7d953dcb0e14d6849207ca0dc (patch)
tree885f8eb5280e5b5143001f82df89d93988b5427f
parente3380aecad73c5e9114862db9d39368beb76a48c (diff)
downloadxombrero-1df03fd0b17313e7d953dcb0e14d6849207ca0dc.tar.gz
Add a custom_uri setting to check if a URI should be handled by an
external script rather then through xombrero.  This makes it possible
to use scripts to support things such as mailto URIs.  Fixes FS#253
-rw-r--r--settings.c68
-rw-r--r--xombrero.118
-rw-r--r--xombrero.c32
-rw-r--r--xombrero.h8
4 files changed, 124 insertions, 2 deletions
diff --git a/settings.c b/settings.c
index 09aef8c..8f33809 100644
--- a/settings.c
+++ b/settings.c
@@ -126,6 +126,7 @@ int		add_mime_type(struct settings *, char *);
 int		add_alias(struct settings *, char *);
 int		add_kb(struct settings *, char *);
 int		add_ua(struct settings *, char *);
+int		add_custom_uri(struct settings *, char *);
 
 int		set_append_next(char *);
 int		set_cmd_font(char *);
@@ -196,6 +197,8 @@ void		walk_kb(struct settings *, void (*)(struct settings *, char *,
 		    void *), void *);
 void		walk_ua(struct settings *, void (*)(struct settings *, char *,
 		    void *), void *);
+void		walk_custom_uri(struct settings *, void (*)(struct settings *,
+		    char *, void *), void *);
 
 int
 set_http_proxy(char *proxy)
@@ -284,6 +287,12 @@ struct special		s_cookie_wl = {
 	walk_cookie_wl
 };
 
+struct special		s_uri = {
+	add_custom_uri,
+	NULL,
+	walk_custom_uri,
+};
+
 struct special		s_default_script = {
 	set_default_script,
 	get_default_script,
@@ -414,7 +423,8 @@ struct settings		rs[] = {
 	{ "keybinding",			XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_kb, NULL, NULL },
 	{ "mime_type",			XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_mime, NULL, NULL },
 	{ "pl_wl",			XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_pl, NULL, NULL },
-	{ "user_agent",			XT_S_STR, XT_SF_RUNTIME, NULL,	NULL, &s_ua, NULL, NULL },
+	{ "user_agent",			XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_ua, NULL, NULL },
+	{ "custom_uri",			XT_S_STR, XT_SF_RUNTIME, NULL, NULL, &s_uri, NULL, NULL },
 };
 
 int
@@ -1218,6 +1228,28 @@ keybinding_add(char *cmd, char *key, int use_in_entry)
 }
 
 int
+custom_uri_add(char *uri, char *cmd)
+{
+	struct custom_uri	*u;
+
+	TAILQ_FOREACH(u, &cul, entry)
+		if (!strcmp((uri), u->uri) && !strcmp(cmd, u->cmd)) {
+			TAILQ_REMOVE(&cul, u, entry);
+			g_free(u);
+		}
+
+	u = g_malloc(sizeof (struct custom_uri));
+	u->uri = g_strdup(uri);
+	u->cmd = g_strdup(cmd);
+
+	DNPRINTF(XT_D_CUSTOM_URI, "custom_uri_add: %s %s\n", u->uri, u->cmd);
+
+	/* don't check here if the script is valid, wait until running it */
+	TAILQ_INSERT_HEAD(&cul, u, entry);
+	return (0);
+}
+
+int
 add_kb(struct settings *s, char *entry)
 {
 	char			*kb, *key;
@@ -1240,6 +1272,40 @@ add_kb(struct settings *s, char *entry)
 }
 
 int
+add_custom_uri(struct settings *s, char *entry)
+{
+	char			*uri, *cmd;
+
+	DNPRINTF(XT_D_CUSTOM_URI, "add_custom_uri: %s\n", entry);
+
+	uri = strstr(entry, ",");
+	if (uri == NULL)
+		return (1);
+	*uri = '\0';
+	cmd = uri + 1;
+
+	return (custom_uri_add(entry, cmd));
+}
+
+void
+walk_custom_uri(struct settings *s,
+    void (*cb)(struct settings *, char *, void *), void *cb_args)
+{
+	struct custom_uri	*u;
+	char			buf[1024];
+
+	if (s == NULL || cb == NULL) {
+		show_oops(NULL, "walk_custom_uri invalid parameters");
+		return;
+	}
+
+	TAILQ_FOREACH(u, &cul, entry) {
+		snprintf(buf, sizeof buf, "%s,%s", u->uri, u->cmd);
+		cb(s, buf, cb_args);
+	}
+}
+
+int
 add_ua(struct settings *s, char *value)
 {
 	struct user_agent *ua;
diff --git a/xombrero.1 b/xombrero.1
index 69154ab..00dfad8 100644
--- a/xombrero.1
+++ b/xombrero.1
@@ -1011,6 +1011,24 @@ A fully qualified host is also valid and is for example www.moo.com.
 Enable cookies.
 .It Cm ctrl_click_focus
 Give focus in newly created tab instead of opening it in the background.
+.It Cm custom_uri
+This setting provides the ability to run custom executables for
+special URIs.
+The syntax for this setting is
+.Pa custom_uri\ =\ protocol,command .
+The URI is passed as a single argument to
+.Pa command
+to be parsed and executed.
+.Pp
+For example, to add the ability to use custom
+.Pa mailto
+URIs, add the setting
+.Pa custom_uri = mailto,command
+where
+.Pa command
+is a program that will parse the
+.Pa mailto
+URI and open your mail client.
 .It Cm default_script
 Path to the script used as the default value for the run_script
 command.
diff --git a/xombrero.c b/xombrero.c
index 6835fb7..67dac8b 100644
--- a/xombrero.c
+++ b/xombrero.c
@@ -221,6 +221,7 @@ struct undo_tailq	undos;
 struct keybinding_list	kbl;
 struct sp_list		spl;
 struct user_agent_list	ua_list;
+struct custom_uri_list	cul;
 int			user_agent_count = 0;
 struct command_list	chl;
 struct command_list	shl;
@@ -3290,7 +3291,29 @@ tab_close_cb(GtkWidget *btn, GdkEventButton *e, struct tab *t)
 	return (FALSE);
 }
 
+int
+parse_custom_uri(struct tab *t, const char *uri)
+{
+	struct custom_uri	*u;
+	int			handled = 0;
+	char			*cmd, *esc_uri;
+
+	TAILQ_FOREACH(u, &cul, entry) {
+		if (strncmp(uri, u->uri, strlen(u->uri)))
+			continue;
+
+		handled = 1;
+		esc_uri = g_strescape(uri, "");
+		cmd = g_strdup_printf("%s \"%s\"", u->cmd, esc_uri);
+		if (system(cmd))
+			show_oops(t, "custom uri command failed: %s",
+			    cmd);
+		g_free(esc_uri);
+		g_free(cmd);
+	}
 
+	return (handled);
+}
 
 void
 activate_uri_entry_cb(GtkWidget* entry, struct tab *t)
@@ -3315,6 +3338,9 @@ activate_uri_entry_cb(GtkWidget* entry, struct tab *t)
 	if (parse_xtp_url(t, uri))
 		return;
 
+	if (parse_custom_uri(t, uri))
+		return;
+
 	/* otherwise continue to load page normally */
 	load_uri(t, (gchar *)uri);
 	focus_webview(t);
@@ -4535,7 +4561,10 @@ webview_npd_cb(WebKitWebView *wv, WebKitWebFrame *wf,
 
 	/* If this is an xtp url, we don't load anything else. */
 	if (parse_xtp_url(t, uri))
-		    return (TRUE);
+		return (TRUE);
+
+	if (parse_custom_uri(t, uri))
+		return (TRUE);
 
 	if ((t->mode == XT_MODE_HINT && t->new_tab) || t->ctrl_click) {
 		t->ctrl_click = 0;
@@ -7734,6 +7763,7 @@ main(int argc, char **argv)
 	TAILQ_INIT(&chl);
 	TAILQ_INIT(&shl);
 	TAILQ_INIT(&ua_list);
+	TAILQ_INIT(&cul);
 
 #ifndef XT_RESOURCE_LIMITS_DISABLE
 	struct rlimit		rlp;
diff --git a/xombrero.h b/xombrero.h
index 8a11040..d9222b5 100644
--- a/xombrero.h
+++ b/xombrero.h
@@ -573,6 +573,13 @@ struct key_binding {
 };
 TAILQ_HEAD(keybinding_list, key_binding);
 
+struct custom_uri {
+	char			*uri;
+	char			*cmd;
+	TAILQ_ENTRY(custom_uri)	entry;
+};
+TAILQ_HEAD(custom_uri_list, custom_uri);
+
 struct user_agent {
 	char *value;
 	TAILQ_ENTRY(user_agent)	entry;
@@ -729,6 +736,7 @@ extern struct mime_type_list	mtl;
 extern struct keybinding_list	kbl;
 extern struct sp_list		spl;
 extern struct user_agent_list	ua_list;
+extern struct custom_uri_list	cul;
 extern int			user_agent_count;
 
 extern PangoFontDescription	*cmd_font;