do not reset if IGNORE has been requested
[unix-history] / usr / src / sbin / umount / umount.c
CommitLineData
8c5eec2f 1/*
724216f4
KM
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 is permitted
6 * provided that all copyright information, including this notice,
7 * is retained in all such forms, and that any documentation,
8 * advertising or other materials related to such distribution and
9 * use acknowledge that the software was
10 * developed by the University of California, Berkeley. The name
11 * of the University may not be used to endorse or promote products
12 * derived from this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8c5eec2f
DF
17 */
18
19#ifndef lint
20char copyright[] =
724216f4 21"@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\
8c5eec2f 22 All rights reserved.\n";
724216f4 23#endif /* not lint */
8c5eec2f 24
7a6d69cb 25#ifndef lint
ed05fc2d 26static char sccsid[] = "@(#)umount.c 5.14 (Berkeley) %G%";
724216f4 27#endif /* not lint */
15de4e1e 28
cfbe3c25 29/*
f0861f40 30 * umount
cfbe3c25 31 */
7a6d69cb 32#include <sys/param.h>
7a6d69cb
SL
33#include <stdio.h>
34#include <fstab.h>
4efd8d38 35#include <sys/stat.h>
71799463
KM
36#include <sys/mount.h>
37#ifdef NFS
38#include <sys/time.h>
39#include <sys/socket.h>
40#include <sys/socketvar.h>
41#include <netdb.h>
42#include <rpc/rpc.h>
43#include <rpc/pmap_clnt.h>
44#include <rpc/pmap_prot.h>
45#include <nfs/rpcv2.h>
f6bc1314 46#endif /* NFS */
cfbe3c25 47
71799463
KM
48#ifdef NFS
49extern int errno;
50int xdr_dir();
51char *index();
f6bc1314
KM
52char *nfshost;
53#endif /* NFS */
54
55int vflag, all, errs, fake;
b368c10d 56int fflag = MNT_NOFORCE;
c638d1b9 57char *rindex(), *getmntname();
4efd8d38
KM
58#define MNTON 1
59#define MNTFROM 2
f6bc1314
KM
60#define MNTTYPE 3
61
62int *typelist, *maketypelist();
15de4e1e 63
cfbe3c25 64main(argc, argv)
15de4e1e
BJ
65 int argc;
66 char **argv;
cfbe3c25 67{
f6bc1314
KM
68 extern char *optarg;
69 extern int optind;
70 int ch;
cfbe3c25
BJ
71
72 sync();
f6bc1314
KM
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();
15de4e1e 109 if (all) {
f6bc1314
KM
110 if (argc > 0)
111 usage();
83dfa04a
BJ
112 if (setfsent() == 0)
113 perror(FSTAB), exit(1);
f6bc1314 114 umountall(typelist);
15de4e1e 115 exit(0);
71799463
KM
116 } else
117 setfsent();
15de4e1e 118 while (argc > 0) {
f6bc1314 119 if (umountfs(*argv++, 0) == 0)
15de4e1e
BJ
120 errs++;
121 argc--;
cfbe3c25 122 }
15de4e1e 123 exit(errs);
cfbe3c25 124}
15de4e1e 125
f6bc1314
KM
126usage()
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
140umountall(typelist)
141 char **typelist;
83dfa04a 142{
f6bc1314
KM
143 register struct fstab *fs;
144 struct fstab *allocfsent();
15de4e1e 145
0c6d0430 146 if ((fs = getfsent()) == (struct fstab *)0)
83dfa04a 147 return;
7a6d69cb 148 fs = allocfsent(fs);
f6bc1314 149 umountall(typelist);
7a6d69cb
SL
150 if (strcmp(fs->fs_file, "/") == 0) {
151 freefsent(fs);
83dfa04a 152 return;
7a6d69cb
SL
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);
15de4e1e
BJ
158 return;
159 }
f6bc1314 160 (void) umountfs(fs->fs_file, typelist);
7a6d69cb
SL
161 freefsent(fs);
162}
163
164struct fstab *
165allocfsent(fs)
166 register struct fstab *fs;
167{
168 register struct fstab *new;
169 register char *cp;
170 char *malloc();
171
0c6d0430
KM
172 new = (struct fstab *)malloc((unsigned)sizeof (*fs));
173 cp = malloc((unsigned)strlen(fs->fs_file) + 1);
7a6d69cb
SL
174 strcpy(cp, fs->fs_file);
175 new->fs_file = cp;
0c6d0430 176 cp = malloc((unsigned)strlen(fs->fs_type) + 1);
7a6d69cb
SL
177 strcpy(cp, fs->fs_type);
178 new->fs_type = cp;
0c6d0430 179 cp = malloc((unsigned)strlen(fs->fs_spec) + 1);
7a6d69cb
SL
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
187freefsent(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);
83dfa04a 198}
cfbe3c25 199
f6bc1314 200umountfs(name, typelist)
15de4e1e 201 char *name;
f6bc1314 202 int *typelist;
cfbe3c25 203{
4efd8d38
KM
204 char *mntpt;
205 struct stat stbuf;
f6bc1314 206 int type;
71799463
KM
207#ifdef NFS
208 register CLIENT *clp;
f6bc1314 209 struct hostent *hp = 0;
71799463
KM
210 struct sockaddr_in saddr;
211 struct timeval pertry, try;
212 enum clnt_stat clnt_stat;
213 int so = RPC_ANYSOCK;
71799463 214 char *hostp, *delimp;
f6bc1314 215#endif /* NFS */
cfbe3c25 216
4efd8d38 217 if (stat(name, &stbuf) < 0) {
f6bc1314 218 if ((mntpt = getmntname(name, MNTON, &type)) == 0)
4efd8d38 219 return (0);
49d93ed5 220 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
f6bc1314 221 if ((mntpt = getmntname(name, MNTON, &type)) == 0)
4efd8d38 222 return (0);
49d93ed5 223 } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
4efd8d38 224 mntpt = name;
f6bc1314 225 if ((name = getmntname(mntpt, MNTFROM, &type)) == 0)
4efd8d38
KM
226 return (0);
227 } else {
0c6d0430
KM
228 fprintf(stderr, "%s: not a directory or special device\n",
229 name);
15de4e1e 230 return (0);
cfbe3c25 231 }
f6bc1314
KM
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) {
4efd8d38
KM
253 perror(mntpt);
254 return (0);
255 }
256 if (vflag)
257 fprintf(stderr, "%s: Unmounted from %s\n", name, mntpt);
f6bc1314
KM
258
259#ifdef NFS
260 if (!fake && hp != NULL && (fflag & MNT_FORCE) == 0) {
4efd8d38 261 *delimp = '\0';
4efd8d38
KM
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);
71799463 271 }
4efd8d38
KM
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);
71799463 280 }
4efd8d38
KM
281 auth_destroy(clp->cl_auth);
282 clnt_destroy(clp);
760b60ac 283 }
f6bc1314 284#endif /* NFS */
760b60ac 285 return (1);
cfbe3c25 286}
71799463 287
4efd8d38 288char *
f6bc1314 289getmntname(name, what, type)
4efd8d38
KM
290 char *name;
291 int what;
f6bc1314 292 int *type;
4efd8d38 293{
0c6d0430
KM
294 int mntsize, i;
295 struct statfs *mntbuf;
4efd8d38 296
52f4d3d5 297 if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
4efd8d38
KM
298 perror("umount");
299 return (0);
300 }
4efd8d38 301 for (i = 0; i < mntsize; i++) {
f6bc1314
KM
302 if (what == MNTON && !strcmp(mntbuf[i].f_mntfromname, name)) {
303 if (type)
304 *type = mntbuf[i].f_type;
4efd8d38 305 return (mntbuf[i].f_mntonname);
f6bc1314
KM
306 }
307 if (what == MNTFROM && !strcmp(mntbuf[i].f_mntonname, name)) {
308 if (type)
309 *type = mntbuf[i].f_type;
4efd8d38 310 return (mntbuf[i].f_mntfromname);
f6bc1314 311 }
4efd8d38
KM
312 }
313 fprintf(stderr, "%s: not currently mounted\n", name);
314 return (0);
315}
316
f6bc1314
KM
317static int skipvfs;
318
319badtype(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
333int *
334maketypelist(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
371namematch(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
71799463
KM
399/*
400 * xdr routines for mount rpc's
401 */
402xdr_dir(xdrsp, dirp)
403 XDR *xdrsp;
404 char *dirp;
405{
406 return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
407}
f6bc1314 408#endif /* NFS */