18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1980, 1989, 1993, 1994 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * 58fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 68fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 78fae3551SRodney W. Grimes * are met: 88fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 98fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 108fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 118fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 128fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 138fae3551SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 148fae3551SRodney W. Grimes * must display the following acknowledgement: 158fae3551SRodney W. Grimes * This product includes software developed by the University of 168fae3551SRodney W. Grimes * California, Berkeley and its contributors. 178fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 188fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 198fae3551SRodney W. Grimes * without specific prior written permission. 208fae3551SRodney W. Grimes * 218fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 228fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 238fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 248fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 258fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 268fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 278fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 288fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 298fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 308fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 318fae3551SRodney W. Grimes * SUCH DAMAGE. 328fae3551SRodney W. Grimes */ 338fae3551SRodney W. Grimes 348fae3551SRodney W. Grimes #ifndef lint 358fae3551SRodney W. Grimes static char copyright[] = 368fae3551SRodney W. Grimes "@(#) Copyright (c) 1980, 1989, 1993, 1994\n\ 378fae3551SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 388fae3551SRodney W. Grimes #endif /* not lint */ 398fae3551SRodney W. Grimes 408fae3551SRodney W. Grimes #ifndef lint 418fae3551SRodney W. Grimes static char sccsid[] = "@(#)mount.c 8.19 (Berkeley) 4/19/94"; 428fae3551SRodney W. Grimes #endif /* not lint */ 438fae3551SRodney W. Grimes 448fae3551SRodney W. Grimes #include <sys/param.h> 458fae3551SRodney W. Grimes #include <sys/mount.h> 468fae3551SRodney W. Grimes #include <sys/wait.h> 478fae3551SRodney W. Grimes 488fae3551SRodney W. Grimes #include <err.h> 498fae3551SRodney W. Grimes #include <errno.h> 508fae3551SRodney W. Grimes #include <fstab.h> 518fae3551SRodney W. Grimes #include <signal.h> 528fae3551SRodney W. Grimes #include <stdio.h> 538fae3551SRodney W. Grimes #include <stdlib.h> 548fae3551SRodney W. Grimes #include <string.h> 558fae3551SRodney W. Grimes #include <unistd.h> 568fae3551SRodney W. Grimes 578fae3551SRodney W. Grimes #include "pathnames.h" 588fae3551SRodney W. Grimes 598fae3551SRodney W. Grimes int debug, verbose, skipvfs; 608fae3551SRodney W. Grimes 618fae3551SRodney W. Grimes int badvfsname __P((const char *, const char **)); 628fae3551SRodney W. Grimes int badvfstype __P((int, const char **)); 638fae3551SRodney W. Grimes char *catopt __P((char *, const char *)); 648fae3551SRodney W. Grimes struct statfs 658fae3551SRodney W. Grimes *getmntpt __P((const char *)); 668fae3551SRodney W. Grimes const char 678fae3551SRodney W. Grimes **makevfslist __P((char *)); 688fae3551SRodney W. Grimes void mangle __P((char *, int *, const char **)); 698fae3551SRodney W. Grimes int mountfs __P((const char *, const char *, const char *, 708fae3551SRodney W. Grimes int, const char *, const char *)); 718fae3551SRodney W. Grimes void prmount __P((const char *, const char *, int)); 728fae3551SRodney W. Grimes void usage __P((void)); 738fae3551SRodney W. Grimes 748fae3551SRodney W. Grimes /* From mount_ufs.c. */ 758fae3551SRodney W. Grimes int mount_ufs __P((int, char * const *)); 768fae3551SRodney W. Grimes 778fae3551SRodney W. Grimes /* Map from mount otions to printable formats. */ 788fae3551SRodney W. Grimes static struct opt { 798fae3551SRodney W. Grimes int o_opt; 808fae3551SRodney W. Grimes const char *o_name; 818fae3551SRodney W. Grimes } optnames[] = { 828fae3551SRodney W. Grimes { MNT_ASYNC, "asynchronous" }, 838fae3551SRodney W. Grimes { MNT_EXPORTED, "NFS exported" }, 848fae3551SRodney W. Grimes { MNT_LOCAL, "local" }, 858fae3551SRodney W. Grimes { MNT_NODEV, "nodev" }, 868fae3551SRodney W. Grimes { MNT_NOEXEC, "noexec" }, 878fae3551SRodney W. Grimes { MNT_NOSUID, "nosuid" }, 888fae3551SRodney W. Grimes { MNT_QUOTA, "with quotas" }, 898fae3551SRodney W. Grimes { MNT_RDONLY, "read-only" }, 908fae3551SRodney W. Grimes { MNT_SYNCHRONOUS, "synchronous" }, 918fae3551SRodney W. Grimes { MNT_UNION, "union" }, 928fae3551SRodney W. Grimes { MNT_USER, "user mount" }, 938fae3551SRodney W. Grimes { NULL } 948fae3551SRodney W. Grimes }; 958fae3551SRodney W. Grimes 968fae3551SRodney W. Grimes int 978fae3551SRodney W. Grimes main(argc, argv) 988fae3551SRodney W. Grimes int argc; 998fae3551SRodney W. Grimes char * const argv[]; 1008fae3551SRodney W. Grimes { 1018fae3551SRodney W. Grimes const char *mntonname, **vfslist, *vfstype; 1028fae3551SRodney W. Grimes struct fstab *fs; 1038fae3551SRodney W. Grimes struct statfs *mntbuf; 1048fae3551SRodney W. Grimes FILE *mountdfp; 1058fae3551SRodney W. Grimes pid_t pid; 1068fae3551SRodney W. Grimes int all, ch, i, init_flags, mntsize, rval; 1078fae3551SRodney W. Grimes char *options; 1088fae3551SRodney W. Grimes 1098fae3551SRodney W. Grimes all = init_flags = 0; 1108fae3551SRodney W. Grimes options = NULL; 1118fae3551SRodney W. Grimes vfslist = NULL; 1128fae3551SRodney W. Grimes vfstype = "ufs"; 1138fae3551SRodney W. Grimes while ((ch = getopt(argc, argv, "adfo:rwt:uv")) != EOF) 1148fae3551SRodney W. Grimes switch (ch) { 1158fae3551SRodney W. Grimes case 'a': 1168fae3551SRodney W. Grimes all = 1; 1178fae3551SRodney W. Grimes break; 1188fae3551SRodney W. Grimes case 'd': 1198fae3551SRodney W. Grimes debug = 1; 1208fae3551SRodney W. Grimes break; 1218fae3551SRodney W. Grimes case 'f': 1228fae3551SRodney W. Grimes init_flags |= MNT_FORCE; 1238fae3551SRodney W. Grimes break; 1248fae3551SRodney W. Grimes case 'o': 1258fae3551SRodney W. Grimes if (*optarg) 1268fae3551SRodney W. Grimes options = catopt(options, optarg); 1278fae3551SRodney W. Grimes break; 1288fae3551SRodney W. Grimes case 'r': 1298fae3551SRodney W. Grimes init_flags |= MNT_RDONLY; 1308fae3551SRodney W. Grimes break; 1318fae3551SRodney W. Grimes case 't': 1328fae3551SRodney W. Grimes if (vfslist != NULL) 1338fae3551SRodney W. Grimes errx(1, "only one -t option may be specified."); 1348fae3551SRodney W. Grimes vfslist = makevfslist(optarg); 1358fae3551SRodney W. Grimes vfstype = optarg; 1368fae3551SRodney W. Grimes break; 1378fae3551SRodney W. Grimes case 'u': 1388fae3551SRodney W. Grimes init_flags |= MNT_UPDATE; 1398fae3551SRodney W. Grimes break; 1408fae3551SRodney W. Grimes case 'v': 1418fae3551SRodney W. Grimes verbose = 1; 1428fae3551SRodney W. Grimes break; 1438fae3551SRodney W. Grimes case 'w': 1448fae3551SRodney W. Grimes init_flags &= ~MNT_RDONLY; 1458fae3551SRodney W. Grimes break; 1468fae3551SRodney W. Grimes case '?': 1478fae3551SRodney W. Grimes default: 1488fae3551SRodney W. Grimes usage(); 1498fae3551SRodney W. Grimes /* NOTREACHED */ 1508fae3551SRodney W. Grimes } 1518fae3551SRodney W. Grimes argc -= optind; 1528fae3551SRodney W. Grimes argv += optind; 1538fae3551SRodney W. Grimes 1548fae3551SRodney W. Grimes #define BADTYPE(type) \ 1558fae3551SRodney W. Grimes (strcmp(type, FSTAB_RO) && \ 1568fae3551SRodney W. Grimes strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) 1578fae3551SRodney W. Grimes 1588fae3551SRodney W. Grimes rval = 0; 1598fae3551SRodney W. Grimes switch (argc) { 1608fae3551SRodney W. Grimes case 0: 1618fae3551SRodney W. Grimes if (all) 1628fae3551SRodney W. Grimes while ((fs = getfsent()) != NULL) { 1638fae3551SRodney W. Grimes if (BADTYPE(fs->fs_type)) 1648fae3551SRodney W. Grimes continue; 1658fae3551SRodney W. Grimes if (badvfsname(fs->fs_vfstype, vfslist)) 1668fae3551SRodney W. Grimes continue; 1678fae3551SRodney W. Grimes if (mountfs(fs->fs_vfstype, fs->fs_spec, 1688fae3551SRodney W. Grimes fs->fs_file, init_flags, options, 1698fae3551SRodney W. Grimes fs->fs_mntops)) 1708fae3551SRodney W. Grimes rval = 1; 1718fae3551SRodney W. Grimes } 1728fae3551SRodney W. Grimes else { 1738fae3551SRodney W. Grimes if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) 1748fae3551SRodney W. Grimes err(1, "getmntinfo"); 1758fae3551SRodney W. Grimes for (i = 0; i < mntsize; i++) { 1768fae3551SRodney W. Grimes if (badvfstype(mntbuf[i].f_type, vfslist)) 1778fae3551SRodney W. Grimes continue; 1788fae3551SRodney W. Grimes prmount(mntbuf[i].f_mntfromname, 1798fae3551SRodney W. Grimes mntbuf[i].f_mntonname, mntbuf[i].f_flags); 1808fae3551SRodney W. Grimes } 1818fae3551SRodney W. Grimes } 1828fae3551SRodney W. Grimes exit(rval); 1838fae3551SRodney W. Grimes case 1: 1848fae3551SRodney W. Grimes if (vfslist != NULL) 1858fae3551SRodney W. Grimes usage(); 1868fae3551SRodney W. Grimes 1878fae3551SRodney W. Grimes if (init_flags & MNT_UPDATE) { 1888fae3551SRodney W. Grimes if ((mntbuf = getmntpt(*argv)) == NULL) 1898fae3551SRodney W. Grimes errx(1, 1908fae3551SRodney W. Grimes "unknown special file or file system %s.", 1918fae3551SRodney W. Grimes *argv); 1928fae3551SRodney W. Grimes if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL) 1938fae3551SRodney W. Grimes errx(1, "can't find fstab entry for %s.", 1948fae3551SRodney W. Grimes *argv); 1958fae3551SRodney W. Grimes /* If it's an update, ignore the fstab file options. */ 1968fae3551SRodney W. Grimes fs->fs_mntops = NULL; 1978fae3551SRodney W. Grimes mntonname = mntbuf->f_mntonname; 1988fae3551SRodney W. Grimes } else { 1998fae3551SRodney W. Grimes if ((fs = getfsfile(*argv)) == NULL && 2008fae3551SRodney W. Grimes (fs = getfsspec(*argv)) == NULL) 2018fae3551SRodney W. Grimes errx(1, 2028fae3551SRodney W. Grimes "%s: unknown special file or file system.", 2038fae3551SRodney W. Grimes *argv); 2048fae3551SRodney W. Grimes if (BADTYPE(fs->fs_type)) 2058fae3551SRodney W. Grimes errx(1, "%s has unknown file system type.", 2068fae3551SRodney W. Grimes *argv); 2078fae3551SRodney W. Grimes mntonname = fs->fs_file; 2088fae3551SRodney W. Grimes } 2098fae3551SRodney W. Grimes rval = mountfs(fs->fs_vfstype, fs->fs_spec, 2108fae3551SRodney W. Grimes mntonname, init_flags, options, fs->fs_mntops); 2118fae3551SRodney W. Grimes break; 2128fae3551SRodney W. Grimes case 2: 2138fae3551SRodney W. Grimes /* 2148fae3551SRodney W. Grimes * If -t flag has not been specified, and spec contains either 2158fae3551SRodney W. Grimes * a ':' or a '@' then assume that an NFS filesystem is being 2168fae3551SRodney W. Grimes * specified ala Sun. 2178fae3551SRodney W. Grimes */ 2188fae3551SRodney W. Grimes if (vfslist == NULL && strpbrk(argv[0], ":@") != NULL) 2198fae3551SRodney W. Grimes vfstype = "nfs"; 2208fae3551SRodney W. Grimes rval = mountfs(vfstype, 2218fae3551SRodney W. Grimes argv[0], argv[1], init_flags, options, NULL); 2228fae3551SRodney W. Grimes break; 2238fae3551SRodney W. Grimes default: 2248fae3551SRodney W. Grimes usage(); 2258fae3551SRodney W. Grimes /* NOTREACHED */ 2268fae3551SRodney W. Grimes } 2278fae3551SRodney W. Grimes 2288fae3551SRodney W. Grimes /* 2298fae3551SRodney W. Grimes * If the mount was successfully, and done by root, tell mountd the 2308fae3551SRodney W. Grimes * good news. Pid checks are probably unnecessary, but don't hurt. 2318fae3551SRodney W. Grimes */ 2328fae3551SRodney W. Grimes if (rval == 0 && getuid() == 0 && 2338fae3551SRodney W. Grimes (mountdfp = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 2348fae3551SRodney W. Grimes if (fscanf(mountdfp, "%ld", &pid) == 1 && 2358fae3551SRodney W. Grimes pid > 0 && kill(pid, SIGHUP) == -1 && errno != ESRCH) 2368fae3551SRodney W. Grimes err(1, "signal mountd"); 2378fae3551SRodney W. Grimes (void)fclose(mountdfp); 2388fae3551SRodney W. Grimes } 2398fae3551SRodney W. Grimes 2408fae3551SRodney W. Grimes exit(rval); 2418fae3551SRodney W. Grimes } 2428fae3551SRodney W. Grimes 2438fae3551SRodney W. Grimes int 2448fae3551SRodney W. Grimes mountfs(vfstype, spec, name, flags, options, mntopts) 2458fae3551SRodney W. Grimes const char *vfstype, *spec, *name, *options, *mntopts; 2468fae3551SRodney W. Grimes int flags; 2478fae3551SRodney W. Grimes { 2488fae3551SRodney W. Grimes /* List of directories containing mount_xxx subcommands. */ 2498fae3551SRodney W. Grimes static const char *edirs[] = { 2508fae3551SRodney W. Grimes _PATH_SBIN, 2518fae3551SRodney W. Grimes _PATH_USRSBIN, 2528fae3551SRodney W. Grimes NULL 2538fae3551SRodney W. Grimes }; 2548fae3551SRodney W. Grimes const char *argv[100], **edir; 2558fae3551SRodney W. Grimes struct statfs sf; 2568fae3551SRodney W. Grimes pid_t pid; 2578fae3551SRodney W. Grimes int argc, i, status; 2588fae3551SRodney W. Grimes char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN]; 2598fae3551SRodney W. Grimes 2608fae3551SRodney W. Grimes if (realpath(name, mntpath) == NULL) { 2618fae3551SRodney W. Grimes warn("%s", mntpath); 2628fae3551SRodney W. Grimes return (1); 2638fae3551SRodney W. Grimes } 2648fae3551SRodney W. Grimes 2658fae3551SRodney W. Grimes name = mntpath; 2668fae3551SRodney W. Grimes 2678fae3551SRodney W. Grimes if (options == NULL) { 2688fae3551SRodney W. Grimes if (mntopts == NULL || *mntopts == '\0') 2698fae3551SRodney W. Grimes options = "rw"; 2708fae3551SRodney W. Grimes else 2718fae3551SRodney W. Grimes options = mntopts; 2728fae3551SRodney W. Grimes mntopts = ""; 2738fae3551SRodney W. Grimes } 2748fae3551SRodney W. Grimes optbuf = catopt(strdup(mntopts), options); 2758fae3551SRodney W. Grimes 2768fae3551SRodney W. Grimes if (strcmp(name, "/") == 0) 2778fae3551SRodney W. Grimes flags |= MNT_UPDATE; 2788fae3551SRodney W. Grimes if (flags & MNT_FORCE) 2798fae3551SRodney W. Grimes optbuf = catopt(optbuf, "force"); 2808fae3551SRodney W. Grimes if (flags & MNT_RDONLY) 2818fae3551SRodney W. Grimes optbuf = catopt(optbuf, "ro"); 2828fae3551SRodney W. Grimes /* 2838fae3551SRodney W. Grimes * XXX 2848fae3551SRodney W. Grimes * The mount_mfs (newfs) command uses -o to select the 2858fae3551SRodney W. Grimes * optimisation mode. We don't pass the default "-o rw" 2868fae3551SRodney W. Grimes * for that reason. 2878fae3551SRodney W. Grimes */ 2888fae3551SRodney W. Grimes if (flags & MNT_UPDATE) 2898fae3551SRodney W. Grimes optbuf = catopt(optbuf, "update"); 2908fae3551SRodney W. Grimes 2918fae3551SRodney W. Grimes argc = 0; 2928fae3551SRodney W. Grimes argv[argc++] = vfstype; 2938fae3551SRodney W. Grimes mangle(optbuf, &argc, argv); 2948fae3551SRodney W. Grimes argv[argc++] = spec; 2958fae3551SRodney W. Grimes argv[argc++] = name; 2968fae3551SRodney W. Grimes argv[argc] = NULL; 2978fae3551SRodney W. Grimes 2988fae3551SRodney W. Grimes if (debug) { 2998fae3551SRodney W. Grimes (void)printf("exec: mount_%s", vfstype); 3008fae3551SRodney W. Grimes for (i = 1; i < argc; i++) 3018fae3551SRodney W. Grimes (void)printf(" %s", argv[i]); 3028fae3551SRodney W. Grimes (void)printf("\n"); 3038fae3551SRodney W. Grimes return (0); 3048fae3551SRodney W. Grimes } 3058fae3551SRodney W. Grimes 3068fae3551SRodney W. Grimes switch (pid = vfork()) { 3078fae3551SRodney W. Grimes case -1: /* Error. */ 3088fae3551SRodney W. Grimes warn("vfork"); 3098fae3551SRodney W. Grimes free(optbuf); 3108fae3551SRodney W. Grimes return (1); 3118fae3551SRodney W. Grimes case 0: /* Child. */ 3128fae3551SRodney W. Grimes if (strcmp(vfstype, "ufs") == 0) 3138fae3551SRodney W. Grimes exit(mount_ufs(argc, (char * const *) argv)); 3148fae3551SRodney W. Grimes 3158fae3551SRodney W. Grimes /* Go find an executable. */ 3168fae3551SRodney W. Grimes edir = edirs; 3178fae3551SRodney W. Grimes do { 3188fae3551SRodney W. Grimes (void)snprintf(execname, 3198fae3551SRodney W. Grimes sizeof(execname), "%s/mount_%s", *edir, vfstype); 3208fae3551SRodney W. Grimes execv(execname, (char * const *)argv); 3218fae3551SRodney W. Grimes if (errno != ENOENT) 3228fae3551SRodney W. Grimes warn("exec %s for %s", execname, name); 3238fae3551SRodney W. Grimes } while (*++edir != NULL); 3248fae3551SRodney W. Grimes 3258fae3551SRodney W. Grimes if (errno == ENOENT) 3268fae3551SRodney W. Grimes warn("exec %s for %s", execname, name); 3278fae3551SRodney W. Grimes exit(1); 3288fae3551SRodney W. Grimes /* NOTREACHED */ 3298fae3551SRodney W. Grimes default: /* Parent. */ 3308fae3551SRodney W. Grimes free(optbuf); 3318fae3551SRodney W. Grimes 3328fae3551SRodney W. Grimes if (waitpid(pid, &status, 0) < 0) { 3338fae3551SRodney W. Grimes warn("waitpid"); 3348fae3551SRodney W. Grimes return (1); 3358fae3551SRodney W. Grimes } 3368fae3551SRodney W. Grimes 3378fae3551SRodney W. Grimes if (WIFEXITED(status)) { 3388fae3551SRodney W. Grimes if (WEXITSTATUS(status) != 0) 3398fae3551SRodney W. Grimes return (WEXITSTATUS(status)); 3408fae3551SRodney W. Grimes } else if (WIFSIGNALED(status)) { 3418fae3551SRodney W. Grimes warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]); 3428fae3551SRodney W. Grimes return (1); 3438fae3551SRodney W. Grimes } 3448fae3551SRodney W. Grimes 3458fae3551SRodney W. Grimes if (verbose) { 3468fae3551SRodney W. Grimes if (statfs(name, &sf) < 0) { 3478fae3551SRodney W. Grimes warn("%s", name); 3488fae3551SRodney W. Grimes return (1); 3498fae3551SRodney W. Grimes } 3508fae3551SRodney W. Grimes prmount(sf.f_mntfromname, sf.f_mntonname, sf.f_flags); 3518fae3551SRodney W. Grimes } 3528fae3551SRodney W. Grimes break; 3538fae3551SRodney W. Grimes } 3548fae3551SRodney W. Grimes 3558fae3551SRodney W. Grimes return (0); 3568fae3551SRodney W. Grimes } 3578fae3551SRodney W. Grimes 3588fae3551SRodney W. Grimes void 3598fae3551SRodney W. Grimes prmount(spec, name, flags) 3608fae3551SRodney W. Grimes const char *spec, *name; 3618fae3551SRodney W. Grimes int flags; 3628fae3551SRodney W. Grimes { 3638fae3551SRodney W. Grimes struct opt *o; 3648fae3551SRodney W. Grimes int f; 3658fae3551SRodney W. Grimes 3668fae3551SRodney W. Grimes (void)printf("%s on %s", spec, name); 3678fae3551SRodney W. Grimes 3688fae3551SRodney W. Grimes flags &= MNT_VISFLAGMASK; 3698fae3551SRodney W. Grimes for (f = 0, o = optnames; flags && o->o_opt; o++) 3708fae3551SRodney W. Grimes if (flags & o->o_opt) { 3718fae3551SRodney W. Grimes (void)printf("%s%s", !f++ ? " (" : ", ", o->o_name); 3728fae3551SRodney W. Grimes flags &= ~o->o_opt; 3738fae3551SRodney W. Grimes } 3748fae3551SRodney W. Grimes (void)printf(f ? ")\n" : "\n"); 3758fae3551SRodney W. Grimes } 3768fae3551SRodney W. Grimes 3778fae3551SRodney W. Grimes struct statfs * 3788fae3551SRodney W. Grimes getmntpt(name) 3798fae3551SRodney W. Grimes const char *name; 3808fae3551SRodney W. Grimes { 3818fae3551SRodney W. Grimes struct statfs *mntbuf; 3828fae3551SRodney W. Grimes int i, mntsize; 3838fae3551SRodney W. Grimes 3848fae3551SRodney W. Grimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 3858fae3551SRodney W. Grimes for (i = 0; i < mntsize; i++) 3868fae3551SRodney W. Grimes if (strcmp(mntbuf[i].f_mntfromname, name) == 0 || 3878fae3551SRodney W. Grimes strcmp(mntbuf[i].f_mntonname, name) == 0) 3888fae3551SRodney W. Grimes return (&mntbuf[i]); 3898fae3551SRodney W. Grimes return (NULL); 3908fae3551SRodney W. Grimes } 3918fae3551SRodney W. Grimes 3928fae3551SRodney W. Grimes int 3938fae3551SRodney W. Grimes badvfsname(vfsname, vfslist) 3948fae3551SRodney W. Grimes const char *vfsname; 3958fae3551SRodney W. Grimes const char **vfslist; 3968fae3551SRodney W. Grimes { 3978fae3551SRodney W. Grimes 3988fae3551SRodney W. Grimes if (vfslist == NULL) 3998fae3551SRodney W. Grimes return (0); 4008fae3551SRodney W. Grimes while (*vfslist != NULL) { 4018fae3551SRodney W. Grimes if (strcmp(vfsname, *vfslist) == 0) 4028fae3551SRodney W. Grimes return (skipvfs); 4038fae3551SRodney W. Grimes ++vfslist; 4048fae3551SRodney W. Grimes } 4058fae3551SRodney W. Grimes return (!skipvfs); 4068fae3551SRodney W. Grimes } 4078fae3551SRodney W. Grimes 4088fae3551SRodney W. Grimes int 4098fae3551SRodney W. Grimes badvfstype(vfstype, vfslist) 4108fae3551SRodney W. Grimes int vfstype; 4118fae3551SRodney W. Grimes const char **vfslist; 4128fae3551SRodney W. Grimes { 4138fae3551SRodney W. Grimes static const char *vfsnames[] = INITMOUNTNAMES; 4148fae3551SRodney W. Grimes 4158fae3551SRodney W. Grimes if ((vfstype < 0) || (vfstype > MOUNT_MAXTYPE)) 4168fae3551SRodney W. Grimes return (0); 4178fae3551SRodney W. Grimes 4188fae3551SRodney W. Grimes return (badvfsname(vfsnames[vfstype], vfslist)); 4198fae3551SRodney W. Grimes } 4208fae3551SRodney W. Grimes 4218fae3551SRodney W. Grimes const char ** 4228fae3551SRodney W. Grimes makevfslist(fslist) 4238fae3551SRodney W. Grimes char *fslist; 4248fae3551SRodney W. Grimes { 4258fae3551SRodney W. Grimes const char **av; 4268fae3551SRodney W. Grimes int i; 4278fae3551SRodney W. Grimes char *nextcp; 4288fae3551SRodney W. Grimes 4298fae3551SRodney W. Grimes if (fslist == NULL) 4308fae3551SRodney W. Grimes return (NULL); 4318fae3551SRodney W. Grimes if (fslist[0] == 'n' && fslist[1] == 'o') { 4328fae3551SRodney W. Grimes fslist += 2; 4338fae3551SRodney W. Grimes skipvfs = 1; 4348fae3551SRodney W. Grimes } 4358fae3551SRodney W. Grimes for (i = 0, nextcp = fslist; *nextcp; nextcp++) 4368fae3551SRodney W. Grimes if (*nextcp == ',') 4378fae3551SRodney W. Grimes i++; 4388fae3551SRodney W. Grimes if ((av = malloc((size_t)(i + 2) * sizeof(char *))) == NULL) { 4398fae3551SRodney W. Grimes warn(NULL); 4408fae3551SRodney W. Grimes return (NULL); 4418fae3551SRodney W. Grimes } 4428fae3551SRodney W. Grimes nextcp = fslist; 4438fae3551SRodney W. Grimes i = 0; 4448fae3551SRodney W. Grimes av[i++] = nextcp; 4458fae3551SRodney W. Grimes while ((nextcp = strchr(nextcp, ',')) != NULL) { 4468fae3551SRodney W. Grimes *nextcp++ = '\0'; 4478fae3551SRodney W. Grimes av[i++] = nextcp; 4488fae3551SRodney W. Grimes } 4498fae3551SRodney W. Grimes av[i++] = NULL; 4508fae3551SRodney W. Grimes return (av); 4518fae3551SRodney W. Grimes } 4528fae3551SRodney W. Grimes 4538fae3551SRodney W. Grimes char * 4548fae3551SRodney W. Grimes catopt(s0, s1) 4558fae3551SRodney W. Grimes char *s0; 4568fae3551SRodney W. Grimes const char *s1; 4578fae3551SRodney W. Grimes { 4588fae3551SRodney W. Grimes size_t i; 4598fae3551SRodney W. Grimes char *cp; 4608fae3551SRodney W. Grimes 4618fae3551SRodney W. Grimes if (s0 && *s0) { 4628fae3551SRodney W. Grimes i = strlen(s0) + strlen(s1) + 1 + 1; 4638fae3551SRodney W. Grimes if ((cp = malloc(i)) == NULL) 4648fae3551SRodney W. Grimes err(1, NULL); 4658fae3551SRodney W. Grimes (void)snprintf(cp, i, "%s,%s", s0, s1); 4668fae3551SRodney W. Grimes } else 4678fae3551SRodney W. Grimes cp = strdup(s1); 4688fae3551SRodney W. Grimes 4698fae3551SRodney W. Grimes if (s0) 4708fae3551SRodney W. Grimes free(s0); 4718fae3551SRodney W. Grimes return (cp); 4728fae3551SRodney W. Grimes } 4738fae3551SRodney W. Grimes 4748fae3551SRodney W. Grimes void 4758fae3551SRodney W. Grimes mangle(options, argcp, argv) 4768fae3551SRodney W. Grimes char *options; 4778fae3551SRodney W. Grimes int *argcp; 4788fae3551SRodney W. Grimes const char **argv; 4798fae3551SRodney W. Grimes { 4808fae3551SRodney W. Grimes char *p, *s; 4818fae3551SRodney W. Grimes int argc; 4828fae3551SRodney W. Grimes 4838fae3551SRodney W. Grimes argc = *argcp; 4848fae3551SRodney W. Grimes for (s = options; (p = strsep(&s, ",")) != NULL;) 4858fae3551SRodney W. Grimes if (*p != '\0') 4868fae3551SRodney W. Grimes if (*p == '-') { 4878fae3551SRodney W. Grimes argv[argc++] = p; 4888fae3551SRodney W. Grimes p = strchr(p, '='); 4898fae3551SRodney W. Grimes if (p) { 4908fae3551SRodney W. Grimes *p = '\0'; 4918fae3551SRodney W. Grimes argv[argc++] = p+1; 4928fae3551SRodney W. Grimes } 4938fae3551SRodney W. Grimes } else if (strcmp(p, "rw") != 0) { 4948fae3551SRodney W. Grimes argv[argc++] = "-o"; 4958fae3551SRodney W. Grimes argv[argc++] = p; 4968fae3551SRodney W. Grimes } 4978fae3551SRodney W. Grimes 4988fae3551SRodney W. Grimes *argcp = argc; 4998fae3551SRodney W. Grimes } 5008fae3551SRodney W. Grimes 5018fae3551SRodney W. Grimes void 5028fae3551SRodney W. Grimes usage() 5038fae3551SRodney W. Grimes { 5048fae3551SRodney W. Grimes 5058fae3551SRodney W. Grimes (void)fprintf(stderr, 5068fae3551SRodney W. Grimes "usage: mount %s %s\n mount %s\n mount %s\n", 5078fae3551SRodney W. Grimes "[-dfruvw] [-o options] [-t ufs | external_type]", 5088fae3551SRodney W. Grimes "special node", 5098fae3551SRodney W. Grimes "[-adfruvw] [-t ufs | external_type]", 5108fae3551SRodney W. Grimes "[-dfruvw] special | node"); 5118fae3551SRodney W. Grimes exit(1); 5128fae3551SRodney W. Grimes } 513