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