Workaround FUSE/Linux-kernel to try ourselves to modprobe FUSE on ENODEV.
[captive.git] / src / client / fuse / fusermount.c
index 8d5562e..9ceadc1 100644 (file)
 #include <sys/utsname.h>
 #include <sys/sysmacros.h>
 
+/* Captive */
+#include <captive/client.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <grp.h>
+
 #define FUSE_COMMFD_ENV         "_FUSE_COMMFD"
 
 #define FUSE_DEV_OLD "/proc/fs/fuse/dev"
@@ -115,7 +121,7 @@ static int lock_mtab(void)
 static void unlock_mtab(int mtablock)
 {
     if (mtablock >= 0) {
-       lockf(mtablock, F_ULOCK, 0);
+       int trash0=lockf(mtablock, F_ULOCK, 0);
        close(mtablock);
     }
 }
@@ -283,8 +289,9 @@ static int unmount_rename(const char *mnt, int quiet, int lazy,
     if (res == -1)
         return -1;
 
-    if (stat(mtab, &sbuf) == 0)
-        chown(mtab_new, sbuf.st_uid, sbuf.st_gid);
+    if (stat(mtab, &sbuf) == 0) {
+        int trash0=chown(mtab_new, sbuf.st_uid, sbuf.st_gid);
+                               }
 
     res = rename(mtab_new, mtab);
     if (res == -1) {
@@ -776,6 +783,26 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,
 static int try_open(const char *dev, char **devp, int silent)
 {
     int fd = open(dev, O_RDWR);
+    /* Captive */
+    if (fd == -1 && errno == ENOENT && !strcmp(dev, FUSE_DEV_NEW)
+        && !mknod(dev, 0660 | S_IFCHR, MKDEV(MISC_MAJOR, 229))) {
+        struct group *group;
+
+        fprintf(stderr, "%s: Notice: Created FUSE device: %s\n", progname, dev);
+        if ((group = getgrnam("fuse")) && !chown(dev, 0, group->gr_gid))
+            fd = open(dev, O_RDWR);
+    }
+    if (fd == -1 && errno == ENODEV) {
+        const char *cmd = "/sbin/modprobe fuse";
+
+        if (!system(cmd))
+            fprintf(stderr, "%s: Notice: Loaded Linux kernel module FUSE: %s\n",
+                    progname, cmd);
+        else
+            fprintf(stderr, "%s: Warning: \"%s\" cannot be opened and even failed: %s\n",
+                    progname, dev, cmd);
+        fd = open(dev, O_RDWR);
+    }
     if (fd != -1) {
         *devp = strdup(dev);
         if (*devp == NULL) {
@@ -875,7 +902,7 @@ static int mount_fuse(const char *mnt, const char *opts)
         restore_privs();
 
     if (currdir_fd != -1) {
-        fchdir(currdir_fd);
+        int trash0=fchdir(currdir_fd);
         close(currdir_fd);
     }
     if (mountpoint_fd != -1)
@@ -1049,6 +1076,9 @@ int main(int argc, char *argv[])
         {"version", no_argument, NULL, 'v'},
         {0, 0, 0, 0}};
 
+    /* Captive */
+    captive_standalone_init();
+
     progname = strdup(argv[0]);
     if (progname == NULL) {
         fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);