--- src/balsa-message.c	2001/08/10 13:40:52	1.174
+++ src/balsa-message.c	2001/08/21 09:17:34
@@ -53,6 +53,14 @@
 
 #define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
 
+#ifndef GNOME_EXEC_WORKS
+#include <sys/types.h>
+#include <sys/wait.h>
+#define gnome_execute_async(dir, argc, argv) _gnome_execute_async((dir), (argc), (argv)) 
+#define gnome_execute_shell(dir, cmd) _gnome_execute_shell((dir), (cmd))
+#define gnome_url_show(url) _gnome_url_show((url))
+#endif
+
 enum {
     SELECT_PART,
     LAST_SIGNAL,
@@ -1045,6 +1053,172 @@
 
 
 /* HELPER FUNCTIONS ----------------------------------------------- */
+static int _gnome_execute_async(const char *dir, int argc, char * const argv[])
+{
+    pid_t child;
+
+    if((child=fork())==0) {
+	pid_t grand_child;
+
+	if((grand_child=fork())==0) {
+#ifdef _NO_SYSTEM
+	    if(dir) chdir(dir);
+	    
+	    execvp(argv[0], argv);	/* **** But this is what fails... */
+	    _exit(1);		/* If exec fails */
+#else
+	    char cmd[PATH_MAX+1];
+	    int i;
+	
+	    if(dir) chdir(dir);
+	    
+	    cmd[0]='\0';
+	    for(i=0; i<argc && argv[i]; i++) {
+		strncat(cmd, "'", sizeof(cmd));
+		strncat(cmd, argv[i], sizeof(cmd));
+		strncat(cmd, "' ", sizeof(cmd));
+	    }
+	    system(cmd);
+	    _exit(0);
+#endif /* _NO_SYSTEM */
+	}
+	_exit(0);
+
+    } else if(child>0) {
+	waitpid(child, NULL, 0);
+    }
+	
+    return child;
+}
+
+
+static int _gnome_execute_shell(const char *dir, const char *cmd) 
+{
+    char *shell=gnome_util_user_shell(), *argv[4];
+    int status;
+    
+    g_return_val_if_fail(cmd != NULL, -1);
+
+    argv[0]=shell;
+    argv[1]="-c";
+    argv[2]=(char *)cmd;
+    argv[3]=NULL;
+	
+    status=gnome_execute_async(dir, 4, argv);
+    
+    g_free(shell);
+
+    return status;
+}
+
+#define DEFAULT_HANDLER "gnome-moz-remote --newwin \"%s\""
+
+static gchar *gnome_url_default_handler ()
+{
+	static gchar *default_handler = 0;
+	
+	if (!default_handler) {
+		gchar *str, *app;
+		gboolean def;
+		str = gnome_config_get_string_with_default ("/Gnome/URL Handlers/default-show",
+							    &def);
+		if (def) {
+			app = gnome_is_program_in_path ("nautilus");
+			if (app) {
+				g_free (app);
+				app = "nautilus \"%s\"";
+			} else
+				app = "gnome-help-browser \"%s\"";
+
+			/* first time gnome_url_show is run -- set up some useful defaults */
+			default_handler = DEFAULT_HANDLER;
+			gnome_config_set_string ("/Gnome/URL Handlers/default-show", default_handler);
+
+			g_free (gnome_config_get_string_with_default(
+				"/Gnome/URL Handlers/info-show", &def));
+			if (def)
+				gnome_config_set_string ("/Gnome/URL Handlers/info-show", app);
+			g_free (gnome_config_get_string_with_default(
+				"/Gnome/URL Handlers/man-show", &def));
+			if (def)
+				gnome_config_set_string ("/Gnome/URL Handlers/man-show", app);
+			g_free (gnome_config_get_string_with_default(
+				"/Gnome/URL Handlers/ghelp-show", &def));
+			if (def)
+				gnome_config_set_string ("/Gnome/URL Handlers/ghelp-show", app);
+
+			gnome_config_sync_file ("/Gnome/");
+		} else
+			default_handler = str;
+	}
+	return default_handler;
+}
+
+static void _gnome_url_show(const gchar *url)
+{
+	gint i;
+	gchar *pos, *template;
+	gboolean free_template = FALSE;
+	int argc;
+       	char **argv;
+	
+	g_return_if_fail (url != NULL);
+	pos = strchr (url, ':');
+
+	if (pos){
+		gchar *protocol, *path;
+		gboolean def;
+		
+		g_return_if_fail (pos >= url);
+		protocol = g_new (gchar, pos - url + 1);
+		strncpy (protocol, url, pos - url);
+		protocol [pos - url] = '\0';
+		g_strdown (protocol);
+		
+		path = g_strconcat ("/Gnome/URL Handlers/", protocol, "-show", NULL);
+		template = gnome_config_get_string_with_default (path, &def);
+		g_free (path);
+		if (def)
+		    template = gnome_url_default_handler ();
+		else
+			free_template = TRUE;
+		g_free (protocol);
+	} else /* no : ? -- this shouldn't happen.  Use default handler */
+		template = gnome_url_default_handler ();
+
+	/* we use a popt function as it does exactly what we want to do and
+	   gnome already uses popt */
+	if(poptParseArgvString(template, &argc, &argv) != 0) {
+		/* can't parse */
+		g_warning("Parse error of '%s'", template);
+		return;
+	}
+
+	/* we can just replace the entry in the array since the
+	 * array is all in one buffer, we won't leak */
+	for(i = 0; i < argc; i++) {
+		if(strcmp(argv[i], "%s") == 0)
+			/* we can safely cast as it will not get freed nor
+			 * modified */
+			argv[i] = (char *)url;
+	}
+
+	/* use execute async, and not the shell, shell is evil and a
+	 * security hole */
+	gnome_execute_async (NULL, argc, argv);
+
+	if (free_template)
+		g_free (template);
+
+	/* the way the poptParseArgvString works is that the entire thing
+	 * is allocated as one buffer, so just free will suffice, also
+	 * it must be free and not g_free */
+	free(argv);
+}
+
+
+
+
 static GdkFont*
 find_body_font(LibBalsaMessageBody * body)
 {
