f29903a
diff -ur afuse-0.2.orig/src/afuse.c afuse-0.2/src/afuse.c
f29903a
--- afuse-0.2.orig/src/afuse.c	2008-02-18 17:16:32.000000000 -0500
f29903a
+++ afuse-0.2/src/afuse.c	2008-07-10 21:50:06.000000000 -0400
f29903a
@@ -280,14 +280,19 @@
f29903a
 }
f29903a
 
f29903a
 
f29903a
-// !!FIXME!! allow escaping of %'s
f29903a
 // Note: this method strips out quotes and applies them itself as should be appropriate
f29903a
-char *expand_template(const char *template, const char *mount_point, const char *root_name)
f29903a
+bool run_template(const char *template, const char *mount_point, const char *root_name)
f29903a
 {
f29903a
 	int len = 0;
f29903a
+	int nargs = 1;
f29903a
 	int i;
f29903a
-	char *expanded_name;
f29903a
-	char *expanded_name_start;
f29903a
+	char *buf;
f29903a
+	char *p;
f29903a
+	char **args;
f29903a
+	char **arg;
f29903a
+	bool quote = false;
f29903a
+	pid_t pid;
f29903a
+	int status;
f29903a
 
f29903a
 	// calculate length
f29903a
 	for(i = 0; template[i]; i++)
f29903a
@@ -295,53 +300,100 @@
f29903a
 			switch(template[i + 1])
f29903a
 			{
f29903a
 				case 'm':
f29903a
-					len += strlen(mount_point) + 2;
f29903a
+					len += strlen(mount_point);
f29903a
 					i++;
f29903a
 					break;
f29903a
 				case 'r':
f29903a
-					len += strlen(root_name) + 2;
f29903a
+					len += strlen(root_name);
f29903a
+					i++;
f29903a
+					break;
f29903a
+				case '%':
f29903a
+					len++;
f29903a
 					i++;
f29903a
 					break;
f29903a
 			}
f29903a
-		} else if(template[i] != '"')
f29903a
+		} else if(template[i] == ' ' && !quote) {
f29903a
+			len++;
f29903a
+			nargs++;
f29903a
+		} else if(template[i] == '"')
f29903a
+			quote = !quote;
f29903a
+		else if(template[i] == '\\' && template[i + 1])
f29903a
+			len++, i++;
f29903a
+		else
f29903a
 			len++;
f29903a
 
f29903a
-	expanded_name_start = expanded_name = my_malloc(len + 1);
f29903a
+	buf = my_malloc(len + 1);
f29903a
+	args = my_malloc((nargs + 1) * sizeof(*args));
f29903a
+
f29903a
+	p = buf;
f29903a
+	arg = args;
f29903a
+	*arg++ = p;
f29903a
 
f29903a
 	for(i = 0; template[i]; i++)
f29903a
 		if(template[i] == '%') {
f29903a
-			int j = 0;
f29903a
 			switch(template[i + 1])
f29903a
 			{
f29903a
 				case 'm':
f29903a
-					*expanded_name++ = '"';
f29903a
-					while(mount_point[j])
f29903a
-						*expanded_name++ = mount_point[j++];
f29903a
-					*expanded_name++ = '"';
f29903a
+					strcpy(p, mount_point);
f29903a
+					p += strlen(mount_point);
f29903a
 					i++;
f29903a
 					break;
f29903a
 				case 'r':
f29903a
-					*expanded_name++ = '"';
f29903a
-					while(root_name[j])
f29903a
-						*expanded_name++ = root_name[j++];
f29903a
-					*expanded_name++ = '"';
f29903a
+					strcpy(p, root_name);
f29903a
+					p += strlen(root_name);
f29903a
+					i++;
f29903a
+					break;
f29903a
+				case '%':
f29903a
+					*p++ = '%';
f29903a
 					i++;
f29903a
 					break;
f29903a
 			}
f29903a
-		} else if(template[i] != '"')
f29903a
-			*expanded_name++ = template[i];
f29903a
-
f29903a
-	*expanded_name = '\0';
f29903a
-
f29903a
-	return expanded_name_start;
f29903a
+		} else if(template[i] == ' ' && !quote) {
f29903a
+			*p++ = '\0';
f29903a
+			*arg++ = p;
f29903a
+		} else if(template[i] == '"')
f29903a
+			quote = !quote;
f29903a
+		else if(template[i] == '\\' && template[i + 1])
f29903a
+			*p++ = template[++i];
f29903a
+		else
f29903a
+			*p++ = template[i];
f29903a
+
f29903a
+	*p = '\0';
f29903a
+	*arg = NULL;
f29903a
+
f29903a
+	pid = fork();
f29903a
+	if(pid == -1) {
f29903a
+		fprintf(stderr, "Failed to fork (%s)\n", strerror(errno));
f29903a
+		free(args);
f29903a
+		free(buf);
f29903a
+		return false;
f29903a
+	}
f29903a
+	if(pid == 0) {
f29903a
+		execvp(args[0], args);
f29903a
+		abort();
f29903a
+	}
f29903a
+	pid = waitpid(pid, &status, 0);
f29903a
+	if(pid == -1) {
f29903a
+		fprintf(stderr, "Failed to waitpid (%s)\n", strerror(errno));
f29903a
+		free(args);
f29903a
+		free(buf);
f29903a
+		return false;
f29903a
+	}
f29903a
+	if(!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
f29903a
+		fprintf(stderr, "Failed to invoke command: %s\n", args[0]);
f29903a
+		free(args);
f29903a
+		free(buf);
f29903a
+		return false;
f29903a
+	}
f29903a
+	free(args);
f29903a
+	free(buf);
f29903a
+	return true;
f29903a
 }
