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