mount.c revision 23678
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1980, 1989, 1993, 1994 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 351558Srgrimesstatic char copyright[] = 361558Srgrimes"@(#) Copyright (c) 1980, 1989, 1993, 1994\n\ 371558Srgrimes The Regents of the University of California. All rights reserved.\n"; 381558Srgrimes#endif /* not lint */ 391558Srgrimes 401558Srgrimes#ifndef lint 4123678Speterstatic char sccsid[] = "@(#)mount.c 8.25 (Berkeley) 5/8/95"; 421558Srgrimes#endif /* not lint */ 431558Srgrimes 441558Srgrimes#include <sys/param.h> 451558Srgrimes#include <sys/mount.h> 461558Srgrimes#include <sys/wait.h> 476441Sdg#include <sys/types.h> 486441Sdg#include <sys/stat.h> 491558Srgrimes 501558Srgrimes#include <err.h> 511558Srgrimes#include <errno.h> 521558Srgrimes#include <fstab.h> 5323678Speter#include <pwd.h> 541558Srgrimes#include <signal.h> 551558Srgrimes#include <stdio.h> 561558Srgrimes#include <stdlib.h> 571558Srgrimes#include <string.h> 581558Srgrimes#include <unistd.h> 591558Srgrimes 601558Srgrimes#include "pathnames.h" 611558Srgrimes 6223678Speterint debug, verbose; 6317243Sjkhint fstab_style = 0; 641558Srgrimes 6523678Speterint checkvfsname __P((const char *, const char **)); 661558Srgrimeschar *catopt __P((char *, const char *)); 671558Srgrimesstruct statfs 681558Srgrimes *getmntpt __P((const char *)); 6923678Speterint hasopt __P((const char *, const char *)); 701558Srgrimesconst char 711558Srgrimes **makevfslist __P((char *)); 721558Srgrimesvoid mangle __P((char *, int *, const char **)); 731558Srgrimesint mountfs __P((const char *, const char *, const char *, 741558Srgrimes int, const char *, const char *)); 7523678Spetervoid prmount __P((struct statfs *)); 761558Srgrimesvoid usage __P((void)); 7717243Sjkhvoid putfsent __P((const struct statfs *)); 781558Srgrimes 791558Srgrimes/* From mount_ufs.c. */ 801558Srgrimesint mount_ufs __P((int, char * const *)); 811558Srgrimes 821558Srgrimes/* Map from mount otions to printable formats. */ 831558Srgrimesstatic struct opt { 841558Srgrimes int o_opt; 851558Srgrimes const char *o_name; 861558Srgrimes} optnames[] = { 871558Srgrimes { MNT_ASYNC, "asynchronous" }, 881558Srgrimes { MNT_EXPORTED, "NFS exported" }, 891558Srgrimes { MNT_LOCAL, "local" }, 9018007Sdg { MNT_NOATIME, "noatime" }, 911558Srgrimes { MNT_NODEV, "nodev" }, 921558Srgrimes { MNT_NOEXEC, "noexec" }, 931558Srgrimes { MNT_NOSUID, "nosuid" }, 941558Srgrimes { MNT_QUOTA, "with quotas" }, 951558Srgrimes { MNT_RDONLY, "read-only" }, 961558Srgrimes { MNT_SYNCHRONOUS, "synchronous" }, 971558Srgrimes { MNT_UNION, "union" }, 9823678Speter { MNT_NOATIME, "noatime" }, 991558Srgrimes { NULL } 1001558Srgrimes}; 1011558Srgrimes 1021558Srgrimesint 1031558Srgrimesmain(argc, argv) 1041558Srgrimes int argc; 1051558Srgrimes char * const argv[]; 1061558Srgrimes{ 10723678Speter const char *mntfromname, **vfslist, *vfstype; 1081558Srgrimes struct fstab *fs; 1091558Srgrimes struct statfs *mntbuf; 1101558Srgrimes FILE *mountdfp; 1111558Srgrimes pid_t pid; 1121558Srgrimes int all, ch, i, init_flags, mntsize, rval; 1131558Srgrimes char *options; 1141558Srgrimes 1151558Srgrimes all = init_flags = 0; 1161558Srgrimes options = NULL; 1171558Srgrimes vfslist = NULL; 1181558Srgrimes vfstype = "ufs"; 11917243Sjkh while ((ch = getopt(argc, argv, "padfo:rwt:uv")) != EOF) 1201558Srgrimes switch (ch) { 12117243Sjkh case 'p': 12217243Sjkh fstab_style = 1; 12317243Sjkh verbose = 1; 12417243Sjkh break; 1251558Srgrimes case 'a': 1261558Srgrimes all = 1; 1271558Srgrimes break; 1281558Srgrimes case 'd': 1291558Srgrimes debug = 1; 1301558Srgrimes break; 1311558Srgrimes case 'f': 1321558Srgrimes init_flags |= MNT_FORCE; 1331558Srgrimes break; 1341558Srgrimes case 'o': 1351558Srgrimes if (*optarg) 1361558Srgrimes options = catopt(options, optarg); 1371558Srgrimes break; 1381558Srgrimes case 'r': 1391558Srgrimes init_flags |= MNT_RDONLY; 1401558Srgrimes break; 1411558Srgrimes case 't': 1421558Srgrimes if (vfslist != NULL) 1431558Srgrimes errx(1, "only one -t option may be specified."); 1441558Srgrimes vfslist = makevfslist(optarg); 1451558Srgrimes vfstype = optarg; 1461558Srgrimes break; 1471558Srgrimes case 'u': 1481558Srgrimes init_flags |= MNT_UPDATE; 1491558Srgrimes break; 1501558Srgrimes case 'v': 1511558Srgrimes verbose = 1; 1521558Srgrimes break; 1531558Srgrimes case 'w': 1541558Srgrimes init_flags &= ~MNT_RDONLY; 1551558Srgrimes break; 1561558Srgrimes case '?': 1571558Srgrimes default: 1581558Srgrimes usage(); 1591558Srgrimes /* NOTREACHED */ 1601558Srgrimes } 1611558Srgrimes argc -= optind; 1621558Srgrimes argv += optind; 1631558Srgrimes 1641558Srgrimes#define BADTYPE(type) \ 1651558Srgrimes (strcmp(type, FSTAB_RO) && \ 1661558Srgrimes strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) 1671558Srgrimes 1681558Srgrimes rval = 0; 1691558Srgrimes switch (argc) { 1701558Srgrimes case 0: 1711558Srgrimes if (all) 1721558Srgrimes while ((fs = getfsent()) != NULL) { 1731558Srgrimes if (BADTYPE(fs->fs_type)) 1741558Srgrimes continue; 17523678Speter if (checkvfsname(fs->fs_vfstype, vfslist)) 1761558Srgrimes continue; 17723678Speter if (hasopt(fs->fs_mntops, "noauto")) 17810288Sdg continue; 1791558Srgrimes if (mountfs(fs->fs_vfstype, fs->fs_spec, 18010288Sdg fs->fs_file, init_flags, options, 18110288Sdg fs->fs_mntops)) 18210199Sjkh rval = 1; 1831558Srgrimes } 18417243Sjkh else if (fstab_style) { 18517243Sjkh if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) 18617243Sjkh err(1, "getmntinfo"); 18717243Sjkh for (i = 0; i < mntsize; i++) { 18823678Speter if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 18917243Sjkh continue; 19017243Sjkh putfsent (&mntbuf[i]); 19117243Sjkh } 19217243Sjkh } 1931558Srgrimes else { 1941558Srgrimes if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) 1951558Srgrimes err(1, "getmntinfo"); 1961558Srgrimes for (i = 0; i < mntsize; i++) { 19723678Speter if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) 1981558Srgrimes continue; 19923678Speter prmount(&mntbuf[i]); 2001558Srgrimes } 2011558Srgrimes } 2021558Srgrimes exit(rval); 2031558Srgrimes case 1: 2041558Srgrimes if (vfslist != NULL) 2051558Srgrimes usage(); 2061558Srgrimes 2071558Srgrimes if (init_flags & MNT_UPDATE) { 2081558Srgrimes if ((mntbuf = getmntpt(*argv)) == NULL) 2091558Srgrimes errx(1, 2101558Srgrimes "unknown special file or file system %s.", 2111558Srgrimes *argv); 21223678Speter if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) 21323678Speter mntfromname = fs->fs_spec; 21423678Speter else 21523678Speter mntfromname = mntbuf->f_mntfromname; 21623678Speter rval = mountfs(mntbuf->f_fstypename, mntfromname, 21723678Speter mntbuf->f_mntonname, init_flags, options, 0); 21823678Speter break; 2191558Srgrimes } 22023678Speter if ((fs = getfsfile(*argv)) == NULL && 22123678Speter (fs = getfsspec(*argv)) == NULL) 22223678Speter errx(1, "%s: unknown special file or file system.", 22323678Speter *argv); 22423678Speter if (BADTYPE(fs->fs_type)) 22523678Speter errx(1, "%s has unknown file system type.", 22623678Speter *argv); 22723678Speter rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, 22823678Speter init_flags, options, fs->fs_mntops); 2291558Srgrimes break; 2301558Srgrimes case 2: 2311558Srgrimes /* 2321558Srgrimes * If -t flag has not been specified, and spec contains either 2331558Srgrimes * a ':' or a '@' then assume that an NFS filesystem is being 2341558Srgrimes * specified ala Sun. 2351558Srgrimes */ 2361558Srgrimes if (vfslist == NULL && strpbrk(argv[0], ":@") != NULL) 2371558Srgrimes vfstype = "nfs"; 2381558Srgrimes rval = mountfs(vfstype, 2391558Srgrimes argv[0], argv[1], init_flags, options, NULL); 2401558Srgrimes break; 2411558Srgrimes default: 2421558Srgrimes usage(); 2431558Srgrimes /* NOTREACHED */ 2441558Srgrimes } 2451558Srgrimes 2461558Srgrimes /* 2471558Srgrimes * If the mount was successfully, and done by root, tell mountd the 2481558Srgrimes * good news. Pid checks are probably unnecessary, but don't hurt. 2491558Srgrimes */ 2501558Srgrimes if (rval == 0 && getuid() == 0 && 2511558Srgrimes (mountdfp = fopen(_PATH_MOUNTDPID, "r")) != NULL) { 2521558Srgrimes if (fscanf(mountdfp, "%ld", &pid) == 1 && 2531558Srgrimes pid > 0 && kill(pid, SIGHUP) == -1 && errno != ESRCH) 2541558Srgrimes err(1, "signal mountd"); 2551558Srgrimes (void)fclose(mountdfp); 2561558Srgrimes } 2571558Srgrimes 2581558Srgrimes exit(rval); 2591558Srgrimes} 2601558Srgrimes 2611558Srgrimesint 26223678Speterhasopt(mntopts, option) 26323678Speter const char *mntopts, *option; 26423678Speter{ 26523678Speter int negative, found; 26623678Speter char *opt, *optbuf; 26723678Speter 26823678Speter if (option[0] == 'n' && option[1] == 'o') { 26923678Speter negative = 1; 27023678Speter option += 2; 27123678Speter } else 27223678Speter negative = 0; 27323678Speter optbuf = strdup(mntopts); 27423678Speter found = 0; 27523678Speter for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) { 27623678Speter if (opt[0] == 'n' && opt[1] == 'o') { 27723678Speter if (!strcasecmp(opt + 2, option)) 27823678Speter found = negative; 27923678Speter } else if (!strcasecmp(opt, option)) 28023678Speter found = !negative; 28123678Speter } 28223678Speter free(optbuf); 28323678Speter return (found); 28423678Speter} 28523678Speter 28623678Speterint 2871558Srgrimesmountfs(vfstype, spec, name, flags, options, mntopts) 2881558Srgrimes const char *vfstype, *spec, *name, *options, *mntopts; 2891558Srgrimes int flags; 2901558Srgrimes{ 2916441Sdg struct stat sb; 2926441Sdg 2931558Srgrimes /* List of directories containing mount_xxx subcommands. */ 2941558Srgrimes static const char *edirs[] = { 2951558Srgrimes _PATH_SBIN, 2961558Srgrimes _PATH_USRSBIN, 2971558Srgrimes NULL 2981558Srgrimes }; 2991558Srgrimes const char *argv[100], **edir; 3001558Srgrimes struct statfs sf; 3011558Srgrimes pid_t pid; 3021558Srgrimes int argc, i, status; 3031558Srgrimes char *optbuf, execname[MAXPATHLEN + 1], mntpath[MAXPATHLEN]; 3041558Srgrimes 3056491Sbde if (realpath(name, mntpath) != NULL && stat(mntpath, &sb) == 0) { 3066444Sdg if (!S_ISDIR(sb.st_mode)) { 3076441Sdg warnx("%s: Not a directory", mntpath); 3086441Sdg return (1); 3096441Sdg } 3106441Sdg } else { 3111558Srgrimes warn("%s", mntpath); 3121558Srgrimes return (1); 3131558Srgrimes } 3146441Sdg 3151818Sdg if (mntopts == NULL) 3161818Sdg mntopts = ""; 3171558Srgrimes 3181558Srgrimes name = mntpath; 3191558Srgrimes 32023678Speter if (mntopts == NULL) 32123678Speter mntopts = ""; 3221558Srgrimes if (options == NULL) { 32323678Speter if (*mntopts == '\0') { 3241558Srgrimes options = "rw"; 32523678Speter } else { 3261558Srgrimes options = mntopts; 32723678Speter mntopts = ""; 32823678Speter } 3291558Srgrimes } 3301558Srgrimes optbuf = catopt(strdup(mntopts), options); 3311558Srgrimes 3321558Srgrimes if (strcmp(name, "/") == 0) 3331558Srgrimes flags |= MNT_UPDATE; 3341558Srgrimes if (flags & MNT_FORCE) 3351558Srgrimes optbuf = catopt(optbuf, "force"); 3361558Srgrimes if (flags & MNT_RDONLY) 3371558Srgrimes optbuf = catopt(optbuf, "ro"); 3381558Srgrimes /* 3391558Srgrimes * XXX 3401558Srgrimes * The mount_mfs (newfs) command uses -o to select the 3411558Srgrimes * optimisation mode. We don't pass the default "-o rw" 3421558Srgrimes * for that reason. 3431558Srgrimes */ 3441558Srgrimes if (flags & MNT_UPDATE) 3451558Srgrimes optbuf = catopt(optbuf, "update"); 3461558Srgrimes 3471558Srgrimes argc = 0; 3481558Srgrimes argv[argc++] = vfstype; 3491558Srgrimes mangle(optbuf, &argc, argv); 3501558Srgrimes argv[argc++] = spec; 3511558Srgrimes argv[argc++] = name; 3521558Srgrimes argv[argc] = NULL; 3531558Srgrimes 3541558Srgrimes if (debug) { 3551558Srgrimes (void)printf("exec: mount_%s", vfstype); 3561558Srgrimes for (i = 1; i < argc; i++) 3571558Srgrimes (void)printf(" %s", argv[i]); 3581558Srgrimes (void)printf("\n"); 3591558Srgrimes return (0); 3601558Srgrimes } 3611558Srgrimes 3621558Srgrimes switch (pid = vfork()) { 3631558Srgrimes case -1: /* Error. */ 3641558Srgrimes warn("vfork"); 3651558Srgrimes free(optbuf); 3661558Srgrimes return (1); 3671558Srgrimes case 0: /* Child. */ 3681558Srgrimes if (strcmp(vfstype, "ufs") == 0) 3691558Srgrimes exit(mount_ufs(argc, (char * const *) argv)); 3701558Srgrimes 3711558Srgrimes /* Go find an executable. */ 37214626Sasami for (edir = edirs; *edir; edir++) { 3731558Srgrimes (void)snprintf(execname, 3741558Srgrimes sizeof(execname), "%s/mount_%s", *edir, vfstype); 3751558Srgrimes execv(execname, (char * const *)argv); 37614626Sasami } 37714626Sasami if (errno == ENOENT) { 37814626Sasami int len = 0; 37914626Sasami char *cp; 38014626Sasami for (edir = edirs; *edir; edir++) 38114626Sasami len += strlen(*edir) + 2; /* ", " */ 38214626Sasami if ((cp = malloc(len)) == NULL) { 38314626Sasami warn(NULL); 38414626Sasami exit(1); 38514626Sasami } 38614626Sasami cp[0] = '\0'; 38714626Sasami for (edir = edirs; *edir; edir++) { 38814626Sasami strcat(cp, *edir); 38914626Sasami if (edir[1] != NULL) 39014626Sasami strcat(cp, ", "); 39114626Sasami } 39214626Sasami warn("exec mount_%s not found in %s", vfstype, cp); 39314626Sasami } 3941558Srgrimes exit(1); 3951558Srgrimes /* NOTREACHED */ 3961558Srgrimes default: /* Parent. */ 3971558Srgrimes free(optbuf); 3981558Srgrimes 3991558Srgrimes if (waitpid(pid, &status, 0) < 0) { 4001558Srgrimes warn("waitpid"); 4011558Srgrimes return (1); 4021558Srgrimes } 4031558Srgrimes 4041558Srgrimes if (WIFEXITED(status)) { 4051558Srgrimes if (WEXITSTATUS(status) != 0) 4061558Srgrimes return (WEXITSTATUS(status)); 4071558Srgrimes } else if (WIFSIGNALED(status)) { 4081558Srgrimes warnx("%s: %s", name, sys_siglist[WTERMSIG(status)]); 4091558Srgrimes return (1); 4101558Srgrimes } 4111558Srgrimes 4121558Srgrimes if (verbose) { 4131558Srgrimes if (statfs(name, &sf) < 0) { 41423678Speter warn("statfs %s", name); 4151558Srgrimes return (1); 4161558Srgrimes } 41717243Sjkh if (fstab_style) 41823678Speter putfsent (&sf); 41917243Sjkh else 42023678Speter prmount(&sf); 4211558Srgrimes } 4221558Srgrimes break; 4231558Srgrimes } 4241558Srgrimes 4251558Srgrimes return (0); 4261558Srgrimes} 4271558Srgrimes 4281558Srgrimesvoid 42923678Speterprmount(sfp) 43023678Speter struct statfs *sfp; 43123678Speter{ 4321558Srgrimes int flags; 4331558Srgrimes struct opt *o; 43423678Speter struct passwd *pw; 4351558Srgrimes int f; 4361558Srgrimes 43723678Speter (void)printf("%s on %s", sfp->f_mntfromname, sfp->f_mntonname); 4381558Srgrimes 43923678Speter flags = sfp->f_flags & MNT_VISFLAGMASK; 4401558Srgrimes for (f = 0, o = optnames; flags && o->o_opt; o++) 4411558Srgrimes if (flags & o->o_opt) { 4421558Srgrimes (void)printf("%s%s", !f++ ? " (" : ", ", o->o_name); 4431558Srgrimes flags &= ~o->o_opt; 4441558Srgrimes } 44523678Speter if (sfp->f_owner) { 44623678Speter (void)printf("%smounted by ", !f++ ? " (" : ", "); 44723678Speter if ((pw = getpwuid(sfp->f_owner)) != NULL) 44823678Speter (void)printf("%s", pw->pw_name); 44923678Speter else 45023678Speter (void)printf("%d", sfp->f_owner); 45123678Speter } 4521558Srgrimes (void)printf(f ? ")\n" : "\n"); 4531558Srgrimes} 4541558Srgrimes 4551558Srgrimesstruct statfs * 4561558Srgrimesgetmntpt(name) 4571558Srgrimes const char *name; 4581558Srgrimes{ 4591558Srgrimes struct statfs *mntbuf; 4601558Srgrimes int i, mntsize; 4611558Srgrimes 4621558Srgrimes mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 4631558Srgrimes for (i = 0; i < mntsize; i++) 4641558Srgrimes if (strcmp(mntbuf[i].f_mntfromname, name) == 0 || 4651558Srgrimes strcmp(mntbuf[i].f_mntonname, name) == 0) 4661558Srgrimes return (&mntbuf[i]); 4671558Srgrimes return (NULL); 4681558Srgrimes} 4691558Srgrimes 4701558Srgrimeschar * 4711558Srgrimescatopt(s0, s1) 4721558Srgrimes char *s0; 4731558Srgrimes const char *s1; 4741558Srgrimes{ 4751558Srgrimes size_t i; 4761558Srgrimes char *cp; 4771558Srgrimes 4781558Srgrimes if (s0 && *s0) { 4791558Srgrimes i = strlen(s0) + strlen(s1) + 1 + 1; 4801558Srgrimes if ((cp = malloc(i)) == NULL) 4811558Srgrimes err(1, NULL); 4821558Srgrimes (void)snprintf(cp, i, "%s,%s", s0, s1); 4831558Srgrimes } else 4841558Srgrimes cp = strdup(s1); 4851558Srgrimes 4861558Srgrimes if (s0) 4871558Srgrimes free(s0); 4881558Srgrimes return (cp); 4891558Srgrimes} 4901558Srgrimes 4911558Srgrimesvoid 4921558Srgrimesmangle(options, argcp, argv) 4931558Srgrimes char *options; 4941558Srgrimes int *argcp; 4951558Srgrimes const char **argv; 4961558Srgrimes{ 4971558Srgrimes char *p, *s; 4981558Srgrimes int argc; 4991558Srgrimes 5001558Srgrimes argc = *argcp; 5011558Srgrimes for (s = options; (p = strsep(&s, ",")) != NULL;) 5021558Srgrimes if (*p != '\0') 5031558Srgrimes if (*p == '-') { 5041558Srgrimes argv[argc++] = p; 5051558Srgrimes p = strchr(p, '='); 5061558Srgrimes if (p) { 5071558Srgrimes *p = '\0'; 5081558Srgrimes argv[argc++] = p+1; 5091558Srgrimes } 5101558Srgrimes } else if (strcmp(p, "rw") != 0) { 5111558Srgrimes argv[argc++] = "-o"; 5121558Srgrimes argv[argc++] = p; 5131558Srgrimes } 5141558Srgrimes 5151558Srgrimes *argcp = argc; 5161558Srgrimes} 5171558Srgrimes 5181558Srgrimesvoid 5191558Srgrimesusage() 5201558Srgrimes{ 5211558Srgrimes 5221558Srgrimes (void)fprintf(stderr, 5231558Srgrimes "usage: mount %s %s\n mount %s\n mount %s\n", 52417243Sjkh "[-dfpruvw] [-o options] [-t ufs | external_type]", 5251558Srgrimes "special node", 52617243Sjkh "[-adfpruvw] [-t ufs | external_type]", 52717243Sjkh "[-dfpruvw] special | node"); 5281558Srgrimes exit(1); 5291558Srgrimes} 53017243Sjkh 53117243Sjkhvoid 53217243Sjkhputfsent (ent) 53317243Sjkh const struct statfs *ent; 53417243Sjkh{ 53517243Sjkh struct fstab *fst; 53617243Sjkh 53717243Sjkh printf ("%s\t%s\t%s %s", 53817243Sjkh ent->f_mntfromname, ent->f_mntonname, 53923678Speter ent->f_fstypename, 54017243Sjkh (ent->f_flags & MNT_RDONLY) ? "ro" : "rw"); 54117243Sjkh 54217243Sjkh if (ent->f_flags & MNT_SYNCHRONOUS) 54317243Sjkh printf (",sync"); 54417243Sjkh 54517243Sjkh if (ent->f_flags & MNT_NOEXEC) 54617243Sjkh printf (",noexec"); 54717243Sjkh 54817243Sjkh if (ent->f_flags & MNT_NOSUID) 54917243Sjkh printf (",nosuid"); 55017243Sjkh 55117243Sjkh if (ent->f_flags & MNT_NODEV) 55217243Sjkh printf (",nodev"); 55317243Sjkh 55417243Sjkh if (ent->f_flags & MNT_UNION) 55517243Sjkh printf (",union"); 55617243Sjkh 55717243Sjkh if (ent->f_flags & MNT_ASYNC) 55817243Sjkh printf (",async"); 55917243Sjkh 56023678Speter if (ent->f_flags & MNT_NOATIME) 56123678Speter printf (",noatime"); 56223678Speter 56317243Sjkh if (fst = getfsspec (ent->f_mntfromname)) 56417243Sjkh printf ("\t%u %u\n", fst->fs_freq, fst->fs_passno); 56517243Sjkh else if (fst = getfsfile (ent->f_mntonname)) 56617243Sjkh printf ("\t%u %u\n", fst->fs_freq, fst->fs_passno); 56717243Sjkh else if (ent->f_type == MOUNT_UFS) 56817243Sjkh printf ("\t1 1\n"); 56917243Sjkh else 57017243Sjkh printf ("\t0 0\n"); 57117243Sjkh} 572