示例#1
0
int
main(int argc, char **argv)
{
	struct udf_args args;
	char node[MAXPATHLEN];
	int ch, flags = 0;

	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			getmntopts(optarg, opts, &flags);
			break;
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	args.fspec = argv[0];
	args.lastblock = lastblock(argv[0]);

	if (realpath(argv[1], node) == NULL)
		err(1, "realpath %s", argv[1]);

	if (mount(MOUNT_UDF, node, flags, &args) < 0)
		err(1, "mount");

	exit(0);
}
示例#2
0
void
mount_ext2fs_parseargs(int argc, char *argv[],
	struct ufs_args *args, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	int ch;
	mntoptparse_t mp;

	memset(args, 0, sizeof(*args));
	*mntflags = 0;
	optind = optreset = 1;		/* Reset for parse of new argv. */
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case '?':
		default:
			ext2fs_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		ext2fs_usage();

	pathadj(argv[0], canon_dev);
	args->fspec = canon_dev;

	pathadj(argv[1], canon_dir);
}
示例#3
0
int
main(int argc, char **argv)
{
	int ch, mntflags;
	char mntpath[MAXPATHLEN];
	struct vfsconf vfc;
	int error;

	/*
	 * XXX
	 * mount(8) calls the mount programs with an argv[0] which is
	 * /just/ the filesystem name.  So, if there is no underscore
	 * in argv[0], we assume that we are being called from mount(8)
	 * and that argv[0] is thus the name of the filesystem type.
	 */
	fsname = strrchr(argv[0], '_');
	if (fsname) {
		if (strcmp(fsname, "_std") == 0)
			errx(EX_USAGE, "argv[0] must end in _fsname");
		fsname++;
	} else {
		fsname = argv[0];
	}

	mntflags = 0;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	error = getvfsbyname(fsname, &vfc);
	if (error && vfsisloadable(fsname)) {
		if(vfsload(fsname))
			err(EX_OSERR, "vfsload(%s)", fsname);
		endvfsent();
		error = getvfsbyname(fsname, &vfc);
	}
	if (error)
		errx(EX_OSERR, "%s filesystem not available", fsname);

	/* resolve the mountpoint with realpath(3) */
	checkpath(argv[1], mntpath);

	if (mount(vfc.vfc_name, mntpath, mntflags, NULL))
		err(EX_OSERR, NULL);
	exit(0);
}
示例#4
0
int
main(int argc, char *argv[])
{
	struct ufs_args args;		/* XXX ffs_args */
	int ch, mntflags;
	char fs_name[PATH_MAX], *errcause;

	mntflags = 0;
	optind = optreset = 1;		/* Reset for parse of new argv. */
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags);
			break;
		case '?':
		default:
			ffs_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		ffs_usage();

	args.fspec = argv[0];		/* The name of the device file. */
	if (realpath(argv[1], fs_name) == NULL) 	/* The mount point. */
		err(1, "realpath %s", argv[1]);

