aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2007-04-18 16:04:27 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2007-04-18 16:04:27 +0000
commit0ac820ee6a02e761ad00e70b93c448de4d227877 (patch)
treed01b9f55860359bce18bf1bd7f50e001cfbe14e1 /util
parentc49573731c2b9286fc9773840da1a4fa8597dc70 (diff)
Replace utils/mount.fuse "sh" script with a "C" program
Diffstat (limited to 'util')
-rw-r--r--util/Makefile.am4
-rw-r--r--util/mount.fuse68
-rw-r--r--util/mount.fuse.c151
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;
+}