aboutsummaryrefslogtreecommitdiffstats
path: root/lib/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/helper.c')
-rw-r--r--lib/helper.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/helper.c b/lib/helper.c
new file mode 100644
index 0000000..f4a8a16
--- /dev/null
+++ b/lib/helper.c
@@ -0,0 +1,154 @@
+/*
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001 Miklos Szeredi (mszeredi@inf.bme.hu)
+
+ This program can be distributed under the terms of the GNU GPL.
+ See the file COPYING.
+*/
+
+#include "fuse.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <signal.h>
+#include <errno.h>
+
+#define FUSE_MOUNTED_ENV "_FUSE_MOUNTED"
+#define FUSE_UMOUNT_CMD_ENV "_FUSE_UNMOUNT_CMD"
+
+static void usage(char *progname)
+{
+ fprintf(stderr,
+ "usage: %s mountpoint [options] \n"
+ "Options:\n"
+ " -d enable debug output\n"
+ " -s disable multithreaded operation\n"
+ " -h print help\n",
+ progname);
+ exit(1);
+}
+
+static void fuse_unmount()
+{
+ close(0);
+ system(getenv(FUSE_UMOUNT_CMD_ENV));
+}
+
+static int fuse_mount(int *argcp, char **argv)
+{
+ char *isreexec = getenv(FUSE_MOUNTED_ENV);
+
+ if(isreexec == NULL) {
+ int i;
+ int argc = *argcp;
+ char *mountprog = "fusermount";
+ char **newargv = (char **) malloc((1 + argc + 1) * sizeof(char *));
+
+ if(argc < 2 || argv[1][0] == '-')
+ usage(argv[0]);
+
+ /* oldargs: "PROG MOUNTPOINT ARGS..."
+ newargs: "fusermount MOUNTPOINT PROG ARGS..." */
+
+ newargv[0] = mountprog;
+ newargv[1] = argv[1];
+ newargv[2] = argv[0];
+ for(i = 2; i < argc; i++)
+ newargv[i+1] = argv[i];
+ newargv[i+1] = NULL;
+
+ execvp(mountprog, newargv);
+ fprintf(stderr, "fuse: failed to exec %s: %s\n", mountprog,
+ strerror(errno));
+ return -1;
+ }
+ unsetenv(FUSE_MOUNTED_ENV);
+
+ /* The actual file descriptor is stdin */
+ return 0;
+}
+
+
+static void exit_handler()
+{
+ exit(0);
+}
+
+static void set_signal_handlers()
+{
+ struct sigaction sa;
+
+ sa.sa_handler = exit_handler;
+ sigemptyset(&(sa.sa_mask));
+ sa.sa_flags = 0;
+
+ if (sigaction(SIGHUP, &sa, NULL) == -1 ||
+ sigaction(SIGINT, &sa, NULL) == -1 ||
+ sigaction(SIGTERM, &sa, NULL) == -1) {
+
+ perror("Cannot set exit signal handlers");
+ exit(1);
+ }
+
+ sa.sa_handler = SIG_IGN;
+
+ if(sigaction(SIGPIPE, &sa, NULL) == -1) {
+ perror("Cannot set ignored signals");
+ exit(1);
+ }
+}
+
+void fuse_main(int argc, char *argv[], const struct fuse_operations *op)
+{
+ int fd;
+ int argctr;
+ int flags;
+ int multithreaded;
+ struct fuse *fuse;
+
+ fd = fuse_mount(&argc, argv);
+ if(fd == -1)
+ exit(1);
+
+ atexit(fuse_unmount);
+ set_signal_handlers();
+
+ argctr = 1;
+ flags = 0;
+ multithreaded = 1;
+ for(; argctr < argc && argv[argctr][0] == '-'; argctr ++) {
+ switch(argv[argctr][1]) {
+ case 'd':
+ flags |= FUSE_DEBUG;
+ break;
+
+ case 's':
+ multithreaded = 0;
+ break;
+
+ case 'h':
+ usage(argv[0]);
+ break;
+
+ default:
+ fprintf(stderr, "invalid option: %s\n", argv[argctr]);
+ exit(1);
+ }
+ }
+ if(argctr != argc) {
+ fprintf(stderr, "missing or surplus argument\n");
+ exit(1);
+ }
+
+ fuse = fuse_new(fd, flags);
+ fuse_set_operations(fuse, op);
+
+ if(multithreaded)
+ fuse_loop_mt(fuse);
+ else
+ fuse_loop(fuse);
+}
+