|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1980, 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)umount.c 5.14 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/param.h> ! 31: #include <sys/stat.h> ! 32: #include <sys/mount.h> ! 33: ! 34: #ifdef NFS ! 35: #include <sys/time.h> ! 36: #include <sys/socket.h> ! 37: #include <sys/socketvar.h> ! 38: #include <netdb.h> ! 39: #include <rpc/rpc.h> ! 40: #include <rpc/pmap_clnt.h> ! 41: #include <rpc/pmap_prot.h> ! 42: #include <nfs/rpcv2.h> ! 43: #endif ! 44: ! 45: #include <fstab.h> ! 46: #include <stdio.h> ! 47: #include <string.h> ! 48: ! 49: #ifdef NFS ! 50: int xdr_dir(); ! 51: char *nfshost; ! 52: #endif ! 53: ! 54: int vflag, all, errs, fake; ! 55: int fflag = MNT_NOFORCE; ! 56: char *getmntname(); ! 57: ! 58: #define MNTON 1 ! 59: #define MNTFROM 2 ! 60: #define MNTTYPE 3 ! 61: ! 62: int *typelist, *maketypelist(); ! 63: ! 64: main(argc, argv) ! 65: int argc; ! 66: char **argv; ! 67: { ! 68: extern char *optarg; ! 69: extern int optind; ! 70: int ch; ! 71: ! 72: sync(); ! 73: while ((ch = getopt(argc, argv, "afFh:t:v")) != EOF) ! 74: switch((char)ch) { ! 75: case 'v': ! 76: vflag++; ! 77: break; ! 78: case 'f': ! 79: fflag = MNT_FORCE; ! 80: break; ! 81: case 'F': ! 82: fake++; ! 83: break; ! 84: case 'a': ! 85: all++; ! 86: break; ! 87: case 't': ! 88: typelist = maketypelist(optarg); ! 89: break; ! 90: #ifdef NFS ! 91: case 'h': ! 92: /* -h flag implies -a, and "-t nfs" if no -t flag */ ! 93: nfshost = optarg; ! 94: all++; ! 95: if (typelist == NULL) ! 96: typelist = maketypelist("nfs"); ! 97: break; ! 98: #endif /* NFS */ ! 99: case '?': ! 100: default: ! 101: usage(); ! 102: /* NOTREACHED */ ! 103: } ! 104: argc -= optind; ! 105: argv += optind; ! 106: ! 107: if (argc == 0 && !all) ! 108: usage(); ! 109: if (all) { ! 110: if (argc > 0) ! 111: usage(); ! 112: if (setfsent() == 0) ! 113: perror(FSTAB), exit(1); ! 114: umountall(typelist); ! 115: exit(0); ! 116: } else ! 117: setfsent(); ! 118: while (argc > 0) { ! 119: if (umountfs(*argv++, 0) == 0) ! 120: errs++; ! 121: argc--; ! 122: } ! 123: exit(errs); ! 124: } ! 125: ! 126: usage() ! 127: { ! 128: fprintf(stderr, ! 129: "%s\n%s\n", ! 130: "Usage: umount [-fv] special | node", ! 131: #ifndef NFS ! 132: " or umount -a[fv] [-t fstypelist]" ! 133: #else ! 134: " or umount -a[fv] [-h host] [-t fstypelist]" ! 135: #endif ! 136: ); ! 137: exit(1); ! 138: } ! 139: ! 140: umountall(typelist) ! 141: char **typelist; ! 142: { ! 143: register struct fstab *fs; ! 144: struct fstab *allocfsent(); ! 145: ! 146: if ((fs = getfsent()) == (struct fstab *)0) ! 147: return; ! 148: fs = allocfsent(fs); ! 149: umountall(typelist); ! 150: if (strcmp(fs->fs_file, "/") == 0) { ! 151: freefsent(fs); ! 152: return; ! 153: } ! 154: if (strcmp(fs->fs_type, FSTAB_RW) && ! 155: strcmp(fs->fs_type, FSTAB_RO) && ! 156: strcmp(fs->fs_type, FSTAB_RQ)) { ! 157: freefsent(fs); ! 158: return; ! 159: } ! 160: (void) umountfs(fs->fs_file, typelist); ! 161: freefsent(fs); ! 162: } ! 163: ! 164: struct fstab * ! 165: allocfsent(fs) ! 166: register struct fstab *fs; ! 167: { ! 168: register struct fstab *new; ! 169: register char *cp; ! 170: char *malloc(); ! 171: ! 172: new = (struct fstab *)malloc((unsigned)sizeof (*fs)); ! 173: cp = malloc((unsigned)strlen(fs->fs_file) + 1); ! 174: strcpy(cp, fs->fs_file); ! 175: new->fs_file = cp; ! 176: cp = malloc((unsigned)strlen(fs->fs_type) + 1); ! 177: strcpy(cp, fs->fs_type); ! 178: new->fs_type = cp; ! 179: cp = malloc((unsigned)strlen(fs->fs_spec) + 1); ! 180: strcpy(cp, fs->fs_spec); ! 181: new->fs_spec = cp; ! 182: new->fs_passno = fs->fs_passno; ! 183: new->fs_freq = fs->fs_freq; ! 184: return (new); ! 185: } ! 186: ! 187: freefsent(fs) ! 188: register struct fstab *fs; ! 189: { ! 190: ! 191: if (fs->fs_file) ! 192: free(fs->fs_file); ! 193: if (fs->fs_spec) ! 194: free(fs->fs_spec); ! 195: if (fs->fs_type) ! 196: free(fs->fs_type); ! 197: free((char *)fs); ! 198: } ! 199: ! 200: umountfs(name, typelist) ! 201: char *name; ! 202: int *typelist; ! 203: { ! 204: char *mntpt; ! 205: struct stat stbuf; ! 206: int type; ! 207: #ifdef NFS ! 208: register CLIENT *clp; ! 209: struct hostent *hp = 0; ! 210: struct sockaddr_in saddr; ! 211: struct timeval pertry, try; ! 212: enum clnt_stat clnt_stat; ! 213: int so = RPC_ANYSOCK; ! 214: char *hostp, *delimp; ! 215: #endif /* NFS */ ! 216: ! 217: if (stat(name, &stbuf) < 0) { ! 218: if ((mntpt = getmntname(name, MNTON, &type)) == 0) ! 219: return (0); ! 220: } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) { ! 221: if ((mntpt = getmntname(name, MNTON, &type)) == 0) ! 222: return (0); ! 223: } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { ! 224: mntpt = name; ! 225: if ((name = getmntname(mntpt, MNTFROM, &type)) == 0) ! 226: return (0); ! 227: } else { ! 228: fprintf(stderr, "%s: not a directory or special device\n", ! 229: name); ! 230: return (0); ! 231: } ! 232: ! 233: if (badtype(type, typelist)) ! 234: return(1); ! 235: #ifdef NFS ! 236: if ((delimp = index(name, '@')) != NULL) { ! 237: hostp = delimp + 1; ! 238: *delimp = '\0'; ! 239: hp = gethostbyname(hostp); ! 240: *delimp = '@'; ! 241: } else if ((delimp = index(name, ':')) != NULL) { ! 242: *delimp = '\0'; ! 243: hostp = name; ! 244: hp = gethostbyname(hostp); ! 245: name = delimp+1; ! 246: *delimp = ':'; ! 247: } ! 248: ! 249: if (!namematch(hp, nfshost)) ! 250: return(1); ! 251: #endif /* NFS */ ! 252: if (!fake && unmount(mntpt, fflag) < 0) { ! 253: perror(mntpt); ! 254: return (0); ! 255: } ! 256: if (vflag) ! 257: fprintf(stderr, "%s: Unmounted from %s\n", name, mntpt); ! 258: ! 259: #ifdef NFS ! 260: if (!fake && hp != NULL && (fflag & MNT_FORCE) == 0) { ! 261: *delimp = '\0'; ! 262: bcopy(hp->h_addr,(caddr_t)&saddr.sin_addr,hp->h_length); ! 263: saddr.sin_family = AF_INET; ! 264: saddr.sin_port = 0; ! 265: pertry.tv_sec = 3; ! 266: pertry.tv_usec = 0; ! 267: if ((clp = clntudp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1, ! 268: pertry, &so)) == NULL) { ! 269: clnt_pcreateerror("Cannot MNT PRC"); ! 270: return (1); ! 271: } ! 272: clp->cl_auth = authunix_create_default(); ! 273: try.tv_sec = 20; ! 274: try.tv_usec = 0; ! 275: clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir, name, ! 276: xdr_void, (caddr_t)0, try); ! 277: if (clnt_stat != RPC_SUCCESS) { ! 278: clnt_perror(clp, "Bad MNT RPC"); ! 279: return (1); ! 280: } ! 281: auth_destroy(clp->cl_auth); ! 282: clnt_destroy(clp); ! 283: } ! 284: #endif /* NFS */ ! 285: return (1); ! 286: } ! 287: ! 288: char * ! 289: getmntname(name, what, type) ! 290: char *name; ! 291: int what; ! 292: int *type; ! 293: { ! 294: int mntsize, i; ! 295: struct statfs *mntbuf; ! 296: ! 297: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { ! 298: perror("umount"); ! 299: return (0); ! 300: } ! 301: for (i = 0; i < mntsize; i++) { ! 302: if (what == MNTON && !strcmp(mntbuf[i].f_mntfromname, name)) { ! 303: if (type) ! 304: *type = mntbuf[i].f_type; ! 305: return (mntbuf[i].f_mntonname); ! 306: } ! 307: if (what == MNTFROM && !strcmp(mntbuf[i].f_mntonname, name)) { ! 308: if (type) ! 309: *type = mntbuf[i].f_type; ! 310: return (mntbuf[i].f_mntfromname); ! 311: } ! 312: } ! 313: fprintf(stderr, "%s: not currently mounted\n", name); ! 314: return (0); ! 315: } ! 316: ! 317: static int skipvfs; ! 318: ! 319: badtype(type, typelist) ! 320: int type; ! 321: int *typelist; ! 322: { ! 323: if (typelist == 0) ! 324: return(0); ! 325: while (*typelist) { ! 326: if (type == *typelist) ! 327: return(skipvfs); ! 328: typelist++; ! 329: } ! 330: return(!skipvfs); ! 331: } ! 332: ! 333: int * ! 334: maketypelist(fslist) ! 335: char *fslist; ! 336: { ! 337: register char *nextcp; ! 338: register int *av, i; ! 339: char *malloc(); ! 340: ! 341: if (fslist == NULL) ! 342: return(NULL); ! 343: if (fslist[0] == 'n' && fslist[1] == 'o') { ! 344: fslist += 2; ! 345: skipvfs = 1; ! 346: } else ! 347: skipvfs = 0; ! 348: for (i = 0, nextcp = fslist; *nextcp; nextcp++) ! 349: if (*nextcp == ',') ! 350: i++; ! 351: av = (int *)malloc((i+2) * sizeof(int)); ! 352: if (av == NULL) ! 353: return(NULL); ! 354: for (i = 0; fslist; fslist = nextcp) { ! 355: if (nextcp = index(fslist, ',')) ! 356: *nextcp++ = '\0'; ! 357: if (strcmp(fslist, "ufs") == 0) ! 358: av[i++] = MOUNT_UFS; ! 359: else if (strcmp(fslist, "nfs") == 0) ! 360: av[i++] = MOUNT_NFS; ! 361: else if (strcmp(fslist, "mfs") == 0) ! 362: av[i++] = MOUNT_MFS; ! 363: else if (strcmp(fslist, "pc") == 0) ! 364: av[i++] = MOUNT_PC; ! 365: } ! 366: av[i++] = 0; ! 367: return(av); ! 368: } ! 369: ! 370: #ifdef NFS ! 371: namematch(hp, nfshost) ! 372: struct hostent *hp; ! 373: char *nfshost; ! 374: { ! 375: register char *cp; ! 376: register char **np; ! 377: ! 378: if (hp == NULL || nfshost == NULL) ! 379: return(1); ! 380: if (strcasecmp(nfshost, hp->h_name) == 0) ! 381: return(1); ! 382: if (cp = index(hp->h_name, '.')) { ! 383: *cp = '\0'; ! 384: if (strcasecmp(nfshost, hp->h_name) == 0) ! 385: return(1); ! 386: } ! 387: for (np = hp->h_aliases; *np; np++) { ! 388: if (strcasecmp(nfshost, *np) == 0) ! 389: return(1); ! 390: if (cp = index(*np, '.')) { ! 391: *cp = '\0'; ! 392: if (strcasecmp(nfshost, *np) == 0) ! 393: return(1); ! 394: } ! 395: } ! 396: return(0); ! 397: } ! 398: ! 399: /* ! 400: * xdr routines for mount rpc's ! 401: */ ! 402: xdr_dir(xdrsp, dirp) ! 403: XDR *xdrsp; ! 404: char *dirp; ! 405: { ! 406: return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); ! 407: } ! 408: #endif /* NFS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.