f29903a
 
f29903a
 mount_list_t *do_mount(const char *root_name)
f29903a
 {
f29903a
 	char *mount_point;
f29903a
-	char *mount_command;
f29903a
 	mount_list_t *mount;
f29903a
-	int sysret;
f29903a
 
f29903a
 	fprintf(stderr, "Mounting: %s\n", root_name);
f29903a
 
f29903a
@@ -351,57 +403,33 @@
f29903a
 		return NULL;
f29903a
 	}
f29903a
 
f29903a
-	mount_command = expand_template(user_options.mount_command_template,
f29903a
-	                                mount_point, root_name);
f29903a
-	sysret = system(mount_command);
f29903a
-
f29903a
-	fprintf(stderr, "sysret: %.8x\n", sysret);
f29903a
-
f29903a
-	if(sysret) {
f29903a
-		fprintf(stderr, "Failed to invoke mount command: '%s' (%s)\n",
f29903a
-			mount_command, sysret != -1 ?
f29903a
-				"Error executing mount" :
f29903a
-				strerror(errno));
f29903a
-
f29903a
+	if(!run_template(user_options.mount_command_template,
f29903a
+			 mount_point, root_name)) {
f29903a
 		// remove the now unused directory
f29903a
 		if( rmdir(mount_point) == -1 )
f29903a
 			fprintf(stderr, "Failed to remove mount point dir: %s (%s)",
f29903a
 				mount_point, strerror(errno));
f29903a
 
f29903a
-		free(mount_command);
f29903a
 		free(mount_point);
f29903a
 		return NULL;
f29903a
 	}
f29903a
 
f29903a
 	mount = add_mount(root_name, mount_point);
f29903a
-
f29903a
-	free(mount_command);
f29903a
 	return mount;
f29903a
 }
f29903a
 
f29903a
 int do_umount(mount_list_t *mount)
f29903a
 {
f29903a
-	char *unmount_command;
f29903a
-	int sysret;
f29903a
-
f29903a
 	fprintf(stderr, "Unmounting: %s\n", mount->root_name);
f29903a
 
f29903a
-	unmount_command = expand_template(user_options.unmount_command_template,
f29903a
-	                                  mount->mount_point, mount->root_name);
f29903a
-	sysret = system(unmount_command);
f29903a
-	if(sysret) {
f29903a
-		fprintf(stderr, "Failed to invoke unmount command: '%s' (%s)\n",
f29903a
-		        unmount_command, sysret != -1 ?
f29903a
-			               "Error executing mount" :
f29903a
-				       strerror(errno));
f29903a
-		/* Still unmount anyway */
f29903a
-	}
f29903a
+	run_template(user_options.unmount_command_template,
f29903a
+		     mount->mount_point, mount->root_name);
f29903a
+	/* Still unmount anyway */
f29903a
 
f29903a
 	if( rmdir(mount->mount_point) == -1 )
f29903a
 		fprintf(stderr, "Failed to remove mount point dir: %s (%s)",
f29903a
 				mount->mount_point, strerror(errno));
f29903a
 	remove_mount(mount);
f29903a
-	free(unmount_command);
f29903a
 	return 1;
f29903a
 }
f29903a
 
f29903a
f29903a