#define DEFAULT_ROOTUID	-2
	args.export_info.ex_root = DEFAULT_ROOTUID;
	if (mntflags & MNT_RDONLY)
		args.export_info.ex_flags = MNT_EXRDONLY;
	else
		args.export_info.ex_flags = 0;

	if (mount(MOUNT_FFS, fs_name, mntflags, &args) < 0) {
		switch (errno) {
		case EMFILE:
			errcause = "mount table full";
			break;
		case EOPNOTSUPP:
			errcause = "filesystem not supported by kernel";
			break;
		case EROFS:
			errcause =
			    "filesystem must be mounted read-only; you may need to run fsck";
			break;
		default:
			errcause = strerror(errno);
			break;
		}
		errx(1, "%s on %s: %s", args.fspec, fs_name, errcause);
	}
	exit(0);
}
示例#5
0
int
mount_null(int argc, char *argv[])
{
	struct null_args args;
	int ch, mntflags;
	char target[MAXPATHLEN], canon_dir[MAXPATHLEN];
	mntoptparse_t mp;

	mntflags = 0;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch(ch) {
		case 'o':
			mp = getmntopts(optarg, mopts, &mntflags, 0);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	if (realpath(argv[0], target) == NULL)        /* Check device path */
		err(1, "realpath %s", argv[0]);
	if (strncmp(argv[0], target, MAXPATHLEN)) {
		warnx("\"%s\" is a relative path.", argv[0]);
		warnx("using \"%s\" instead.", target);
	}

	if (realpath(argv[1], canon_dir) == NULL)    /* Check mounton path */
		err(1, "realpath %s", argv[1]);
	if (strncmp(argv[1], canon_dir, MAXPATHLEN)) {
		warnx("\"%s\" is a relative path.", argv[1]);
		warnx("using \"%s\" instead.", canon_dir);
	}

	if (strcmp(target, canon_dir) == 0)
		errx(1, "%s (%s) and %s (%s) are identical paths",
		    argv[0], target, argv[1], canon_dir);

	args.la.target = target;

	if (mount(MOUNT_NULL, canon_dir, mntflags, &args, sizeof args) == -1)
		err(1, "%s on %s", target, canon_dir);
	exit(0);
}
示例#6
0
int
main(int argc, char *argv[])
{
	struct iovec iov[6];
	int ch, mntflags;
	char source[MAXPATHLEN];
	char target[MAXPATHLEN];

	mntflags = 0;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch(ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	/* resolve target and source with realpath(3) */
	if (checkpath(argv[0], target) != 0)
		err(EX_USAGE, "%s", target);
	if (checkpath(argv[1], source) != 0)
		err(EX_USAGE, "%s", source);

	if (subdir(target, source) || subdir(source, target))
		errx(EX_USAGE, "%s (%s) and %s are not distinct paths",
		    argv[0], target, argv[1]);

	iov[0].iov_base = strdup("fstype");
	iov[0].iov_len = sizeof("fstype");
	iov[1].iov_base = strdup("nullfs");
	iov[1].iov_len = strlen(iov[1].iov_base) + 1;
	iov[2].iov_base = strdup("fspath");
	iov[2].iov_len = sizeof("fspath");
	iov[3].iov_base = source;
	iov[3].iov_len = strlen(source) + 1;
	iov[4].iov_base = strdup("target");
	iov[4].iov_len = sizeof("target");
	iov[5].iov_base = target;
	iov[5].iov_len = strlen(target) + 1;

	if (nmount(iov, 6, mntflags))
		err(1, NULL);
	exit(0);
}
示例#7
0
int
mount_procfs(int argc, char *argv[])
{
	int ch, mntflags, altflags;
	struct procfs_args args;
	char canon_dir[MAXPATHLEN];
	mntoptparse_t mp;

	mntflags = 0;
	altflags = PROCFSMNT_LINUXCOMPAT;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			mp = getmntopts(optarg, mopts, &mntflags, &altflags);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	if (realpath(argv[1], canon_dir) == NULL)   /* Check mounton path */
		err(1, "realpath %s", argv[1]);
	if (strncmp(argv[1], canon_dir, MAXPATHLEN)) {
		warnx("\"%s\" is a relative path.", argv[1]);
		warnx("using \"%s\" instead.", canon_dir);
	}

	args.version = PROCFS_ARGSVERSION;
	args.flags = altflags;

	if (mount(MOUNT_PROCFS, canon_dir, mntflags, &args, sizeof args) == -1)
		err(1, "procfs on %s", canon_dir);
	if (mntflags & MNT_GETARGS) {
		char buf[1024];
		(void)snprintb(buf, sizeof(buf), PROCFSMNT_BITS, args.flags);
		printf("version=%d, flags=%s\n", args.version, buf);
	}
	exit(0);
}
示例#8
0
void
mount_v7fs_parseargs(int argc, char **argv, struct v7fs_args *args,
    int *mntflags, char *canon_dev, char *canon_dir)
{
	int ch;
	mntoptparse_t mp;
	int endian = _BYTE_ORDER;
	*mntflags = 0;
	optind = optreset = 1;		/* Reset for parse of new argv. */
	while ((ch = getopt(argc, argv, "o:B:")) != -1)
		switch (ch) {
		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case 'B':
		  switch (optarg[0]) {
		    case 'l':
		      endian = _LITTLE_ENDIAN;
		      break;
		    case 'b':
		      endian = _BIG_ENDIAN;
		      break;
		    case 'p':
		      endian = _PDP_ENDIAN;
		      break;
		    }
		  break;
		case '?':

		default:
			v7fs_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		v7fs_usage();

	pathadj(argv[0], canon_dev);
	args->endian = endian;
	args->fspec = canon_dev;
	pathadj(argv[1], canon_dir);
}
示例#9
0
int main( int argc, char **argv ) {
    char mntpath[MAXPATHLEN];
    char fstype[] = "udf";
    struct iovec *iov;
    char *cs_disk, *cs_local, *dev, *dir;
    int ch, i, iovlen, mntflags, udf_flags, verbose;
    i = iovlen = mntflags = udf_flags = verbose = 0;
    cs_disk = cs_local = NULL;
    iov = NULL;
    while ( ( ch = getopt( argc, argv, "o:vC:" ) ) != -1 )
        switch ( ch ) {
        case 'o':
            getmntopts( optarg, mopts, &mntflags, NULL );
            break;
        case 'v':
            verbose++;
            break;
        case 'C':
            if ( set_charset( &cs_disk, &cs_local, optarg ) == -1 ) err( EX_OSERR, "udf_iconv" );
            udf_flags |= UDFMNT_KICONV;
            break;
        case '?':
        default:
            usage();
        }
    argc -= optind;
    argv += optind;
    if ( argc != 2 ) usage();
    dev = argv[0];
    dir = argv[1];
    if ( checkpath( dir, mntpath ) != 0 ) err( EX_USAGE, "%s", mntpath );
    (void) rmslashes( dev, dev );
    mntflags |= MNT_RDONLY;
    build_iovec( &iov, &iovlen, "fstype", fstype, ( size_t ) - 1 );
    build_iovec( &iov, &iovlen, "fspath", mntpath, ( size_t ) - 1 );
    build_iovec( &iov, &iovlen, "from", dev, ( size_t ) - 1 );
    build_iovec( &iov, &iovlen, "flags", &udf_flags, sizeof( udf_flags ) );
    if ( udf_flags & UDFMNT_KICONV ) {
        build_iovec( &iov, &iovlen, "cs_disk", cs_disk, ( size_t ) - 1 );
        build_iovec( &iov, &iovlen, "cs_local", cs_local, ( size_t ) - 1 );
    }
    if ( nmount( iov, i, mntflags ) < 0 ) err( 1, "%s", dev );
    exit( 0 );
}
示例#10
0
void
mount_kernfs_parseargs(int argc, char *argv[], void *dummy, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	int ch;
	mntoptparse_t mp;

	*mntflags = 0;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	/* not supported, fail silently */
	if (*mntflags & MNT_GETARGS)
		exit(0);

	strlcpy(canon_dev, argv[0], MAXPATHLEN);
	if (realpath(argv[1], canon_dir) == NULL)    /* Check mounton path */
		err(1, "realpath %s", argv[1]);
	if (strncmp(argv[1], canon_dir, MAXPATHLEN)) {
		warnx("\"%s\" is a relative path.", argv[1]);
		warnx("using \"%s\" instead.", canon_dir);
	}
}
示例#11
0
int
main(int argc, char **argv)
{
	int ch;
	int mntflags = 0;
	char path[MAXPATHLEN];

	optind = optreset = 1;
	while ((ch = getopt(argc, argv, "o:")) != -1)
		switch (ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags);
			break;
		case '?':
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	if (realpath(argv[1], path) == NULL)
		err(1, "realpath %s", argv[1]);

	if (mount(MOUNT_XFS, path, mntflags, argv[0])) {
		if (errno == EOPNOTSUPP)
			errx(1, "Filesystem not supported by kernel");
		else
			err(1, NULL);
	}

	return 0;
}
示例#12
0
int
main(int argc, char *argv[])
{
	struct portal_args args;
	struct sockaddr_un un;
	char *conf;
	char mountpt[MAXPATHLEN];
	int mntflags = 0;
	char tag[32];
	mode_t um;

	qelem q;
	int rc;
	int so;
	int error = 0;

	/*
	 * Crack command line args
	 */
	int ch;

	while ((ch = getopt(argc, argv, "o:")) != -1) {
		switch (ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			break;
		default:
			error = 1;
			break;
		}
	}

	if (optind != (argc - 2))
		error = 1;

	if (error)
		usage();

	/*
	 * Get config file and mount point
	 */
	conf = argv[optind];
	if (conf[0] != '/') {
		(void)fprintf(stderr,
		    "The configuration file must be specified"
		    "through an absolute file path.\n");
		exit(EX_USAGE);
	}

	/* resolve the mountpoint with realpath(3) */
	if (checkpath(argv[optind+1], mountpt) != 0)
		err(EX_USAGE, "%s", mountpt);

	/*
	 * Construct the listening socket
	 */
	un.sun_family = AF_UNIX;
	if (sizeof(_PATH_TMPPORTAL) >= sizeof(un.sun_path)) {
		errx(EX_SOFTWARE, "portal socket name too long");
	}
	strcpy(un.sun_path, _PATH_TMPPORTAL);
	mktemp(un.sun_path);
	un.sun_len = strlen(un.sun_path);

	so = socket(AF_UNIX, SOCK_STREAM, 0);
	if (so < 0) {
		err(EX_OSERR, "socket");
	}
	um = umask(077);
	(void) unlink(un.sun_path);
	if (bind(so, (struct sockaddr *) &un, sizeof(un)) < 0)
		err(1, NULL);

	(void) unlink(un.sun_path);
	(void) umask(um);

	(void) listen(so, 5);

	args.pa_socket = so;
	sprintf(tag, "portal:%d", getpid());
	args.pa_config = tag;

	rc = mount("portalfs", mountpt, mntflags, &args);
	if (rc < 0)
		err(1, NULL);

	/*
	 * Everything is ready to go - now is a good time to fork
	 */
#ifndef DEBUG
	daemon(0, 0);
#endif

	/*
	 * Start logging (and change name)
	 */
	openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON);

	q.q_forw = q.q_back = &q;
	readcf = 1;

	signal(SIGCHLD, sigchld);
	signal(SIGHUP, sighup);

	/*
	 * Just loop waiting for new connections and activating them
	 */
	for (;;) {
		struct sockaddr_un un2;
		int len2 = sizeof(un2);
		int so2;
		pid_t pid;
		fd_set fdset;

		/*
		 * Check whether we need to re-read the configuration file
		 */
		if (readcf) {
#ifdef DEBUG
			printf ("re-reading configuration file\n");
#endif
			readcf = 0;
			conf_read(&q, conf);
			continue;
		}

		/*
		 * Accept a new connection
		 * Will get EINTR if a signal has arrived, so just
		 * ignore that error code
		 */
		FD_ZERO(&fdset);
		FD_SET(so, &fdset);
		rc = select(so+1, &fdset, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
		if (rc < 0) {
			if (errno == EINTR)
				continue;
			syslog(LOG_ERR, "select: %s", strerror(errno));
			exit(EX_OSERR);
		}
		if (rc == 0)
			break;
		so2 = accept(so, (struct sockaddr *) &un2, &len2);
		if (so2 < 0) {
			/*
			 * The unmount function does a shutdown on the socket
			 * which will generated ECONNABORTED on the accept.
			 */
			if (errno == ECONNABORTED)
				break;
			if (errno != EINTR) {
				syslog(LOG_ERR, "accept: %s", strerror(errno));
				exit(EX_OSERR);
			}
			continue;
		}

		/*
		 * Now fork a new child to deal with the connection
		 */
	eagain:;
		switch (pid = fork()) {
		case -1:
			if (errno == EAGAIN) {
				sleep(1);
				goto eagain;
			}
			syslog(LOG_ERR, "fork: %s", strerror(errno));
			break;
		case 0:
			(void) close(so);
			activate(&q, so2);
			exit(0);
		default:
			(void) close(so2);
			break;
		}
	}
	syslog(LOG_INFO, "%s unmounted", mountpt);
	exit(0);
}
示例#13
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       fd        = -1;
    int32_t   dindex    = -1;
    char     *fdnam     = NULL;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    int i, ch = '\0', done = 0;
    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    if (!getenv("MOUNT_FUSEFS_CALL_BY_LIB")) {
        showhelp();
        /* NOTREACHED */
    }

    /* Kludge to make "<fsdaemon> --version" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--version", strlen("--version"))) ||
         (!strncmp(argv[1], "-v", strlen("-v"))))) {
        showversion(1);
    }

    /* Kludge to make "<fsdaemon> --help" happy. */
    if ((argc == 2) &&
        ((!strncmp(argv[1], "--help", strlen("--help"))) ||
         (!strncmp(argv[1], "-h", strlen("-h"))))) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    do {
        for (i = 0; i < 3; i++) {
            if (optind < argc && argv[optind][0] != '-') {
                if (mntpath) {
                    done = 1;
                    break;
                }
                if (fdnam)
                    mntpath = argv[optind];
                else
                    fdnam = argv[optind];
                optind++;
            }
        }

        switch(ch) {
        case 'o':
            getmntopts(optarg, mopts, &mntflags, &altflags);
            for (mv = mvals; mv->mv_mntflag; ++mv) {
                if (!(altflags & mv->mv_mntflag)) {
                    continue;
                }
                for (mo = mopts; mo->m_option; ++mo) {
                    char *p, *q;
                    if (mo->m_flag != mv->mv_mntflag) {
                        continue;
                    }
                    p = strstr(optarg, mo->m_option);
                    if (p) {
                        p += strlen(mo->m_option);
                        q = p;
                        while (*q != '\0' && *q != ',') {
                            q++;
                        }
                        mv->mv_len = q - p + 1;
                        mv->mv_value = malloc(mv->mv_len);
                        memcpy(mv->mv_value, p, mv->mv_len - 1);
                        ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                        break;
                    }
                }
            }
            break;

        case '\0':
            break;

        case 'v':
            showversion(1);
            break;

        case '?':
        case 'h':
        default:
            showhelp();
            break;
        }

        if (done) {
            break;
        }

    } while ((ch = getopt(argc, argv, "ho:v")) != -1);

    argc -= optind;
    argv += optind;

    if ((!fdnam) && argc > 0) {
        fdnam = *argv++;
        argc--;
    }

    if (!fdnam) {
        errx(EX_USAGE, "missing " OSXFUSE_DISPLAY_NAME
             " device file descriptor");
    }

    errno = 0;
    fd = (int)strtol(fdnam, NULL, 10);
    if ((errno == EINVAL) || (errno == ERANGE)) {
        errx(EX_USAGE, "invalid name (%s) for " OSXFUSE_DISPLAY_NAME
             " device file descriptor", fdnam);
    }

    signal_fd = fd;

    {
        char  ndev[MAXPATHLEN];
        char *ndevbas;
        struct stat sb;

        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME
                " device file descriptor");
        }
        args.rdev = sb.st_rdev;
        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(sb.st_rdev, S_IFCHR, ndevbas,
                  (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME,
                    strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME),
                             NULL, 10);
        if ((errno == EINVAL) || (errno == ERANGE) ||
            (dindex < 0) || (dindex > OSXFUSE_NDEVICES)) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME
                 " device unit (#%d)\n", dindex);
        }
    }

    signal_idx = dindex;

    atexit(signal_idx_atexit_handler);

    result = check_kext_status();

    switch (result) {

    case 0:
        break;

    case ESRCH:
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
             " kernel extension is not loaded");
        break;

    case EINVAL:
        errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension has a mismatched version");
        break;

    default:
        errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
             " kernel extension (%d)", result);
        break;
    }

    if ((!mntpath) && argc > 0) {
        mntpath = *argv++;
        argc--;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    (void)checkpath(mntpath, args.mntpath);

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t) blocksize;
    args.daemon_timeout = (uint32_t) daemon_timeout;
    args.fsid           = (uint32_t) fsid;
    args.fssubtype      = (uint32_t) fssubtype;
    args.iosize         = (uint32_t) iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_idx = -1;

    exit(0);
}
示例#14
0
文件: psshfs.c 项目: ryo/netbsd-src
int
main(int argc, char *argv[])
{
	struct psshfs_ctx pctx;
	struct puffs_usermount *pu;
	struct puffs_ops *pops;
	struct psshfs_node *root = &pctx.psn_root;
	struct puffs_node *pn_root;
	puffs_framev_fdnotify_fn notfn;
	struct vattr *rva;
	mntoptparse_t mp;
	char **sshargs;
	char *user;
	char *host;
	char *path;
	int mntflags, pflags, ch;
	int detach;
	int exportfs, refreshival, numconnections;
	int nargs;

	setprogname(argv[0]);
	puffs_unmountonsignal(SIGINT, true);
	puffs_unmountonsignal(SIGTERM, true);

	if (argc < 3)
		usage();

	memset(&pctx, 0, sizeof(pctx));
	mntflags = pflags = exportfs = nargs = 0;
	numconnections = 1;
	detach = 1;
	refreshival = DEFAULTREFRESH;
	notfn = puffs_framev_unmountonclose;
	sshargs = NULL;
	add_ssharg(&sshargs, &nargs, SSH_PATH);
	add_ssharg(&sshargs, &nargs, "-axs");
	add_ssharg(&sshargs, &nargs, "-oClearAllForwardings=yes");

	while ((ch = getopt(argc, argv, "c:eF:g:o:O:pr:st:u:")) != -1) {
		switch (ch) {
		case 'c':
			numconnections = atoi(optarg);
			if (numconnections < 1 || numconnections > 2) {
				fprintf(stderr, "%s: only 1 or 2 connections "
				    "permitted currently\n", getprogname());
				usage();
				/*NOTREACHED*/
			}
			break;
		case 'e':
			exportfs = 1;
			break;
		case 'F':
			add_ssharg(&sshargs, &nargs, "-F");
			add_ssharg(&sshargs, &nargs, optarg);
			break;
		case 'g':
			pctx.domanglegid = 1;
			pctx.manglegid = atoi(optarg);
			if (pctx.manglegid == (gid_t)-1)
				errx(1, "-1 not allowed for -g");
			pctx.mygid = getegid();
			break;
		case 'O':
			add_ssharg(&sshargs, &nargs, "-o");
			add_ssharg(&sshargs, &nargs, optarg);
			break;
		case 'o':
			mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case 'p':
			notfn = psshfs_notify;
			break;
		case 'r':
			max_reads = atoi(optarg);
			break;
		case 's':
			detach = 0;
			break;
		case 't':
			refreshival = atoi(optarg);
			if (refreshival < 0 && refreshival != -1)
				errx(1, "invalid timeout %d", refreshival);
			break;
		case 'u':
			pctx.domangleuid = 1;
			pctx.mangleuid = atoi(optarg);
			if (pctx.mangleuid == (uid_t)-1)
				errx(1, "-1 not allowed for -u");
			pctx.myuid = geteuid();
			break;
		default:
			usage();
			/*NOTREACHED*/
		}
	}
	argc -= optind;
	argv += optind;

	if (pflags & PUFFS_FLAG_OPDUMP)
		detach = 0;
	pflags |= PUFFS_FLAG_BUILDPATH;
	pflags |= PUFFS_KFLAG_WTCACHE | PUFFS_KFLAG_IAONDEMAND;

	if (argc != 2)
		usage();

	PUFFSOP_INIT(pops);

	PUFFSOP_SET(pops, psshfs, fs, unmount);
	PUFFSOP_SETFSNOP(pops, sync); /* XXX */
	PUFFSOP_SET(pops, psshfs, fs, statvfs);
	PUFFSOP_SET(pops, psshfs, fs, nodetofh);
	PUFFSOP_SET(pops, psshfs, fs, fhtonode);

	PUFFSOP_SET(pops, psshfs, node, lookup);
	PUFFSOP_SET(pops, psshfs, node, create);
	PUFFSOP_SET(pops, psshfs, node, open);
	PUFFSOP_SET(pops, psshfs, node, inactive);
	PUFFSOP_SET(pops, psshfs, node, readdir);
	PUFFSOP_SET(pops, psshfs, node, getattr);
	PUFFSOP_SET(pops, psshfs, node, setattr);
	PUFFSOP_SET(pops, psshfs, node, mkdir);
	PUFFSOP_SET(pops, psshfs, node, remove);
	PUFFSOP_SET(pops, psshfs, node, readlink);
	PUFFSOP_SET(pops, psshfs, node, rmdir);
	PUFFSOP_SET(pops, psshfs, node, symlink);
	PUFFSOP_SET(pops, psshfs, node, rename);
	PUFFSOP_SET(pops, psshfs, node, read);
	PUFFSOP_SET(pops, psshfs, node, write);
	PUFFSOP_SET(pops, psshfs, node, reclaim);

	pu = puffs_init(pops, argv[0], "psshfs", &pctx, pflags);
	if (pu == NULL)
		err(1, "puffs_init");

	pctx.mounttime = time(NULL);
	pctx.refreshival = refreshival;
	pctx.numconnections = numconnections;

	user = strdup(argv[0]);
	if ((host = strrchr(user, '@')) == NULL) {
		host = user;
	} else {
		*host++ = '\0';		/* break at the '@' */
		if (user[0] == '\0') {
			fprintf(stderr, "Missing username\n");
			usage();
		}
		add_ssharg(&sshargs, &nargs, "-l");
		add_ssharg(&sshargs, &nargs, user);
	}

	if ((path = colon(host)) != NULL) {
		*path++ = '\0';		/* break at the ':' */
		pctx.mountpath = path;
	} else {
		pctx.mountpath = ".";
	}

	host = cleanhostname(host);
	if (host[0] == '\0') {
		fprintf(stderr, "Missing hostname\n");
		usage();
	}

	add_ssharg(&sshargs, &nargs, host);
	add_ssharg(&sshargs, &nargs, "sftp");
	pctx.sshargs = sshargs;

	pctx.nextino = 2;
	memset(root, 0, sizeof(struct psshfs_node));
	TAILQ_INIT(&root->pw);
	pn_root = puffs_pn_new(pu, root);
	if (pn_root == NULL)
		return errno;
	puffs_setroot(pu, pn_root);

	puffs_framev_init(pu, psbuf_read, psbuf_write, psbuf_cmp, NULL, notfn);

	signal(SIGHUP, takehup);
	puffs_ml_setloopfn(pu, psshfs_loopfn);
	if (pssh_connect(pu, PSSHFD_META) == -1)
		err(1, "can't connect meta");
	if (puffs_framev_addfd(pu, pctx.sshfd,
	    PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
		err(1, "framebuf addfd meta");
	if (numconnections == 2) {
		if (pssh_connect(pu, PSSHFD_DATA) == -1)
			err(1, "can't connect data");
		if (puffs_framev_addfd(pu, pctx.sshfd_data,
		    PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
			err(1, "framebuf addfd data");
	} else {
		pctx.sshfd_data = pctx.sshfd;
	}

	if (exportfs)
		puffs_setfhsize(pu, sizeof(struct psshfs_fid),
		    PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3);

	rva = &pn_root->pn_va;
	rva->va_fileid = pctx.nextino++;

	/*
	 * For root link count, just guess something ridiculously high.
	 * Guessing too high has no known adverse effects, but fts(3)
	 * doesn't like too low values.  This guess will be replaced
	 * with the real value when readdir is first called for
	 * the root directory.
	 */
	rva->va_nlink = 8811;

	if (detach)
		if (puffs_daemon(pu, 1, 1) == -1)
			err(1, "puffs_daemon");

	if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1)
		err(1, "puffs_mount");
	if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1)
		err(1, "setblockingmode");

	if (puffs_mainloop(pu) == -1)
		err(1, "mainloop");
	puffs_exit(pu, 1);

	return 0;
}
示例#15
0
int
main(int argc, char *argv[])
{
	struct puffs_usermount *pu;
	struct puffs_ops *pops;
	mntoptparse_t mp;
	int mntflags, pflags;
	int detach;
	int ch;

	setprogname(argv[0]);

	if (argc < 2)
		usage();

	mntflags = pflags = 0;
	detach = 1;
	while ((ch = getopt(argc, argv, "o:rs")) != -1) {
		switch (ch) {
		case 'o':
			mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
			if (mp == NULL)
				err(EXIT_FAILURE, "getmntopts");
			freemntopts(mp);
			break;
		case 'r':
			rflag = 1;
			break;
		case 's':
			detach = 0;
			break;
		}
	}
	argv += optind;
	argc -= optind;
	pflags |= PUFFS_FLAG_BUILDPATH | PUFFS_KFLAG_NOCACHE;

	if (pflags & PUFFS_FLAG_OPDUMP)
		detach = 0;

	if (argc != 2)
		usage();

	PUFFSOP_INIT(pops);

	PUFFSOP_SETFSNOP(pops, unmount);
	PUFFSOP_SETFSNOP(pops, sync);
	PUFFSOP_SETFSNOP(pops, statvfs);
	PUFFSOP_SET(pops, sysctlfs, fs, nodetofh);
	PUFFSOP_SET(pops, sysctlfs, fs, fhtonode);

	PUFFSOP_SET(pops, sysctlfs, node, lookup);
	PUFFSOP_SET(pops, sysctlfs, node, getattr);
	PUFFSOP_SET(pops, sysctlfs, node, setattr);
	PUFFSOP_SET(pops, sysctlfs, node, readdir);
	PUFFSOP_SET(pops, sysctlfs, node, read);
	PUFFSOP_SET(pops, sysctlfs, node, write);
	PUFFSOP_SET(pops, puffs_genfs, node, reclaim);

	pu = puffs_init(pops, _PATH_PUFFS, "sysctlfs", NULL, pflags);
	if (pu == NULL)
		err(EXIT_FAILURE, "puffs_init");

	puffs_set_pathbuild(pu, sysctlfs_pathbuild);
	puffs_set_pathtransform(pu, sysctlfs_pathtransform);
	puffs_set_pathcmp(pu, sysctlfs_pathcmp);
	puffs_set_pathfree(pu, sysctlfs_pathfree);

	puffs_setfhsize(pu, sizeof(struct sfsfid), PUFFS_FHFLAG_NFSV3);

	if (sysctlfs_domount(pu) != 0)
		errx(EXIT_FAILURE, "domount");

	if (detach)
		if (puffs_daemon(pu, 1, 1) == -1)
			err(EXIT_FAILURE, "puffs_daemon");

#ifdef RUMP_ACTION
	{
		extern int puffs_fakecc;
		puffs_fakecc = 1;
		rump_init();
	}
#endif

	if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1)
		err(EXIT_FAILURE, "puffs_mount");
	if (puffs_mainloop(pu) == -1)
		err(EXIT_FAILURE, "mainloop");

	return 0;
}
示例#16
0
文件: mount_smbfs.c 项目: B1NG0/cifs
int main(int argc, char *argv[])
{
	SMBHANDLE serverConnection = NULL;
	uint64_t options = kSMBOptionSessionOnly;
	uint64_t mntOptions = 0;
	int altflags = SMBFS_MNT_STREAMS_ON;
	mode_t fileMode = 0, dirMode = 0;
	int mntflags = 0;
	NTSTATUS	status;
	char mountPoint[MAXPATHLEN];
	struct stat st;
	char *next;
	int opt;
	const char * url = NULL;
	int version = SMBFrameworkVersion();

	while ((opt = getopt(argc, argv, "Nvhd:f:o:")) != -1) {
		switch (opt) {
		    case 'd':
				errno = 0;
				dirMode = strtol(optarg, &next, 8);
				if (errno || *next != 0)
					errx(EX_DATAERR, "invalid value for directory mode");
				break;
		    case 'f':
				errno = 0;
				fileMode = strtol(optarg, &next, 8);
				if (errno || *next != 0)
					errx(EX_DATAERR, "invalid value for file mode");
				break;
			case 'N':
				options |= kSMBOptionNoPrompt;
				break;
			case 'o': {
				mntoptparse_t mp = getmntopts(optarg, mopts, &mntflags, &altflags);
				if (mp == NULL)
					err(1, NULL);
				freemntopts(mp);
				break;
			}
			case 'v':
				errx(EX_OK, "version %d.%d.%d", 
					version / 100000, (version % 10000) / 1000, (version % 1000) / 100);
				break;
			case '?':
			case 'h':
		    default:
				usage();
				break;
		}
	}
	if (optind >= argc)
		usage();
	
	argc -= optind;
	/* At this point we should only have a url and a mount point */
	if (argc != 2)
		usage();
	url = argv[optind];
	optind++;
	realpath(unpercent(argv[optind]), mountPoint);
	
	if (stat(mountPoint, &st) == -1)
		err(EX_OSERR, "could not find mount point %s", mountPoint);
	
	if (!S_ISDIR(st.st_mode)) {
		errno = ENOTDIR;
		err(EX_OSERR, "can't mount on %s", mountPoint);
	}
	
	if (mntflags & MNT_AUTOMOUNTED) {
		/* Automount volume, don't look in the user home directory */
		options |= kSMBOptionNoUserPreferences;
	}

	if ((altflags & SMBFS_MNT_STREAMS_ON) != SMBFS_MNT_STREAMS_ON) {
		/* They told us to turn of named streams */
		mntOptions |= kSMBMntOptionNoStreams;
	}
	if ((altflags & SMBFS_MNT_NOTIFY_OFF) == SMBFS_MNT_NOTIFY_OFF) {
		/* They told us to turn off remote notifications */
		mntOptions |= kSMBMntOptionNoNotifcations;
	}
	if ((altflags & SMBFS_MNT_SOFT) == SMBFS_MNT_SOFT) {
		/* Make this a soft mount */
		mntOptions |= kSMBMntOptionSoftMount;
	}
	if ((altflags & SMBFS_MNT_TIME_MACHINE) == SMBFS_MNT_TIME_MACHINE) {
		/* Make this a tm mount */
		mntOptions |= kSMBReservedTMMount;
	}
	
	status = SMBOpenServerEx(url, &serverConnection, options);
	if (NT_SUCCESS(status)) {
		status = SMBMountShareEx(serverConnection, NULL, mountPoint, mntflags, 
								 mntOptions, fileMode, dirMode, setNetworkAccountSID, NULL);
	}
	/* 
	 * SMBOpenServerEx now sets errno, so err will work correctly. We change 
	 * the string based on the NTSTATUS Error.
	 */
	if (!NT_SUCCESS(status)) {
		switch (status) {
			case STATUS_NO_SUCH_DEVICE:
				err(EX_UNAVAILABLE, "failed to intitialize the smb library");
				break;
			case STATUS_LOGON_FAILURE:
				err(EX_NOPERM, "server rejected the connection");
				break;
			case STATUS_CONNECTION_REFUSED:
				err(EX_NOHOST, "server connection failed");
			break;
			case STATUS_INVALID_HANDLE:
			case STATUS_NO_MEMORY:
				err(EX_UNAVAILABLE, "internal error");
				break;
			case STATUS_UNSUCCESSFUL:
				err(EX_USAGE, "mount error: %s", mountPoint);
				break;
			case STATUS_INVALID_PARAMETER:
				err(EX_USAGE, "URL parsing failed, please correct the URL and try again");
				break;
			case STATUS_BAD_NETWORK_NAME:
				err(EX_NOHOST, "share connection failed");
				break;
			default:
				err(EX_OSERR, "unknown status %d", status);
				break;
		}
	}

	/* We are done clean up anything left around */
	if (serverConnection)
		SMBReleaseServer(serverConnection);
	return 0;
}
示例#17
0
int
main(int argc, char **argv)
{
	struct iovec iov[12];
	int ch, i, mntflags, opts, udf_flags;
	char *dev, *dir, mntpath[MAXPATHLEN];
	char *cs_disk, *cs_local;
	int verbose;

	i = mntflags = opts = udf_flags = verbose = 0;
	cs_disk = cs_local = NULL;
	while ((ch = getopt(argc, argv, "o:vC:")) != -1)
		switch (ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags, &opts);
			break;
		case 'v':
			verbose++;
			break;
		case 'C':
			if (set_charset(&cs_disk, &cs_local, optarg) == -1)
				err(EX_OSERR, "udf_iconv");
			udf_flags |= UDFMNT_KICONV;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	dev = argv[0];
	dir = argv[1];

	/*
	 * Resolve the mountpoint with realpath(3) and remove unnecessary
	 * slashes from the devicename if there are any.
	 */
	(void)checkpath(dir, mntpath);
	(void)rmslashes(dev, dev);

	/*
	 * UDF file systems are not writeable.
	 */
	mntflags |= MNT_RDONLY;

	iov[i].iov_base = "fstype";
	iov[i++].iov_len = sizeof("fstype");
	iov[i].iov_base = "udf";
	iov[i].iov_len = strlen(iov[i].iov_base) + 1;
	i++;
	iov[i].iov_base = "fspath";
	iov[i++].iov_len = sizeof("fspath");
	iov[i].iov_base = mntpath;
	iov[i++].iov_len = strlen(mntpath) + 1;
	iov[i].iov_base = "from";
	iov[i++].iov_len = sizeof("from");
	iov[i].iov_base = dev;
	iov[i++].iov_len = strlen(dev) + 1;
	iov[i].iov_base = "flags";
	iov[i++].iov_len = sizeof("flags");
	iov[i].iov_base = &udf_flags;
	iov[i++].iov_len = sizeof(udf_flags);
	if (udf_flags & UDFMNT_KICONV) {
		iov[i].iov_base = "cs_disk";
		iov[i++].iov_len = sizeof("cs_disk");
		iov[i].iov_base = cs_disk;
		iov[i++].iov_len = strlen(cs_disk) + 1;
		iov[i].iov_base = "cs_local";
		iov[i++].iov_len = sizeof("cs_local");
		iov[i].iov_base = cs_local;
		iov[i++].iov_len = strlen(cs_local) + 1;
	}
	if (nmount(iov, i, mntflags) < 0)
		err(1, "%s", dev);
	exit(0);
}
示例#18
0
int
main(int argc, char **argv)
{
    int       result    = -1;
    int       mntflags  = 0;
    int       cfd       = -1;
    char     *fdnam     = NULL;
    char     *dev       = NULL;
    int       r         = 0;
    char      devpath[MAXPATHLEN];
    int       fd        = -1;
    int32_t   dindex    = -1;
    uint64_t  altflags  = 0ULL;
    char     *mntpath   = NULL;

    struct mntopt *mo;
    struct mntval *mv;
    struct statfs statfsb;
    fuse_mount_args args;

    // Drop to real uid and gid
    seteuid(getuid());
    setegid(getgid());

    if (!getenv("MOUNT_OSXFUSE_CALL_BY_LIB")) {
        showhelp();
    }

    memset((void *)&args, 0, sizeof(args));

    while (true) {
        static struct option long_options[] = {
            { "help",    no_argument, NULL, 'h' },
            { "version", no_argument, NULL, 'v' },
            { NULL, 0, NULL, 0 }
        };

        int c = getopt_long(argc, argv, "ho:qv", long_options, NULL);
        if (c == -1) {
            break;
        }

        switch (c) {
            case 'o':
                getmntopts(optarg, mopts, &mntflags, &altflags);
                for (mv = mvals; mv->mv_mntflag; ++mv) {
                    if (!(altflags & mv->mv_mntflag)) {
                        continue;
                    }
                    for (mo = mopts; mo->m_option; ++mo) {
                        char *p, *q;
                        if (!mo->m_altloc || mo->m_flag != mv->mv_mntflag) {
                            continue;
                        }
                        p = strstr(optarg, mo->m_option);
                        if (p) {
                            p += strlen(mo->m_option);
                            q = p;
                            while (*q != '\0' && *q != ',') {
                                q++;
                            }
                            mv->mv_len = q - p + 1;
                            mv->mv_value = malloc(mv->mv_len);
                            memcpy(mv->mv_value, p, mv->mv_len - 1);
                            ((char *)mv->mv_value)[mv->mv_len - 1] = '\0';
                            break;
                        }
                    }
                }
                break;

            case 'q':
                quiet_mode = true;
                break;

            case 'v':
                showversion(true);
                break;

            case 'h':
            case '?':
            default:
                showhelp();
                break;
        }
    }

    argc -= optind;
    argv += optind;

    if (argc >= 1) {
        mntpath = argv[0];
        argc--;
        argv++;
    }

    if (!mntpath) {
        errx(EX_USAGE, "missing mount point");
    }

    {
        char *commfd;

        commfd = getenv("_FUSE_COMMFD");
        if (commfd == NULL) {
            errx(EX_USAGE, "mew style mounting requires commfd");
        }

        errno = 0;
        cfd = (int)strtol(commfd, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || cfd < 0) {
            errx(EX_USAGE, "invalid commfd");
        }
    }

    result = load_kext();
    if (result) {
        if (result == EINVAL) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too new for the operating system. Please downgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_OLD, NULL, 0);
        }
        if (result == ENOENT) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("Installed version of macOS unsupported"),
                    CFSTR("The installed version of FUSE is too old for the operating system. Please upgrade your FUSE installation to one that is compatible with the currently running version of macOS."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_OS_IS_TOO_NEW, NULL, 0);
        } else if (result == EBUSY) {
            if (!quiet_mode) {
                CFUserNotificationDisplayNotice(
                    (CFTimeInterval)0,
                    kCFUserNotificationCautionAlertLevel,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    (CFURLRef)0,
                    CFSTR("FUSE version mismatch"),
                    CFSTR("FUSE has been updated but an incompatible or old version of the FUSE kernel extension is already loaded. It failed to unload, possibly because a FUSE volume is currently mounted.\n\nPlease eject all FUSE volumes and try again, or simply restart the system for changes to take effect."),
                    CFSTR("OK"));
            }
            post_notification(NOTIFICATION_VERSION_MISMATCH, NULL, 0);
        }
        errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME " file system is not available (%d)", result);
    }

    result = check_kext_status();
    switch (result) {
        case 0:
            break;

        case ESRCH:
            errx(EX_UNAVAILABLE, "the " OSXFUSE_DISPLAY_NAME
                 " kernel extension is not loaded");
            break;

        case EINVAL:
            errx(EX_UNAVAILABLE, "the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension has a mismatched version");
            break;

        default:
            errx(EX_UNAVAILABLE, "failed to query the loaded " OSXFUSE_DISPLAY_NAME
                 " kernel extension (%d)", result);
            break;
    }

    fdnam = getenv("FUSE_DEV_FD");
    if (fdnam) {
        errno = 0;
        fd = (int)strtol(fdnam, NULL, 10);
        if (errno == EINVAL || errno == ERANGE || fd < 0) {
            errx(EX_USAGE, "invalid value given in FUSE_DEV_FD");
        }

        goto mount;
    }

    dev = getenv("FUSE_DEV_NAME");
    if (dev) {
        fd = open(dev, O_RDWR);
        if (fd < 0) {
            errx(EX_USAGE, "failed to open device");
        }

        goto mount;
    }

    for (r = 0; r < OSXFUSE_NDEVICES; r++) {
        snprintf(devpath, MAXPATHLEN - 1,
                 _PATH_DEV OSXFUSE_DEVICE_BASENAME "%d", r);
        fd = open(devpath, O_RDWR);
        if (fd >= 0) {
            dindex = r;
            break;
        }
    }
    if (dindex == -1) {
        errx(EX_OSERR, "failed to open device");
    }

