Some mount helpers may live in /usr/sbin, so rewrite the helper function check_special_mountprog() to work off a list of paths. Now the default search path is /sbin and /usr/sbin, and it should be easy to extend to other locations as well. Signed-off-by: Mike Frysinger <vapier@xxxxxxxxxx> --- mount/mount.c | 151 +++++++++++++++++++++++++++++++------------------------- 1 files changed, 84 insertions(+), 67 deletions(-) diff --git a/mount/mount.c b/mount/mount.c index 0cef101..5be6087 100644 --- a/mount/mount.c +++ b/mount/mount.c @@ -631,6 +631,8 @@ do_mount (struct mountargs *args, int *special, int *status) { return ret; } +#define MOUNT_SEARCH_PATH "/sbin:/usr/sbin" + /* * check_special_mountprog() * If there is a special mount program for this type, exec it. @@ -639,74 +641,89 @@ do_mount (struct mountargs *args, int *special, int *status) { static int check_special_mountprog(const char *spec, const char *node, const char *type, int flags, char *extra_opts, int *status) { - char mountprog[120]; - struct stat statbuf; - int res; - - if (!external_allowed) - return 0; - - if (type == NULL || strcmp(type, "none") == 0) - return 0; - - if (strlen(type) < 100) { - sprintf(mountprog, "/sbin/mount.%s", type); - if (stat(mountprog, &statbuf) == 0) { - if (verbose) - fflush(stdout); - res = fork(); - if (res == 0) { - char *oo, *mountargs[10]; - int i = 0; - - if(setgid(getgid()) < 0) - die(EX_FAIL, _("mount: cannot set group id: %s"), strerror(errno)); - - if(setuid(getuid()) < 0) - die(EX_FAIL, _("mount: cannot set user id: %s"), strerror(errno)); - - oo = fix_opts_string (flags, extra_opts, NULL); - mountargs[i++] = mountprog; /* 1 */ - mountargs[i++] = (char *) spec; /* 2 */ - mountargs[i++] = (char *) node; /* 3 */ - if (sloppy && strncmp(type, "nfs", 3) == 0) - mountargs[i++] = "-s"; /* 4 */ - if (fake) - mountargs[i++] = "-f"; /* 5 */ - if (nomtab) - mountargs[i++] = "-n"; /* 6 */ - if (verbose) - mountargs[i++] = "-v"; /* 7 */ - if (oo && *oo) { - mountargs[i++] = "-o"; /* 8 */ - mountargs[i++] = oo; /* 9 */ - } - mountargs[i] = NULL; /* 10 */ - - if (verbose > 2) { - i = 0; - while(mountargs[i]) { - printf("mount: external mount: argv[%d] = \"%s\"\n", - i, mountargs[i]); - i++; - } + char search_path[] = MOUNT_SEARCH_PATH; + char *path, mountprog[150]; + struct stat statbuf; + int res; + + if (!external_allowed) + return 0; + + if (type == NULL || strcmp(type, "none") == 0) + return 0; + + path = strtok(search_path, ":"); + while (path) { + res = snprintf(mountprog, sizeof(mountprog), "%s/mount.%s", + path, type); + path = strtok(NULL, ":"); + if (res >= sizeof(mountprog) || res < 0) + continue; + + if (stat(mountprog, &statbuf)) + continue; + + if (verbose) fflush(stdout); - } - - execv(mountprog, mountargs); - exit(1); /* exec failed */ - } else if (res != -1) { - int st; - wait(&st); - *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR); - return 1; - } else { - int errsv = errno; - error(_("mount: cannot fork: %s"), strerror(errsv)); - } - } - } - return 0; + + switch (fork()) { + case 0: { /* child */ + char *oo, *mountargs[10]; + int i = 0; + + if (setgid(getgid()) < 0) + die(EX_FAIL, _("mount: cannot set group id: %s"), strerror(errno)); + + if (setuid(getuid()) < 0) + die(EX_FAIL, _("mount: cannot set user id: %s"), strerror(errno)); + + oo = fix_opts_string (flags, extra_opts, NULL); + mountargs[i++] = mountprog; /* 1 */ + mountargs[i++] = (char *) spec; /* 2 */ + mountargs[i++] = (char *) node; /* 3 */ + if (sloppy && strncmp(type, "nfs", 3) == 0) + mountargs[i++] = "-s"; /* 4 */ + if (fake) + mountargs[i++] = "-f"; /* 5 */ + if (nomtab) + mountargs[i++] = "-n"; /* 6 */ + if (verbose) + mountargs[i++] = "-v"; /* 7 */ + if (oo && *oo) { + mountargs[i++] = "-o"; /* 8 */ + mountargs[i++] = oo; /* 9 */ + } + mountargs[i] = NULL; /* 10 */ + + if (verbose > 2) { + i = 0; + while (mountargs[i]) { + printf("mount: external mount: argv[%d] = \"%s\"\n", + i, mountargs[i]); + i++; + } + fflush(stdout); + } + + execv(mountprog, mountargs); + exit(1); /* exec failed */ + } + + default: { /* parent */ + int st; + wait(&st); + *status = (WIFEXITED(st) ? WEXITSTATUS(st) : EX_SYSERR); + return 1; + } + + case -1: { /* error */ + int errsv = errno; + error(_("mount: cannot fork: %s"), strerror(errsv)); + } + } + } + + return 0; } -- 1.6.6 -- To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html