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
badvfstype defined in line 393; used 2 times
catopt defined in line 438; used 7 times
getmntpt defined in line 362; used 2 times
main defined in line 87; never used
makevfslist defined in line 406; used 2 times
mangle defined in line 459; used 2 times
mountfs defined in line 235; used 4 times
prmount defined in line 343; used 3 times
usage defined in line 487; used 4 times

Defined variables

copyright defined in line 35; never used
debug defined in line 56; used 3 times
mountrw defined in line 56; used 3 times
optnames defined in line 75; used 1 times
sccsid defined in line 39; never used
skipvfs defined in line 56; used 3 times
verbose defined in line 56; used 2 times

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
Last modified: 1997-06-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4466
Valid CSS Valid XHTML 1.0 Strict