# 2.11BSD#431 - /usr/src/sbin/mount/mount.c

##### Functions

    badvfsname        X
    badvfstype        X
    catopt            X
    getmntpt          X
    main              X
    makevfslist       X
    mangle            X
    mountfs           X
    prmount           X
    usage             X

##### Variables

    debug             X
    mountrw           X
    skipvfs           X
    verbose           X

##### Macros

    BADTYPE           X

##### struct's

    opt               X

       1: /*
       2:  * Copyright (c) 1980, 1989, 1993, 1994
       3:  *	The Regents of the University of California.  All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms, with or without
       6:  * modification, are permitted provided that the following conditions
       7:  * are met:
       8:  * 1. Redistributions of source code must retain the above copyright
       9:  *    notice, this list of conditions and the following disclaimer.
      10:  * 2. Redistributions in binary form must reproduce the above copyright
      11:  *    notice, this list of conditions and the following disclaimer in the
      12:  *    documentation and/or other materials provided with the distribution.
      13:  * 3. All advertising materials mentioning features or use of this software
      14:  *    must display the following acknowledgement:
      15:  *	This product includes software developed by the University of
      16:  *	California, Berkeley and its contributors.
      17:  * 4. Neither the name of the University nor the names of its contributors
      18:  *    may be used to endorse or promote products derived from this software
      19:  *    without specific prior written permission.
      20:  *
      21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31:  * SUCH DAMAGE.
      32:  */
      33:
      34: #if !defined(lint) && defined(DOSCCS)
      35: static char copyright[] =
      36: "@(#) Copyright (c) 1980, 1989, 1993, 1994\n\
      37: 	The Regents of the University of California.  All rights reserved.\n";
      38:
      39: static char sccsid[] = "@(#)mount.c	8.19.4 (2.11BSD) 1997/6/29";
      40: #endif /* not lint */
      41:
      42: #include <sys/param.h>
      43: #include <sys/mount.h>
      44: #include <sys/wait.h>
      45:
      46: #include <errno.h>
      47: #include <fstab.h>
      48: #include <signal.h>
      49: #include <stdio.h>
      50: #include <stdlib.h>
      51: #include <string.h>
      52: #include <unistd.h>
      53:
      54: #include "pathnames.h"
      55:
      56: int debug, verbose, skipvfs, mountrw;
      57:
      58: int badvfsname();
      59: int badvfstype();
      60: char   *catopt();
      61: struct statfs *getmntpt();
      62: char **makevfslist();
      63: void    mangle();
      64: int mountfs();
      65: void    prmount();
      66: void    usage();
      67:
      68: /* From mount_ufs.c. */
      69: int mount_ufs();
      70:
      71: /* Map from mount otions to printable formats. */
      72: static struct opt {
      73:     int o_opt;
      74:     char *o_name;
      75: } optnames[] = {
      76:     { MNT_ASYNC,        "asynchronous" },
      77:     { MNT_NOATIME,      "noaccesstime" },
      78:     { MNT_NODEV,        "nodev" },
      79:     { MNT_NOEXEC,       "noexec" },
      80:     { MNT_NOSUID,       "nosuid" },
      81:     { MNT_QUOTA,        "with quotas" },
      82:     { MNT_RDONLY,       "read-only" },
      83:     { MNT_SYNCHRONOUS,  "synchronous" },
      84:     { NULL }
      85: };
      86:
      87: int
      88: main(argc, argv)
      89:     int argc;
      90:     register char *argv[];
      91: {
      92:     char *mntonname, **vfslist, *vfstype;
      93:     register struct fstab *fs;
      94:     struct statfs *mntbuf;
      95:     int all, ch, i, init_flags, mntsize, rval;
      96:     char *options, *na;
      97:
      98:     all = init_flags = 0;
      99:     options = NULL;
     100:     vfslist = NULL;
     101:     vfstype = "ufs";
     102:     while ((ch = getopt(argc, argv, "adfo:rwt:uv")) != EOF)
     103:         switch (ch) {
     104:         case 'a':
     105:             all = 1;
     106:             break;
     107:         case 'd':
     108:             debug = 1;
     109:             break;
     110:         case 'f':
     111: #ifdef  notnow
     112:             init_flags |= MNT_FORCE;
     113: #endif
     114:             break;
     115:         case 'o':
     116:             if (*optarg)
     117:                 options = catopt(options, optarg);
     118:             break;
     119:         case 'r':
     120:             init_flags |= MNT_RDONLY;
     121:             mountrw = 0;
     122:             break;
     123:         case 't':
     124:             if (vfslist != NULL)
     125:                 errx(1, "only one -t option may be specified.");
     126:             vfslist = makevfslist(optarg);
     127:             vfstype = optarg;
     128:             break;
     129:         case 'u':
     130:             init_flags |= MNT_UPDATE;
     131:             break;
     132:         case 'v':
     133:             verbose = 1;
     134:             break;
     135:         case 'w':
     136:             init_flags &= ~MNT_RDONLY;
     137:             mountrw = 1;
     138:             break;
     139:         case '?':
     140:         default:
     141:             usage();
     142:             /* NOTREACHED */
     143:         }
     144:     argc -= optind;
     145:     argv += optind;
     146:
     147: #define BADTYPE(type)                           \
     148:     (strcmp(type, FSTAB_RO) &&                  \
     149:         strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))
     150:
     151:     rval = 0;
     152:     switch (argc) {
     153:     case 0:
     154:         if (all)
     155:             while ((fs = getfsent()) != NULL) {
     156:                 if (BADTYPE(fs->fs_type))
     157:                     continue;
     158:                 /*
     159: 				 * Check to see if "na" is one of the options,
     160: 				 * if so, don't mount it.
     161: 				*/
     162:                 if (fs->fs_mntops &&
     163:                     (na = strstr(fs->fs_mntops, "na")) &&
     164:                     ((na = fs->fs_mntops) || na[-1] == ',') &&
     165:                     (na[2] == ',' || na[2] == '\0')) {
     166:                     continue;
     167:                 }
     168:                 if (badvfsname(fs->fs_vfstype, vfslist))
     169:                     continue;
     170:                 if (mountfs(fs->fs_vfstype, fs->fs_spec,
     171:                     fs->fs_file, init_flags, options,
     172:                     fs->fs_mntops))
     173:                     rval = 1;
     174:             }
     175:         else {
     176:             if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
     177:                 err(1, "getmntinfo");
     178:             for (i = 0; i < mntsize; i++) {
     179:                 if (badvfstype(mntbuf[i].f_type, vfslist))
     180:                     continue;
     181:                 prmount(mntbuf[i].f_mntfromname,
     182:                     mntbuf[i].f_mntonname, mntbuf[i].f_flags);
     183:             }
     184:         }
     185:         exit(rval);
     186:     case 1:
     187:         if (vfslist != NULL)
     188:             usage();
     189:
     190:         if (init_flags & MNT_UPDATE) {
     191:             if ((mntbuf = getmntpt(*argv)) == NULL)
     192:                 errx(1,
     193:                     "unknown special file or file system %s.",
     194:                     *argv);
     195:             if ((fs = getfsfile(mntbuf->f_mntonname)) == NULL)
     196:                 errx(1, "can't find fstab entry for %s.",
     197:                     *argv);
     198:             /* If it's an update, ignore the fstab file options. */
     199:             fs->fs_mntops = NULL;
     200:             mntonname = mntbuf->f_mntonname;
     201:         } else {
     202:             if ((fs = getfsfile(*argv)) == NULL &&
     203:                 (fs = getfsspec(*argv)) == NULL)
     204:                 errx(1,
     205:                     "%s: unknown special file or file system.",
     206:                     *argv);
     207:             if (BADTYPE(fs->fs_type))
     208:                 errx(1, "%s has unknown file system type.",
     209:                     *argv);
     210:             mntonname = fs->fs_file;
     211:         }
     212:         rval = mountfs(fs->fs_vfstype, fs->fs_spec,
     213:             mntonname, init_flags, options, fs->fs_mntops);
     214:         break;
     215:     case 2:
     216:         /*
     217: 		 * If -t flag has not been specified, and spec contains either
     218: 		 * a ':' or a '@' then assume that an NFS filesystem is being
     219: 		 * specified ala Sun.  Since 2BSD does not support nfs an
     220: 		 * error is declared here rather than from mountfs().
     221: 		 */
     222:         if (vfslist == NULL && strpbrk(argv[0], ":@") != NULL)
     223:             err(1, "nfs not supported");
     224:         rval = mountfs(vfstype,
     225:             argv[0], argv[1], init_flags, options, NULL);
     226:         break;
     227:     default:
     228:         usage();
     229:         /* NOTREACHED */
     230:     }
     231:
     232:     exit(rval);
     233: }
     234:
     235: int
     236: mountfs(vfstype, spec, name, flags, options, mntopts)
     237:     char *vfstype, *spec, *name, *options, *mntopts;
     238:     int flags;
     239: {
     240:     /* List of directories containing mount_xxx subcommands. */
     241:     static char *edirs[] = {
     242:         _PATH_SBIN,
     243:         _PATH_USRSBIN,
     244:         NULL
     245:     };
     246:     char *argv[100], **edir;
     247:     struct statfs sf;
     248:     pid_t pid;
     249:     int argc, i;
     250:     union   wait status;
     251:     char *optbuf, execname[MAXPATHLEN + 1];
     252:
     253:     if (options == NULL) {
     254:         if (mntopts == NULL || *mntopts == '\0')
     255:             options = "rw";
     256:         else
     257:             options = mntopts;
     258:         mntopts = "";
     259:     if (debug)
     260:         printf("options: %s\n", options);
     261:     }
     262:     optbuf = catopt(mntopts ? strdup(mntopts) : 0, options);
     263:
     264:     if (strcmp(name, "/") == 0)
     265:         flags |= MNT_UPDATE;
     266: #ifdef  notnow
     267:     if (flags & MNT_FORCE)
     268:         optbuf = catopt(optbuf, "force");
     269: #endif
     270:     if (flags & MNT_RDONLY)
     271:         optbuf = catopt(optbuf, "ro");
     272:     if (mountrw)
     273:         optbuf = catopt(optbuf, "rw");
     274:     if (flags & MNT_UPDATE)
     275:         optbuf = catopt(optbuf, "update");
     276:
     277:     argc = 0;
     278:     argv[argc++] = vfstype;
     279:     mangle(optbuf, &argc, argv);
     280:     argv[argc++] = spec;
     281:     argv[argc++] = name;
     282:     argv[argc] = NULL;
     283:
     284:     if (debug) {
     285:         (void)printf("exec: mount_%s", vfstype);
     286:         for (i = 1; i < argc; i++)
     287:             (void)printf(" %s", argv[i]);
     288:         (void)printf("\n");
     289:         return (0);
     290:     }
     291:
     292:     switch (pid = vfork()) {
     293:     case -1:                /* Error. */
     294:         warn("vfork");
     295:         free(optbuf);
     296:         return (1);
     297:     case 0:                 /* Child. */
     298:         if (strcmp(vfstype, "ufs") == 0)
     299:             _exit(mount_ufs(argc, (char **) argv));
     300:
     301:         /* Go find an executable. */
     302:         edir = edirs;
     303:         do {
     304:             (void)sprintf(execname, "%s/mount_%s", *edir, vfstype);
     305:             execv(execname, (char **)argv);
     306:             if (errno != ENOENT)
     307:                 warn("exec %s for %s", execname, name);
     308:         } while (*++edir != NULL);
     309:
     310:         if (errno == ENOENT)
     311:             warn("exec %s for %s", execname, name);
     312:         _exit(1);
     313:         /* NOTREACHED */
     314:     default:                /* Parent. */
     315:         free(optbuf);
     316:
     317:         if (waitpid(pid, &status, 0) < 0) {
     318:             warn("waitpid");
     319:             return (1);
     320:         }
     321:
     322:         if (WIFEXITED(status)) {
     323:             if (WEXITSTATUS(status) != 0)
     324:                 return (WEXITSTATUS(status));
     325:         } else if (WIFSIGNALED(status)) {
     326:             warnx("%s: %s", name, sys_siglist[status.w_termsig]);
     327:             return (1);
     328:         }
     329:
     330:         if (verbose) {
     331:             if (statfs(name, &sf) < 0) {
     332:                 warn("%s", name);
     333:                 return (1);
     334:             }
     335:             prmount(sf.f_mntfromname, sf.f_mntonname, sf.f_flags);
     336:         }
     337:         break;
     338:     }
     339:
     340:     return (0);
     341: }
     342:
     343: void
     344: prmount(spec, name, flags)
     345:     char *spec, *name;
     346:     int flags;
     347: {
     348:     register struct opt *o;
     349:     register int f;
     350:
     351:     (void)printf("%s on %s", spec, name);
     352:
     353:     flags &= MNT_VISFLAGMASK;
     354:     for (f = 0, o = optnames; flags && o->o_opt; o++)
     355:         if (flags & o->o_opt) {
     356:             (void)printf("%s%s", !f++ ? " (" : ", ", o->o_name);
     357:             flags &= ~o->o_opt;
     358:         }
     359:     (void)printf(f ? ")\n" : "\n");
     360: }
     361:
     362: struct statfs *
     363: getmntpt(name)
     364:     char *name;
     365: {
     366:     struct statfs *mntbuf;
     367:     register int i, mntsize;
     368:
     369:     mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
     370:     for (i = 0; i < mntsize; i++)
     371:         if (strcmp(mntbuf[i].f_mntfromname, name) == 0 ||
     372:             strcmp(mntbuf[i].f_mntonname, name) == 0)
     373:             return (&mntbuf[i]);
     374:     return (NULL);
     375: }
     376:
     377: int
     378: badvfsname(vfsname, vfslist)
     379:     char *vfsname;
     380:     register char **vfslist;
     381: {
     382:
     383:     if (vfslist == NULL)
     384:         return (0);
     385:     while (*vfslist != NULL) {
     386:         if (strcmp(vfsname, *vfslist) == 0)
     387:             return (skipvfs);
     388:         ++vfslist;
     389:     }
     390:     return (!skipvfs);
     391: }
     392:
     393: int
     394: badvfstype(vfstype, vfslist)
     395:     int vfstype;
     396:     register char **vfslist;
     397: {
     398: static char *vfsnames[] = INITMOUNTNAMES;
     399:
     400:     if ((vfstype < 0) || (vfstype > MOUNT_MAXTYPE))
     401:         return (0);
     402:
     403:     return (badvfsname(vfsnames[vfstype], vfslist));
     404: }
     405:
     406: char **
     407: makevfslist(fslist)
     408:     char *fslist;
     409: {
     410:     register char **av;
     411:     int i;
     412:     register char *nextcp;
     413:
     414:     if (fslist == NULL)
     415:         return (NULL);
     416:     if (fslist[0] == 'n' && fslist[1] == 'o') {
     417:         fslist += 2;
     418:         skipvfs = 1;
     419:     }
     420:     for (i = 0, nextcp = fslist; *nextcp; nextcp++)
     421:         if (*nextcp == ',')
     422:             i++;
     423:     if ((av = (char **)malloc((size_t)(i + 2) * sizeof(char *))) == NULL) {
     424:         warn(NULL);
     425:         return (NULL);
     426:     }
     427:     nextcp = fslist;
     428:     i = 0;
     429:     av[i++] = nextcp;
     430:     while ((nextcp = strchr(nextcp, ',')) != NULL) {
     431:         *nextcp++ = '\0';
     432:         av[i++] = nextcp;
     433:     }
     434:     av[i++] = NULL;
     435:     return (av);
     436: }
     437:
     438: char *
     439: catopt(s0, s1)
     440:     char *s0;
     441:     char *s1;
     442: {
     443:     size_t i;
     444:     char *cp;
     445:
     446:     if (s0 && *s0) {
     447:         i = strlen(s0) + strlen(s1) + 1 + 1;
     448:         if ((cp = (char *)malloc(i)) == NULL)
     449:             err(1, NULL);
     450:         (void)sprintf(cp, "%s,%s", s0, s1);
     451:     } else
     452:         cp = strdup(s1);
     453:
     454:     if (s0)
     455:         free(s0);
     456:     return (cp);
     457: }
     458:
     459: void
     460: mangle(options, argcp, argv)
     461:     char *options;
     462:     int *argcp;
     463:     register char **argv;
     464: {
     465:     register char *p;
     466:     char *s;
     467:     register int argc;
     468:
     469:     argc = *argcp;
     470:     for (s = options; (p = strsep(&s, ",")) != NULL;)
     471:         if (*p != '\0')
     472:             if (*p == '-') {
     473:                 argv[argc++] = p;
     474:                 p = strchr(p, '=');
     475:                 if (p) {
     476:                     *p = '\0';
     477:                     argv[argc++] = p+1;
     478:                 }
     479:             } else {
     480:                 argv[argc++] = "-o";
     481:                 argv[argc++] = p;
     482:             }
     483:
     484:     *argcp = argc;
     485: }
     486:
     487: void
     488: usage()
     489: {
     490:
     491:     (void)fprintf(stderr,
     492:         "usage: mount %s %s\n       mount %s\n       mount %s\n",
     493:         "[-dfruvw] [-o options] [-t ufs | external_type]",
     494:             "special node",
     495:         "[-adfruvw] [-t ufs | external_type]",
     496:         "[-dfruvw] special | node");
     497:     exit(1);
     498: }

