diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/Makefile.am | 4 | ||||
-rw-r--r-- | util/mount.fuse | 68 | ||||
-rw-r--r-- | util/mount.fuse.c | 151 |
3 files changed, 154 insertions, 69 deletions
diff --git a/util/Makefile.am b/util/Makefile.am index dcd69f6..56046c0 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -2,8 +2,10 @@ AM_CPPFLAGS = -D_FILE_OFFSET_BITS=64 bin_PROGRAMS = fusermount ulockmgr_server +noinst_PROGRAMS = mount.fuse fusermount_SOURCES = fusermount.c +mount_fuse_SOURCES = mount.fuse.c ulockmgr_server_SOURCES = ulockmgr_server.c ulockmgr_server_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_REENTRANT @@ -18,7 +20,7 @@ install-exec-hook: mknod $(DESTDIR)/dev/fuse -m 0666 c 10 229 || true; \ fi -EXTRA_DIST = mount.fuse udev.rules init_script +EXTRA_DIST = udev.rules init_script MOUNT_FUSE_PATH = @MOUNT_FUSE_PATH@ UDEV_RULES_PATH = @UDEV_RULES_PATH@ diff --git a/util/mount.fuse b/util/mount.fuse deleted file mode 100644 index c4ff72f..0000000 --- a/util/mount.fuse +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash -# -# FUSE mount helper -# Petr Klima <qaxi@seznam.cz> -# Thanks to Miklos Szeredi <miklos@szeredi.hu> -# to kick me to the right way -# - -VERSION="0.0.2" -PRGNAME=`basename $0` - -if [ -z "$HOME" ]; then - HOME=/root -fi -export HOME - -USAGE="${PRGNAME} version ${VERSION} -usage: ${PRGNAME} fusefs_type#[mountpath] mountpoint [FUSE options] - - example: ${PRGNAME} sshfs#root@tux:/ /mnt/tuxssh -o rw -" - -function die { - echo -e "$PRGNAME# $1" >&2 - [ -z "$2" ] && exit 128 - exit "$2" -} - -[ "$#" -ge 2 ] || die "${USAGE}" - -# for now i have to be same as FUSE mount binary -# should be configurable -eval `echo "$1" | sed -n 's,\(^[^#][^#]*\)\(#\(.*\)\)*,FSTYPE="\1" MOUNTPATH="\3",p'` - -export PATH -FSBIN=`which ${FSTYPE} 2>/dev/null` \ - || die "Can not find FUSE mount binary for FS ${FSTYPE}" 1 - -# was there an # in $1 -[ "$1" = "$MOUNTPATH" ] && MOUNTPATH="" - -MOUNTPOINT="$2" -[ -d "${MOUNTPOINT}" ] || die "Directory ${MOUNTPOINT} does not exist" - -shift -shift - -eval `echo $@ | sed -n "s/\([^,]*,\)*setuid=\([^,]*\).*/SETUID=\2/p"` - -ignore_opts='\(-o\|user\|nouser\|users\|auto\|noauto\|_netdev\|setuid=[^,]*\)' - -# loop over each mount option and skip all that should be ignored -IFS="," -for OPT in $@; do - OPT=`echo $OPT | sed "s/^$ignore_opts$/IGNORE/"` - if [ "$OPT" == "IGNORE" ]; then continue; fi - OPTIONS="$OPTIONS$OPT," -done -IFS=" " - -# add "-o " and remove trailing comma -OPTIONS="-o `echo $OPTIONS | sed "s/,$//"`" - -if test -z "$SETUID"; then - ${FSTYPE} ${MOUNTPATH} ${MOUNTPOINT} ${OPTIONS} -else - su - "$SETUID" -c "${FSTYPE} ${MOUNTPATH} ${MOUNTPOINT} ${OPTIONS}" -fi diff --git a/util/mount.fuse.c b/util/mount.fuse.c new file mode 100644 index 0000000..d156009 --- /dev/null +++ b/util/mount.fuse.c @@ -0,0 +1,151 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +static char *progname; + + +static char *xstrdup(const char *s) +{ + char *t = strdup(s); + if (!t) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + exit(1); + } + return t; +} + +static void *xrealloc(void *oldptr, size_t size) +{ + void *ptr = realloc(oldptr, size); + if (!ptr) { + fprintf(stderr, "%s: failed to allocate memory\n", progname); + exit(1); + } + return ptr; +} + +static void add_arg(char **cmdp, const char *opt) +{ + size_t optlen = strlen(opt); + size_t cmdlen = *cmdp ? strlen(*cmdp) : 0; + char *cmd = xrealloc(*cmdp, cmdlen + optlen * 4 + 4); + char *s; + s = cmd + cmdlen; + if (*cmdp) + *s++ = ' '; + + *s++ = '\''; + for (; *opt; opt++) { + if (*opt == '\'') { + *s++ = '\''; + *s++ = '\\'; + *s++ = '\''; + *s++ = '\''; + } else + *s++ = *opt; + } + *s++ = '\''; + *s = '\0'; + *cmdp = cmd; +} + +int main(int argc, char *argv[]) +{ + char *type; + char *source; + const char *mountpoint; + char *options = NULL; + char *command = NULL; + char *setuid = NULL; + int i; + + progname = argv[0]; + if (argc < 3) { + fprintf(stderr, + "usage: %s type#[source] mountpoint [-o opt[,opts...]]\n", + progname); + exit(1); + } + + type = xstrdup(argv[1]); + source = strchr(type, '#'); + if (source) + *source++ = '\0'; + + if (!type[0]) { + fprintf(stderr, "%s: empty filesystem type\n", progname); + exit(1); + } + mountpoint = argv[2]; + + for (i = 3; i < argc; i++) { + if (strcmp(argv[i], "-v") == 0) + continue; + if (strcmp(argv[i], "-o") == 0) { + char *opts; + char *opt; + i++; + if (i == argc) + break; + + opts = xstrdup(argv[i]); + opt = strtok(opts, ","); + while (opt) { + int j; + int ignore = 0; + const char *ignore_opts[] = { "", "user", "nouser", "users", + "auto", "noauto", "_netdev", + NULL}; + if (strncmp(opt, "setuid=", 7) == 0) { + setuid = xstrdup(opt + 7); + ignore = 1; + } + for (j = 0; ignore_opts[j]; j++) + if (strcmp(opt, ignore_opts[j]) == 0) + ignore = 1; + + if (!ignore) { + int oldlen = options ? strlen(options) : 0; + options = xrealloc(options, oldlen + 1 + strlen(opt) + 1); + if (!oldlen) + strcpy(options, opt); + else { + strcat(options, ","); + strcat(options, opt); + } + } + opt = strtok(NULL, ","); + } + } + } + + add_arg(&command, type); + if (source) + add_arg(&command, source); + add_arg(&command, mountpoint); + if (options) { + add_arg(&command, "-o"); + add_arg(&command, options); + } + + if (setuid && setuid[0]) { + char *sucommand = command; + command = NULL; + add_arg(&command, "su"); + add_arg(&command, "-"); + add_arg(&command, setuid); + add_arg(&command, "-c"); + add_arg(&command, sucommand); + } else if (!getenv("HOME")) { + /* Hack to make filesystems work in the boot environment */ + setenv("HOME", "/root", 0); + } + + execl("/bin/sh", "/bin/sh", "-c", command, NULL); + fprintf(stderr, "%s: failed to execute /bin/sh: %s\n", progname, + strerror(errno)); + return 1; +} |