summaryrefslogtreecommitdiff
Diffstat
-rwxr-xr-xAndroid.mk138
-rwxr-xr-xAndroid.mk.bak89
-rwxr-xr-xCREDITS20
-rwxr-xr-xINSTALL200
-rwxr-xr-xMakefile715
-rwxr-xr-xMakefile.am106
-rwxr-xr-xMakefile.in955
-rwxr-xr-xNEWS4
-rwxr-xr-xREADME80
-rwxr-xr-xTODO.ntfsprogs126
-rwxr-xr-xaclocal.m47091
-rwxr-xr-xcompile21
-rwxr-xr-xconfig.guess292
-rw-r--r--[-rwxr-xr-x]config.h165
-rwxr-xr-xconfig.h.in110
-rwxr-xr-xconfig.log3290
-rwxr-xr-xconfig.status1220
-rwxr-xr-xconfig.sub104
-rwxr-xr-xconfigure26448
-rwxr-xr-xconfigure.ac291
-rwxr-xr-xdepcomp87
-rwxr-xr-xinclude/Makefile.in181
-rwxr-xr-xinclude/fuse-lite/Makefile.in112
-rwxr-xr-xinclude/fuse-lite/fuse.h61
-rwxr-xr-xinclude/fuse-lite/fuse_common.h49
-rwxr-xr-xinclude/fuse-lite/fuse_kernel.h6
-rwxr-xr-xinclude/fuse-lite/fuse_lowlevel.h20
-rwxr-xr-xinclude/ntfs-3g/Makefile.am4
-rwxr-xr-xinclude/ntfs-3g/Makefile.in163
-rwxr-xr-xinclude/ntfs-3g/acls.h3
-rwxr-xr-xinclude/ntfs-3g/attrib.h50
-rwxr-xr-xinclude/ntfs-3g/cache.h7
-rwxr-xr-xinclude/ntfs-3g/compat.h6
-rwxr-xr-xinclude/ntfs-3g/compress.h6
-rwxr-xr-xinclude/ntfs-3g/debug.h4
-rwxr-xr-xinclude/ntfs-3g/device.h18
-rwxr-xr-xinclude/ntfs-3g/device_io.h21
-rwxr-xr-xinclude/ntfs-3g/dir.h11
-rwxr-xr-xinclude/ntfs-3g/layout.h32
-rwxr-xr-xinclude/ntfs-3g/lcnalloc.h1
-rwxr-xr-xinclude/ntfs-3g/logging.h3
-rwxr-xr-xinclude/ntfs-3g/mst.h3
-rwxr-xr-xinclude/ntfs-3g/ntfstime.h12
-rwxr-xr-xinclude/ntfs-3g/param.h72
-rwxr-xr-xinclude/ntfs-3g/realpath.h24
-rwxr-xr-xinclude/ntfs-3g/runlist.h3
-rwxr-xr-xinclude/ntfs-3g/security.h20
-rwxr-xr-xinclude/ntfs-3g/types.h8
-rwxr-xr-xinclude/ntfs-3g/unistr.h13
-rwxr-xr-xinclude/ntfs-3g/volume.h78
-rwxr-xr-xinclude/ntfs-3g/xattrs.h75
-rwxr-xr-xinstall-sh5
-rwxr-xr-xlibfuse-lite/Makefile.am3
-rwxr-xr-xlibfuse-lite/Makefile.in188
-rwxr-xr-xlibfuse-lite/fuse.c418
-rwxr-xr-xlibfuse-lite/fuse_kern_chan.c2
-rwxr-xr-xlibfuse-lite/fuse_lowlevel.c53
-rwxr-xr-xlibfuse-lite/fuse_opt.c20
-rwxr-xr-xlibfuse-lite/fuse_session.c12
-rwxr-xr-xlibfuse-lite/fusermount.c97
-rwxr-xr-xlibfuse-lite/helper.c21
-rwxr-xr-xlibfuse-lite/mount.c486
-rwxr-xr-xlibfuse-lite/mount_util.c246
-rwxr-xr-xlibfuse-lite/mount_util.h11
-rwxr-xr-xlibntfs-3g/Makefile.am15
-rwxr-xr-xlibntfs-3g/Makefile.in420
-rwxr-xr-xlibntfs-3g/acls.c219
-rwxr-xr-xlibntfs-3g/attrib.c1205
-rwxr-xr-xlibntfs-3g/bootsect.c4
-rwxr-xr-xlibntfs-3g/cache.c7
-rwxr-xr-xlibntfs-3g/compress.c962
-rwxr-xr-xlibntfs-3g/device.c252
-rwxr-xr-xlibntfs-3g/dir.c374
-rwxr-xr-xlibntfs-3g/efs.c217
-rwxr-xr-xlibntfs-3g/index.c30
-rwxr-xr-xlibntfs-3g/inode.c46
-rwxr-xr-xlibntfs-3g/lcnalloc.c36
-rw-r--r--libntfs-3g/libntfs-3g.pc10
-rw-r--r--libntfs-3g/libntfs-3g.script.so2
-rwxr-xr-xlibntfs-3g/logfile.c23
-rwxr-xr-xlibntfs-3g/logging.c24
-rwxr-xr-xlibntfs-3g/mft.c12
-rwxr-xr-xlibntfs-3g/mst.c24
-rwxr-xr-xlibntfs-3g/object_id.c9
-rwxr-xr-xlibntfs-3g/realpath.c103
-rwxr-xr-xlibntfs-3g/reparse.c67
-rwxr-xr-xlibntfs-3g/runlist.c62
-rwxr-xr-xlibntfs-3g/security.c345
-rwxr-xr-xlibntfs-3g/unistr.c244
-rwxr-xr-xlibntfs-3g/unix_io.c19
-rwxr-xr-xlibntfs-3g/volume.c365
-rwxr-xr-xlibntfs-3g/win32_io.c708
-rwxr-xr-xlibntfs-3g/xattrs.c791
-rwxr-xr-xlibtool9301
-rwxr-xr-xltmain.sh8439
-rwxr-xr-xm4/libtool.m47377
-rwxr-xr-xm4/ltoptions.m4368
-rwxr-xr-xm4/ltsugar.m4123
-rwxr-xr-xm4/ltversion.m423
-rwxr-xr-xm4/lt~obsolete.m492
-rwxr-xr-xmissing49
-rwxr-xr-xntfsprogs/Makefile.am154
-rwxr-xr-xntfsprogs/Makefile.in1199
-rwxr-xr-xntfsprogs/attrdef.c168
-rwxr-xr-xntfsprogs/attrdef.h7
-rwxr-xr-xntfsprogs/boot.c268
-rwxr-xr-xntfsprogs/boot.h7
-rwxr-xr-xntfsprogs/cluster.c118
-rwxr-xr-xntfsprogs/cluster.h39
-rwxr-xr-xntfsprogs/list.h194
-rw-r--r--ntfsprogs/mkntfs.8290
-rwxr-xr-xntfsprogs/mkntfs.8.in290
-rwxr-xr-xntfsprogs/mkntfs.c5177
-rw-r--r--ntfsprogs/ntfscat.8136
-rwxr-xr-xntfsprogs/ntfscat.8.in136
-rwxr-xr-xntfsprogs/ntfscat.c440
-rwxr-xr-xntfsprogs/ntfscat.h46
-rwxr-xr-xntfsprogs/ntfsck.c883
-rw-r--r--ntfsprogs/ntfsclone.8391
-rwxr-xr-xntfsprogs/ntfsclone.8.in391
-rwxr-xr-xntfsprogs/ntfsclone.c2701
-rw-r--r--ntfsprogs/ntfscluster.8124
-rwxr-xr-xntfsprogs/ntfscluster.8.in124
-rwxr-xr-xntfsprogs/ntfscluster.c563
-rwxr-xr-xntfsprogs/ntfscluster.h63
-rw-r--r--ntfsprogs/ntfscmp.877
-rwxr-xr-xntfsprogs/ntfscmp.8.in77
-rwxr-xr-xntfsprogs/ntfscmp.c1012
-rw-r--r--ntfsprogs/ntfscp.8111
-rwxr-xr-xntfsprogs/ntfscp.8.in111
-rwxr-xr-xntfsprogs/ntfscp.c590
-rwxr-xr-xntfsprogs/ntfsdecrypt.c1436
-rwxr-xr-xntfsprogs/ntfsdump_logfile.c779
-rw-r--r--ntfsprogs/ntfsfix.881
-rwxr-xr-xntfsprogs/ntfsfix.8.in81
-rwxr-xr-xntfsprogs/ntfsfix.c1657
-rw-r--r--ntfsprogs/ntfsinfo.889
-rwxr-xr-xntfsprogs/ntfsinfo.8.in89
-rwxr-xr-xntfsprogs/ntfsinfo.c2384
-rw-r--r--ntfsprogs/ntfslabel.8118
-rwxr-xr-xntfsprogs/ntfslabel.8.in118
-rwxr-xr-xntfsprogs/ntfslabel.c458
-rw-r--r--ntfsprogs/ntfsls.8172
-rwxr-xr-xntfsprogs/ntfsls.8.in172
-rwxr-xr-xntfsprogs/ntfsls.c717
-rwxr-xr-xntfsprogs/ntfsmftalloc.c368
-rwxr-xr-xntfsprogs/ntfsmove.c923
-rwxr-xr-xntfsprogs/ntfsmove.h46
-rw-r--r--ntfsprogs/ntfsprogs.869
-rwxr-xr-xntfsprogs/ntfsprogs.8.in69
-rw-r--r--ntfsprogs/ntfsresize.8326
-rwxr-xr-xntfsprogs/ntfsresize.8.in326
-rwxr-xr-xntfsprogs/ntfsresize.c4497
-rwxr-xr-xntfsprogs/ntfstruncate.c809
-rw-r--r--ntfsprogs/ntfsundelete.8324
-rwxr-xr-xntfsprogs/ntfsundelete.8.in324
-rwxr-xr-xntfsprogs/ntfsundelete.c2490
-rwxr-xr-xntfsprogs/ntfsundelete.h112
-rwxr-xr-xntfsprogs/ntfswipe.c2131
-rwxr-xr-xntfsprogs/ntfswipe.h54
-rwxr-xr-xntfsprogs/sd.c607
-rwxr-xr-xntfsprogs/sd.h11
-rwxr-xr-xntfsprogs/utils.c1184
-rwxr-xr-xntfsprogs/utils.h137
-rwxr-xr-xprog.IAB1071
-rwxr-xr-xprog.IAD5
-rwxr-xr-xprog.IMB466
-rwxr-xr-xprog.IMD2
-rwxr-xr-xprog.PFI2
-rwxr-xr-xprog.PO1
-rwxr-xr-xprog.PR14
-rwxr-xr-xprog.PRI219
-rwxr-xr-xprog.PS979
-rwxr-xr-xprog.SearchResults3
-rwxr-xr-xprog.WK39
-rwxr-xr-xsrc/Makefile.am86
-rwxr-xr-xsrc/Makefile.in938
-rwxr-xr-xsrc/lowntfs-3g.c1538
-rw-r--r--src/ntfs-3g.8448
-rwxr-xr-xsrc/ntfs-3g.8.in217
-rwxr-xr-xsrc/ntfs-3g.c1357
-rw-r--r--src/ntfs-3g.probe.881
-rwxr-xr-xsrc/ntfs-3g.probe.8.in4
-rwxr-xr-xsrc/ntfs-3g.probe.c9
-rw-r--r--src/ntfs-3g.secaudit.8184
-rwxr-xr-xsrc/ntfs-3g.secaudit.8.in15
-rw-r--r--src/ntfs-3g.usermap.896
-rwxr-xr-xsrc/ntfs-3g_common.c745
-rwxr-xr-xsrc/ntfs-3g_common.h185
-rwxr-xr-xsrc/secaudit.c673
-rwxr-xr-xsrc/secaudit.h32
-rwxr-xr-xsrc/usermap.c3
-rw-r--r--[-rwxr-xr-x]stamp-h10
193 files changed, 80411 insertions, 44563 deletions
diff --git a/libfuse-lite/mount.c b/libfuse-lite/mount.c
index 0bb3aee..70454f4 100755
--- a/libfuse-lite/mount.c
+++ b/libfuse-lite/mount.c
@@ -12,6 +12,7 @@
#include "mount_util.h"
#include <stdio.h>
+#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
@@ -23,6 +24,21 @@
#include <sys/wait.h>
#include <sys/mount.h>
+#ifdef __SOLARIS__
+
+#define FUSERMOUNT_PROG "fusermount"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+
+#ifndef FUSERMOUNT_DIR
+#define FUSERMOUNT_DIR "/usr"
+#endif /* FUSERMOUNT_DIR */
+
+#ifndef HAVE_FORK
+#define fork() vfork()
+#endif
+
+#endif /* __SOLARIS__ */
+
#ifndef MS_DIRSYNC
#define MS_DIRSYNC 128
#endif
@@ -44,8 +60,16 @@ struct mount_opts {
int allow_root;
int ishelp;
int flags;
+#ifdef __SOLARIS__
+ int nonempty;
+ int blkdev;
+ char *fsname;
+ char *subtype;
+ char *subtype_opt;
+#else
int blkdev;
char *fsname;
+#endif
char *mtab_opts;
char *fusermount_opts;
char *kernel_opts;
@@ -54,14 +78,19 @@ struct mount_opts {
#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
static const struct fuse_opt fuse_mount_opts[] = {
+#ifdef __SOLARIS__
FUSE_MOUNT_OPT("allow_other", allow_other),
FUSE_MOUNT_OPT("allow_root", allow_root),
+ FUSE_MOUNT_OPT("nonempty", nonempty),
FUSE_MOUNT_OPT("blkdev", blkdev),
FUSE_MOUNT_OPT("fsname=%s", fsname),
+ FUSE_MOUNT_OPT("subtype=%s", subtype),
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
@@ -73,6 +102,38 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("-g", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("-m", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("-O", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("setuid", KEY_KERN_OPT),
+ FUSE_OPT_KEY("nosetuid", KEY_KERN_OPT),
+ FUSE_OPT_KEY("devices", KEY_KERN_OPT),
+ FUSE_OPT_KEY("nodevices", KEY_KERN_OPT),
+ FUSE_OPT_KEY("exec", KEY_KERN_OPT),
+ FUSE_OPT_KEY("noexec", KEY_KERN_OPT),
+ FUSE_OPT_KEY("nbmand", KEY_KERN_OPT),
+ FUSE_OPT_KEY("nonbmand", KEY_KERN_OPT),
+#else /* __SOLARIS__ */
+ FUSE_MOUNT_OPT("allow_other", allow_other),
+ FUSE_MOUNT_OPT("allow_root", allow_root),
+ FUSE_MOUNT_OPT("blkdev", blkdev),
+ FUSE_MOUNT_OPT("fsname=%s", fsname),
+ FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
+ FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
+ FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
+ FUSE_OPT_KEY("context=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
+ FUSE_OPT_KEY("-r", KEY_RO),
+ FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
@@ -82,6 +143,7 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
+#endif /* __SOLARIS__ */
FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
FUSE_OPT_KEY("-V", KEY_VERSION),
@@ -89,6 +151,42 @@ static const struct fuse_opt fuse_mount_opts[] = {
FUSE_OPT_END
};
+#ifdef __SOLARIS__
+
+static void mount_help(void)
+{
+ fprintf(stderr,
+ " -o allow_other allow access to other users\n"
+ " -o allow_root allow access to root\n"
+ " -o nonempty allow mounts over non-empty file/dir\n"
+ " -o default_permissions enable permission checking by kernel\n"
+ " -o fsname=NAME set filesystem name\n"
+ " -o subtype=NAME set filesystem type\n"
+ " -o large_read issue large read requests (2.4 only)\n"
+ " -o max_read=N set maximum size of read requests\n"
+ "\n"
+ );
+}
+
+static void exec_fusermount(const char *argv[])
+{
+ execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
+ execvp(FUSERMOUNT_PROG, (char **) argv);
+}
+
+static void mount_version(void)
+{
+ int pid = fork();
+ if (!pid) {
+ const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
+ exec_fusermount(argv);
+ _exit(1);
+ } else if (pid != -1)
+ waitpid(pid, NULL, 0);
+}
+
+#endif /* __SOLARIS__ */
+
struct mount_flags {
const char *opt;
unsigned long flag;
@@ -100,6 +198,7 @@ static struct mount_flags mount_flags[] = {
{"ro", MS_RDONLY, 1},
{"suid", MS_NOSUID, 0},
{"nosuid", MS_NOSUID, 1},
+#ifndef __SOLARIS__
{"dev", MS_NODEV, 0},
{"nodev", MS_NODEV, 1},
{"exec", MS_NOEXEC, 0},
@@ -109,9 +208,42 @@ static struct mount_flags mount_flags[] = {
{"atime", MS_NOATIME, 0},
{"noatime", MS_NOATIME, 1},
{"dirsync", MS_DIRSYNC, 1},
+#else /* __SOLARIS__ */
+ {"-g", MS_GLOBAL, 1}, /* 1eaf4 */
+ {"-m", MS_NOMNTTAB, 1}, /* 1eb00 */
+ {"-O", MS_OVERLAY, 1}, /* 1eb0c */
+#endif /* __SOLARIS__ */
{NULL, 0, 0}
};
+#ifdef __SOLARIS__
+
+/*
+ * See comments in fuse_kern_mount()
+ */
+struct solaris_mount_opts {
+ int nosuid;
+ int setuid;
+ int nosetuid;
+ int devices;
+ int nodevices;
+};
+
+#define SOLARIS_MOUNT_OPT(t, p, n) \
+ { t, offsetof(struct solaris_mount_opts, p), n }
+static const struct fuse_opt solaris_mnt_opts[] = {
+ SOLARIS_MOUNT_OPT("suid", setuid, 1),
+ SOLARIS_MOUNT_OPT("suid", devices, 1),
+ SOLARIS_MOUNT_OPT("nosuid", nosuid, 1),
+ SOLARIS_MOUNT_OPT("setuid", setuid, 1),
+ SOLARIS_MOUNT_OPT("nosetuid", nosetuid, 1),
+ SOLARIS_MOUNT_OPT("devices", devices, 1),
+ SOLARIS_MOUNT_OPT("nodevices", nodevices, 1),
+ FUSE_OPT_END
+};
+
+#endif /* __SOLARIS__ */
+
static void set_mount_flag(const char *s, int *flags)
{
int i;
@@ -155,23 +287,85 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
case KEY_FUSERMOUNT_OPT:
return fuse_opt_add_opt(&mo->fusermount_opts, arg);
+#ifdef __SOLARIS__
+ case KEY_SUBTYPE_OPT:
+ return fuse_opt_add_opt(&mo->subtype_opt, arg);
+#endif /* __SOLARIS__ */
+
case KEY_MTAB_OPT:
return fuse_opt_add_opt(&mo->mtab_opts, arg);
case KEY_HELP:
+#ifdef __SOLARIS__
+ mount_help();
+#endif /* __SOLARIS__ */
mo->ishelp = 1;
break;
case KEY_VERSION:
+#ifdef __SOLARIS__
+ mount_version();
+#endif /* __SOLARIS__ */
mo->ishelp = 1;
break;
}
return 1;
}
+#ifdef __SOLARIS__
+
+/* return value:
+ * >= 0 => fd
+ * -1 => error
+ */
+static int receive_fd(int fd)
+{
+ struct msghdr msg;
+ struct iovec iov;
+ char buf[1];
+ int rv;
+ size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ /* old BSD implementations should use msg_accrights instead of
+ * msg_control; the interface is different. */
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof(ccmsg);
+
+ while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
+ if (rv == -1) {
+ perror("recvmsg");
+ return -1;
+ }
+ if(!rv) {
+ /* EOF */
+ return -1;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr, "got control message of unknown type %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ return *(int*)CMSG_DATA(cmsg);
+}
+
+#endif /* __SOLARIS__ */
+
void fuse_kern_unmount(const char *mountpoint, int fd)
{
int res;
+#ifdef __SOLARIS__
+ int pid;
+#endif /* __SOLARIS__ */
if (!mountpoint)
return;
@@ -187,11 +381,214 @@ void fuse_kern_unmount(const char *mountpoint, int fd)
if (res == 1 && (pfd.revents & POLLERR))
return;
}
+#ifndef __SOLARIS__
close(fd);
fusermount(1, 0, 1, "", mountpoint);
+#else /* __SOLARIS__ */
+ if (geteuid() == 0) {
+ fuse_mnt_umount("fuse", mountpoint, 1);
+ return;
+ }
+
+ res = umount2(mountpoint, 2);
+ if (res == 0)
+ return;
+
+ pid = fork();
+ if(pid == -1)
+ return;
+
+ if(pid == 0) {
+ const char *argv[] =
+ { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL };
+
+ exec_fusermount(argv);
+ _exit(1);
+ }
+ waitpid(pid, NULL, 0);
+#endif /* __SOLARIS__ */
}
+#ifdef __SOLARIS__
+
+static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
+ int quiet)
+{
+ int fds[2], pid;
+ int res;
+ int rv;
+
+ if (!mountpoint) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+ if(res == -1) {
+ perror("fuse: socketpair() failed");
+ return -1;
+ }
+
+ pid = fork();
+ if(pid == -1) {
+ perror("fuse: fork() failed");
+ close(fds[0]);
+ close(fds[1]);
+ return -1;
+ }
+
+ if(pid == 0) {
+ char env[10];
+ const char *argv[32];
+ int a = 0;
+
+ if (quiet) {
+ int fd = open("/dev/null", O_RDONLY);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ }
+
+ argv[a++] = FUSERMOUNT_PROG;
+ if (opts) {
+ argv[a++] = "-o";
+ argv[a++] = opts;
+ }
+ argv[a++] = "--";
+ argv[a++] = mountpoint;
+ argv[a++] = NULL;
+
+ close(fds[1]);
+ fcntl(fds[0], F_SETFD, 0);
+ snprintf(env, sizeof(env), "%i", fds[0]);
+ setenv(FUSE_COMMFD_ENV, env, 1);
+ exec_fusermount(argv);
+ perror("fuse: failed to exec fusermount");
+ _exit(1);
+ }
+
+ close(fds[0]);
+ rv = receive_fd(fds[1]);
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+
+ return rv;
+}
+
+static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
+ const char *mnt_opts)
+{
+ char tmp[128];
+ const char *devname = "/dev/fuse";
+ char *source = NULL;
+ char *type = NULL;
+ struct stat stbuf;
+ int fd;
+ int res;
+
+ if (!mnt) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = lstat(mnt, &stbuf);
+ if (res == -1) {
+ fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
+ mnt, strerror(errno));
+ return -1;
+ }
+
+ if (!mo->nonempty) {
+ res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size);
+ if (res == -1)
+ return -1;
+ }
+
+ fd = open(devname, O_RDWR);
+ if (fd == -1) {
+ if (errno == ENODEV || errno == ENOENT)
+ fprintf(stderr,
+ "fuse: device not found, try 'modprobe fuse' first\n");
+ else
+ fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
+ strerror(errno));
+ return -1;
+ }
+
+ snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
+ stbuf.st_mode & S_IFMT, getuid(), getgid());
+
+ res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
+ if (res == -1)
+ goto out_close;
+
+ source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
+ (mo->subtype ? strlen(mo->subtype) : 0) +
+ strlen(devname) + 32);
+
+ type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
+ if (!type || !source) {
+ fprintf(stderr, "fuse: failed to allocate memory\n");
+ goto out_close;
+ }
+
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->subtype) {
+ strcat(type, ".");
+ strcat(type, mo->subtype);
+ }
+ strcpy(source,
+ mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
+
+ /* JPA added two final zeroes */
+ res = mount(source, mnt, MS_OPTIONSTR|mo->flags, type, NULL, 0,
+ mo->kernel_opts, MAX_MNTOPT_STR, 0, 0);
+
+ if (res == -1 && errno == EINVAL && mo->subtype) {
+ /* Probably missing subtype support */
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->fsname) {
+ if (!mo->blkdev)
+ sprintf(source, "%s#%s", mo->subtype, mo->fsname);
+ } else {
+ strcpy(source, type);
+ }
+ /* JPA two null args added */
+ res = mount(source, mnt, MS_OPTIONSTR|mo->flags, type, NULL, 0,
+ mo->kernel_opts, MAX_MNTOPT_STR, 0, 0);
+ }
+ if (res == -1) {
+ /*
+ * Maybe kernel doesn't support unprivileged mounts, in this
+ * case try falling back to fusermount
+ */
+ if (errno == EPERM) {
+ res = -2;
+ } else {
+ int errno_save = errno;
+ if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
+ fprintf(stderr, "fuse: 'fuseblk' support missing\n");
+ else
+ fprintf(stderr, "fuse: mount failed: %s\n",
+ strerror(errno_save));
+ }
+
+ goto out_close;
+ }
+
+ return fd;
+
+ out_umount:
+ umount2(mnt, 2); /* lazy umount */
+ out_close:
+ free(type);
+ free(source);
+ close(fd);
+ return res;
+}
+
+#endif /* __SOLARIS__ */
+
static int get_mnt_flag_opts(char **mnt_optsp, int flags)
{
int i;
@@ -201,8 +598,8 @@ static int get_mnt_flag_opts(char **mnt_optsp, int flags)
for (i = 0; mount_flags[i].opt != NULL; i++) {
if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
- fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
- return -1;
+ fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
+ return -1;
}
return 0;
}
@@ -212,14 +609,59 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
struct mount_opts mo;
int res = -1;
char *mnt_opts = NULL;
+#ifdef __SOLARIS__
+ struct solaris_mount_opts smo;
+ struct fuse_args sa = FUSE_ARGS_INIT(0, NULL);
+#endif /* __SOLARIS__ */
memset(&mo, 0, sizeof(mo));
+#ifndef __SOLARIS__
if (getuid())
mo.flags = MS_NOSUID | MS_NODEV;
+#else /* __SOLARIS__ */
+ mo.flags = 0;
+ memset(&smo, 0, sizeof(smo));
+ if (args != NULL) {
+ while (args->argv[sa.argc] != NULL)
+ fuse_opt_add_arg(&sa, args->argv[sa.argc]);
+ }
+#endif /* __SOLARIS__ */
if (args &&
fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+#ifndef __SOLARIS__
return -1;
+#else /* __SOLARIS__ */
+ goto out; /* if SOLARIS, clean up 'sa' */
+
+ /*
+ * In Solaris, nosuid is equivalent to nosetuid + nodevices. We only
+ * have MS_NOSUID for mount flags (no MS_(NO)SETUID, etc.). But if
+ * we set that as a default, it restricts specifying just nosetuid
+ * or nodevices; there is no way for the user to specify setuid +
+ * nodevices or vice-verse. So we parse the existing options, then
+ * add restrictive defaults if needed.
+ */
+ if (fuse_opt_parse(&sa, &smo, solaris_mnt_opts, NULL) == -1)
+ goto out;
+ if (smo.nosuid || (!smo.nodevices && !smo.devices
+ && !smo.nosetuid && !smo.setuid)) {
+ mo.flags |= MS_NOSUID;
+ } else {
+ /*
+ * Defaults; if neither nodevices|devices,nosetuid|setuid has
+ * been specified, add the default negative option string. If
+ * both have been specified (i.e., -osuid,nosuid), leave them
+ * alone; the last option will have precedence.
+ */
+ if (!smo.nodevices && !smo.devices)
+ if (fuse_opt_add_opt(&mo.kernel_opts, "nodevices") == -1)
+ goto out;
+ if (!smo.nosetuid && !smo.setuid)
+ if (fuse_opt_add_opt(&mo.kernel_opts, "nosetuid") == -1)
+ goto out;
+ }
+#endif /* __SOLARIS__ */
if (mo.allow_other && mo.allow_root) {
fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
@@ -232,6 +674,7 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
res = -1;
if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
goto out;
+#ifndef __SOLARIS__
if (!(mo.flags & MS_NODEV) && fuse_opt_add_opt(&mnt_opts, "dev") == -1)
goto out;
if (!(mo.flags & MS_NOSUID) && fuse_opt_add_opt(&mnt_opts, "suid") == -1)
@@ -242,15 +685,48 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
goto out;
if (mo.fusermount_opts && fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) < 0)
goto out;
-
res = fusermount(0, 0, 0, mnt_opts ? mnt_opts : "", mountpoint);
-
+#else /* __SOLARIS__ */
+ if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
+ goto out;
+ if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
+ goto out;
+ res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
+ if (res == -2) {
+ if (mo.fusermount_opts &&
+ fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
+ goto out;
+
+ if (mo.subtype) {
+ char *tmp_opts = NULL;
+
+ res = -1;
+ if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
+ fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
+ free(tmp_opts);
+ goto out;
+ }
+
+ res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
+ free(tmp_opts);
+ if (res == -1)
+ res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+ } else {
+ res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+ }
+ }
+#endif /* __SOLARIS__ */
+
out:
free(mnt_opts);
+#ifdef __SOLARIS__
+ fuse_opt_free_args(&sa);
+ free(mo.subtype);
+ free(mo.subtype_opt);
+#endif /* __SOLARIS__ */
free(mo.fsname);
free(mo.fusermount_opts);
free(mo.kernel_opts);
free(mo.mtab_opts);
return res;
}
-