#### Defined functions

badvfsname defined in line 377; used 3 times

- in line 58, 168, 403

badvfstype defined in line 393; used 2 times

- in line 59, 179

catopt defined in line 438; used 7 times

- in line 60, 117, 262, 268-275(4)

getmntpt defined in line 362; used 2 times

- in line 61, 191

main defined in line 87; never used
makevfslist defined in line 406; used 2 times

- in line 62, 126

mangle defined in line 459; used 2 times

- in line 63, 279

mountfs defined in line 235; used 4 times

- in line 64, 170, 212, 224

prmount defined in line 343; used 3 times

- in line 65, 181, 335

usage defined in line 487; used 4 times

- in line 66, 141, 188, 228

#### Defined variables

copyright defined in line 35; never used
debug defined in line 56; used 3 times

- in line 108, 259, 284

mountrw defined in line 56; used 3 times

- in line 121, 137, 272

optnames defined in line 75; used 1 times

- in line 354

sccsid defined in line 39; never used
skipvfs defined in line 56; used 3 times

- in line 387-390(2), 418

verbose defined in line 56; used 2 times

- in line 133, 330

#### Defined struct's

opt defined in line 72; used 2 times

- in line 348(2)

#### Defined macros

BADTYPE defined in line 147; used 2 times

- in line 156, 207

Last modified: 1997-06-30 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1951 |