|
|
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.