date and time created 94/02/20 16:17:57 by bostic
[unix-history] / usr / src / sbin / umount / umount.c
CommitLineData
0fc6e47b 1/*-
3d3434ed
KB
2 * Copyright (c) 1980, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
724216f4 4 *
0fc6e47b 5 * %sccs.include.redist.c%
8c5eec2f
DF
6 */
7
8#ifndef lint
3d3434ed
KB
9static char copyright[] =
10"@(#) Copyright (c) 1980, 1989, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
724216f4 12#endif /* not lint */
8c5eec2f 13
7a6d69cb 14#ifndef lint
3c64732d 15static char sccsid[] = "@(#)umount.c 8.2 (Berkeley) %G%";
724216f4 16#endif /* not lint */
15de4e1e 17
7a6d69cb 18#include <sys/param.h>
4efd8d38 19#include <sys/stat.h>
71799463 20#include <sys/mount.h>
896b9bf5 21
71799463
KM
22#ifdef NFS
23#include <sys/time.h>
24#include <sys/socket.h>
25#include <sys/socketvar.h>
26#include <netdb.h>
27#include <rpc/rpc.h>
28#include <rpc/pmap_clnt.h>
29#include <rpc/pmap_prot.h>
30#include <nfs/rpcv2.h>
896b9bf5
KB
31#endif
32
3c64732d 33#include <err.h>
896b9bf5
KB
34#include <fstab.h>
35#include <stdio.h>
3c64732d 36#include <stdlib.h>
896b9bf5 37#include <string.h>
3c64732d 38#include <unistd.h>
cfbe3c25 39
71799463 40#ifdef NFS
3c64732d
JSP
41char *nfshost;
42int namematch __P((struct hostent *, char *));
43int xdr_dir __P((XDR *, char *));
896b9bf5 44#endif
f6bc1314 45
3c64732d 46typedef enum { MNTON, MNTFROM } mntwhat;
651dda56 47
3c64732d
JSP
48int all, errs, fake, vflag;
49int fflag = 0;
50char *namelist[] = INITMOUNTNAMES;
51int *typelist;
52
53int badtype __P((int, int *));
54int fsnametotype __P((char *));
55char *getmntname __P((char *, mntwhat, int *));
56int *maketypelist __P((char *));
57void umountall __P((int *));
58int umountfs __P((char *, int *));
59void usage __P((void));
60
61int
cfbe3c25 62main(argc, argv)
15de4e1e
BJ
63 int argc;
64 char **argv;
cfbe3c25 65{
f6bc1314 66 int ch;
cfbe3c25
BJ
67
68 sync();
f6bc1314 69 while ((ch = getopt(argc, argv, "afFh:t:v")) != EOF)
3c64732d
JSP
70 switch (ch) {
71 case 'a':
72 all++;
f6bc1314
KM
73 break;
74 case 'f':
75 fflag = MNT_FORCE;
76 break;
77 case 'F':
78 fake++;
79 break;
f6bc1314
KM
80#ifdef NFS
81 case 'h':
82 /* -h flag implies -a, and "-t nfs" if no -t flag */
83 nfshost = optarg;
84 all++;
85 if (typelist == NULL)
86 typelist = maketypelist("nfs");
87 break;
88#endif /* NFS */
3c64732d
JSP
89 case 't':
90 typelist = maketypelist(optarg);
91 break;
92 case 'v':
93 vflag++;
94 break;
f6bc1314
KM
95 default:
96 usage();
97 /* NOTREACHED */
98 }
99 argc -= optind;
100 argv += optind;
101
102 if (argc == 0 && !all)
103 usage();
3c64732d
JSP
104
105 if (setfsent() == 0)
106 err(1, "%s", FSTAB);
107
15de4e1e 108 if (all) {
f6bc1314
KM
109 if (argc > 0)
110 usage();
f6bc1314 111 umountall(typelist);
15de4e1e 112 exit(0);
3c64732d
JSP
113 }
114
15de4e1e 115 while (argc > 0) {
f6bc1314 116 if (umountfs(*argv++, 0) == 0)
15de4e1e
BJ
117 errs++;
118 argc--;
cfbe3c25 119 }
3c64732d 120 exit(errs ? 1 : 0);
cfbe3c25 121}
15de4e1e 122
3c64732d 123void
f6bc1314
KM
124usage()
125{
126 fprintf(stderr,
3c64732d
JSP
127 "usage:\n%s\n%s\n",
128 " umount [-fv] special | node",
f6bc1314 129#ifndef NFS
3c64732d 130 " umount -a[fv] [-t fstypelist]"
f6bc1314 131#else
3c64732d 132 " umount -a[fv] [-h host] [-t fstypelist]"
f6bc1314
KM
133#endif
134 );
135 exit(1);
136}
137
3c64732d 138void
f6bc1314 139umountall(typelist)
3c64732d 140 int *typelist;
83dfa04a 141{
651dda56 142 char *cp;
3c64732d 143 struct fstab *fs;
651dda56
KM
144
145 while (fs = getfsent()) {
146 if (badtype(fsnametotype(fs->fs_vfstype), typelist))
147 continue;
148 if (strcmp(fs->fs_file, "/") == 0)
149 continue;
150 if (strcmp(fs->fs_type, FSTAB_RW) &&
151 strcmp(fs->fs_type, FSTAB_RO) &&
152 strcmp(fs->fs_type, FSTAB_RQ))
153 continue;
3c64732d
JSP
154 cp = (char *)malloc((size_t)strlen(fs->fs_file) + 1);
155 if (cp == NULL)
156 err(2, "malloc");
651dda56
KM
157 strcpy(cp, fs->fs_file);
158 umountall(typelist);
159 break;
7a6d69cb 160 }
651dda56
KM
161 if (fs) {
162 (void) umountfs(cp, typelist);
163 free(cp);
15de4e1e 164 }
83dfa04a 165}
cfbe3c25 166
3c64732d 167int
f6bc1314 168umountfs(name, typelist)
15de4e1e 169 char *name;
f6bc1314 170 int *typelist;
cfbe3c25 171{
71799463 172#ifdef NFS
3c64732d
JSP
173 enum clnt_stat clnt_stat;
174 CLIENT *clp;
175 char *delimp, *hostp;
f6bc1314 176 struct hostent *hp = 0;
71799463
KM
177 struct sockaddr_in saddr;
178 struct timeval pertry, try;
71799463 179 int so = RPC_ANYSOCK;
f6bc1314 180#endif /* NFS */
3c64732d
JSP
181 char *mntpt;
182 struct stat stbuf;
183 int type;
184 char rname[MAXPATHLEN];
185
186 if (realpath(name, rname) == NULL) {
187 warn("%s", rname);
188 return (0);
189 }
190
191 name = rname;
cfbe3c25 192
4efd8d38 193 if (stat(name, &stbuf) < 0) {
3c64732d
JSP
194 if (((mntpt = getmntname(name, MNTFROM, &type)) == 0) &&
195 ((mntpt = getmntname(name, MNTON, &type)) == 0)) {
196 warnx("%s: not currently mounted", name);
4efd8d38 197 return (0);
6aa97e2e 198 }
49d93ed5 199 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
6aa97e2e 200 if ((mntpt = getmntname(name, MNTON, &type)) == 0) {
3c64732d 201 warnx("%s: not currently mounted", name);
4efd8d38 202 return (0);
6aa97e2e 203 }
49d93ed5 204 } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
4efd8d38 205 mntpt = name;
3c64732d
JSP
206 if ((name = getmntname(mntpt, MNTFROM, &type)) == 0) {
207 warnx("%s: not currently mounted", mntpt);
4efd8d38 208 return (0);
6aa97e2e 209 }
4efd8d38 210 } else {
3c64732d 211 warnx("%s: not a directory or special device", name);
15de4e1e 212 return (0);
cfbe3c25 213 }
f6bc1314
KM
214
215 if (badtype(type, typelist))
3c64732d 216 return (1);
f6bc1314 217#ifdef NFS
3c64732d 218 if ((delimp = strchr(name, '@')) != NULL) {
f6bc1314
KM
219 hostp = delimp + 1;
220 *delimp = '\0';
221 hp = gethostbyname(hostp);
222 *delimp = '@';
3c64732d 223 } else if ((delimp = strchr(name, ':')) != NULL) {
f6bc1314
KM
224 *delimp = '\0';
225 hostp = name;
226 hp = gethostbyname(hostp);
227 name = delimp+1;
228 *delimp = ':';
229 }
230
231 if (!namematch(hp, nfshost))
3c64732d 232 return (1);
f6bc1314
KM
233#endif /* NFS */
234 if (!fake && unmount(mntpt, fflag) < 0) {
3c64732d 235 warn("%s", mntpt);
4efd8d38
KM
236 return (0);
237 }
238 if (vflag)
3c64732d 239 warnx("%s: unmounted from %s", name, mntpt);
f6bc1314
KM
240
241#ifdef NFS
3c64732d 242 if (!fake && (hp != NULL) && ((fflag & MNT_FORCE) == 0)) {
4efd8d38 243 *delimp = '\0';
3c64732d 244 bzero(&saddr, sizeof(saddr));
4efd8d38
KM
245 saddr.sin_family = AF_INET;
246 saddr.sin_port = 0;
3c64732d 247 bcopy(hp->h_addr, &saddr.sin_addr, hp->h_length);
4efd8d38
KM
248 pertry.tv_sec = 3;
249 pertry.tv_usec = 0;
250 if ((clp = clntudp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1,
251 pertry, &so)) == NULL) {
252 clnt_pcreateerror("Cannot MNT PRC");
253 return (1);
71799463 254 }
4efd8d38
KM
255 clp->cl_auth = authunix_create_default();
256 try.tv_sec = 20;
257 try.tv_usec = 0;
258 clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir, name,
259 xdr_void, (caddr_t)0, try);
260 if (clnt_stat != RPC_SUCCESS) {
261 clnt_perror(clp, "Bad MNT RPC");
262 return (1);
71799463 263 }
4efd8d38
KM
264 auth_destroy(clp->cl_auth);
265 clnt_destroy(clp);
760b60ac 266 }
f6bc1314 267#endif /* NFS */
760b60ac 268 return (1);
cfbe3c25 269}
71799463 270
4efd8d38 271char *
f6bc1314 272getmntname(name, what, type)
4efd8d38 273 char *name;
3c64732d 274 mntwhat what;
f6bc1314 275 int *type;
4efd8d38 276{
3c64732d 277 int i, mntsize;
0c6d0430 278 struct statfs *mntbuf;
4efd8d38 279
52f4d3d5 280 if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
3c64732d
JSP
281 warn("getmntinfo");
282 return (NULL);
4efd8d38 283 }
4efd8d38 284 for (i = 0; i < mntsize; i++) {
f6bc1314
KM
285 if (what == MNTON && !strcmp(mntbuf[i].f_mntfromname, name)) {
286 if (type)
287 *type = mntbuf[i].f_type;
4efd8d38 288 return (mntbuf[i].f_mntonname);
f6bc1314
KM
289 }
290 if (what == MNTFROM && !strcmp(mntbuf[i].f_mntonname, name)) {
291 if (type)
292 *type = mntbuf[i].f_type;
4efd8d38 293 return (mntbuf[i].f_mntfromname);
f6bc1314 294 }
4efd8d38 295 }
3c64732d 296 return (NULL);
4efd8d38
KM
297}
298
f6bc1314
KM
299static int skipvfs;
300
3c64732d 301int
f6bc1314
KM
302badtype(type, typelist)
303 int type;
304 int *typelist;
305{
306 if (typelist == 0)
3c64732d
JSP
307 return (0);
308
f6bc1314
KM
309 while (*typelist) {
310 if (type == *typelist)
3c64732d 311 return (skipvfs);
f6bc1314
KM
312 typelist++;
313 }
3c64732d 314 return (!skipvfs);
f6bc1314
KM
315}
316
317int *
318maketypelist(fslist)
319 char *fslist;
320{
3c64732d
JSP
321 char *nextcp;
322 int *av, i;
f6bc1314
KM
323
324 if (fslist == NULL)
3c64732d
JSP
325 return (NULL);
326
f6bc1314
KM
327 if (fslist[0] == 'n' && fslist[1] == 'o') {
328 fslist += 2;
329 skipvfs = 1;
330 } else
331 skipvfs = 0;
332 for (i = 0, nextcp = fslist; *nextcp; nextcp++)
333 if (*nextcp == ',')
334 i++;
3c64732d 335
f6bc1314
KM
336 av = (int *)malloc((i+2) * sizeof(int));
337 if (av == NULL)
3c64732d
JSP
338 return (NULL);
339
f6bc1314 340 for (i = 0; fslist; fslist = nextcp) {
3c64732d 341 if (nextcp = strchr(fslist, ','))
f6bc1314 342 *nextcp++ = '\0';
651dda56 343 av[i++] = fsnametotype(fslist);
f6bc1314
KM
344 }
345 av[i++] = 0;
3c64732d 346 return (av);
f6bc1314
KM
347}
348
3c64732d 349int
651dda56
KM
350fsnametotype(name)
351 char *name;
352{
353 char **cp;
354
355 for (cp = namelist; *cp; cp++)
356 if (strcmp(name, *cp) == 0)
357 return (cp - namelist);
358 return (MOUNT_NONE);
359}
360
3c64732d
JSP
361#ifdef NFS
362int
f6bc1314
KM
363namematch(hp, nfshost)
364 struct hostent *hp;
365 char *nfshost;
366{
3c64732d
JSP
367 char *cp;
368 char **np;
f6bc1314
KM
369
370 if (hp == NULL || nfshost == NULL)
3c64732d
JSP
371 return (1);
372
f6bc1314 373 if (strcasecmp(nfshost, hp->h_name) == 0)
3c64732d
JSP
374 return (1);
375
376 if (cp = strchr(hp->h_name, '.')) {
f6bc1314
KM
377 *cp = '\0';
378 if (strcasecmp(nfshost, hp->h_name) == 0)
3c64732d 379 return (1);
f6bc1314
KM
380 }
381 for (np = hp->h_aliases; *np; np++) {
382 if (strcasecmp(nfshost, *np) == 0)
3c64732d
JSP
383 return (1);
384 if (cp = strchr(*np, '.')) {
385
f6bc1314
KM
386 *cp = '\0';
387 if (strcasecmp(nfshost, *np) == 0)
3c64732d 388 return (1);
f6bc1314
KM
389 }
390 }
3c64732d 391 return (0);
f6bc1314
KM
392}
393
71799463
KM
394/*
395 * xdr routines for mount rpc's
396 */
3c64732d 397int
71799463
KM
398xdr_dir(xdrsp, dirp)
399 XDR *xdrsp;
400 char *dirp;
401{
402 return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
403}
f6bc1314 404#endif /* NFS */