mount:
    signal_fd = fd;
    atexit(&signal_idx_atexit_handler);

    {
        struct stat sb;
        if (fstat(fd, &sb) == -1) {
            err(EX_OSERR, "fstat failed for " OSXFUSE_DISPLAY_NAME " device file descriptor");
        }
        args.rdev = sb.st_rdev;
    }

    if (dindex < 0) {
        char  ndev[MAXPATHLEN];
        char *ndevbas;

        (void)strlcpy(ndev, _PATH_DEV, sizeof(ndev));
        ndevbas = ndev + strlen(_PATH_DEV);
        devname_r(args.rdev, S_IFCHR, ndevbas, (int)(sizeof(ndev) - strlen(_PATH_DEV)));

        if (strncmp(ndevbas, OSXFUSE_DEVICE_BASENAME, strlen(OSXFUSE_DEVICE_BASENAME))) {
            errx(EX_USAGE, "mounting inappropriate device");
        }

        errno = 0;
        dindex = (int)strtol(ndevbas + strlen(OSXFUSE_DEVICE_BASENAME), NULL, 10);
        if (errno == EINVAL || errno == ERANGE || dindex < 0 || dindex > OSXFUSE_NDEVICES) {
            errx(EX_USAGE, "invalid " OSXFUSE_DISPLAY_NAME " device unit (#%d)\n", dindex);
        }
    }

    while (true) {
        struct stat sb;

        if (realpath(mntpath, args.mntpath) != NULL &&
            stat(args.mntpath, &sb) == 0) {

            if (S_ISDIR(sb.st_mode)) {
                break;
            } else {
                errx(EX_USAGE, "%s: not a directory", args.mntpath);
            }

        } else if (errno == ENOENT) {
            bool volumes = strncmp(args.mntpath, "/Volumes/", 9) == 0 &&
                           strchr(args.mntpath + 9, '/') == NULL;

            if (volumes) {
                (void)seteuid(0);
                (void)setegid(0);
            }

            if (mkdir(args.mntpath, 0755)) {
                errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
            }

            if (volumes) {
                uid_t uid = getuid();
                gid_t gid = getgid();

                (void)chown(args.mntpath, uid, gid);
                (void)seteuid(uid);
                (void)setegid(gid);
            }

        } else {
            errx(EX_USAGE, "%s: %s", args.mntpath, strerror(errno));
        }
    }

    mntpath = args.mntpath;

    fuse_process_mvals();

    if (statfs(mntpath, &statfsb)) {
        errx(EX_OSFILE, "cannot stat the mount point %s", mntpath);
    }

    if (((strlen(statfsb.f_fstypename) == strlen(OSXFUSE_NAME)) &&
         (strcmp(statfsb.f_fstypename, OSXFUSE_NAME) == 0)) ||
        ((strlen(OSXFUSE_TYPE_NAME_PREFIX) > 0) &&
         (strncmp(statfsb.f_fstypename, OSXFUSE_TYPE_NAME_PREFIX,
                  strlen(OSXFUSE_TYPE_NAME_PREFIX)) == 0))) {
        if (!(altflags & FUSE_MOPT_ALLOW_RECURSION)) {
            errx(EX_USAGE, "mount point %s is itself on a "
                 OSXFUSE_DISPLAY_NAME " volume", mntpath);
        }
    }

    /* allow_root and allow_other checks are done in the kernel. */

    if (altflags & FUSE_MOPT_NO_LOCALCACHES) {
        altflags |= FUSE_MOPT_NO_ATTRCACHE;
        altflags |= FUSE_MOPT_NO_READAHEAD;
        altflags |= FUSE_MOPT_NO_UBC;
        altflags |= FUSE_MOPT_NO_VNCACHE;
    }

    if ((altflags & FUSE_MOPT_NEGATIVE_VNCACHE) &&
        (altflags & FUSE_MOPT_NO_VNCACHE)) {
        errx(EX_USAGE, "'negative_vncache' can't be used with 'novncache'");
    }

    /*
     * 'nosyncwrites' must not appear with either 'noubc' or 'noreadahead'.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCWRITES) &&
        (altflags & (FUSE_MOPT_NO_UBC | FUSE_MOPT_NO_READAHEAD))) {
        errx(EX_USAGE,
             "disabling local caching can't be used with 'nosyncwrites'");
    }

    /*
     * 'nosynconclose' only allowed if 'nosyncwrites' is also there.
     */
    if ((altflags & FUSE_MOPT_NO_SYNCONCLOSE) &&
        !(altflags & FUSE_MOPT_NO_SYNCWRITES)) {
        errx(EX_USAGE, "the 'nosynconclose' option requires 'nosyncwrites'");
    }

    if ((altflags & FUSE_MOPT_DEFAULT_PERMISSIONS) &&
        (altflags & FUSE_MOPT_DEFER_PERMISSIONS)) {
        errx(EX_USAGE,
             "'default_permissions' can't be used with 'defer_permissions'");
    }

    if ((altflags & FUSE_MOPT_AUTO_XATTR) &&
        (altflags & FUSE_MOPT_NATIVE_XATTR)) {
        errx(EX_USAGE,
             "'auto_xattr' can't be used with 'native_xattr'");
    }

    if (daemon_timeout < FUSE_MIN_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MIN_DAEMON_TIMEOUT;
    }

    if (daemon_timeout > FUSE_MAX_DAEMON_TIMEOUT) {
        daemon_timeout = FUSE_MAX_DAEMON_TIMEOUT;
    }

    result = ioctl(fd, FUSEDEVIOCGETRANDOM, &drandom);
    if (result) {
        errx(EX_UNAVAILABLE, "failed to negotiate with /dev/"
             OSXFUSE_DEVICE_BASENAME "%d", dindex);
    }

    args.altflags       = altflags;
    args.blocksize      = (uint32_t)blocksize;
    args.daemon_timeout = (uint32_t)daemon_timeout;
    args.fsid           = (uint32_t)fsid;
    args.fssubtype      = (uint32_t)fssubtype;
    args.iosize         = (uint32_t)iosize;
    args.random         = drandom;

    char *daemon_name = NULL;
    char *daemon_path = getenv("MOUNT_OSXFUSE_DAEMON_PATH");
    if (daemon_path) {
        daemon_name = basename(daemon_path);
    }

    if (!fsname) {
        if (daemon_name) {
            snprintf(args.fsname, MAXPATHLEN, "%s@" OSXFUSE_DEVICE_BASENAME
                     "%d", daemon_name, dindex);
        } else {
            snprintf(args.fsname, MAXPATHLEN, "instance@"
                     OSXFUSE_DEVICE_BASENAME "%d", dindex);
        }
    } else {
        snprintf(args.fsname, MAXPATHLEN, "%s", fsname);
    }

    if (fstypename) {
        if (strlen(fstypename) > FUSE_TYPE_NAME_MAXLEN) {
            errx(EX_USAGE, "fstypename can be at most %lu characters",
                 (long unsigned int) FUSE_TYPE_NAME_MAXLEN);
        } else {
            snprintf(args.fstypename, MFSTYPENAMELEN, "%s", fstypename);
        }
    }

    if (!volname) {
        #if __clang__
            #pragma clang diagnostic push
            #pragma clang diagnostic ignored "-Wformat-extra-args"
        #endif

        if (daemon_name) {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_DAEMON_FORMAT,
                     dindex, daemon_name);
        } else {
            snprintf(args.volname, MAXPATHLEN, OSXFUSE_VOLNAME_FORMAT, dindex);
        }

        #if __clang__
            #pragma clang diagnostic pop
        #endif
    } else {
        snprintf(args.volname, MAXPATHLEN, "%s", volname);
    }

    if (cfd != -1) {
        result = send_fd(cfd, fd);
        if (result == -1) {
            err(EX_OSERR, "failed to send file descriptor");
        }
    }

    /* Finally! */
    result = mount(OSXFUSE_NAME, mntpath, mntflags, (void *)&args);

    if (result < 0) {
        err(EX_OSERR, "failed to mount %s@/dev/" OSXFUSE_DEVICE_BASENAME "%d",
            mntpath, dindex);
    } else {
        const char *dict[][2] = { { kFUSEMountPathKey, mntpath } };
        post_notification(NOTIFICATION_MOUNT, dict, 1);
    }

    signal_fd = -1;
    exit(0);
}
示例#19
0
int
main(int argc, char **argv)
{
	int c;
	int usenetauth = 0;
	mntoptparse_t mp;
	int flags, altflags;
	CFURLRef URL;
	CFStringRef mountdir_CFString;
	CFMutableDictionaryRef open_options, mount_options;
	CFDictionaryRef mount_info;
	int res;

	flags = altflags = 0;
	getmnt_silent = 1;
	while ((c = getopt(argc, argv, "no:rw")) != -1) {
		switch (c) {

		case 'n':
			usenetauth = 1;
			break;

		case 'o':
			/*
			 * OK, parse these options, and update the flags.
			 */
			mp = getmntopts(optarg, mopts_std, &flags, &altflags);
			freemntopts(mp);
			break;

		case 'r':
			flags |= MNT_RDONLY;
			break;

		case 'w':
			flags &= ~MNT_RDONLY;
			break;

		case '?':
		default:
			usage();
			break;
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	/*
	 * Nothing can stop the Duke of...
	 */
	URL = CFURLCreateWithBytes(kCFAllocatorDefault, (const UInt8 *)argv[0],
	    strlen(argv[0]), kCFStringEncodingUTF8, NULL);
	if (URL == NULL)
		exit(ENOMEM);

	mountdir_CFString = CFStringCreateWithCString(kCFAllocatorDefault,
	    argv[1], kCFStringEncodingUTF8);
	if (mountdir_CFString == NULL)
		exit(ENOMEM);

	open_options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
	    &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (open_options == NULL)
		exit(ENOMEM);
	/*
	 * It's OK to use an existing session.
	 */
	CFDictionaryAddValue(open_options, kNetFSForceNewSessionKey,
	    kCFBooleanFalse);
	/*
	 * And it's OK to mount something from ourselves.
	 */
	CFDictionaryAddValue(open_options, kNetFSAllowLoopbackKey,
	    kCFBooleanTrue);
	/*
	 * This could be mounting a home directory, so we don't want
	 * the mount to look at user preferences in the home directory.
	 */
	CFDictionaryAddValue(open_options, kNetFSNoUserPreferencesKey,
	    kCFBooleanTrue);
	/*
	 * We don't want any UI popped up for the mount.
	 */
	CFDictionaryAddValue(open_options, kUIOptionKey, kUIOptionNoUI);

	mount_options = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
	    &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	if (mount_options == NULL)
		exit(ENOMEM);
	/*
	 * It's OK to use an existing session.
	 */
	CFDictionaryAddValue(mount_options, kNetFSForceNewSessionKey,
	    kCFBooleanFalse);
	/*
	 * We want the URL mounted exactly where we specify.
	 */
	CFDictionaryAddValue(mount_options, kNetFSMountAtMountDirKey,
	    kCFBooleanTrue);
	/*
	 * This could be mounting a home directory, so we don't want
	 * the mount to look at user preferences in the home directory.
	 */
	CFDictionaryAddValue(mount_options, kNetFSNoUserPreferencesKey,
	    kCFBooleanTrue);
	/*
	 * We want to allow the URL to specify a directory underneath
	 * a share point for file systems that support the notion of
	 * shares.
	 */
	CFDictionaryAddValue(mount_options, kNetFSAllowSubMountsKey,
	    kCFBooleanTrue);
	/*
	 * Add the mount flags.
	 */
	CFDictionaryAddValue(mount_options, kNetFSMountFlagsKey,
	    CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type,
	      &flags));
	/*
	 * Add the soft mount flag.
	 */
	CFDictionaryAddValue(mount_options, kNetFSSoftMountKey,
	    (altflags & ALT_SOFT) ? kCFBooleanTrue : kCFBooleanFalse);
	/*
	 * We don't want any UI popped up for the mount.
	 */
	CFDictionaryAddValue(mount_options, kUIOptionKey, kUIOptionNoUI);

	if (usenetauth)
		res = NAConnectToServerSync(URL, mountdir_CFString,
		    open_options, mount_options, &mount_info);
	else
		res = do_mount_direct(URL, mountdir_CFString, open_options,
		    mount_options, &mount_info);
	/*
	 * 0 means "no error", EEXIST means "that's already mounted, and
	 * mountinfo says where it's mounted".  In those cases, a
	 * directory of mount information was returned; release it.
	 */
	if (res == 0 || res == EEXIST)
		CFRelease(mount_info);
	CFRelease(mount_options);
	CFRelease(open_options);
	CFRelease(mountdir_CFString);
	CFRelease(URL);
	if (res != 0) {
		/*
		 * Report any failure status that doesn't fit in the
		 * 8 bits of a UN*X exit status, and map it to EIO
		 * by default and EAUTH for ENETFS errors.
		 */
		if ((res & 0xFFFFFF00) != 0) {
			syslog(LOG_ERR,
			    "mount_url: Mount of %s on %s gives status %d",
			    argv[0], argv[1], res);
			switch (res) {

			case ENETFSACCOUNTRESTRICTED:
			case ENETFSPWDNEEDSCHANGE:
			case ENETFSPWDPOLICY:
				res = EAUTH;
				break;

			default:
				res = EIO;
				break;
			}
		}
	}

	return res;
}
示例#20
0
int
main(int ac, char **av)
{
	struct hammer_mount_info info;
	struct vfsconf vfc;
	struct hammer_volume_ondisk *od;
	int mount_flags = 0;
	int error;
	int ch;
	int init_flags = 0;
	int ax;
	int fd;
	int pr;
	int fdevs_size;
	char *mountpt;
	char *ptr;
	char *fdevs;


	bzero(&info, sizeof(info));
	info.asof = 0;
	mount_flags = 0;
	info.hflags = 0;

	while ((ch = getopt(ac, av, "o:T:u")) != -1) {
		switch(ch) {
		case 'T':
			info.asof = strtoull(optarg, NULL, 0);
			break;
		case 'o':
			getmntopts(optarg, mopts, &mount_flags, &info.hflags);


			/*
			 * Handle extended flags with parameters.
			 */
			if (info.hflags & HMNT_MASTERID) {
				ptr = strstr(optarg, "master=");
				if (ptr) {
					info.master_id = strtol(ptr + 7, NULL, 0);
					if (info.master_id == 0) {
						fprintf(stderr,
	"hammer_mount: Warning: a master id of 0 is the default, explicit\n"
	"settings should probably use 1-15\n");
					}
				}
				ptr = strstr(optarg, "nomirror");
				if (ptr)
					info.master_id = -1;
			}
			break;
		case 'u':
			init_flags |= MNT_UPDATE;
			break;
		default:
			usage();
			/* not reached */
		}
	}
	ac -= optind;
	av += optind;
	mount_flags |= init_flags;

	/*
	 * Only the mount point need be specified in update mode.
	 */
	if (init_flags & MNT_UPDATE) {
		if (ac != 1) {
			usage();
			/* not reached */
		}
		mountpt = av[0];
		if (mount(vfc.vfc_name, mountpt, mount_flags, &info))
			err(1, "mountpoint %s", mountpt);
		exit(0);
	}

	if (ac < 2) {
		usage();
		/* not reached */
	}

	/*
	 * Mount arguments: vol [vol...] mountpt
	 */
	extract_volumes(&info.volumes, &info.nvolumes, av, ac - 1);
	mountpt = av[ac - 1];

	/*
	 * Load the hammer module if necessary (this bit stolen from
	 * mount_null).
	 */
	error = getvfsbyname("hammer", &vfc);
	if (error && vfsisloadable("hammer")) {
		if (vfsload("hammer") != 0)
			err(1, "vfsload(hammer)");
		endvfsent();
		error = getvfsbyname("hammer", &vfc);
	}
	if (error)
		errx(1, "hammer filesystem is not available");

	if (mount(vfc.vfc_name, mountpt, mount_flags, &info)) {
		/* Build fdevs in case of error to report failed devices */
		fdevs_size = ac * PATH_MAX;
		fdevs = malloc(fdevs_size);
		for (ax = 0; ax < ac - 1; ax++) {
			fd = open(info.volumes[ax], O_RDONLY);
			if (fd < 0 ) {
				printf ("%s: open failed\n", info.volumes[ax]);
				strlcat(fdevs, info.volumes[ax], fdevs_size);
				if (ax < ac - 2)
					strlcat(fdevs, " ", fdevs_size);
				continue;
			}

			od = malloc(HAMMER_BUFSIZE);
			if (od == NULL) {
				close (fd);
				perror("malloc");
				continue;
			}

			bzero(od, HAMMER_BUFSIZE);
			pr = pread(fd, od, HAMMER_BUFSIZE, 0);
			if (pr != HAMMER_BUFSIZE ||
				od->vol_signature != HAMMER_FSBUF_VOLUME) {
					printf("%s: Not a valid HAMMER filesystem\n", info.volumes[ax]);
					strlcat(fdevs, info.volumes[ax], fdevs_size);
					if (ax < ac - 2)
						strlcat(fdevs, " ", fdevs_size);
			}
			close(fd);
		}
		err(1,"mount %s on %s", fdevs, mountpt);
	}
	exit (0);
}
示例#21
0
int
mount_fs(const char *vfstype, int argc, char *argv[])
{
	struct iovec *iov;
	int iovlen;
	int mntflags = 0;
	int ch;
	char *dev, *dir, mntpath[MAXPATHLEN];
	char fstype[32];
	char errmsg[255];
	char *p, *val;

	strlcpy(fstype, vfstype, sizeof(fstype));
	memset(errmsg, 0, sizeof(errmsg));

	getmnt_silent = 1;
	iov = NULL;
	iovlen = 0;

	optind = optreset = 1;		/* Reset for parse of new argv. */
	while ((ch = getopt(argc, argv, "o:")) != -1) {
		switch(ch) {
		case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			p = strchr(optarg, '=');
			val = NULL;
			if (p != NULL) {
				*p = '\0';
				val = p + 1;
			}
			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
			break;
		case '?':
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;
	if (argc != 2)
		usage();

	dev = argv[0];
	dir = argv[1];

	if (checkpath(dir, mntpath) != 0) {
		warn("%s", mntpath);
		return (1);
	}
	(void)rmslashes(dev, dev);

	build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
	build_iovec(&iov, &iovlen, "fspath", mntpath, (size_t)-1);
	build_iovec(&iov, &iovlen, "from", dev, (size_t)-1);
	build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));

	if (nmount(iov, iovlen, mntflags) == -1) {
		if (*errmsg != '\0')
			warn("%s: %s", dev, errmsg);
		else
			warn("%s", dev);
		return (1);
	}
	return (0);
}
示例#22
0
文件: newfs.c 项目: ajinkya93/OpenBSD
int
main(int argc, char *argv[])
{
	int ch;
	struct partition *pp;
	struct disklabel *lp;
	struct disklabel mfsfakelabel;
	struct partition oldpartition;
	struct stat st;
	struct statfs *mp;
	struct rlimit rl;
	int fsi = -1, oflagset = 0, fso, len, n, maxpartitions;
	char *cp = NULL, *s1, *s2, *special, *opstring, *realdev;
#ifdef MFS
	char mountfromname[BUFSIZ];
	char *pop = NULL, node[PATH_MAX];
	pid_t pid, res;
	struct statfs sf;
	struct stat mountpoint;
	int status;
#endif
	uid_t mfsuid = 0;
	gid_t mfsgid = 0;
	mode_t mfsmode = 0;
	char *fstype = NULL;
	char **saveargv = argv;
	int ffsflag = 1;
	const char *errstr;
	long long fssize_input = 0;
	int fssize_usebytes = 0;
	u_int64_t nsecs;

	if (strstr(__progname, "mfs"))
		mfs = Nflag = quiet = 1;

	getphysmem();
	maxpartitions = getmaxpartitions();
	if (maxpartitions > 26)
		fatal("insane maxpartitions value %d", maxpartitions);

	opstring = mfs ?
	    "P:T:b:c:e:f:i:m:o:s:" :
	    "NO:S:T:b:c:e:f:g:h:i:m:o:qs:t:";
	while ((ch = getopt(argc, argv, opstring)) != -1) {
		switch (ch) {
		case 'N':
			Nflag = 1;
			break;
		case 'O':
			Oflag = strtonum(optarg, 0, 2, &errstr);
			if (errstr)
				fatal("%s: invalid ffs version", optarg);
			oflagset = 1;
			break;
		case 'S':
			if (scan_scaled(optarg, &sectorsize) == -1 ||
			    sectorsize <= 0 || (sectorsize % DEV_BSIZE))
				fatal("sector size invalid: %s", optarg);
			break;
		case 'T':
			disktype = optarg;
			break;
		case 'b':
			bsize = strtonum(optarg, MINBSIZE, MAXBSIZE, &errstr);
			if (errstr)
				fatal("block size is %s: %s", errstr, optarg);
			break;
		case 'c':
			maxfrgspercg = strtonum(optarg, 1, INT_MAX, &errstr);
			if (errstr)
				fatal("fragments per cylinder group is %s: %s",
				    errstr, optarg);
			break;
		case 'e':
			maxbpg = strtonum(optarg, 1, INT_MAX, &errstr);
			if (errstr)
				fatal("blocks per file in a cylinder group is"
				    " %s: %s", errstr, optarg);
			break;
		case 'f':
			fsize = strtonum(optarg, MINBSIZE / MAXFRAG, MAXBSIZE,
			    &errstr);
			if (errstr)
				fatal("fragment size is %s: %s",
				    errstr, optarg);
			break;
		case 'g':
			avgfilesize = strtonum(optarg, 1, INT_MAX, &errstr);
			if (errstr)
				fatal("average file size is %s: %s",
				    errstr, optarg);
			break;
		case 'h':
			avgfilesperdir = strtonum(optarg, 1, INT_MAX, &errstr);
			if (errstr)
				fatal("average files per dir is %s: %s",
				    errstr, optarg);
			break;
		case 'i':
			density = strtonum(optarg, 1, INT_MAX, &errstr);
			if (errstr)
				fatal("bytes per inode is %s: %s",
				    errstr, optarg);
			break;
		case 'm':
			minfree = strtonum(optarg, 0, 99, &errstr);
			if (errstr)
				fatal("free space %% is %s: %s",
				    errstr, optarg);
			break;
		case 'o':
			if (mfs)
				getmntopts(optarg, mopts, &mntflags);
			else {
				if (strcmp(optarg, "space") == 0)
					reqopt = opt = FS_OPTSPACE;
				else if (strcmp(optarg, "time") == 0)
					reqopt = opt = FS_OPTTIME;
				else
					fatal("%s: unknown optimization "
					    "preference: use `space' or `time'.",
					    optarg);
			}
			break;
		case 'q':
			quiet = 1;
			break;
		case 's':
			if (scan_scaled(optarg, &fssize_input) == -1 ||
			    fssize_input <= 0)
				fatal("file system size invalid: %s", optarg);
			fssize_usebytes = 0;    /* in case of multiple -s */
			for (s1 = optarg; *s1 != '\0'; s1++)
				if (isalpha((unsigned char)*s1)) {
					fssize_usebytes = 1;
					break;
				}
			break;
		case 't':
			fstype = optarg;
			if (strcmp(fstype, "ffs"))
				ffsflag = 0;
			break;
#ifdef MFS
		case 'P':
			pop = optarg;
			break;
#endif
		case '?':
		default:
			usage();
		}
		if (!ffsflag)
			break;
	}
	argc -= optind;
	argv += optind;

	if (ffsflag && argc - mfs != 1)
		usage();

	if (mfs) {
		/* Increase our data size to the max */
		if (getrlimit(RLIMIT_DATA, &rl) == 0) {
			rl.rlim_cur = rl.rlim_max;
			(void)setrlimit(RLIMIT_DATA, &rl);
		}
	}

	special = argv[0];

	if (!mfs) {
		char execname[PATH_MAX], name[PATH_MAX];

		if (fstype == NULL)
			fstype = readlabelfs(special, 0);
		if (fstype != NULL && strcmp(fstype, "ffs")) {
			snprintf(name, sizeof name, "newfs_%s", fstype);
			saveargv[0] = name;
			snprintf(execname, sizeof execname, "%s/newfs_%s",
			    _PATH_SBIN, fstype);
			(void)execv(execname, saveargv);
			snprintf(execname, sizeof execname, "%s/newfs_%s",
			    _PATH_USRSBIN, fstype);
			(void)execv(execname, saveargv);
			err(1, "%s not found", name);
		}
	}

	if (mfs && !strcmp(special, "swap")) {
		/*
		 * it's an MFS, mounted on "swap."  fake up a label.
		 * XXX XXX XXX
		 */
		fso = -1;	/* XXX; normally done below. */

		memset(&mfsfakelabel, 0, sizeof(mfsfakelabel));
		mfsfakelabel.d_secsize = 512;
		mfsfakelabel.d_nsectors = 64;
		mfsfakelabel.d_ntracks = 16;
		mfsfakelabel.d_ncylinders = 16;
		mfsfakelabel.d_secpercyl = 1024;
		DL_SETDSIZE(&mfsfakelabel, 16384);
		mfsfakelabel.d_npartitions = 1;
		mfsfakelabel.d_version = 1;
		DL_SETPSIZE(&mfsfakelabel.d_partitions[0], 16384);
		mfsfakelabel.d_partitions[0].p_fragblock =
		    DISKLABELV1_FFS_FRAGBLOCK(1024, 8);
		mfsfakelabel.d_partitions[0].p_cpg = 16;

		lp = &mfsfakelabel;
		pp = &mfsfakelabel.d_partitions[0];

		goto havelabel;
	}
	if (Nflag) {
		fso = -1;
	} else {
		fso = opendev(special, O_WRONLY, 0, &realdev);
		if (fso < 0)
			fatal("%s: %s", special, strerror(errno));
		special = realdev;

		/* Bail if target special is mounted */
		n = getmntinfo(&mp, MNT_NOWAIT);
		if (n == 0)
			fatal("%s: getmntinfo: %s", special, strerror(errno));

		len = sizeof(_PATH_DEV) - 1;
		s1 = special;
		if (strncmp(_PATH_DEV, s1, len) == 0)
			s1 += len;

		while (--n >= 0) {
			s2 = mp->f_mntfromname;
			if (strncmp(_PATH_DEV, s2, len) == 0) {
				s2 += len - 1;
				*s2 = 'r';
			}
			if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0)
				fatal("%s is mounted on %s",
				    special, mp->f_mntonname);
			++mp;
		}
	}
	if (mfs && disktype != NULL) {
		lp = (struct disklabel *)getdiskbyname(disktype);
		if (lp == NULL)
			fatal("%s: unknown disk type", disktype);
		pp = &lp->d_partitions[1];
	} else {
		fsi = opendev(special, O_RDONLY, 0, NULL);
		if (fsi < 0)
			fatal("%s: %s", special, strerror(errno));
		if (fstat(fsi, &st) < 0)
			fatal("%s: %s", special, strerror(errno));
		if (!mfs) {
			if (S_ISBLK(st.st_mode))
				fatal("%s: block device", special);
			if (!S_ISCHR(st.st_mode))
				warnx("%s: not a character-special device",
				    special);
		}
		if (*argv[0] == '\0')
			fatal("empty partition name supplied");
		cp = argv[0] + strlen(argv[0]) - 1;
		if ((*cp < 'a' || *cp > ('a' + maxpartitions - 1))
		    && !isdigit((unsigned char)*cp))
			fatal("%s: can't figure out file system partition",
			    argv[0]);
		lp = getdisklabel(special, fsi);
		if (!mfs) {
			if (pledge("stdio disklabel tty", NULL) == -1)
				err(1, "pledge");
		}
		if (isdigit((unsigned char)*cp))
			pp = &lp->d_partitions[0];
		else
			pp = &lp->d_partitions[*cp - 'a'];
		if (DL_GETPSIZE(pp) == 0)
			fatal("%s: `%c' partition is unavailable",
			    argv[0], *cp);
		if (pp->p_fstype == FS_BOOT)
			fatal("%s: `%c' partition overlaps boot program",
			      argv[0], *cp);
	}
havelabel:
	if (sectorsize == 0) {
		sectorsize = lp->d_secsize;
		if (sectorsize <= 0)
			fatal("%s: no default sector size", argv[0]);
	}

	if (fssize_usebytes) {
		nsecs = fssize_input / sectorsize;
		if (fssize_input % sectorsize != 0)
			nsecs++;
	} else if (fssize_input == 0)
		nsecs = DL_GETPSIZE(pp);
	else
		nsecs = fssize_input;

	if (nsecs > DL_GETPSIZE(pp) && !mfs)
	       fatal("%s: maximum file system size on the `%c' partition is "
		   "%llu sectors", argv[0], *cp, DL_GETPSIZE(pp));

	/* Can't use DL_SECTOBLK() because sectorsize may not be from label! */
	fssize = nsecs * (sectorsize / DEV_BSIZE);
	if (oflagset == 0 && fssize >= INT_MAX)
		Oflag = 2;	/* FFS2 */
	if (fsize == 0) {
		fsize = DISKLABELV1_FFS_FSIZE(pp->p_fragblock);
		if (fsize <= 0)
			fsize = MAXIMUM(DFL_FRAGSIZE, lp->d_secsize);
	}
	if (bsize == 0) {
		bsize = DISKLABELV1_FFS_BSIZE(pp->p_fragblock);
		if (bsize <= 0)
			bsize = MINIMUM(DFL_BLKSIZE, 8 * fsize);
	}
	if (density == 0)
		density = NFPI * fsize;
	if (minfree < MINFREE && opt != FS_OPTSPACE && reqopt == -1) {
		warnx("warning: changing optimization to space "
		    "because minfree is less than %d%%\n", MINFREE);
		opt = FS_OPTSPACE;
	}
	if (maxbpg == 0) {
		if (Oflag <= 1)
			maxbpg = MAXBLKPG_FFS1(bsize);
		else
			maxbpg = MAXBLKPG_FFS2(bsize);
	}
	oldpartition = *pp;
#ifdef MFS
	if (mfs) {
		if (realpath(argv[1], node) == NULL)
			err(1, "realpath %s", argv[1]);
		if (stat(node, &mountpoint) < 0)
			err(ECANCELED, "stat %s", node);
		mfsuid = mountpoint.st_uid;
		mfsgid = mountpoint.st_gid;
		mfsmode = mountpoint.st_mode & ALLPERMS;
	}
#endif

	mkfs(pp, special, fsi, fso, mfsmode, mfsuid, mfsgid);
	if (!Nflag && memcmp(pp, &oldpartition, sizeof(oldpartition)))
		rewritelabel(special, fso, lp);
	if (!Nflag)
		close(fso);
	close(fsi);
#ifdef MFS
	if (mfs) {
		struct mfs_args args;
		memset(&args, 0, sizeof(args));
		args.base = membase;
		args.size = fssize * DEV_BSIZE;
		args.export_info.ex_root = -2;
		if (mntflags & MNT_RDONLY)
			args.export_info.ex_flags = MNT_EXRDONLY;

		switch (pid = fork()) {
		case -1:
			err(10, "mfs");
		case 0:
			snprintf(mountfromname, sizeof(mountfromname),
			    "mfs:%d", getpid());
			break;
		default:
			snprintf(mountfromname, sizeof(mountfromname),
			    "mfs:%d", pid);
			for (;;) {
				/*
				 * spin until the mount succeeds
				 * or the child exits
				 */
				usleep(1);

				/*
				 * XXX Here is a race condition: another process
				 * can mount a filesystem which hides our
				 * ramdisk before we see the success.
				 */
				if (statfs(node, &sf) < 0)
					err(ECANCELED, "statfs %s", node);
				if (!strcmp(sf.f_mntfromname, mountfromname) &&
				    !strncmp(sf.f_mntonname, node,
					     MNAMELEN) &&
				    !strcmp(sf.f_fstypename, "mfs")) {
					if (pop != NULL)
						copy(pop, node, &args);
					exit(0);
				}
				res = waitpid(pid, &status, WNOHANG);
				if (res == -1)
					err(EDEADLK, "waitpid");
				if (res != pid)
					continue;
				if (WIFEXITED(status)) {
					if (WEXITSTATUS(status) == 0)
						exit(0);
					errx(1, "%s: mount: %s", node,
					     strerror(WEXITSTATUS(status)));
				} else
					errx(EDEADLK, "abnormal termination");
			}
			/* NOTREACHED */
		}

		(void) setsid();
		(void) close(0);
		(void) close(1);
		(void) close(2);
		(void) chdir("/");

		args.fspec = mountfromname;
		if (mntflags & MNT_RDONLY && pop != NULL)
			mntflags &= ~MNT_RDONLY;
		if (mount(MOUNT_MFS, node, mntflags, &args) < 0)
			exit(errno); /* parent prints message */
	}
#endif
	exit(0);
}
示例#23
0
/* main routine */
int
mount_udf_parseargs(int argc, char **argv,
	struct udf_args *args, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	uid_t	 anon_uid, nobody_uid;
	gid_t	 anon_gid, nobody_gid;
	int	 ch, set_gmtoff;
	uint32_t sector_size;
	mntoptparse_t mp;

	/* initialise */
	(void)memset(args, 0, sizeof(*args));

	set_gmtoff = *mntflags = 0;
	sector_size = 0;

	/* get nobody */
	nobody_uid = anon_uid = a_uid("nobody");
	nobody_gid = anon_gid = a_gid("nobody");

	while ((ch = getopt(argc, argv, "cg:o:s:t:u:")) != -1) {
		switch (ch) {
#ifdef notyet
		case 'c' :
			args->udfmflags |= UDFMNT_CLOSESESSION;
			break;
#endif
		case 'g' :
			/* convert groupname or numeric equiv. */
			anon_gid = a_gid(optarg);
			break;
		case 'u' :
			/* convert username or numeric equiv. */
			anon_uid = a_uid(optarg);
			break;
		case 'o' :
			/* process generic mount options */
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL) {
				warn("getmntopts");
				return 1;
			}
			freemntopts(mp);
			break;
		case 's' :
			args->sessionnr = a_num(optarg, "session number");
			break;
		case 't' :
			args->gmtoff = a_num(optarg, "gmtoff");
			set_gmtoff  = 1;
			break;
		default  :
			return 1;
			/* NOTREACHED */
		}
	}

	if (optind + 2 != argc)
		return 1;

	if (!set_gmtoff) {
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
		time_t	 now;
		struct tm *tm;

		/* use user's time zone as default */
		(void)time(&now);
		tm = localtime(&now);
		args->gmtoff = tm->tm_gmtoff;
#else
		args->gmtoff = 0;
#endif
	}

	/* get device and directory specifier */
	pathadj(argv[optind], canon_dev);
	pathadj(argv[optind+1], canon_dir);

	args->version = UDFMNT_VERSION;
	args->fspec = canon_dev;
	args->anon_uid    = anon_uid;
	args->anon_gid    = anon_gid;
	args->nobody_uid  = nobody_uid;
	args->nobody_gid  = nobody_gid;
	args->sector_size = sector_size;		/* invalid */

	return 0;
}
示例#24
0
int
main(int argc, char *argv[])
{
	struct iovec *iov;
	unsigned int iovlen;
	struct smb_ctx sctx, *ctx = &sctx;
	struct stat st;
#ifdef APPLE
	extern void dropsuid();
	extern int loadsmbvfs();
#else
	struct xvfsconf vfc;
#endif
	char *next, *p, *val;
	int opt, error, mntflags, caseopt, fd;
	uid_t uid;
	gid_t gid;
	mode_t dir_mode, file_mode;
	char errmsg[255] = { 0 };

	iov = NULL;
	iovlen = 0;
	fd = 0;
	uid = (uid_t)-1;
	gid = (gid_t)-1;
	caseopt = 0;
	file_mode = 0;
	dir_mode = 0;

#ifdef APPLE
	dropsuid();
#endif
	if (argc == 2) {
		if (strcmp(argv[1], "-h") == 0) {
			usage();
		}
	}
	if (argc < 3)
		usage();

#ifdef APPLE
	error = loadsmbvfs();
#else
	error = getvfsbyname(smbfs_vfsname, &vfc);
	if (error) {
		if (kldload(smbfs_vfsname) < 0)
			err(EX_OSERR, "kldload(%s)", smbfs_vfsname);
		error = getvfsbyname(smbfs_vfsname, &vfc);
	}
#endif
	if (error)
		errx(EX_OSERR, "SMB filesystem is not available");

	if (smb_lib_init() != 0)
		exit(1);

	mntflags = error = 0;

	caseopt = SMB_CS_NONE;

	if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_DISK) != 0)
		exit(1);
	if (smb_ctx_readrc(ctx) != 0)
		exit(1);
	if (smb_rc)
		rc_close(smb_rc);

	while ((opt = getopt(argc, argv, STDPARAM_OPT"c:d:f:g:l:n:o:u:w:")) != -1) {
		switch (opt) {
		    case STDPARAM_ARGS:
			error = smb_ctx_opt(ctx, opt, optarg);
			if (error)
				exit(1);
			break;
		    case 'u': {
			struct passwd *pwd;

			pwd = isdigit(optarg[0]) ?
			    getpwuid(atoi(optarg)) : getpwnam(optarg);
			if (pwd == NULL)
				errx(EX_NOUSER, "unknown user '%s'", optarg);
			uid = pwd->pw_uid;
			break;
		    }
		    case 'g': {
			struct group *grp;

			grp = isdigit(optarg[0]) ?
			    getgrgid(atoi(optarg)) : getgrnam(optarg);
			if (grp == NULL)
				errx(EX_NOUSER, "unknown group '%s'", optarg);
			gid = grp->gr_gid;
			break;
		    }
		    case 'd':
			errno = 0;
			dir_mode = strtol(optarg, &next, 8);
			if (errno || *next != 0)
				errx(EX_DATAERR, "invalid value for directory mode");
			break;
		    case 'f':
			errno = 0;
			file_mode = strtol(optarg, &next, 8);
			if (errno || *next != 0)
				errx(EX_DATAERR, "invalid value for file mode");
			break;
		    case '?':
			usage();
			/*NOTREACHED*/
		    case 'n': {
			char *inp, *nsp;

			nsp = inp = optarg;
			while ((nsp = strsep(&inp, ",;:")) != NULL) {
				if (strcasecmp(nsp, "LONG") == 0) {
					build_iovec(&iov, &iovlen,
					    "nolong", NULL, 0);
				} else {
					errx(EX_DATAERR,
					    "unknown suboption '%s'", nsp);
				}
			}
			break;
		    };
		    case 'o':
			getmntopts(optarg, mopts, &mntflags, 0);
			p = strchr(optarg, '=');
			val = NULL;
			if (p != NULL) {
				*p = '\0';
				val = p + 1;
			}
			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
			break;
		    case 'c':
			switch (optarg[0]) {
			    case 'l':
				caseopt |= SMB_CS_LOWER;
				break;
			    case 'u':
				caseopt |= SMB_CS_UPPER;
				break;
			    default:
		    		errx(EX_DATAERR, "invalid suboption '%c' for -c",
				    optarg[0]);
			}
			break;
		    default:
			usage();
		}
	}

	if (optind == argc - 2)
		optind++;
	
	if (optind != argc - 1)
		usage();
	realpath(argv[optind], mount_point);

	if (stat(mount_point, &st) == -1)
		err(EX_OSERR, "could not find mount point %s", mount_point);
	if (!S_ISDIR(st.st_mode)) {
		errno = ENOTDIR;
		err(EX_OSERR, "can't mount on %s", mount_point);
	}
