[Glibc-bsd-commits] r3557 - in trunk: . fuse4bsd fuse4bsd/debian fuse4bsd/debian/patches fuse4bsd/debian/source
Robert Millan
rmh at alioth.debian.org
Sun Jul 10 22:15:33 UTC 2011
Author: rmh
Date: 2011-07-10 22:15:33 +0000 (Sun, 10 Jul 2011)
New Revision: 3557
Added:
trunk/fuse4bsd/
trunk/fuse4bsd/debian/
trunk/fuse4bsd/debian/changelog
trunk/fuse4bsd/debian/compat
trunk/fuse4bsd/debian/control
trunk/fuse4bsd/debian/fuse-dkms.dkms
trunk/fuse4bsd/debian/fuse4bsd.dirs
trunk/fuse4bsd/debian/fuse4bsd.install
trunk/fuse4bsd/debian/fuse4bsd.manpages
trunk/fuse4bsd/debian/patches/
trunk/fuse4bsd/debian/patches/000_sbin_mount.diff
trunk/fuse4bsd/debian/patches/001_ports.diff
trunk/fuse4bsd/debian/patches/002_misc.diff
trunk/fuse4bsd/debian/patches/003_kernel_api.diff
trunk/fuse4bsd/debian/patches/004_freebsd_macro.diff
trunk/fuse4bsd/debian/patches/007_mount.diff
trunk/fuse4bsd/debian/patches/series
trunk/fuse4bsd/debian/rules
trunk/fuse4bsd/debian/source/
trunk/fuse4bsd/debian/source/format
Log:
Import preliminar fuse4bsd package
Added: trunk/fuse4bsd/debian/changelog
===================================================================
--- trunk/fuse4bsd/debian/changelog (rev 0)
+++ trunk/fuse4bsd/debian/changelog 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,5 @@
+fuse4bsd (0.3.9~pre1.20080208-1) UNRELEASED; urgency=low
+
+ * Initial release. (Closes: #613300)
+
+ -- Robert Millan <rmh at debian.org> Sat, 25 Jun 2011 20:28:11 +0200
Added: trunk/fuse4bsd/debian/compat
===================================================================
--- trunk/fuse4bsd/debian/compat (rev 0)
+++ trunk/fuse4bsd/debian/compat 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1 @@
+7
Added: trunk/fuse4bsd/debian/control
===================================================================
--- trunk/fuse4bsd/debian/control (rev 0)
+++ trunk/fuse4bsd/debian/control 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,30 @@
+Source: fuse4bsd
+Section: libs
+Priority: optional
+Maintainer: GNU/kFreeBSD Maintainers <debian-bsd at lists.debian.org>
+Uploaders: Robert Millan <rmh at debian.org>
+Build-Depends: debhelper (>= 7), po-debconf,
+ freebsd-buildutils,
+ libbsd-dev,
+ dkms (>= 2.1.1.2-6.FIXME),
+# for MNT_NFS4ACLS
+ libc0.1-dev (>= 2.13-6),
+Standards-Version: 3.9.2
+
+Package: fuse4bsd
+Section: utils
+Architecture: kfreebsd-any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Recommends: fuse-dkms
+Description: Filesystem in USErspace (utilities)
+ Simple interface for userspace programs to export a virtual
+ filesystem to kFreeBSD.
+ .
+ This package contains the fusermount utility which is necessary to
+ mount fuse filesystems.
+
+Package: fuse-dkms
+Architecture: all
+Depends: ${shlibs:Depends}, ${misc:Depends}, dkms
+Description: FUSE module for kFreeBSD
+ This package provides FUSE module for kernel of FreeBSD.
Added: trunk/fuse4bsd/debian/fuse-dkms.dkms
===================================================================
--- trunk/fuse4bsd/debian/fuse-dkms.dkms (rev 0)
+++ trunk/fuse4bsd/debian/fuse-dkms.dkms 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,8 @@
+PACKAGE_NAME="fuse"
+PACKAGE_VERSION="#MODULE_VERSION#"
+MAKE[0]="PATH=/usr/lib/freebsd:$PATH WERROR= make -C fuse_module"
+CLEAN="PATH=/usr/lib/freebsd:$PATH make clean"
+BUILT_MODULE_NAME[0]="fuse"
+BUILT_MODULE_LOCATION[0]="fuse_module/"
+DEST_MODULE_LOCATION[0]="/extra"
+AUTOINSTALL="yes"
Added: trunk/fuse4bsd/debian/fuse4bsd.dirs
===================================================================
--- trunk/fuse4bsd/debian/fuse4bsd.dirs (rev 0)
+++ trunk/fuse4bsd/debian/fuse4bsd.dirs 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1 @@
+usr/bin
Added: trunk/fuse4bsd/debian/fuse4bsd.install
===================================================================
--- trunk/fuse4bsd/debian/fuse4bsd.install (rev 0)
+++ trunk/fuse4bsd/debian/fuse4bsd.install 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1 @@
+mount_fusefs/mount_fusefs /usr/bin
Added: trunk/fuse4bsd/debian/fuse4bsd.manpages
===================================================================
--- trunk/fuse4bsd/debian/fuse4bsd.manpages (rev 0)
+++ trunk/fuse4bsd/debian/fuse4bsd.manpages 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1 @@
+mount_fusefs/mount_fusefs.8
Added: trunk/fuse4bsd/debian/patches/000_sbin_mount.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/000_sbin_mount.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/000_sbin_mount.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,2302 @@
+
+Import FreeBSD mount.
+
+--- /dev/null
++++ b/sbin/mount/pathnames.h
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (c) 1989, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * @(#)pathnames.h 8.2 (Berkeley) 3/27/94
++ * $FreeBSD$
++ */
++
++#define _PATH_MOUNTDPID "/var/run/mountd.pid"
+--- /dev/null
++++ b/sbin/mount/vfslist.c
+@@ -0,0 +1,92 @@
++/*-
++ * Copyright (c) 1995
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#ifndef lint
++#if 0
++static char sccsid[] = "@(#)vfslist.c 8.1 (Berkeley) 5/8/95";
++#endif
++#endif /* not lint */
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
++
++#include <err.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "extern.h"
++
++static int skipvfs;
++
++int
++checkvfsname(vfsname, vfslist)
++ const char *vfsname;
++ const char **vfslist;
++{
++
++ if (vfslist == NULL)
++ return (0);
++ while (*vfslist != NULL) {
++ if (strcmp(vfsname, *vfslist) == 0)
++ return (skipvfs);
++ ++vfslist;
++ }
++ return (!skipvfs);
++}
++
++const char **
++makevfslist(fslist)
++ char *fslist;
++{
++ const char **av;
++ int i;
++ char *nextcp;
++
++ if (fslist == NULL)
++ return (NULL);
++ if (fslist[0] == 'n' && fslist[1] == 'o') {
++ fslist += 2;
++ skipvfs = 1;
++ }
++ for (i = 0, nextcp = fslist; *nextcp; nextcp++)
++ if (*nextcp == ',')
++ i++;
++ if ((av = malloc((size_t)(i + 2) * sizeof(char *))) == NULL) {
++ warnx("malloc failed");
++ return (NULL);
++ }
++ nextcp = fslist;
++ i = 0;
++ av[i++] = nextcp;
++ while ((nextcp = strchr(nextcp, ',')) != NULL) {
++ *nextcp++ = '\0';
++ av[i++] = nextcp;
++ }
++ av[i++] = NULL;
++ return (av);
++}
+--- /dev/null
++++ b/sbin/mount/mount.c
+@@ -0,0 +1,925 @@
++/*-
++ * Copyright (c) 1980, 1989, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#ifndef lint
++static const char copyright[] =
++"@(#) Copyright (c) 1980, 1989, 1993, 1994\n\
++ The Regents of the University of California. All rights reserved.\n";
++#if 0
++static char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95";
++#endif
++#endif /* not lint */
++
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
++
++#include <sys/param.h>
++#include <sys/mount.h>
++#include <sys/stat.h>
++#include <sys/wait.h>
++
++#include <ctype.h>
++#include <err.h>
++#include <errno.h>
++#include <fstab.h>
++#include <paths.h>
++#include <pwd.h>
++#include <signal.h>
++#include <stdint.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <libutil.h>
++
++#include "extern.h"
++#include "mntopts.h"
++#include "pathnames.h"
++
++/* `meta' options */
++#define MOUNT_META_OPTION_FSTAB "fstab"
++#define MOUNT_META_OPTION_CURRENT "current"
++
++int debug, fstab_style, verbose;
++
++struct cpa {
++ char **a;
++ ssize_t sz;
++ int c;
++};
++
++char *catopt(char *, const char *);
++struct statfs *getmntpt(const char *);
++int hasopt(const char *, const char *);
++int ismounted(struct fstab *, struct statfs *, int);
++int isremountable(const char *);
++void mangle(char *, struct cpa *);
++char *update_options(char *, char *, int);
++int mountfs(const char *, const char *, const char *,
++ int, const char *, const char *);
++void remopt(char *, const char *);
++void prmount(struct statfs *);
++void putfsent(struct statfs *);
++void usage(void);
++char *flags2opts(int);
++
++/* Map from mount options to printable formats. */
++static struct opt {
++ uint64_t o_opt;
++ const char *o_name;
++} optnames[] = {
++ { MNT_ASYNC, "asynchronous" },
++ { MNT_EXPORTED, "NFS exported" },
++ { MNT_LOCAL, "local" },
++ { MNT_NOATIME, "noatime" },
++ { MNT_NOEXEC, "noexec" },
++ { MNT_NOSUID, "nosuid" },
++ { MNT_NOSYMFOLLOW, "nosymfollow" },
++ { MNT_QUOTA, "with quotas" },
++ { MNT_RDONLY, "read-only" },
++ { MNT_SYNCHRONOUS, "synchronous" },
++ { MNT_UNION, "union" },
++ { MNT_NOCLUSTERR, "noclusterr" },
++ { MNT_NOCLUSTERW, "noclusterw" },
++ { MNT_SUIDDIR, "suiddir" },
++ { MNT_SOFTDEP, "soft-updates" },
++ { MNT_MULTILABEL, "multilabel" },
++ { MNT_ACLS, "acls" },
++ { MNT_NFS4ACLS, "nfsv4acls" },
++ { MNT_GJOURNAL, "gjournal" },
++ { 0, NULL }
++};
++
++/*
++ * List of VFS types that can be remounted without becoming mounted on top
++ * of each other.
++ * XXX Is this list correct?
++ */
++static const char *
++remountable_fs_names[] = {
++ "ufs", "ffs", "ext2fs",
++ 0
++};
++
++static const char userquotaeq[] = "userquota=";
++static const char groupquotaeq[] = "groupquota=";
++
++static char *mountprog = NULL;
++
++static int
++use_mountprog(const char *vfstype)
++{
++ /* XXX: We need to get away from implementing external mount
++ * programs for every filesystem, and move towards having
++ * each filesystem properly implement the nmount() system call.
++ */
++ unsigned int i;
++ const char *fs[] = {
++ "cd9660", "mfs", "msdosfs", "newnfs", "nfs", "ntfs",
++ "nwfs", "nullfs", "portalfs", "smbfs", "udf", "unionfs",
++ NULL
++ };
++
++ if (mountprog != NULL)
++ return (1);
++
++ for (i = 0; fs[i] != NULL; ++i) {
++ if (strcmp(vfstype, fs[i]) == 0)
++ return (1);
++ }
++
++ return (0);
++}
++
++static int
++exec_mountprog(const char *name, const char *execname, char *const argv[])
++{
++ pid_t pid;
++ int status;
++
++ switch (pid = fork()) {
++ case -1: /* Error. */
++ warn("fork");
++ exit (1);
++ case 0: /* Child. */
++ /* Go find an executable. */
++ execvP(execname, _PATH_SYSPATH, argv);
++ if (errno == ENOENT) {
++ warn("exec %s not found", execname);
++ if (execname[0] != '/') {
++ warnx("in path: %s", _PATH_SYSPATH);
++ }
++ }
++ exit(1);
++ default: /* Parent. */
++ if (waitpid(pid, &status, 0) < 0) {
++ warn("waitpid");
++ return (1);
++ }
++
++ if (WIFEXITED(status)) {
++ if (WEXITSTATUS(status) != 0)
++ return (WEXITSTATUS(status));
++ } else if (WIFSIGNALED(status)) {
++ warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]);
++ return (1);
++ }
++ break;
++ }
++
++ return (0);
++}
++
++static int
++specified_ro(const char *arg)
++{
++ char *optbuf, *opt;
++ int ret = 0;
++
++ optbuf = strdup(arg);
++ if (optbuf == NULL)
++ err(1, NULL);
++
++ for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
++ if (strcmp(opt, "ro") == 0) {
++ ret = 1;
++ break;
++ }
++ }
++ free(optbuf);
++ return (ret);
++}
++
++static void
++restart_mountd(void)
++{
++ struct pidfh *pfh;
++ pid_t mountdpid;
++
++ pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid);
++ if (pfh != NULL) {
++ /* Mountd is not running. */
++ pidfile_remove(pfh);
++ return;
++ }
++ if (errno != EEXIST) {
++ /* Cannot open pidfile for some reason. */
++ return;
++ }
++ /* We have mountd(8) PID in mountdpid varible, let's signal it. */
++ if (kill(mountdpid, SIGHUP) == -1)
++ err(1, "signal mountd");
++}
++
++int
++main(int argc, char *argv[])
++{
++ const char *mntfromname, **vfslist, *vfstype;
++ struct fstab *fs;
++ struct statfs *mntbuf;
++ int all, ch, i, init_flags, late, mntsize, rval, have_fstab, ro;
++ char *cp, *ep, *options;
++
++ all = init_flags = late = 0;
++ ro = 0;
++ options = NULL;
++ vfslist = NULL;
++ vfstype = "ufs";
++ while ((ch = getopt(argc, argv, "adF:flo:prt:uvw")) != -1)
++ switch (ch) {
++ case 'a':
++ all = 1;
++ break;
++ case 'd':
++ debug = 1;
++ break;
++ case 'F':
++ setfstab(optarg);
++ break;
++ case 'f':
++ init_flags |= MNT_FORCE;
++ break;
++ case 'l':
++ late = 1;
++ break;
++ case 'o':
++ if (*optarg) {
++ options = catopt(options, optarg);
++ if (specified_ro(optarg))
++ ro = 1;
++ }
++ break;
++ case 'p':
++ fstab_style = 1;
++ verbose = 1;
++ break;
++ case 'r':
++ options = catopt(options, "ro");
++ ro = 1;
++ break;
++ case 't':
++ if (vfslist != NULL)
++ errx(1, "only one -t option may be specified");
++ vfslist = makevfslist(optarg);
++ vfstype = optarg;
++ break;
++ case 'u':
++ init_flags |= MNT_UPDATE;
++ break;
++ case 'v':
++ verbose = 1;
++ break;
++ case 'w':
++ options = catopt(options, "noro");
++ break;
++ case '?':
++ default:
++ usage();
++ /* NOTREACHED */
++ }
++ argc -= optind;
++ argv += optind;
++
++#define BADTYPE(type) \
++ (strcmp(type, FSTAB_RO) && \
++ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))
++
++ if ((init_flags & MNT_UPDATE) && (ro == 0))
++ options = catopt(options, "noro");
++
++ rval = 0;
++ switch (argc) {
++ case 0:
++ if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
++ err(1, "getmntinfo");
++ if (all) {
++ while ((fs = getfsent()) != NULL) {
++ if (BADTYPE(fs->fs_type))
++ continue;
++ if (checkvfsname(fs->fs_vfstype, vfslist))
++ continue;
++ if (hasopt(fs->fs_mntops, "noauto"))
++ continue;
++ if (hasopt(fs->fs_mntops, "late") && !late)
++ continue;
++ if (!(init_flags & MNT_UPDATE) &&
++ ismounted(fs, mntbuf, mntsize))
++ continue;
++ options = update_options(options, fs->fs_mntops,
++ mntbuf->f_flags);
++ if (mountfs(fs->fs_vfstype, fs->fs_spec,
++ fs->fs_file, init_flags, options,
++ fs->fs_mntops))
++ rval = 1;
++ }
++ } else if (fstab_style) {
++ for (i = 0; i < mntsize; i++) {
++ if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
++ continue;
++ putfsent(&mntbuf[i]);
++ }
++ } else {
++ for (i = 0; i < mntsize; i++) {
++ if (checkvfsname(mntbuf[i].f_fstypename,
++ vfslist))
++ continue;
++ if (!verbose &&
++ (mntbuf[i].f_flags & MNT_IGNORE) != 0)
++ continue;
++ prmount(&mntbuf[i]);
++ }
++ }
++ exit(rval);
++ case 1:
++ if (vfslist != NULL)
++ usage();
++
++ rmslashes(*argv, *argv);
++ if (init_flags & MNT_UPDATE) {
++ mntfromname = NULL;
++ have_fstab = 0;
++ if ((mntbuf = getmntpt(*argv)) == NULL)
++ errx(1, "not currently mounted %s", *argv);
++ /*
++ * Only get the mntflags from fstab if both mntpoint
++ * and mntspec are identical. Also handle the special
++ * case where just '/' is mounted and 'spec' is not
++ * identical with the one from fstab ('/dev' is missing
++ * in the spec-string at boot-time).
++ */
++ if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) {
++ if (strcmp(fs->fs_spec,
++ mntbuf->f_mntfromname) == 0 &&
++ strcmp(fs->fs_file,
++ mntbuf->f_mntonname) == 0) {
++ have_fstab = 1;
++ mntfromname = mntbuf->f_mntfromname;
++ } else if (argv[0][0] == '/' &&
++ argv[0][1] == '\0') {
++ fs = getfsfile("/");
++ have_fstab = 1;
++ mntfromname = fs->fs_spec;
++ }
++ }
++ if (have_fstab) {
++ options = update_options(options, fs->fs_mntops,
++ mntbuf->f_flags);
++ } else {
++ mntfromname = mntbuf->f_mntfromname;
++ options = update_options(options, NULL,
++ mntbuf->f_flags);
++ }
++ rval = mountfs(mntbuf->f_fstypename, mntfromname,
++ mntbuf->f_mntonname, init_flags, options, 0);
++ break;
++ }
++ if ((fs = getfsfile(*argv)) == NULL &&
++ (fs = getfsspec(*argv)) == NULL)
++ errx(1, "%s: unknown special file or file system",
++ *argv);
++ if (BADTYPE(fs->fs_type))
++ errx(1, "%s has unknown file system type",
++ *argv);
++ rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file,
++ init_flags, options, fs->fs_mntops);
++ break;
++ case 2:
++ /*
++ * If -t flag has not been specified, the path cannot be
++ * found, spec contains either a ':' or a '@', then assume
++ * that an NFS file system is being specified ala Sun.
++ * Check if the hostname contains only allowed characters
++ * to reduce false positives. IPv6 addresses containing
++ * ':' will be correctly parsed only if the separator is '@'.
++ * The definition of a valid hostname is taken from RFC 1034.
++ */
++ if (vfslist == NULL && ((ep = strchr(argv[0], '@')) != NULL ||
++ (ep = strchr(argv[0], ':')) != NULL)) {
++ if (*ep == '@') {
++ cp = ep + 1;
++ ep = cp + strlen(cp);
++ } else
++ cp = argv[0];
++ while (cp != ep) {
++ if (!isdigit(*cp) && !isalpha(*cp) &&
++ *cp != '.' && *cp != '-' && *cp != ':')
++ break;
++ cp++;
++ }
++ if (cp == ep)
++ vfstype = "nfs";
++ }
++ rval = mountfs(vfstype,
++ argv[0], argv[1], init_flags, options, NULL);
++ break;
++ default:
++ usage();
++ /* NOTREACHED */
++ }
++
++ /*
++ * If the mount was successfully, and done by root, tell mountd the
++ * good news.
++ */
++ if (rval == 0 && getuid() == 0)
++ restart_mountd();
++
++ exit(rval);
++}
++
++int
++ismounted(struct fstab *fs, struct statfs *mntbuf, int mntsize)
++{
++ char realfsfile[PATH_MAX];
++ int i;
++
++ if (fs->fs_file[0] == '/' && fs->fs_file[1] == '\0')
++ /* the root file system can always be remounted */
++ return (0);
++
++ /* The user may have specified a symlink in fstab, resolve the path */
++ if (realpath(fs->fs_file, realfsfile) == NULL) {
++ /* Cannot resolve the path, use original one */
++ strlcpy(realfsfile, fs->fs_file, sizeof(realfsfile));
++ }
++
++ for (i = mntsize - 1; i >= 0; --i)
++ if (strcmp(realfsfile, mntbuf[i].f_mntonname) == 0 &&
++ (!isremountable(fs->fs_vfstype) ||
++ strcmp(fs->fs_spec, mntbuf[i].f_mntfromname) == 0))
++ return (1);
++ return (0);
++}
++
++int
++isremountable(const char *vfsname)
++{
++ const char **cp;
++
++ for (cp = remountable_fs_names; *cp; cp++)
++ if (strcmp(*cp, vfsname) == 0)
++ return (1);
++ return (0);
++}
++
++int
++hasopt(const char *mntopts, const char *option)
++{
++ int negative, found;
++ char *opt, *optbuf;
++
++ if (option[0] == 'n' && option[1] == 'o') {
++ negative = 1;
++ option += 2;
++ } else
++ negative = 0;
++ optbuf = strdup(mntopts);
++ found = 0;
++ for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
++ if (opt[0] == 'n' && opt[1] == 'o') {
++ if (!strcasecmp(opt + 2, option))
++ found = negative;
++ } else if (!strcasecmp(opt, option))
++ found = !negative;
++ }
++ free(optbuf);
++ return (found);
++}
++
++static void
++append_arg(struct cpa *sa, char *arg)
++{
++ if (sa->c + 1 == sa->sz) {
++ sa->sz = sa->sz == 0 ? 8 : sa->sz * 2;
++ sa->a = realloc(sa->a, sizeof(sa->a) * sa->sz);
++ if (sa->a == NULL)
++ errx(1, "realloc failed");
++ }
++ sa->a[++sa->c] = arg;
++}
++
++int
++mountfs(const char *vfstype, const char *spec, const char *name, int flags,
++ const char *options, const char *mntopts)
++{
++ struct statfs sf;
++ int i, ret;
++ char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX];
++ static struct cpa mnt_argv;
++
++ /* resolve the mountpoint with realpath(3) */
++ (void)checkpath(name, mntpath);
++ name = mntpath;
++
++ if (mntopts == NULL)
++ mntopts = "";
++ optbuf = catopt(strdup(mntopts), options);
++
++ if (strcmp(name, "/") == 0)
++ flags |= MNT_UPDATE;
++ if (flags & MNT_FORCE)
++ optbuf = catopt(optbuf, "force");
++ if (flags & MNT_RDONLY)
++ optbuf = catopt(optbuf, "ro");
++ /*
++ * XXX
++ * The mount_mfs (newfs) command uses -o to select the
++ * optimization mode. We don't pass the default "-o rw"
++ * for that reason.
++ */
++ if (flags & MNT_UPDATE)
++ optbuf = catopt(optbuf, "update");
++
++ /* Compatibility glue. */
++ if (strcmp(vfstype, "msdos") == 0) {
++ warnx(
++ "Using \"-t msdosfs\", since \"-t msdos\" is deprecated.");
++ vfstype = "msdosfs";
++ }
++
++ /* Construct the name of the appropriate mount command */
++ (void)snprintf(execname, sizeof(execname), "mount_%s", vfstype);
++
++ mnt_argv.c = -1;
++ append_arg(&mnt_argv, execname);
++ mangle(optbuf, &mnt_argv);
++ if (mountprog != NULL)
++ strcpy(execname, mountprog);
++
++ append_arg(&mnt_argv, strdup(spec));
++ append_arg(&mnt_argv, strdup(name));
++ append_arg(&mnt_argv, NULL);
++
++ if (debug) {
++ if (use_mountprog(vfstype))
++ printf("exec: %s", execname);
++ else
++ printf("mount -t %s", vfstype);
++ for (i = 1; i < mnt_argv.c; i++)
++ (void)printf(" %s", mnt_argv.a[i]);
++ (void)printf("\n");
++ return (0);
++ }
++
++ if (use_mountprog(vfstype)) {
++ ret = exec_mountprog(name, execname, mnt_argv.a);
++ } else {
++ ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a);
++ }
++
++ free(optbuf);
++
++ if (verbose) {
++ if (statfs(name, &sf) < 0) {
++ warn("statfs %s", name);
++ return (1);
++ }
++ if (fstab_style)
++ putfsent(&sf);
++ else
++ prmount(&sf);
++ }
++
++ return (ret);
++}
++
++void
++prmount(struct statfs *sfp)
++{
++ uint64_t flags;
++ unsigned int i;
++ struct opt *o;
++ struct passwd *pw;
++
++ (void)printf("%s on %s (%s", sfp->f_mntfromname, sfp->f_mntonname,
++ sfp->f_fstypename);
++
++ flags = sfp->f_flags & MNT_VISFLAGMASK;
++ for (o = optnames; flags != 0 && o->o_opt != 0; o++)
++ if (flags & o->o_opt) {
++ (void)printf(", %s", o->o_name);
++ flags &= ~o->o_opt;
++ }
++ /*
++ * Inform when file system is mounted by an unprivileged user
++ * or privileged non-root user.
++ */
++ if ((flags & MNT_USER) != 0 || sfp->f_owner != 0) {
++ (void)printf(", mounted by ");
++ if ((pw = getpwuid(sfp->f_owner)) != NULL)
++ (void)printf("%s", pw->pw_name);
++ else
++ (void)printf("%d", sfp->f_owner);
++ }
++ if (verbose) {
++ if (sfp->f_syncwrites != 0 || sfp->f_asyncwrites != 0)
++ (void)printf(", writes: sync %ju async %ju",
++ (uintmax_t)sfp->f_syncwrites,
++ (uintmax_t)sfp->f_asyncwrites);
++ if (sfp->f_syncreads != 0 || sfp->f_asyncreads != 0)
++ (void)printf(", reads: sync %ju async %ju",
++ (uintmax_t)sfp->f_syncreads,
++ (uintmax_t)sfp->f_asyncreads);
++ if (sfp->f_fsid.val[0] != 0 || sfp->f_fsid.val[1] != 0) {
++ printf(", fsid ");
++ for (i = 0; i < sizeof(sfp->f_fsid); i++)
++ printf("%02x", ((u_char *)&sfp->f_fsid)[i]);
++ }
++ }
++ (void)printf(")\n");
++}
++
++struct statfs *
++getmntpt(const char *name)
++{
++ struct statfs *mntbuf;
++ int i, mntsize;
++
++ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
++ for (i = mntsize - 1; i >= 0; i--) {
++ if (strcmp(mntbuf[i].f_mntfromname, name) == 0 ||
++ strcmp(mntbuf[i].f_mntonname, name) == 0)
++ return (&mntbuf[i]);
++ }
++ return (NULL);
++}
++
++char *
++catopt(char *s0, const char *s1)
++{
++ size_t i;
++ char *cp;
++
++ if (s1 == NULL || *s1 == '\0')
++ return (s0);
++
++ if (s0 && *s0) {
++ i = strlen(s0) + strlen(s1) + 1 + 1;
++ if ((cp = malloc(i)) == NULL)
++ errx(1, "malloc failed");
++ (void)snprintf(cp, i, "%s,%s", s0, s1);
++ } else
++ cp = strdup(s1);
++
++ if (s0)
++ free(s0);
++ return (cp);
++}
++
++void
++mangle(char *options, struct cpa *a)
++{
++ char *p, *s, *val;
++
++ for (s = options; (p = strsep(&s, ",")) != NULL;)
++ if (*p != '\0') {
++ if (strcmp(p, "noauto") == 0) {
++ /*
++ * Do not pass noauto option to nmount().
++ * or external mount program. noauto is
++ * only used to prevent mounting a filesystem
++ * when 'mount -a' is specified, and is
++ * not a real mount option.
++ */
++ continue;
++ } else if (strcmp(p, "late") == 0) {
++ /*
++ * "late" is used to prevent certain file
++ * systems from being mounted before late
++ * in the boot cycle; for instance,
++ * loopback NFS mounts can't be mounted
++ * before mountd starts.
++ */
++ continue;
++ } else if (strncmp(p, "mountprog", 9) == 0) {
++ /*
++ * "mountprog" is used to force the use of
++ * userland mount programs.
++ */
++ val = strchr(p, '=');
++ if (val != NULL) {
++ ++val;
++ if (*val != '\0')
++ mountprog = strdup(val);
++ }
++
++ if (mountprog == NULL) {
++ errx(1, "Need value for -o mountprog");
++ }
++ continue;
++ } else if (strcmp(p, "userquota") == 0) {
++ continue;
++ } else if (strncmp(p, userquotaeq,
++ sizeof(userquotaeq) - 1) == 0) {
++ continue;
++ } else if (strcmp(p, "groupquota") == 0) {
++ continue;
++ } else if (strncmp(p, groupquotaeq,
++ sizeof(groupquotaeq) - 1) == 0) {
++ continue;
++ } else if (*p == '-') {
++ append_arg(a, p);
++ p = strchr(p, '=');
++ if (p != NULL) {
++ *p = '\0';
++ append_arg(a, p + 1);
++ }
++ } else {
++ append_arg(a, strdup("-o"));
++ append_arg(a, p);
++ }
++ }
++}
++
++
++char *
++update_options(char *opts, char *fstab, int curflags)
++{
++ char *o, *p;
++ char *cur;
++ char *expopt, *newopt, *tmpopt;
++
++ if (opts == NULL)
++ return (strdup(""));
++
++ /* remove meta options from list */
++ remopt(fstab, MOUNT_META_OPTION_FSTAB);
++ remopt(fstab, MOUNT_META_OPTION_CURRENT);
++ cur = flags2opts(curflags);
++
++ /*
++ * Expand all meta-options passed to us first.
++ */
++ expopt = NULL;
++ for (p = opts; (o = strsep(&p, ",")) != NULL;) {
++ if (strcmp(MOUNT_META_OPTION_FSTAB, o) == 0)
++ expopt = catopt(expopt, fstab);
++ else if (strcmp(MOUNT_META_OPTION_CURRENT, o) == 0)
++ expopt = catopt(expopt, cur);
++ else
++ expopt = catopt(expopt, o);
++ }
++ free(cur);
++ free(opts);
++
++ /*
++ * Remove previous contradictory arguments. Given option "foo" we
++ * remove all the "nofoo" options. Given "nofoo" we remove "nonofoo"
++ * and "foo" - so we can deal with possible options like "notice".
++ */
++ newopt = NULL;
++ for (p = expopt; (o = strsep(&p, ",")) != NULL;) {
++ if ((tmpopt = malloc( strlen(o) + 2 + 1 )) == NULL)
++ errx(1, "malloc failed");
++
++ strcpy(tmpopt, "no");
++ strcat(tmpopt, o);
++ remopt(newopt, tmpopt);
++ free(tmpopt);
++
++ if (strncmp("no", o, 2) == 0)
++ remopt(newopt, o+2);
++
++ newopt = catopt(newopt, o);
++ }
++ free(expopt);
++
++ return (newopt);
++}
++
++void
++remopt(char *string, const char *opt)
++{
++ char *o, *p, *r;
++
++ if (string == NULL || *string == '\0' || opt == NULL || *opt == '\0')
++ return;
++
++ r = string;
++
++ for (p = string; (o = strsep(&p, ",")) != NULL;) {
++ if (strcmp(opt, o) != 0) {
++ if (*r == ',' && *o != '\0')
++ r++;
++ while ((*r++ = *o++) != '\0')
++ ;
++ *--r = ',';
++ }
++ }
++ *r = '\0';
++}
++
++void
++usage(void)
++{
++
++ (void)fprintf(stderr, "%s\n%s\n%s\n",
++"usage: mount [-adflpruvw] [-F fstab] [-o options] [-t ufs | external_type]",
++" mount [-dfpruvw] special | node",
++" mount [-dfpruvw] [-o options] [-t ufs | external_type] special node");
++ exit(1);
++}
++
++void
++putfsent(struct statfs *ent)
++{
++ struct fstab *fst;
++ char *opts;
++ int l;
++
++ opts = flags2opts(ent->f_flags);
++
++ if (strncmp(ent->f_mntfromname, "<below>", 7) == 0 ||
++ strncmp(ent->f_mntfromname, "<above>", 7) == 0) {
++ strcpy(ent->f_mntfromname, (strnstr(ent->f_mntfromname, ":", 8)
++ +1));
++ }
++
++ /*
++ * "rw" is not a real mount option; this is why we print NULL as "rw"
++ * if opts is still NULL here.
++ */
++ l = strlen(ent->f_mntfromname);
++ printf("%s%s%s%s", ent->f_mntfromname,
++ l < 8 ? "\t" : "",
++ l < 16 ? "\t" : "",
++ l < 24 ? "\t" : " ");
++ l = strlen(ent->f_mntonname);
++ printf("%s%s%s%s", ent->f_mntonname,
++ l < 8 ? "\t" : "",
++ l < 16 ? "\t" : "",
++ l < 24 ? "\t" : " ");
++ printf("%s\t", ent->f_fstypename);
++ if (opts == NULL) {
++ printf("%s\t", "rw");
++ } else {
++ l = strlen(opts);
++ printf("%s%s", opts,
++ l < 8 ? "\t" : " ");
++ }
++ free(opts);
++
++ if ((fst = getfsspec(ent->f_mntfromname)))
++ printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
++ else if ((fst = getfsfile(ent->f_mntonname)))
++ printf("\t%u %u\n", fst->fs_freq, fst->fs_passno);
++ else if (strcmp(ent->f_fstypename, "ufs") == 0) {
++ if (strcmp(ent->f_mntonname, "/") == 0)
++ printf("\t1 1\n");
++ else
++ printf("\t2 2\n");
++ } else
++ printf("\t0 0\n");
++}
++
++
++char *
++flags2opts(int flags)
++{
++ char *res;
++
++ res = NULL;
++
++ if (flags & MNT_RDONLY) res = catopt(res, "ro");
++ if (flags & MNT_SYNCHRONOUS) res = catopt(res, "sync");
++ if (flags & MNT_NOEXEC) res = catopt(res, "noexec");
++ if (flags & MNT_NOSUID) res = catopt(res, "nosuid");
++ if (flags & MNT_UNION) res = catopt(res, "union");
++ if (flags & MNT_ASYNC) res = catopt(res, "async");
++ if (flags & MNT_NOATIME) res = catopt(res, "noatime");
++ if (flags & MNT_NOCLUSTERR) res = catopt(res, "noclusterr");
++ if (flags & MNT_NOCLUSTERW) res = catopt(res, "noclusterw");
++ if (flags & MNT_NOSYMFOLLOW) res = catopt(res, "nosymfollow");
++ if (flags & MNT_SUIDDIR) res = catopt(res, "suiddir");
++ if (flags & MNT_MULTILABEL) res = catopt(res, "multilabel");
++ if (flags & MNT_ACLS) res = catopt(res, "acls");
++ if (flags & MNT_NFS4ACLS) res = catopt(res, "nfsv4acls");
++
++ return (res);
++}
+--- /dev/null
++++ b/sbin/mount/getmntopts.3
+@@ -0,0 +1,181 @@
++.\" Copyright (c) 1994
++.\" The Regents of the University of California. All rights reserved.
++.\"
++.\" Redistribution and use in source and binary forms, with or without
++.\" modification, are permitted provided that the following conditions
++.\" are met:
++.\" 1. Redistributions of source code must retain the above copyright
++.\" notice, this list of conditions and the following disclaimer.
++.\" 2. Redistributions in binary form must reproduce the above copyright
++.\" notice, this list of conditions and the following disclaimer in the
++.\" documentation and/or other materials provided with the distribution.
++.\" 4. Neither the name of the University nor the names of its contributors
++.\" may be used to endorse or promote products derived from this software
++.\" without specific prior written permission.
++.\"
++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++.\" SUCH DAMAGE.
++.\"
++.\" @(#)getmntopts.3 8.3 (Berkeley) 3/30/95
++.\" $FreeBSD$
++.\"
++.Dd February 17, 2008
++.Dt GETMNTOPTS 3
++.Os
++.Sh NAME
++.Nm getmntopts
++.Nd scan mount options
++.Sh SYNOPSIS
++.Fd #include \&"mntopts.h"
++.Ft void
++.Fo getmntopts
++.Fa "const char *options" "const struct mntopt *mopts"
++.Fa "int *flagp" "int *altflagp"
++.Fc
++.Sh DESCRIPTION
++The
++.Fn getmntopts
++function takes a comma separated option list and a list
++of valid option names, and computes the bitmask
++corresponding to the requested set of options.
++.Pp
++The string
++.Fa options
++is broken down into a sequence of comma separated tokens.
++Each token is looked up in the table described by
++.Fa mopts
++and the bits in
++the word referenced by either
++.Fa flagp
++or
++.Fa altflagp
++(depending on the
++.Va m_altloc
++field of the option's table entry)
++are updated.
++The flag words are not initialized by
++.Fn getmntopts .
++The table,
++.Fa mopts ,
++has the following format:
++.Bd -literal
++struct mntopt {
++ char *m_option; /* option name */
++ int m_inverse; /* is this a negative option, e.g. "dev" */
++ int m_flag; /* bit to set, e.g. MNT_RDONLY */
++ int m_altloc; /* non-zero to use altflagp rather than flagp */
++};
++.Ed
++.Pp
++The members of this structure are:
++.Bl -tag -width m_inverse
++.It Va m_option
++the option name,
++for example
++.Dq Li suid .
++.It Va m_inverse
++tells
++.Fn getmntopts
++that the name has the inverse meaning of the
++bit.
++For example,
++.Dq Li suid
++is the string, whereas the
++mount flag is
++.Dv MNT_NOSUID .
++In this case, the sense of the string and the flag
++are inverted, so the
++.Va m_inverse
++flag should be set.
++.It Va m_flag
++the value of the bit to be set or cleared in
++the flag word when the option is recognized.
++The bit is set when the option is discovered,
++but cleared if the option name was preceded
++by the letters
++.Dq Li no .
++The
++.Va m_inverse
++flag causes these two operations to be reversed.
++.It Va m_altloc
++the bit should be set or cleared in
++.Fa altflagp
++rather than
++.Fa flagp .
++.El
++.Pp
++Each of the user visible
++.Dv MNT_
++flags has a corresponding
++.Dv MOPT_
++macro which defines an appropriate
++.Vt "struct mntopt"
++entry.
++To simplify the program interface and ensure consistency across all
++programs, a general purpose macro,
++.Dv MOPT_STDOPTS ,
++is defined which
++contains an entry for all the generic VFS options.
++In addition, the macros
++.Dv MOPT_FORCE
++and
++.Dv MOPT_UPDATE
++exist to enable the
++.Dv MNT_FORCE
++and
++.Dv MNT_UPDATE
++flags to be set.
++Finally, the table must be terminated by an entry with a
++.Dv NULL
++first element.
++.Sh EXAMPLES
++Most commands will use the standard option set.
++Local file systems which support the
++.Dv MNT_UPDATE
++flag, would also have an
++.Dv MOPT_UPDATE
++entry.
++This can be declared and used as follows:
++.Bd -literal
++#include "mntopts.h"
++
++struct mntopt mopts[] = {
++ MOPT_STDOPTS,
++ MOPT_UPDATE,
++ { NULL }
++};
++
++ ...
++ mntflags = mntaltflags = 0;
++ ...
++ getmntopts(options, mopts, &mntflags, &mntaltflags);
++ ...
++.Ed
++.Sh DIAGNOSTICS
++If the external integer variable
++.Va getmnt_silent
++is zero, then the
++.Fn getmntopts
++function displays an error message and exits if an
++unrecognized option is encountered.
++Otherwise unrecognized options are silently ignored.
++By default
++.Va getmnt_silent
++is zero.
++.Sh SEE ALSO
++.Xr err 3 ,
++.Xr mount 8
++.Sh HISTORY
++The
++.Fn getmntopts
++function appeared in
++.Bx 4.4 .
+--- /dev/null
++++ b/sbin/mount/getmntopts.c
+@@ -0,0 +1,182 @@
++/*-
++ * Copyright (c) 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#if 0
++#ifndef lint
++static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
++#endif /* not lint */
++#endif
++#include <sys/cdefs.h>
++__FBSDID("$FreeBSD$");
++
++#include <sys/param.h>
++#include <sys/mount.h>
++#include <sys/stat.h>
++#include <sys/uio.h>
++
++#include <err.h>
++#include <errno.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sysexits.h>
++
++#include "mntopts.h"
++
++int getmnt_silent = 0;
++
++void
++getmntopts(const char *options, const struct mntopt *m0, int *flagp,
++ int *altflagp)
++{
++ const struct mntopt *m;
++ int negative, len;
++ char *opt, *optbuf, *p;
++ int *thisflagp;
++
++ /* Copy option string, since it is about to be torn asunder... */
++ if ((optbuf = strdup(options)) == NULL)
++ err(1, NULL);
++
++ for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
++ /* Check for "no" prefix. */
++ if (opt[0] == 'n' && opt[1] == 'o') {
++ negative = 1;
++ opt += 2;
++ } else
++ negative = 0;
++
++ /*
++ * for options with assignments in them (ie. quotas)
++ * ignore the assignment as it's handled elsewhere
++ */
++ p = strchr(opt, '=');
++ if (p != NULL)
++ *++p = '\0';
++
++ /* Scan option table. */
++ for (m = m0; m->m_option != NULL; ++m) {
++ len = strlen(m->m_option);
++ if (strncasecmp(opt, m->m_option, len) == 0)
++ if (opt[len] == '\0' || opt[len] == '=')
++ break;
++ }
++
++ /* Save flag, or fail if option is not recognized. */
++ if (m->m_option) {
++ thisflagp = m->m_altloc ? altflagp : flagp;
++ if (negative == m->m_inverse)
++ *thisflagp |= m->m_flag;
++ else
++ *thisflagp &= ~m->m_flag;
++ } else if (!getmnt_silent) {
++ errx(1, "-o %s: option not supported", opt);
++ }
++ }
++
++ free(optbuf);
++}
++
++void
++rmslashes(char *rrpin, char *rrpout)
++{
++ char *rrpoutstart;
++
++ *rrpout = *rrpin;
++ for (rrpoutstart = rrpout; *rrpin != '\0'; *rrpout++ = *rrpin++) {
++
++ /* skip all double slashes */
++ while (*rrpin == '/' && *(rrpin + 1) == '/')
++ rrpin++;
++ }
++
++ /* remove trailing slash if necessary */
++ if (rrpout - rrpoutstart > 1 && *(rrpout - 1) == '/')
++ *(rrpout - 1) = '\0';
++ else
++ *rrpout = '\0';
++}
++
++void
++checkpath(const char *path, char *resolved)
++{
++ struct stat sb;
++
++ if (realpath(path, resolved) != NULL && stat(resolved, &sb) == 0) {
++ if (!S_ISDIR(sb.st_mode))
++ errx(EX_USAGE, "%s: not a directory", resolved);
++ } else
++ errx(EX_USAGE, "%s: %s", resolved, strerror(errno));
++}
++
++void
++build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val,
++ size_t len)
++{
++ int i;
++
++ if (*iovlen < 0)
++ return;
++ i = *iovlen;
++ *iov = realloc(*iov, sizeof **iov * (i + 2));
++ if (*iov == NULL) {
++ *iovlen = -1;
++ return;
++ }
++ (*iov)[i].iov_base = strdup(name);
++ (*iov)[i].iov_len = strlen(name) + 1;
++ i++;
++ (*iov)[i].iov_base = val;
++ if (len == (size_t)-1) {
++ if (val != NULL)
++ len = strlen(val) + 1;
++ else
++ len = 0;
++ }
++ (*iov)[i].iov_len = (int)len;
++ *iovlen = ++i;
++}
++
++/*
++ * This function is needed for compatibility with parameters
++ * which used to use the mount_argf() command for the old mount() syscall.
++ */
++void
++build_iovec_argf(struct iovec **iov, int *iovlen, const char *name,
++ const char *fmt, ...)
++{
++ va_list ap;
++ char val[255] = { 0 };
++
++ va_start(ap, fmt);
++ vsnprintf(val, sizeof(val), fmt, ap);
++ va_end(ap);
++ build_iovec(iov, iovlen, name, strdup(val), (size_t)-1);
++}
+--- /dev/null
++++ b/sbin/mount/mount_fs.c
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (c) 1992, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * This code is derived from software donated to Berkeley by
++ * Jan-Simon Pendry.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by the University of
++ * California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#ifndef lint
++static const char copyright[] =
++"@(#) Copyright (c) 1992, 1993, 1994\n\
++ The Regents of the University of California. All rights reserved.\n";
++#endif /* not lint */
++
++#ifndef lint
++#if 0
++static char sccsid[] = "@(#)mount_fs.c 8.6 (Berkeley) 4/26/95";
++#endif
++static const char rcsid[] =
++ "$FreeBSD$";
++#endif /* not lint */
++
++#include <sys/param.h>
++#include <sys/mount.h>
++
++#include <err.h>
++#include <getopt.h>
++#include <libgen.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "extern.h"
++#include "mntopts.h"
++
++struct mntopt mopts[] = {
++ MOPT_STDOPTS,
++ MOPT_END
++};
++
++static void
++usage(void)
++{
++ (void)fprintf(stderr,
++ "usage: mount [-t fstype] [-o options] target_fs mount_point\n");
++ exit(1);
++}
++
++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;
++ int ret;
++
++ 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];
++
++ (void)checkpath(dir, mntpath);
++ (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));
++
++ ret = nmount(iov, iovlen, mntflags);
++ if (ret < 0)
++ err(1, "%s %s", dev, errmsg);
++
++ return (ret);
++}
+--- /dev/null
++++ b/sbin/mount/mntopts.h
+@@ -0,0 +1,99 @@
++/*-
++ * Copyright (c) 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * @(#)mntopts.h 8.7 (Berkeley) 3/29/95
++ * $FreeBSD$
++ */
++
++struct mntopt {
++ const char *m_option; /* option name */
++ int m_inverse; /* if a negative option, e.g. "atime" */
++ int m_flag; /* bit to set, e.g. MNT_RDONLY */
++ int m_altloc; /* 1 => set bit in altflags */
++};
++
++/* User-visible MNT_ flags. */
++#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 }
++#define MOPT_NOATIME { "atime", 1, MNT_NOATIME, 0 }
++#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 }
++#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 }
++#define MOPT_NOSYMFOLLOW { "symfollow", 1, MNT_NOSYMFOLLOW, 0 }
++#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 }
++#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 }
++#define MOPT_UNION { "union", 0, MNT_UNION, 0 }
++#define MOPT_USERQUOTA { "userquota", 0, 0, 0 }
++#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
++#define MOPT_NOCLUSTERR { "clusterr", 1, MNT_NOCLUSTERR, 0 }
++#define MOPT_NOCLUSTERW { "clusterw", 1, MNT_NOCLUSTERW, 0 }
++#define MOPT_SUIDDIR { "suiddir", 0, MNT_SUIDDIR, 0 }
++#define MOPT_SNAPSHOT { "snapshot", 0, MNT_SNAPSHOT, 0 }
++#define MOPT_MULTILABEL { "multilabel", 0, MNT_MULTILABEL, 0 }
++#define MOPT_ACLS { "acls", 0, MNT_ACLS, 0 }
++#define MOPT_NFS4ACLS { "nfsv4acls", 0, MNT_NFS4ACLS, 0 }
++
++/* Control flags. */
++#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
++#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
++#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 }
++#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 }
++
++/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
++#define MOPT_AUTO { "auto", 0, 0, 0 }
++
++/* A handy macro as terminator of MNT_ array. */
++#define MOPT_END { NULL, 0, 0, 0 }
++
++#define MOPT_FSTAB_COMPAT \
++ MOPT_RO, \
++ MOPT_RW, \
++ MOPT_AUTO
++
++/* Standard options which all mounts can understand. */
++#define MOPT_STDOPTS \
++ MOPT_USERQUOTA, \
++ MOPT_GROUPQUOTA, \
++ MOPT_FSTAB_COMPAT, \
++ MOPT_NOATIME, \
++ MOPT_NOEXEC, \
++ MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \
++ MOPT_NOSUID, \
++ MOPT_NOSYMFOLLOW, \
++ MOPT_RDONLY, \
++ MOPT_UNION, \
++ MOPT_NOCLUSTERR, \
++ MOPT_NOCLUSTERW, \
++ MOPT_MULTILABEL, \
++ MOPT_ACLS, \
++ MOPT_NFS4ACLS
++
++void getmntopts(const char *, const struct mntopt *, int *, int *);
++void rmslashes(char *, char *);
++void checkpath(const char *, char resolved_path[]);
++extern int getmnt_silent;
++void build_iovec(struct iovec **iov, int *iovlen, const char *name, void *val, size_t len);
++void build_iovec_argf(struct iovec **iov, int *iovlen, const char *name, const char *fmt, ...);
+--- /dev/null
++++ b/sbin/mount/extern.h
+@@ -0,0 +1,33 @@
++/*-
++ * Copyright (c) 1997 FreeBSD Inc.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ *
++ * $FreeBSD$
++ */
++
++/* vfslist.c */
++int checkvfsname(const char *, const char **);
++const char **makevfslist(char *);
++
++int mount_fs(const char *, int, char *[]);
+--- /dev/null
++++ b/sbin/mount/Makefile
+@@ -0,0 +1,13 @@
++# @(#)Makefile 8.6 (Berkeley) 5/8/95
++# $FreeBSD$
++
++PROG= mount
++SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
++WARNS?= 6
++MAN= mount.8
++# We do NOT install the getmntopts.3 man page.
++
++DPADD= ${LIBUTIL}
++LDADD= -lutil
++
++.include <bsd.prog.mk>
+--- /dev/null
++++ b/sbin/mount/mount.8
+@@ -0,0 +1,573 @@
++.\" Copyright (c) 1980, 1989, 1991, 1993
++.\" The Regents of the University of California. All rights reserved.
++.\"
++.\" Redistribution and use in source and binary forms, with or without
++.\" modification, are permitted provided that the following conditions
++.\" are met:
++.\" 1. Redistributions of source code must retain the above copyright
++.\" notice, this list of conditions and the following disclaimer.
++.\" 2. Redistributions in binary form must reproduce the above copyright
++.\" notice, this list of conditions and the following disclaimer in the
++.\" documentation and/or other materials provided with the distribution.
++.\" 4. Neither the name of the University nor the names of its contributors
++.\" may be used to endorse or promote products derived from this software
++.\" without specific prior written permission.
++.\"
++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++.\" SUCH DAMAGE.
++.\"
++.\" @(#)mount.8 8.8 (Berkeley) 6/16/94
++.\" $FreeBSD$
++.\"
++.Dd February 10, 2010
++.Dt MOUNT 8
++.Os
++.Sh NAME
++.Nm mount
++.Nd mount file systems
++.Sh SYNOPSIS
++.Nm
++.Op Fl adflpruvw
++.Op Fl F Ar fstab
++.Op Fl o Ar options
++.Op Fl t Cm ufs | Ar external_type
++.Nm
++.Op Fl dfpruvw
++.Ar special | node
++.Nm
++.Op Fl dfpruvw
++.Op Fl o Ar options
++.Op Fl t Cm ufs | Ar external_type
++.Ar special node
++.Sh DESCRIPTION
++The
++.Nm
++utility calls the
++.Xr nmount 2
++system call to prepare and graft a
++.Ar special
++device or the remote node (rhost:path) on to the file system tree at the point
++.Ar node .
++If either
++.Ar special
++or
++.Ar node
++are not provided, the appropriate information is taken from the
++.Xr fstab 5
++file.
++.Pp
++The system maintains a list of currently mounted file systems.
++If no arguments are given to
++.Nm ,
++this list is printed.
++.Pp
++The options are as follows:
++.Bl -tag -width indent
++.It Fl a
++All the file systems described in
++.Xr fstab 5
++are mounted.
++Exceptions are those marked as
++.Dq Li noauto ,
++those marked as
++.Dq Li late
++(unless the
++.Fl l
++option was specified),
++those excluded by the
++.Fl t
++flag (see below), or if they are already mounted (except the
++root file system which is always remounted to preserve
++traditional single user mode behavior).
++.It Fl d
++Causes everything to be done except for the actual system call.
++This option is useful in conjunction with the
++.Fl v
++flag to
++determine what the
++.Nm
++command is trying to do.
++.It Fl F Ar fstab
++Specify the
++.Pa fstab
++file to use.
++.It Fl f
++Forces the revocation of write access when trying to downgrade
++a file system mount status from read-write to read-only.
++Also
++forces the R/W mount of an unclean file system (dangerous; use with
++caution).
++.It Fl l
++When used in conjunction with the
++.Fl a
++option, also mount those file systems which are marked as
++.Dq Li late .
++.It Fl o
++Options are specified with a
++.Fl o
++flag followed by a comma separated string of options.
++In case of conflicting options being specified, the rightmost option
++takes effect.
++The following options are available:
++.Bl -tag -width indent
++.It Cm acls
++Enable POSIX.1e Access Control Lists, or ACLs, which can be customized via the
++.Xr setfacl 1
++and
++.Xr getfacl 1
++commands.
++This flag is mutually exclusive with
++.Cm nfsv4acls
++flag.
++.It Cm async
++All
++.Tn I/O
++to the file system should be done asynchronously.
++This is a
++.Em dangerous
++flag to set, since it does not guarantee that the file system structure
++on the disk will remain consistent.
++For this reason, the
++.Cm async
++flag should be used sparingly, and only when some data recovery
++mechanism is present.
++.It Cm current
++When used with the
++.Fl u
++flag, this is the same as specifying the options currently in effect for
++the mounted file system.
++.It Cm force
++The same as
++.Fl f ;
++forces the revocation of write access when trying to downgrade
++a file system mount status from read-write to read-only.
++Also
++forces the R/W mount of an unclean file system (dangerous; use with caution).
++.It Cm fstab
++When used with the
++.Fl u
++flag, this is the same as specifying all the options listed in the
++.Xr fstab 5
++file for the file system.
++.It Cm late
++This file system should be skipped when
++.Nm
++is run with the
++.Fl a
++flag but without the
++.Fl l
++flag.
++.It Cm mountprog Ns = Ns Aq Ar program
++Force
++.Nm
++to use the specified program to mount the file system, instead of calling
++.Xr nmount 2
++directly. For example:
++.Bd -literal
++mount -t foofs -o mountprog=/mydir/fooprog /dev/acd0 /mnt
++.Ed
++.It Cm multilabel
++Enable multi-label Mandatory Access Control, or MAC, on the specified file
++system.
++If the file system supports multilabel operation, individual labels will
++be maintained for each object in the file system, rather than using a
++single label for all objects.
++An alternative to the
++.Fl l
++flag in
++.Xr tunefs 8 .
++See
++.Xr mac 4
++for more information, which cause the multilabel mount flag to be set
++automatically at mount-time.
++.It Cm nfsv4acls
++Enable NFSv4 ACLs, which can be customized via the
++.Xr setfacl 1
++and
++.Xr getfacl 1
++commands.
++This flag is mutually exclusive with
++.Cm acls
++flag.
++.It Cm noasync
++Metadata I/O should be done synchronously, while data I/O should be done
++asynchronously.
++This is the default.
++.It Cm noatime
++Do not update the file access time when reading from a file.
++This option
++is useful on file systems where there are large numbers of files and
++performance is more critical than updating the file access time (which is
++rarely ever important).
++This option is currently only supported on local file systems.
++.It Cm noauto
++This file system should be skipped when
++.Nm
++is run with the
++.Fl a
++flag.
++.It Cm noclusterr
++Disable read clustering.
++.It Cm noclusterw
++Disable write clustering.
++.It Cm noexec
++Do not allow execution of any binaries on the mounted file system.
++This option is useful for a server that has file systems containing
++binaries for architectures other than its own.
++Note: This option was not designed as a security feature and no
++guarantee is made that it will prevent malicious code execution; for
++example, it is still possible to execute scripts which reside on a
++.Cm noexec
++mounted partition.
++.It Cm nosuid
++Do not allow set-user-identifier or set-group-identifier bits to take effect.
++Note: this option is worthless if a public available suid or sgid
++wrapper like
++.Xr suidperl 1
++is installed on your system.
++It is set automatically when the user does not have super-user privileges.
++.It Cm nosymfollow
++Do not follow symlinks
++on the mounted file system.
++.It Cm ro
++The same as
++.Fl r ;
++mount the file system read-only (even the super-user may not write it).
++.It Cm snapshot
++This option allows a snapshot of the specified file system to be taken.
++The
++.Fl u
++flag is required with this option.
++Note that snapshot files must be created in the file system that is being
++snapshotted.
++You may create up to 20 snapshots per file system.
++Active snapshots are recorded in the superblock, so they persist across unmount
++and remount operations and across system reboots.
++When you are done with a snapshot, it can be removed with the
++.Xr rm 1
++command.
++Snapshots may be removed in any order, however you may not get back all the
++space contained in the snapshot as another snapshot may claim some of the blocks
++that it is releasing.
++Note that the schg flag is set on snapshots to ensure that not even the root
++user can write to them.
++The unlink command makes an exception for snapshot files in that it allows them
++to be removed even though they have the schg flag set, so it is not necessary to
++clear the schg flag before removing a snapshot file.
++.Pp
++Once you have taken a snapshot, there are three interesting things that you can
++do with it:
++.Pp
++.Bl -enum -compact
++.It
++Run
++.Xr fsck 8
++on the snapshot file.
++Assuming that the file system was clean when it was mounted, you should always
++get a clean (and unchanging) result from running fsck on the snapshot.
++This is essentially what the background fsck process does.
++.Pp
++.It
++Run
++.Xr dump 8
++on the snapshot.
++You will get a dump that is consistent with the file system as of the timestamp
++of the snapshot.
++.Pp
++.It
++Mount the snapshot as a frozen image of the file system.
++To mount the snapshot
++.Pa /var/snapshot/snap1 :
++.Bd -literal
++mdconfig -a -t vnode -f /var/snapshot/snap1 -u 4
++mount -r /dev/md4 /mnt
++.Ed
++.Pp
++You can now cruise around your frozen
++.Pa /var
++file system at
++.Pa /mnt .
++Everything will be in the same state that it was at the time the snapshot was
++taken.
++The one exception is that any earlier snapshots will appear as zero length
++files.
++When you are done with the mounted snapshot:
++.Bd -literal
++umount /mnt
++mdconfig -d -u 4
++.Ed
++.Pp
++Further details can be found in the file at
++.Pa /usr/src/sys/ufs/ffs/README.snapshot .
++.El
++.It Cm suiddir
++A directory on the mounted file system will respond to the SUID bit
++being set, by setting the owner of any new files to be the same
++as the owner of the directory.
++New directories will inherit the bit from their parents.
++Execute bits are removed from
++the file, and it will not be given to root.
++.Pp
++This feature is designed for use on fileservers serving PC users via
++ftp, SAMBA, or netatalk.
++It provides security holes for shell users and as
++such should not be used on shell machines, especially on home directories.
++This option requires the SUIDDIR
++option in the kernel to work.
++Only UFS file systems support this option.
++See
++.Xr chmod 2
++for more information.
++.It Cm sync
++All
++.Tn I/O
++to the file system should be done synchronously.
++.It Cm update
++The same as
++.Fl u ;
++indicate that the status of an already mounted file system should be changed.
++.It Cm union
++Causes the namespace at the mount point to appear as the union
++of the mounted file system root and the existing directory.
++Lookups will be done in the mounted file system first.
++If those operations fail due to a non-existent file the underlying
++directory is then accessed.
++All creates are done in the mounted file system.
++.El
++.Pp
++Any additional options specific to a file system type that is not
++one of the internally known types (see the
++.Fl t
++option) may be passed as a comma separated list; these options are
++distinguished by a leading
++.Dq \&-
++(dash).
++Options that take a value are specified using the syntax -option=value.
++For example, the
++.Nm
++command:
++.Bd -literal -offset indent
++mount -t cd9660 -o -e /dev/cd0 /cdrom
++.Ed
++.Pp
++causes
++.Nm
++to execute the equivalent of:
++.Bd -literal -offset indent
++/sbin/mount_cd9660 -e /dev/cd0 /cdrom
++.Ed
++.Pp
++Additional options specific to file system types
++which are not internally known
++(see the description of the
++.Fl t
++option below)
++may be described in the manual pages for the associated
++.Pa /sbin/mount_ Ns Sy XXX
++utilities.
++.It Fl p
++Print mount information in
++.Xr fstab 5
++format.
++Implies also the
++.Fl v
++option.
++.It Fl r
++The file system is to be mounted read-only.
++Mount the file system read-only (even the super-user may not write it).
++The same as the
++.Cm ro
++argument to the
++.Fl o
++option.
++.It Fl t Cm ufs | Ar external_type
++The argument following the
++.Fl t
++is used to indicate the file system type.
++The type
++.Cm ufs
++is the default.
++The
++.Fl t
++option can be used
++to indicate that the actions should only be taken on
++file systems of the specified type.
++More than one type may be specified in a comma separated list.
++The list of file system types can be prefixed with
++.Dq Li no
++to specify the file system types for which action should
++.Em not
++be taken.
++For example, the
++.Nm
++command:
++.Bd -literal -offset indent
++mount -a -t nonfs,nullfs
++.Ed
++.Pp
++mounts all file systems except those of type
++.Tn NFS
++and
++.Tn NULLFS .
++.Pp
++The default behavior of
++.Nm
++is to pass the
++.Fl t
++option directly to the
++.Xr nmount 2
++system call in the
++.Li fstype
++option.
++.Pp
++However, for the following file system types:
++.Cm cd9660 ,
++.Cm mfs ,
++.Cm msdosfs ,
++.Cm newnfs ,
++.Cm nfs ,
++.Cm ntfs ,
++.Cm nwfs ,
++.Cm nullfs ,
++.Cm portalfs ,
++.Cm smbfs ,
++.Cm udf ,
++and
++.Cm unionfs ,
++.Nm
++will not call
++.Xr nmount 2
++directly and will instead attempt to execute a program in
++.Pa /sbin/mount_ Ns Sy XXX
++where
++.Sy XXX
++is replaced by the file system type name.
++For example, nfs file systems are mounted by the program
++.Pa /sbin/mount_nfs .
++.Pp
++Most file systems will be dynamically loaded by the kernel
++if not already present, and if the kernel module is available.
++.It Fl u
++The
++.Fl u
++flag indicates that the status of an already mounted file
++system should be changed.
++Any of the options discussed above (the
++.Fl o
++option)
++may be changed;
++also a file system can be changed from read-only to read-write
++or vice versa.
++An attempt to change from read-write to read-only will fail if any
++files on the file system are currently open for writing unless the
++.Fl f
++flag is also specified.
++The set of options is determined by applying the options specified
++in the argument to
++.Fl o
++and finally applying the
++.Fl r
++or
++.Fl w
++option.
++.It Fl v
++Verbose mode.
++If the
++.Fl v
++is used alone, show all file systems, including those that were mounted with the
++.Dv MNT_IGNORE
++flag and show additional information about each file system (including fsid
++when run by root).
++.It Fl w
++The file system object is to be read and write.
++.El
++.Sh ENVIRONMENT
++.Bl -tag -width ".Ev PATH_FSTAB"
++.It Ev PATH_FSTAB
++If the environment variable
++.Ev PATH_FSTAB
++is set, all operations are performed against the specified file.
++.Ev PATH_FSTAB
++will not be honored if the process environment or memory address space is
++considered
++.Dq tainted .
++(See
++.Xr issetugid 2
++for more information.)
++.El
++.Sh FILES
++.Bl -tag -width /etc/fstab -compact
++.It Pa /etc/fstab
++file system table
++.El
++.Sh DIAGNOSTICS
++Various, most of them are self-explanatory.
++.Pp
++.Dl XXXXX file system is not available
++.Pp
++The kernel does not support the respective file system type.
++Note that
++support for a particular file system might be provided either on a static
++(kernel compile-time), or dynamic basis (loaded as a kernel module by
++.Xr kldload 8 ) .
++.Sh SEE ALSO
++.Xr getfacl 1 ,
++.Xr setfacl 1 ,
++.Xr nmount 2 ,
++.Xr acl 3 ,
++.Xr mac 4 ,
++.Xr ext2fs 5 ,
++.Xr fstab 5 ,
++.Xr procfs 5 ,
++.Xr kldload 8 ,
++.Xr mount_cd9660 8 ,
++.Xr mount_msdosfs 8 ,
++.Xr mount_nfs 8 ,
++.Xr mount_ntfs 8 ,
++.Xr mount_nullfs 8 ,
++.Xr mount_nwfs 8 ,
++.Xr mount_portalfs 8 ,
++.Xr mount_smbfs 8 ,
++.Xr mount_udf 8 ,
++.Xr mount_unionfs 8 ,
++.Xr umount 8 ,
++.Xr zfs 8 ,
++.Xr zpool 8
++.Sh CAVEATS
++After a successful
++.Nm ,
++the permissions on the original mount point determine if
++.Pa ..\&
++is accessible from the mounted file system.
++The minimum permissions for
++the mount point for traversal across the mount point in both
++directions to be possible for all users is 0111 (execute for all).
++.Pp
++Use of the
++.Nm
++is preferred over the use of the file system specific
++.Pa mount_ Ns Sy XXX
++commands.
++In particular,
++.Xr mountd 8
++gets a
++.Dv SIGHUP
++signal (that causes an update of the export list)
++only when the file system is mounted via
++.Nm .
++.Sh HISTORY
++A
++.Nm
++utility appeared in
++.At v1 .
++.Sh BUGS
++It is possible for a corrupted file system to cause a crash.
Added: trunk/fuse4bsd/debian/patches/001_ports.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/001_ports.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/001_ports.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,352 @@
+
+Based on http://www.freebsd.org/cgi/cvsweb.cgi/ports/sysutils/fusefs-kmod/files/
+
+diff -ur a/fuse_module/Makefile b/fuse_module/Makefile
+--- a/fuse_module/Makefile 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/Makefile 2011-06-06 14:58:54.000000000 +0000
+@@ -1,3 +1,5 @@
++.undef KERNCONF
++
+ .include "../Makefile.common"
+
+ SRCS = fuse_main.c \
+@@ -22,7 +24,8 @@
+
+ .if defined(KERNCONF)
+ KERNCONF1!= echo ${KERNCONF} | sed -e 's/ .*//g'
+-KERNCONFDIR= /usr/obj/usr/src/sys/${KERNCONF1}
++KRNLOBJDIR!= make -C /usr/src -f /usr/src/Makefile.inc1 -V KRNLOBJDIR
++KERNCONFDIR= ${KRNLOBJDIR}/${KERNCONF1}
+ .endif
+
+ .if defined(KERNCONFDIR)
+diff -ur a/fuse_module/fuse.h b/fuse_module/fuse.h
+--- a/fuse_module/fuse.h 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse.h 2011-06-06 14:58:54.000000000 +0000
+@@ -25,6 +25,22 @@
+ #endif
+ #endif
+
++#ifndef VFSOPS_TAKES_THREAD
++#if __FreeBSD_version >= 800087
++#define VFSOPS_TAKES_THREAD 0
++#else
++#define VFSOPS_TAKES_THREAD 1
++#endif
++#endif
++
++#ifndef VOP_ACCESS_TAKES_ACCMODE_T
++#if __FreeBSD_version >= 800052
++#define VOP_ACCESS_TAKES_ACCMODE_T 1
++#else
++#define VOP_ACCESS_TAKES_ACCMODE_T 0
++#endif
++#endif
++
+ #ifndef VOP_OPEN_TAKES_FP
+ #if __FreeBSD_version >= 700044
+ #define VOP_OPEN_TAKES_FP 1
+@@ -49,6 +65,14 @@
+ #endif
+ #endif
+
++#ifndef VOP_GETATTR_TAKES_THREAD
++#if __FreeBSD_version >= 800046
++#define VOP_GETATTR_TAKES_THREAD 0
++#else
++#define VOP_GETATTR_TAKES_THREAD 1
++#endif
++#endif
++
+ #ifndef USE_PRIVILEGE_API
+ /*
+ * __FreeBSD_version bump was omitted for introduction of
+diff -ur a/fuse_module/fuse_dev.c b/fuse_module/fuse_dev.c
+--- a/fuse_module/fuse_dev.c 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse_dev.c 2011-06-06 14:58:54.000000000 +0000
+@@ -52,8 +52,13 @@
+ .d_read = fusedev_read,
+ .d_write = fusedev_write,
+ .d_version = D_VERSION,
++#ifndef D_NEEDMINOR
++#define D_NEEDMINOR 0
++#endif
+ #if ! DO_GIANT_MANUALLY
+- .d_flags = D_NEEDGIANT,
++ .d_flags = D_NEEDMINOR|D_NEEDGIANT,
++#else
++ .d_flags = D_NEEDMINOR,
+ #endif
+ };
+
+@@ -548,7 +553,12 @@
+ /* find any existing device, or allocate new unit number */
+ i = clone_create(&fuseclones, &fuse_cdevsw, &unit, dev, 0);
+ if (i) {
+- *dev = make_dev(&fuse_cdevsw, unit2minor(unit),
++ *dev = make_dev(&fuse_cdevsw,
++#if __FreeBSD_version < 800062
++ unit2minor(unit),
++#else /* __FreeBSD_version >= 800062 */
++ unit,
++#endif /* __FreeBSD_version < 800062 */
+ UID_ROOT, GID_OPERATOR,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
+ "fuse%d", unit);
+diff -ur a/fuse_module/fuse_io.c b/fuse_module/fuse_io.c
+--- a/fuse_module/fuse_io.c 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse_io.c 2011-06-06 14:58:54.000000000 +0000
+@@ -35,6 +35,10 @@
+ #include <vm/vnode_pager.h>
+ #include <vm/vm_object.h>
+
++#if (__FreeBSD__ >= 8)
++#define vfs_bio_set_validclean vfs_bio_set_valid
++#endif
++
+ #include "fuse.h"
+ #include "fuse_session.h"
+ #include "fuse_vnode.h"
+@@ -157,7 +161,11 @@
+ goto out;
+
+ if (uio->uio_rw == UIO_WRITE && fp->f_flag & O_APPEND) {
+- if ((err = VOP_GETATTR(vp, &va, cred, td)))
++ if ((err = VOP_GETATTR(vp, &va, cred
++#if VOP_GETATTR_TAKES_THREAD
++ , td
++#endif
++ )))
+ goto out;
+ uio->uio_offset = va.va_size;
+ } else if ((flags & FOF_OFFSET) == 0)
+@@ -823,7 +831,11 @@
+ #if FUSELIB_CONFORM_BIOREAD
+ struct vattr va;
+
+- if ((err = VOP_GETATTR(vp, &va, cred, curthread)))
++ if ((err = VOP_GETATTR(vp, &va, cred
++#if VOP_GETATTR_TAKES_THREAD
++ , curthread
++#endif
++ )))
+ goto out;
+ #endif
+
+diff -ur a/fuse_module/fuse_main.c b/fuse_module/fuse_main.c
+--- a/fuse_module/fuse_main.c 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse_main.c 2011-06-06 14:58:54.000000000 +0000
+@@ -108,6 +108,9 @@
+ switch (what) {
+ case MOD_LOAD: /* kldload */
+
++#if __FreeBSD_version > 800009
++ fuse_fileops.fo_truncate = vnops.fo_truncate;
++#endif
+ fuse_fileops.fo_ioctl = vnops.fo_ioctl;
+ fuse_fileops.fo_poll = vnops.fo_poll;
+ fuse_fileops.fo_kqfilter = vnops.fo_kqfilter;
+diff -ur a/fuse_module/fuse_vfsops.c b/fuse_module/fuse_vfsops.c
+--- a/fuse_module/fuse_vfsops.c 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse_vfsops.c 2011-06-06 14:58:54.000000000 +0000
+@@ -18,6 +18,7 @@
+ #include <sys/namei.h>
+ #include <sys/mount.h>
+ #include <sys/sysctl.h>
++#include <sys/fcntl.h>
+
+ #include "fuse.h"
+ #include "fuse_session.h"
+@@ -213,8 +214,14 @@
+ * Mount system call
+ */
+ static int
++#if VFSOPS_TAKES_THREAD
+ fuse_mount(struct mount *mp, struct thread *td)
+ {
++#else
++fuse_mount(struct mount *mp)
++{
++ struct thread *td = curthread;
++#endif
+ int err = 0;
+ size_t len;
+ char *fspec, *subtype = NULL;
+@@ -529,8 +536,14 @@
+ * Unmount system call
+ */
+ static int
++#if VFSOPS_TAKES_THREAD
+ fuse_unmount(struct mount *mp, int mntflags, struct thread *td)
+ {
++#else
++fuse_unmount(struct mount *mp, int mntflags)
++{
++ struct thread *td = curthread;
++#endif
+ int flags = 0, err = 0;
+ struct fuse_data *data;
+ struct fuse_secondary_data *fsdat = NULL;
+@@ -633,8 +646,14 @@
+
+ /* stolen from portalfs */
+ static int
++#if VFSOPS_TAKES_THREAD
+ fuse_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
+ {
++#else
++fuse_root(struct mount *mp, int flags, struct vnode **vpp)
++{
++ struct thread *td = curthread;
++#endif
+ /*
+ * Return locked reference to root.
+ */
+@@ -650,7 +669,11 @@
+ data = fsdat->master;
+ sx_slock(&data->mhierlock);
+ if (data->mpri == FM_PRIMARY)
+- err = fuse_root(data->mp, flags, vpp, td);
++ err = fuse_root(data->mp, flags, vpp
++#if VFSOPS_TAKES_THREAD
++ , td
++#endif
++ );
+ else
+ err = ENXIO;
+ sx_sunlock(&data->mhierlock);
+@@ -667,7 +690,11 @@
+ if (vp->v_type == VNON) {
+ struct vattr va;
+
+- (void)VOP_GETATTR(vp, &va, td->td_ucred, td);
++ (void)VOP_GETATTR(vp, &va, td->td_ucred
++#if VOP_GETATTR_TAKES_THREAD
++ , td
++#endif
++ );
+ }
+ *vpp = vp;
+ #if _DEBUG2G
+@@ -678,8 +705,14 @@
+ }
+
+ static int
++#if VFSOPS_TAKES_THREAD
+ fuse_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
+ {
++#else
++fuse_statfs(struct mount *mp, struct statfs *sbp)
++{
++ struct thread *td = curthread;
++#endif
+ struct fuse_dispatcher fdi;
+ struct fuse_statfs_out *fsfo;
+ struct fuse_data *data;
+@@ -696,7 +729,11 @@
+
+ sx_slock(&data->mhierlock);
+ if (data->mpri == FM_PRIMARY)
+- err = fuse_statfs(data->mp, sbp, td);
++ err = fuse_statfs(data->mp, sbp
++#if VFSOPS_TAKES_THREAD
++ , td
++#endif
++ );
+ else
+ err = ENXIO;
+ sx_sunlock(&data->mhierlock);
+@@ -794,7 +831,11 @@
+ if (nodeid == FUSE_ROOT_ID) {
+ if (parentid != FUSE_NULL_ID)
+ return (ENOENT);
+- err = VFS_ROOT(mp, myflags, vpp, td);
++ err = VFS_ROOT(mp, myflags, vpp
++#if VFSOPS_TAKES_THREAD
++ , td
++#endif
++ );
+ if (err)
+ return (err);
+ KASSERT(*vpp, ("we neither err'd nor found the root node"));
+diff -ur a/fuse_module/fuse_vnops.c b/fuse_module/fuse_vnops.c
+--- a/fuse_module/fuse_vnops.c 2009-02-26 22:21:58.000000000 +0000
++++ b/fuse_module/fuse_vnops.c 2011-06-06 14:58:54.000000000 +0000
+@@ -799,8 +799,11 @@
+ struct vnode *vp = ap->a_vp;
+ struct vattr *vap = ap->a_vap;
+ struct ucred *cred = ap->a_cred;
++#if VOP_GETATTR_TAKES_THREAD
+ struct thread *td = ap->a_td;
+-
++#else
++ struct thread *td = curthread;
++#endif
+ struct fuse_dispatcher fdi;
+ struct timespec uptsp;
+ int err = 0;
+@@ -871,7 +874,11 @@
+ fuse_access(ap)
+ struct vop_access_args /* {
+ struct vnode *a_vp;
++#if VOP_ACCESS_TAKES_ACCMODE_T
++ accmode_t a_accmode;
++#else
+ int a_mode;
++#endif
+ struct ucred *a_cred;
+ struct thread *a_td;
+ } */ *ap;
+@@ -886,7 +893,13 @@
+ else
+ facp.facc_flags |= FACCESS_DO_ACCESS;
+
+- return fuse_access_i(vp, ap->a_mode, ap->a_cred, ap->a_td, &facp);
++ return fuse_access_i(vp,
++#if VOP_ACCESS_TAKES_ACCMODE_T
++ ap->a_accmode,
++#else
++ ap->a_mode,
++#endif
++ ap->a_cred, ap->a_td, &facp);
+ }
+
+ /*
+@@ -946,7 +959,11 @@
+ /* We are to do the check in-kernel */
+
+ if (! (facp->facc_flags & FACCESS_VA_VALID)) {
+- err = VOP_GETATTR(vp, VTOVA(vp), cred, td);
++ err = VOP_GETATTR(vp, VTOVA(vp), cred
++#if VOP_GETATTR_TAKES_THREAD
++ , td
++#endif
++ );
+ if (err)
+ return (err);
+ facp->facc_flags |= FACCESS_VA_VALID;
+@@ -1929,7 +1946,11 @@
+ * It will not invalidate pages which are dirty, locked, under
+ * writeback or mapped into pagetables.")
+ */
++#if VOP_GETATTR_TAKES_THREAD
+ err = vinvalbuf(vp, 0, td, PCATCH, 0);
++#else
++ err = vinvalbuf(vp, 0, PCATCH, 0);
++#endif
+ fufh->flags |= FOPEN_KEEP_CACHE;
+ }
+
+@@ -3005,8 +3026,11 @@
+ struct vattr *vap = ap->a_vap;
+ struct vnode *vp = ap->a_vp;
+ struct ucred *cred = ap->a_cred;
++#if VOP_GETATTR_TAKES_THREAD
+ struct thread *td = ap->a_td;
+-
++#else
++ struct thread *td = curthread;
++#endif
+ int err = 0;
+ struct fuse_dispatcher fdi;
+ struct fuse_setattr_in *fsai;
Added: trunk/fuse4bsd/debian/patches/002_misc.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/002_misc.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/002_misc.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,11 @@
+--- a/mount_fusefs/Makefile
++++ b/mount_fusefs/Makefile
+@@ -11,6 +11,8 @@
+ MOUNT ?= /usr/src/sbin/mount
+ CFLAGS += -I${MOUNT} -I../include
+
++LDADD += -lbsd
++
+ .PATH: ${MOUNT}
+
+ .include <bsd.prog.mk>
Added: trunk/fuse4bsd/debian/patches/003_kernel_api.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/003_kernel_api.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/003_kernel_api.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,382 @@
+
+Stolen from FUSE source tree.
+
+--- /dev/null
++++ b/fuse_module/fuse_kernel.h
+@@ -0,0 +1,376 @@
++/*
++ This file defines the kernel interface of FUSE
++ Copyright (C) 2001-2007 Miklos Szeredi <miklos at szeredi.hu>
++
++ This program can be distributed under the terms of the GNU GPL.
++ See the file COPYING.
++
++ This -- and only this -- header file may also be distributed under
++ the terms of the BSD Licence as follows:
++
++ Copyright (C) 2001-2007 Miklos Szeredi. All rights reserved.
++
++ Redistribution and use in source and binary forms, with or without
++ modification, are permitted provided that the following conditions
++ are met:
++ 1. Redistributions of source code must retain the above copyright
++ notice, this list of conditions and the following disclaimer.
++ 2. Redistributions in binary form must reproduce the above copyright
++ notice, this list of conditions and the following disclaimer in the
++ documentation and/or other materials provided with the distribution.
++
++ THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ SUCH DAMAGE.
++*/
++
++#ifndef linux
++#include <sys/types.h>
++#define __u64 uint64_t
++#define __u32 uint32_t
++#define __s32 int32_t
++#else
++#include <asm/types.h>
++#include <linux/major.h>
++#endif
++
++/** Version number of this interface */
++#define FUSE_KERNEL_VERSION 7
++
++/** Minor version number of this interface */
++#define FUSE_KERNEL_MINOR_VERSION 8
++
++/** The node ID of the root inode */
++#define FUSE_ROOT_ID 1
++
++/** The major number of the fuse character device */
++#define FUSE_MAJOR MISC_MAJOR
++
++/** The minor number of the fuse character device */
++#define FUSE_MINOR 229
++
++/* Make sure all structures are padded to 64bit boundary, so 32bit
++ userspace works under 64bit kernels */
++
++struct fuse_attr {
++ __u64 ino;
++ __u64 size;
++ __u64 blocks;
++ __u64 atime;
++ __u64 mtime;
++ __u64 ctime;
++ __u32 atimensec;
++ __u32 mtimensec;
++ __u32 ctimensec;
++ __u32 mode;
++ __u32 nlink;
++ __u32 uid;
++ __u32 gid;
++ __u32 rdev;
++};
++
++struct fuse_kstatfs {
++ __u64 blocks;
++ __u64 bfree;
++ __u64 bavail;
++ __u64 files;
++ __u64 ffree;
++ __u32 bsize;
++ __u32 namelen;
++ __u32 frsize;
++ __u32 padding;
++ __u32 spare[6];
++};
++
++struct fuse_file_lock {
++ __u64 start;
++ __u64 end;
++ __u32 type;
++ __u32 pid; /* tgid */
++};
++
++/**
++ * Bitmasks for fuse_setattr_in.valid
++ */
++#define FATTR_MODE (1 << 0)
++#define FATTR_UID (1 << 1)
++#define FATTR_GID (1 << 2)
++#define FATTR_SIZE (1 << 3)
++#define FATTR_ATIME (1 << 4)
++#define FATTR_MTIME (1 << 5)
++#define FATTR_FH (1 << 6)
++
++/**
++ * Flags returned by the OPEN request
++ *
++ * FOPEN_DIRECT_IO: bypass page cache for this open file
++ * FOPEN_KEEP_CACHE: don't invalidate the data cache on open
++ */
++#define FOPEN_DIRECT_IO (1 << 0)
++#define FOPEN_KEEP_CACHE (1 << 1)
++
++/**
++ * INIT request/reply flags
++ */
++#define FUSE_ASYNC_READ (1 << 0)
++#define FUSE_POSIX_LOCKS (1 << 1)
++
++/**
++ * Release flags
++ */
++#define FUSE_RELEASE_FLUSH (1 << 0)
++
++enum fuse_opcode {
++ FUSE_LOOKUP = 1,
++ FUSE_FORGET = 2, /* no reply */
++ FUSE_GETATTR = 3,
++ FUSE_SETATTR = 4,
++ FUSE_READLINK = 5,
++ FUSE_SYMLINK = 6,
++ FUSE_MKNOD = 8,
++ FUSE_MKDIR = 9,
++ FUSE_UNLINK = 10,
++ FUSE_RMDIR = 11,
++ FUSE_RENAME = 12,
++ FUSE_LINK = 13,
++ FUSE_OPEN = 14,
++ FUSE_READ = 15,
++ FUSE_WRITE = 16,
++ FUSE_STATFS = 17,
++ FUSE_RELEASE = 18,
++ FUSE_FSYNC = 20,
++ FUSE_SETXATTR = 21,
++ FUSE_GETXATTR = 22,
++ FUSE_LISTXATTR = 23,
++ FUSE_REMOVEXATTR = 24,
++ FUSE_FLUSH = 25,
++ FUSE_INIT = 26,
++ FUSE_OPENDIR = 27,
++ FUSE_READDIR = 28,
++ FUSE_RELEASEDIR = 29,
++ FUSE_FSYNCDIR = 30,
++ FUSE_GETLK = 31,
++ FUSE_SETLK = 32,
++ FUSE_SETLKW = 33,
++ FUSE_ACCESS = 34,
++ FUSE_CREATE = 35,
++ FUSE_INTERRUPT = 36,
++ FUSE_BMAP = 37,
++ FUSE_DESTROY = 38,
++};
++
++/* The read buffer is required to be at least 8k, but may be much larger */
++#define FUSE_MIN_READ_BUFFER 8192
++
++struct fuse_entry_out {
++ __u64 nodeid; /* Inode ID */
++ __u64 generation; /* Inode generation: nodeid:gen must
++ be unique for the fs's lifetime */
++ __u64 entry_valid; /* Cache timeout for the name */
++ __u64 attr_valid; /* Cache timeout for the attributes */
++ __u32 entry_valid_nsec;
++ __u32 attr_valid_nsec;
++ struct fuse_attr attr;
++};
++
++struct fuse_forget_in {
++ __u64 nlookup;
++};
++
++struct fuse_attr_out {
++ __u64 attr_valid; /* Cache timeout for the attributes */
++ __u32 attr_valid_nsec;
++ __u32 dummy;
++ struct fuse_attr attr;
++};
++
++struct fuse_mknod_in {
++ __u32 mode;
++ __u32 rdev;
++};
++
++struct fuse_mkdir_in {
++ __u32 mode;
++ __u32 padding;
++};
++
++struct fuse_rename_in {
++ __u64 newdir;
++};
++
++struct fuse_link_in {
++ __u64 oldnodeid;
++};
++
++struct fuse_setattr_in {
++ __u32 valid;
++ __u32 padding;
++ __u64 fh;
++ __u64 size;
++ __u64 unused1;
++ __u64 atime;
++ __u64 mtime;
++ __u64 unused2;
++ __u32 atimensec;
++ __u32 mtimensec;
++ __u32 unused3;
++ __u32 mode;
++ __u32 unused4;
++ __u32 uid;
++ __u32 gid;
++ __u32 unused5;
++};
++
++struct fuse_open_in {
++ __u32 flags;
++ __u32 mode;
++};
++
++struct fuse_open_out {
++ __u64 fh;
++ __u32 open_flags;
++ __u32 padding;
++};
++
++struct fuse_release_in {
++ __u64 fh;
++ __u32 flags;
++ __u32 release_flags;
++ __u64 lock_owner;
++};
++
++struct fuse_flush_in {
++ __u64 fh;
++ __u32 unused;
++ __u32 padding;
++ __u64 lock_owner;
++};
++
++struct fuse_read_in {
++ __u64 fh;
++ __u64 offset;
++ __u32 size;
++ __u32 padding;
++};
++
++struct fuse_write_in {
++ __u64 fh;
++ __u64 offset;
++ __u32 size;
++ __u32 write_flags;
++};
++
++struct fuse_write_out {
++ __u32 size;
++ __u32 padding;
++};
++
++#define FUSE_COMPAT_STATFS_SIZE 48
++
++struct fuse_statfs_out {
++ struct fuse_kstatfs st;
++};
++
++struct fuse_fsync_in {
++ __u64 fh;
++ __u32 fsync_flags;
++ __u32 padding;
++};
++
++struct fuse_setxattr_in {
++ __u32 size;
++ __u32 flags;
++};
++
++struct fuse_getxattr_in {
++ __u32 size;
++ __u32 padding;
++};
++
++struct fuse_getxattr_out {
++ __u32 size;
++ __u32 padding;
++};
++
++struct fuse_lk_in {
++ __u64 fh;
++ __u64 owner;
++ struct fuse_file_lock lk;
++};
++
++struct fuse_lk_out {
++ struct fuse_file_lock lk;
++};
++
++struct fuse_access_in {
++ __u32 mask;
++ __u32 padding;
++};
++
++struct fuse_init_in {
++ __u32 major;
++ __u32 minor;
++ __u32 max_readahead;
++ __u32 flags;
++};
++
++struct fuse_init_out {
++ __u32 major;
++ __u32 minor;
++ __u32 max_readahead;
++ __u32 flags;
++ __u32 unused;
++ __u32 max_write;
++};
++
++struct fuse_interrupt_in {
++ __u64 unique;
++};
++
++struct fuse_bmap_in {
++ __u64 block;
++ __u32 blocksize;
++ __u32 padding;
++};
++
++struct fuse_bmap_out {
++ __u64 block;
++};
++
++struct fuse_in_header {
++ __u32 len;
++ __u32 opcode;
++ __u64 unique;
++ __u64 nodeid;
++ __u32 uid;
++ __u32 gid;
++ __u32 pid;
++ __u32 padding;
++};
++
++struct fuse_out_header {
++ __u32 len;
++ __s32 error;
++ __u64 unique;
++};
++
++struct fuse_dirent {
++ __u64 ino;
++ __u64 off;
++ __u32 namelen;
++ __u32 type;
++ char name[0];
++};
++
++#define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name)
++#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
++#define FUSE_DIRENT_SIZE(d) \
++ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
Added: trunk/fuse4bsd/debian/patches/004_freebsd_macro.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/004_freebsd_macro.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/004_freebsd_macro.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,11 @@
+--- a/fuse_module/fuse_io.c
++++ b/fuse_module/fuse_io.c
+@@ -35,7 +35,7 @@
+ #include <vm/vnode_pager.h>
+ #include <vm/vm_object.h>
+
+-#if (__FreeBSD__ >= 8)
++#if __FreeBSD_version >= 800000
+ #define vfs_bio_set_validclean vfs_bio_set_valid
+ #endif
+
Added: trunk/fuse4bsd/debian/patches/007_mount.diff
===================================================================
--- trunk/fuse4bsd/debian/patches/007_mount.diff (rev 0)
+++ trunk/fuse4bsd/debian/patches/007_mount.diff 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,111 @@
+
+Stolen from freebsd-utils
+
+--- a/sbin/mount/mount_fs.c
++++ b/sbin/mount/mount_fs.c
+@@ -52,7 +52,7 @@
+ #include <sys/mount.h>
+
+ #include <err.h>
+-#include <getopt.h>
++#include <bsd/getopt.h>
+ #include <libgen.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+--- a/sbin/mount/mount.c
++++ b/sbin/mount/mount.c
+@@ -58,6 +58,8 @@
+ #include <unistd.h>
+ #include <libutil.h>
+
++#include <bsd/string.h>
++
+ #include "extern.h"
+ #include "mntopts.h"
+ #include "pathnames.h"
+@@ -160,6 +162,7 @@
+ static int
+ exec_mountprog(const char *name, const char *execname, char *const argv[])
+ {
++ char buf[256];
+ pid_t pid;
+ int status;
+
+@@ -168,13 +171,11 @@
+ warn("fork");
+ exit (1);
+ case 0: /* Child. */
+- /* Go find an executable. */
+- execvP(execname, _PATH_SYSPATH, argv);
++ /* Mount programs are located in /sbin. */
++ snprintf(buf, sizeof(buf), "/sbin/%s", execname);
++ execv(buf, argv);
+ if (errno == ENOENT) {
+ warn("exec %s not found", execname);
+- if (execname[0] != '/') {
+- warnx("in path: %s", _PATH_SYSPATH);
+- }
+ }
+ exit(1);
+ default: /* Parent. */
+@@ -251,7 +252,7 @@
+ options = NULL;
+ vfslist = NULL;
+ vfstype = "ufs";
+- while ((ch = getopt(argc, argv, "adF:flo:prt:uvw")) != -1)
++ while ((ch = getopt(argc, argv, "adflo:prt:uvw")) != -1)
+ switch (ch) {
+ case 'a':
+ all = 1;
+@@ -259,9 +260,6 @@
+ case 'd':
+ debug = 1;
+ break;
+- case 'F':
+- setfstab(optarg);
+- break;
+ case 'f':
+ init_flags |= MNT_FORCE;
+ break;
+@@ -646,11 +644,13 @@
+ (void)printf(", reads: sync %ju async %ju",
+ (uintmax_t)sfp->f_syncreads,
+ (uintmax_t)sfp->f_asyncreads);
++#ifdef __FreeBSD__
+ if (sfp->f_fsid.val[0] != 0 || sfp->f_fsid.val[1] != 0) {
+ printf(", fsid ");
+ for (i = 0; i < sizeof(sfp->f_fsid); i++)
+ printf("%02x", ((u_char *)&sfp->f_fsid)[i]);
+ }
++#endif
+ }
+ (void)printf(")\n");
+ }
+@@ -840,7 +840,7 @@
+ {
+
+ (void)fprintf(stderr, "%s\n%s\n%s\n",
+-"usage: mount [-adflpruvw] [-F fstab] [-o options] [-t ufs | external_type]",
++"usage: mount [-adflpruvw] [-o options] [-t ufs | external_type]",
+ " mount [-dfpruvw] special | node",
+ " mount [-dfpruvw] [-o options] [-t ufs | external_type] special node");
+ exit(1);
+@@ -857,7 +857,7 @@
+
+ if (strncmp(ent->f_mntfromname, "<below>", 7) == 0 ||
+ strncmp(ent->f_mntfromname, "<above>", 7) == 0) {
+- strcpy(ent->f_mntfromname, (strnstr(ent->f_mntfromname, ":", 8)
++ strcpy(ent->f_mntfromname, (memchr(ent->f_mntfromname, ':', 8)
+ +1));
+ }
+
+--- a/sbin/mount/Makefile
++++ b/sbin/mount/Makefile
+@@ -8,6 +8,6 @@
+ # We do NOT install the getmntopts.3 man page.
+
+ DPADD= ${LIBUTIL}
+-LDADD= -lutil
++LDADD= -lutil -lbsd
+
+ .include <bsd.prog.mk>
Added: trunk/fuse4bsd/debian/patches/series
===================================================================
--- trunk/fuse4bsd/debian/patches/series (rev 0)
+++ trunk/fuse4bsd/debian/patches/series 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,6 @@
+000_sbin_mount.diff
+001_ports.diff
+002_misc.diff
+003_kernel_api.diff
+004_freebsd_macro.diff
+007_mount.diff
Added: trunk/fuse4bsd/debian/rules
===================================================================
--- trunk/fuse4bsd/debian/rules (rev 0)
+++ trunk/fuse4bsd/debian/rules 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1,96 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses cdbs. Originaly written by Robert Millan.
+# This file is public domain.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS = -Wall -g -pipe -D_GNU_SOURCE -D'__FBSDID(string)='
+
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+VERSION = $(shell dpkg-parsechangelog | sed -ne 's/^Version: \(.*\)-[^-]*$$/\1/p')
+
+PATH:=/usr/lib/freebsd:$(PATH)
+PMAKE=COPTS="$(CFLAGS)" WERROR= MOUNT=$(CURDIR)/sbin/mount make
+
+
+build: build-arch build-indep
+
+build-arch:
+ $(PMAKE) -C mount_fusefs
+
+build-indep: build-indep-stamp
+build-indep-stamp:
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+
+ -$(PMAKE) -C mount_fusefs clean
+
+ rm -f fuse_module/@ fuse_module/machine
+
+ rm -f *stamp
+ dh_clean
+
+install: install-indep install-arch
+install-indep:
+ dh_testdir
+ dh_testroot
+ dh_prep -i
+ dh_installdirs -i
+ dh_install -i
+ mkdir -p debian/fuse-dkms/usr/src/fuse-$(VERSION)/tools
+ cp -a fuse_module Makefile.common include \
+ debian/fuse-dkms/usr/src/fuse-$(VERSION)/
+ install -m755 tools/genopnames.awk debian/fuse-dkms/usr/src/fuse-$(VERSION)/tools/
+
+install-arch:
+ dh_testdir
+ dh_testroot
+ dh_prep -a
+ dh_installdirs -a
+ dh_install -a
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependant files that arn't kernel modules here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs
+ dh_installdocs
+# dh_installexamples
+# dh_installmenu
+ dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_python
+ dh_dkms -V $(VERSION)
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-arch binary-indep
+.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch configure
Property changes on: trunk/fuse4bsd/debian/rules
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/fuse4bsd/debian/source/format
===================================================================
--- trunk/fuse4bsd/debian/source/format (rev 0)
+++ trunk/fuse4bsd/debian/source/format 2011-07-10 22:15:33 UTC (rev 3557)
@@ -0,0 +1 @@
+3.0 (quilt)
More information about the Glibc-bsd-commits
mailing list