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

##### Functions

    fsnametotype      X
    getmntname        X
    main              X
    maketypelist      X
    selected          X
    umountall         X
    umountfs          X
    usage             X

##### Variables

    fake              X
    fflag             X
    nfshost           X
    typelist          X
    vflag             X

       1: /*-
       2:  * Copyright (c) 1980, 1989, 1993
       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\n\
      37: 	The Regents of the University of California.  All rights reserved.\n";
      38:
      39: static char sccsid[] = "@(#)umount.c	8.3.1 (2.11BSD) 1996/1/16";
      40: #endif /* not lint */
      41:
      42: #include <sys/param.h>
      43: #include <sys/stat.h>
      44: #include <sys/mount.h>
      45: #include <fstab.h>
      46: #include <stdio.h>
      47: #include <stdlib.h>
      48: #include <string.h>
      49: #include <unistd.h>
      50:
      51: typedef enum { MNTON, MNTFROM } mntwhat;
      52:
      53: int fake, fflag, vflag, *typelist;
      54: char    *nfshost;
      55:
      56: int  fsnametotype();
      57: char    *getmntname();
      58: void     maketypelist();
      59: int  selected();
      60: int  namematch();
      61: int  umountall();
      62: int  umountfs();
      63: void     usage();
      64:
      65: int
      66: main(argc, argv)
      67:     int argc;
      68:     register char *argv[];
      69: {
      70:     int all, ch, errs;
      71:
      72:     /* Start disks transferring immediately. */
      73:     sync();
      74:
      75:     all = 0;
      76:     while ((ch = getopt(argc, argv, "aFft:v")) != EOF)
      77:         switch (ch) {
      78:         case 'a':
      79:             all = 1;
      80:             break;
      81:         case 'F':
      82:             fake = 1;
      83:             break;
      84:         case 'f':
      85: #ifdef  notnow
      86:             fflag = MNT_FORCE;
      87: #endif
      88:             break;
      89:         case 't':
      90:             maketypelist(optarg);
      91:             break;
      92:         case 'v':
      93:             vflag = 1;
      94:             break;
      95:         default:
      96:             usage();
      97:             /* NOTREACHED */
      98:         }
      99:     argc -= optind;
     100:     argv += optind;
     101:
     102:     if (argc == 0 && !all || argc != 0 && all)
     103:         usage();
     104:
     105:     if (all) {
     106:         if (setfsent() == 0)
     107:             err(1, "%s", _PATH_FSTAB);
     108:         errs = umountall();
     109:     } else
     110:         for (errs = 0; *argv != NULL; ++argv)
     111:             if (umountfs(*argv) == 0)
     112:                 errs = 1;
     113:     exit(errs);
     114: }
     115:
     116: int
     117: umountall()
     118: {
     119:     register struct fstab *fs;
     120:     int rval, type;
     121:     register char *cp;
     122:
     123:     while ((fs = getfsent()) != NULL) {
     124:         /* Ignore the root. */
     125:         if (strcmp(fs->fs_file, "/") == 0)
     126:             continue;
     127:         /*
     128: 		 * !!!
     129: 		 * Historic practice: ignore unknown FSTAB_* fields.
     130: 		 */
     131:         if (strcmp(fs->fs_type, FSTAB_RW) &&
     132:             strcmp(fs->fs_type, FSTAB_RO) &&
     133:             strcmp(fs->fs_type, FSTAB_RQ))
     134:             continue;
     135:         /* If an unknown file system type, complain. */
     136:         if ((type = fsnametotype(fs->fs_vfstype)) == MOUNT_NONE) {
     137:             warnx("%s: unknown mount type", fs->fs_vfstype);
     138:             continue;
     139:         }
     140:         if (!selected(type))
     141:             continue;
     142:
     143:         /*
     144: 		 * We want to unmount the file systems in the reverse order
     145: 		 * that they were mounted.  So, we save off the file name
     146: 		 * in some allocated memory, and then call recursively.
     147: 		 */
     148:         cp = (char *)malloc((size_t)strlen(fs->fs_file) + 1);
     149:         if (cp == NULL)
     150:             err(1, NULL);
     151:         (void)strcpy(cp, fs->fs_file);
     152:         rval = umountall();
     153:         return (umountfs(cp) || rval);
     154:     }
     155:     return (0);
     156: }
     157:
     158: int
     159: umountfs(name)
     160:     char *name;
     161: {
     162:     struct stat sb;
     163:     int type;
     164:     register char *mntpt;
     165:
     166:     if (stat(name, &sb) < 0) {
     167:         if (((mntpt = getmntname(name, MNTFROM, &type)) == NULL) &&
     168:             ((mntpt = getmntname(name, MNTON, &type)) == NULL)) {
     169:             warnx("%s: not currently mounted", name);
     170:             return (1);
     171:         }
     172:     } else if ((sb.st_mode & S_IFMT) == S_IFBLK) {
     173:         if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
     174:             warnx("%s: not currently mounted", name);
     175:             return (1);
     176:         }
     177:     } else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
     178:         mntpt = name;
     179:         if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
     180:             warnx("%s: not currently mounted", mntpt);
     181:             return (1);
     182:         }
     183:     } else {
     184:         warnx("%s: not a directory or special device", name);
     185:         return (1);
     186:     }
     187:
     188:     if (!selected(type))
     189:         return (0);
     190:
     191:     if (vflag)
     192:         (void)printf("%s: unmount from %s\n", name, mntpt);
     193:     if (fake)
     194:         return (0);
     195:
     196:     if (umount(name) < 0) {
     197:         warn("%s on %s", name, mntpt);
     198:         return (1);
     199:     }
     200:
     201:     return (0);
     202: }
     203:
     204: char *
     205: getmntname(name, what, type)
     206:     char *name;
     207:     mntwhat what;
     208:     int *type;
     209: {
     210:     struct statfs *mntbuf;
     211:     register int i, mntsize;
     212:
     213:     if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
     214:         warn("getmntinfo");
     215:         return (NULL);
     216:     }
     217:     for (i = 0; i < mntsize; i++) {
     218:         if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
     219:             if (type)
     220:                 *type = mntbuf[i].f_type;
     221:             return (mntbuf[i].f_mntonname);
     222:         }
     223:         if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
     224:             if (type)
     225:                 *type = mntbuf[i].f_type;
     226:             return (mntbuf[i].f_mntfromname);
     227:         }
     228:     }
     229:     return (NULL);
     230: }
     231:
     232: static enum { IN_LIST, NOT_IN_LIST } which;
     233:
     234: int
     235: selected(type)
     236:     int type;
     237: {
     238:     /* If no type specified, it's always selected. */
     239:     if (typelist == NULL)
     240:         return (1);
     241:     for (; *typelist != MOUNT_NONE; ++typelist)
     242:         if (type == *typelist)
     243:             return (which == IN_LIST ? 1 : 0);
     244:     return (which == IN_LIST ? 0 : 1);
     245: }
     246:
     247: void
     248: maketypelist(fslist)
     249:     register char *fslist;
     250: {
     251:     register int *av, i;
     252:     char *nextcp;
     253:
     254:     if ((fslist == NULL) || (fslist[0] == '\0'))
     255:         errx(1, "empty type list");
     256:
     257:     /*
     258: 	 * XXX
     259: 	 * Note: the syntax is "noxxx,yyy" for no xxx's and
     260: 	 * no yyy's, not the more intuitive "noyyy,noyyy".
     261: 	 */
     262:     if (fslist[0] == 'n' && fslist[1] == 'o') {
     263:         fslist += 2;
     264:         which = NOT_IN_LIST;
     265:     } else
     266:         which = IN_LIST;
     267:
     268:     /* Count the number of types. */
     269:     for (i = 0, nextcp = fslist; *nextcp != NULL; ++nextcp)
     270:         if (*nextcp == ',')
     271:             i++;
     272:
     273:     /* Build an array of that many types. */
     274:     if ((av = typelist = (int *)malloc((i + 2) * sizeof(int))) == NULL)
     275:         err(1, NULL);
     276:     for (i = 0; fslist != NULL; fslist = nextcp, ++i) {
     277:         if ((nextcp = strchr(fslist, ',')) != NULL)
     278:             *nextcp++ = '\0';
     279:         av[i] = fsnametotype(fslist);
     280:         if (av[i] == MOUNT_NONE)
     281:             errx(1, "%s: unknown mount type", fslist);
     282:     }
     283:     /* Terminate the array. */
     284:     av[i++] = MOUNT_NONE;
     285: }
     286:
     287: int
     288: fsnametotype(name)
     289:     char *name;
     290: {
     291:     static char *namelist[] = INITMOUNTNAMES;
     292:     register char **cp;
     293:
     294:     for (cp = namelist; *cp; ++cp)
     295:         if (strcmp(name, *cp) == 0)
     296:             return (cp - namelist);
     297:     return (MOUNT_NONE);
     298: }
     299:
     300: void
     301: usage()
     302: {
     303:     (void)fprintf(stderr,
     304:         "usage: %s\n       %s\n",
     305:         "umount [-fv] [-t fstypelist] special | node",
     306:         "umount -a[fv] [-t fstypelist]");
     307:     exit(1);
     308: }

#### Defined functions

fsnametotype defined in line 287; used 3 times

- in line 56, 136, 279

getmntname defined in line 204; used 5 times

- in line 57, 167-173(3), 179

main defined in line 65; never used
maketypelist defined in line 247; used 2 times

- in line 58, 90

selected defined in line 234; used 3 times

- in line 59, 140, 188

umountall defined in line 116; used 3 times

- in line 61, 108, 152

umountfs defined in line 158; used 3 times

- in line 62, 111, 153

usage defined in line 300; used 3 times

- in line 63, 96, 103

#### Defined variables

copyright defined in line 35; never used
fake defined in line 53; used 2 times

- in line 82, 193

fflag defined in line 53; used 1 times

- in line 86

nfshost defined in line 54; never used
sccsid defined in line 39; never used
typelist defined in line 53; used 5 times

- in line 239-242(4), 274

vflag defined in line 53; used 2 times

- in line 93, 191

Last modified: 1996-01-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1549 |