/*
	if (smb_getextattr(mount_point, &einfo) == 0)
		errx(EX_OSERR, "can't mount on %s twice", mount_point);
*/
	if (uid == (uid_t)-1)
		uid = st.st_uid;
	if (gid == (gid_t)-1)
		gid = st.st_gid;
	if (file_mode == 0 )
		file_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
	if (dir_mode == 0) {
		dir_mode = file_mode;
		if (dir_mode & S_IRUSR)
			dir_mode |= S_IXUSR;
		if (dir_mode & S_IRGRP)
			dir_mode |= S_IXGRP;
		if (dir_mode & S_IROTH)
			dir_mode |= S_IXOTH;
	}
	/*
	 * For now, let connection be private for this mount
	 */
	ctx->ct_ssn.ioc_opt |= SMBVOPT_PRIVATE;
	ctx->ct_ssn.ioc_owner = ctx->ct_sh.ioc_owner = 0; /* root */
	ctx->ct_ssn.ioc_group = ctx->ct_sh.ioc_group = gid;
	opt = 0;
	if (dir_mode & S_IXGRP)
		opt |= SMBM_EXECGRP;
	if (dir_mode & S_IXOTH)
		opt |= SMBM_EXECOTH;
	ctx->ct_ssn.ioc_rights |= opt;
	ctx->ct_sh.ioc_rights |= opt;
	error = smb_ctx_resolve(ctx);
	if (error)
		exit(1);
	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
	if (error) {
		exit(1);
	}

	fd = ctx->ct_fd;

	build_iovec(&iov, &iovlen, "fstype", strdup("smbfs"), -1);
	build_iovec(&iov, &iovlen, "fspath", mount_point, -1);
	build_iovec_argf(&iov, &iovlen, "fd", "%d", fd);
	build_iovec(&iov, &iovlen, "mountpoint", mount_point, -1);
	build_iovec_argf(&iov, &iovlen, "uid", "%d", uid);
	build_iovec_argf(&iov, &iovlen, "gid", "%d", gid);
	build_iovec_argf(&iov, &iovlen, "file_mode", "%d", file_mode);
	build_iovec_argf(&iov, &iovlen, "dir_mode", "%d", dir_mode);
	build_iovec_argf(&iov, &iovlen, "caseopt", "%d", caseopt);
	build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof errmsg); 

	error = nmount(iov, iovlen, mntflags);
	smb_ctx_done(ctx);
	if (error) {
		smb_error("mount error: %s %s", error, mount_point, errmsg);
		exit(1);
	}
	return 0;
}
示例#25
0
void
mount_ntfs_parseargs(int argc, char **argv,
	struct ntfs_args *args, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	struct stat sb;
	int c, set_gid, set_uid, set_mask;
	char *dev, *dir;
	mntoptparse_t mp;

	*mntflags = set_gid = set_uid = set_mask = 0;
	(void)memset(args, '\0', sizeof(*args));

	while ((c = getopt(argc, argv, "aiu:g:m:o:")) !=  -1) {
		switch (c) {
		case 'u':
			args->uid = a_uid(optarg);
			set_uid = 1;
			break;
		case 'g':
			args->gid = a_gid(optarg);
			set_gid = 1;
			break;
		case 'm':
			args->mode = a_mask(optarg);
			set_mask = 1;
			break;
		case 'i':
			args->flag |= NTFS_MFLAG_CASEINS;
			break;
		case 'a':
			args->flag |= NTFS_MFLAG_ALLNAMES;
			break;
		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case '?':
		default:
			usage();
			break;
		}
	}

	if (optind + 2 != argc)
		usage();

	dev = argv[optind];
	dir = argv[optind + 1];

	pathadj(dev, canon_dev);
	pathadj(dir, canon_dir);

	args->fspec = dev;
	if (!set_gid || !set_uid || !set_mask) {
		if (stat(dir, &sb) == -1)
			err(EX_OSERR, "stat %s", dir);

		if (!set_uid)
			args->uid = sb.st_uid;
		if (!set_gid)
			args->gid = sb.st_gid;
		if (!set_mask)
			args->mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
	}
}
示例#26
0
int main( int argc, char **argv ) {
	struct iovec *iov;
	int iovlen;
	int ch, mntflags;
	char *dev, *dir, *p, *val, mntpath[MAXPATHLEN];
	int verbose;
	int ssector;
	char fstype[] = "cd9660";
	iov = NULL;
	iovlen = 0;
	mntflags = verbose = 0;
	ssector = -1;
	while ( ( ch = getopt( argc, argv, "begjo:rs:vC:" ) ) != -1 )
		switch ( ch ) {
			case 'b':
				build_iovec( &iov, &iovlen, "brokenjoliet", NULL, ( size_t ) - 1 );
				break;
			case 'e':
				build_iovec( &iov, &iovlen, "extatt", NULL, ( size_t ) - 1 );
				break;
			case 'g':
				build_iovec( &iov, &iovlen, "gens", NULL, ( size_t ) - 1 );
				break;
			case 'j':
				build_iovec( &iov, &iovlen, "nojoliet", NULL, ( size_t ) - 1 );
				break;
			case 'o':
				getmntopts( optarg, mopts, &mntflags, NULL );
				p = strchr( optarg, '=' );
				val = NULL;
				if ( p != NULL ) {
					*p = '\0';
					val = p + 1;
				}
				build_iovec( &iov, &iovlen, optarg, val, ( size_t ) - 1 );
				break;
			case 'r':
				build_iovec( &iov, &iovlen, "norrip", NULL, ( size_t ) - 1 );
				break;
			case 's':
				ssector = atoi( optarg );
				break;
			case 'v':
				verbose++;
				break;
			case 'C':
				if ( set_charset( &iov, &iovlen, optarg ) == -1 ) err( EX_OSERR, "cd9660_iconv" );
				build_iovec( &iov, &iovlen, "kiconv", NULL, ( size_t ) - 1 );
				break;
			case '?':
			default:
				usage();
		}
	argc -= optind;
	argv += optind;
	if ( argc != 2 ) usage();
	dev = argv[0];
	dir = argv[1];
	if ( checkpath( dir, mntpath ) != 0 ) err( 1, "%s", mntpath );
	(void) rmslashes( dev, dev );
	if ( ssector == -1 ) {
		if ( ( ssector = get_ssector( dev ) ) == -1 ) {
			if ( verbose ) printf( "could not determine starting sector, "
					"using very first session\n" );
			ssector = 0;
		} else if ( verbose ) printf( "using starting sector %d\n", ssector );
	}
	mntflags |= MNT_RDONLY;
	build_iovec( &iov, &iovlen, "fstype", fstype, ( size_t ) - 1 );
	build_iovec( &iov, &iovlen, "fspath", mntpath, ( size_t ) - 1 );
	build_iovec( &iov, &iovlen, "from", dev, ( size_t ) - 1 );
	build_iovec_argf( &iov, &iovlen, "ssector", "%d", ssector );
	if ( nmount( iov, iovlen, mntflags ) < 0 ) err( 1, "%s", dev );
	exit( 0 );
}
示例#27
0
文件: mount.c 项目: joushou/mac9p
int
main(int argc, char *argv[])
{
    struct vfsconf vfc;
    mntoptparse_t mp;
    struct stat st;
    char *name, *srv, *p;
    char *port, *asrv, *aport;
    char mntpath[MAXPATHLEN];
    char pass[NAMELEN], akey[DESKEYLEN];
    int mntflags, altflags, noauth, c;

    getmnt_silent = 0;
    mntflags = 0;
    altflags = 0;
    pass[0] = '\0';
    port = "564";
    asrv = NULL;
    aport = "567";
    noauth = 0;
    while ((c=getopt(argc, argv, "ho:")) != -1) {
        switch(c) {
        case 'o':
            altflags = 0;
            mp = getmntopts(optarg, mopts, &mntflags, &altflags);
            if (mp == NULL)
                err(EX_USAGE, "getmntopts: %s", optarg);
            if (altflags & ALTF_UNAME)
                args.uname = egetmntoptstr(mp, "uname");
            if (altflags & ALTF_ANAME)
                args.aname = egetmntoptstr(mp, "aname");
            if (altflags & ALTF_VOLUME)
                args.volume = egetmntoptstr(mp, "volume");
            if (altflags & ALTF_PASS) {
                p = egetmntoptstr(mp, "pass");
                strlcpy(pass, p, NAMELEN);
            }
            if (altflags & ALTF_PORT)
                port = egetmntoptstr(mp, "port");
            if (altflags & ALTF_ASRV)
                asrv = egetmntoptstr(mp, "asrv");
            if (altflags & ALTF_APORT)
                aport = egetmntoptstr(mp, "aport");
            if (altflags & ALTF_NOAUTH)
                noauth = 1;
            /* flags */
            if (altflags & ALTF_CHATTY9P)
                args.flags |= FLAG_CHATTY9P;
            if (altflags & ALTF_DSSTORE)
                args.flags &= ~FLAG_DSSTORE;
            if (altflags & ALTF_DOTU)
                args.flags |= FLAG_DOTU;
            freemntopts(mp);
            break;
        default:
Usage:
            fprintf(stderr, "Usage: mount_%s [-o options] srv node\n", VFS9PNAME);
            exit(EX_USAGE);
        }
    }
    argc -= optind;
    argv += optind;
    if (argc != 2)
        goto Usage;

    srv = *argv++;
    name = *argv;

    // check path
    if (!realpath(name, mntpath) || stat(mntpath, &st)<0)
        err(EX_USAGE, "%s", mntpath);
    if (!S_ISDIR(st.st_mode)) {
        errno = ENOTDIR;
        err(EX_USAGE, "%s", mntpath);
    }

    if (*srv == '/')
        noauth++;

    getaddr(&args.addr, &args.addrlen, srv, port);
    if (!noauth) {
        if (asrv == NULL)
            asrv = srv;
        getaddr(&args.authaddr, &args.authaddrlen, asrv, aport);
        if (*pass == '\0') {
            if (!readpassphrase("Password: "******"USER");
    if (!args.uname)
        args.uname = "none";

    args.spec = srv;
    if (getvfsbyname(VFS9PNAME, &vfc) < 0) {
        if (load9p() < 0)
            err(1, NULL);
        if (getvfsbyname(VFS9PNAME, &vfc) < 0)
            errx(EX_UNAVAILABLE, "%s filesystem is not available", VFS9PNAME);
    }
    if (mount(vfc.vfc_name, mntpath, mntflags, &args) < 0)
        err(1, "mount %s %s", srv, mntpath);
    return 0;
}
示例#28
0
void
mount_cd9660_parseargs(int argc, char **argv,
	struct iso_args *args, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	int ch, opts;
	mntoptparse_t mp;
	char *dev, *dir;

	*mntflags = opts = 0;
	memset(args, 0, sizeof(*args));
	while ((ch = getopt(argc, argv, "egijo:r")) != -1)
		switch (ch) {
		case 'e':
			/* obsolete, retained for compatibility only, use
			 * -o extatt */
			opts |= ISOFSMNT_EXTATT;
			break;
		case 'g':
			/* obsolete, retained for compatibility only, use
			 * -o gens */
			opts |= ISOFSMNT_GENS;
			break;
		case 'j':
			/* obsolete, retained fo compatibility only, use
			 * -o nojoliet */
			opts |= ISOFSMNT_NOJOLIET;
			break;
		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, &opts);
			if (mp == NULL)
				err(1, "getmntopts");
			freemntopts(mp);
			break;
		case 'r':
			/* obsolete, retained for compatibility only, use
			 * -o norrip */
			opts |= ISOFSMNT_NORRIP;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	dev = argv[0];
	dir = argv[1];

	pathadj(dev, canon_dev);
	pathadj(dir, canon_dir);

#define DEFAULT_ROOTUID	-2
	/*
	 * ISO 9660 filesystems are not writable.
	 */
	*mntflags |= MNT_RDONLY;
	args->fspec = dev;
	args->flags = opts;
}
示例#29
0
void
mount_tmpfs_parseargs(int argc, char *argv[],
	struct tmpfs_args *args, int *mntflags,
	char *canon_dev, char *canon_dir)
{
	int gidset, modeset, uidset; /* Ought to be 'bool'. */
	int ch;
	gid_t gid;
	uid_t uid;
	mode_t mode;
	int64_t tmpnumber;
	mntoptparse_t mp;
	struct stat sb;

	/* Set default values for mount point arguments. */
	memset(args, 0, sizeof(*args));
	args->ta_version = TMPFS_ARGS_VERSION;
	args->ta_size_max = 0;
	args->ta_nodes_max = 0;
	*mntflags = 0;

	gidset = 0; gid = 0;
	uidset = 0; uid = 0;
	modeset = 0; mode = 0;

	optind = optreset = 1;
	while ((ch = getopt(argc, argv, "g:m:n:o:s:u:")) != -1 ) {
		switch (ch) {
		case 'g':
			gid = a_gid(optarg);
			gidset = 1;
			break;

		case 'm':
			mode = a_mask(optarg);
			modeset = 1;
			break;

		case 'n':
			if (dehumanize_number(optarg, &tmpnumber) == -1)
				err(EXIT_FAILURE, "failed to parse nodes `%s'",
				    optarg);
			args->ta_nodes_max = tmpnumber;
			break;

		case 'o':
			mp = getmntopts(optarg, mopts, mntflags, 0);
			if (mp == NULL)
				err(EXIT_FAILURE, "getmntopts");
			freemntopts(mp);
			break;

		case 's':
			if (dehumanize_number(optarg, &tmpnumber) == -1)
				err(EXIT_FAILURE, "failed to parse size `%s'",
				    optarg);
			args->ta_size_max = tmpnumber;
			break;

		case 'u':
			uid = a_uid(optarg);
			uidset = 1;
			break;

		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	strlcpy(canon_dev, argv[0], MAXPATHLEN);
	pathadj(argv[1], canon_dir);

	if (stat(canon_dir, &sb) == -1)
		err(EXIT_FAILURE, "cannot stat `%s'", canon_dir);

	args->ta_root_uid = uidset ? uid : sb.st_uid;
	args->ta_root_gid = gidset ? gid : sb.st_gid;
	args->ta_root_mode = modeset ? mode : sb.st_mode;
}
示例#30
0
int
main(int argc, char **argv)
{
	struct iovec *iov;
	int iovlen;
	int ch, mntflags;
	char *dev, *dir, *p, *val, mntpath[MAXPATHLEN];
	int verbose;
	int ssector;		/* starting sector, 0 for 1st session */
	char fstype[] = "cd9660";

	iov = NULL;
	iovlen = 0;
	mntflags = verbose = 0;
	ssector = -1;

	while ((ch = getopt(argc, argv, "begjo:rs:vC:")) != -1)
		switch (ch) {
		case 'b':
			build_iovec(&iov, &iovlen, "brokenjoliet", NULL, (size_t)-1);
			break;
		case 'e':
			build_iovec(&iov, &iovlen, "extatt", NULL, (size_t)-1);
			break;
		case 'g':
			build_iovec(&iov, &iovlen, "gens", NULL, (size_t)-1);
			break;
		case 'j':
			build_iovec(&iov, &iovlen, "nojoliet", NULL, (size_t)-1);
			break;
		case 'o':
			getmntopts(optarg, mopts, &mntflags, NULL);
			p = strchr(optarg, '=');
			val = NULL;
			if (p != NULL) {
				*p = '\0';
				val = p + 1;
			}
			build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
			break;
		case 'r':
			build_iovec(&iov, &iovlen, "norrip", NULL, (size_t)-1);
			break;
		case 's':
			ssector = atoi(optarg);
			break;
		case 'v':
			verbose++;
			break;
		case 'C':
			if (set_charset(&iov, &iovlen, optarg) == -1)
				err(EX_OSERR, "cd9660_iconv");
			build_iovec(&iov, &iovlen, "kiconv", NULL, (size_t)-1);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 2)
		usage();

	dev = argv[0];
	dir = argv[1];

	/*
	 * Resolve the mountpoint with realpath(3) and remove unnecessary
	 * slashes from the devicename if there are any.
	 */
	if (checkpath(dir, mntpath) != 0)
		err(1, "%s", mntpath);
	(void)rmslashes(dev, dev);

	if (ssector == -1) {
		/*
		 * The start of the session has not been specified on
		 * the command line.  If we can successfully read the
		 * TOC of a CD-ROM, use the last data track we find.
		 * Otherwise, just use 0, in order to mount the very
		 * first session.  This is compatible with the
		 * historic behaviour of mount_cd9660(8).  If the user
		 * has specified -s <ssector> above, we don't get here
		 * and leave the user's will.
		 */
		if ((ssector = get_ssector(dev)) == -1) {
			if (verbose)
				printf("could not determine starting sector, "
				       "using very first session\n");
			ssector = 0;
		} else if (verbose)
			printf("using starting sector %d\n", ssector);
	}
	mntflags |= MNT_RDONLY;
	build_iovec(&iov, &iovlen, "fstype", fstype, (size_t)-1);
	build_iovec(&iov, &iovlen, "fspath", mntpath, (size_t)-1);
	build_iovec(&iov, &iovlen, "from", dev, (size_t)-1);
	build_iovec_argf(&iov, &iovlen, "ssector", "%d", ssector);

	if (nmount(iov, iovlen, mntflags) < 0)
		err(1, "%s", dev);
	exit(0);
}