new copyright; att/bsd/shared
[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
0fc6e47b 15static char sccsid[] = "@(#)umount.c 5.15 (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) {
f6bc1314 205 if ((mntpt = getmntname(name, MNTON, &type)) == 0)
4efd8d38 206 return (0);
49d93ed5 207 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
f6bc1314 208 if ((mntpt = getmntname(name, MNTON, &type)) == 0)
4efd8d38 209 return (0);
49d93ed5 210 } else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
4efd8d38 211 mntpt = name;
f6bc1314 212 if ((name = getmntname(mntpt, MNTFROM, &type)) == 0)
4efd8d38
KM
213 return (0);
214 } else {
0c6d0430
KM
215 fprintf(stderr, "%s: not a directory or special device\n",
216 name);
15de4e1e 217 return (0);
cfbe3c25 218 }
f6bc1314
KM
219
220 if (badtype(type, typelist))
221 return(1);
222#ifdef NFS
223 if ((delimp = index(name, '@')) != NULL) {
224 hostp = delimp + 1;
225 *delimp = '\0';
226 hp = gethostbyname(hostp);
227 *delimp = '@';
228 } else if ((delimp = index(name, ':')) != NULL) {
229 *delimp = '\0';
230 hostp = name;
231 hp = gethostbyname(hostp);
232 name = delimp+1;
233 *delimp = ':';
234 }
235
236 if (!namematch(hp, nfshost))
237 return(1);
238#endif /* NFS */
239 if (!fake && unmount(mntpt, fflag) < 0) {
4efd8d38
KM
240 perror(mntpt);
241 return (0);
242 }
243 if (vflag)
244 fprintf(stderr, "%s: Unmounted from %s\n", name, mntpt);
f6bc1314
KM
245
246#ifdef NFS
247 if (!fake && hp != NULL && (fflag & MNT_FORCE) == 0) {
4efd8d38 248 *delimp = '\0';
4efd8d38
KM
249 bcopy(hp->h_addr,(caddr_t)&saddr.sin_addr,hp->h_length);
250 saddr.sin_family = AF_INET;
251 saddr.sin_port = 0;
252 pertry.tv_sec = 3;
253 pertry.tv_usec = 0;
254 if ((clp = clntudp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1,
255 pertry, &so)) == NULL) {
256 clnt_pcreateerror("Cannot MNT PRC");
257 return (1);
71799463 258 }
4efd8d38
KM
259 clp->cl_auth = authunix_create_default();
260 try.tv_sec = 20;
261 try.tv_usec = 0;
262 clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir, name,
263 xdr_void, (caddr_t)0, try);
264 if (clnt_stat != RPC_SUCCESS) {
265 clnt_perror(clp, "Bad MNT RPC");
266 return (1);
71799463 267 }
4efd8d38
KM
268 auth_destroy(clp->cl_auth);
269 clnt_destroy(clp);
760b60ac 270 }
f6bc1314 271#endif /* NFS */
760b60ac 272 return (1);
cfbe3c25 273}
71799463 274
4efd8d38 275char *
f6bc1314 276getmntname(name, what, type)
4efd8d38
KM
277 char *name;
278 int what;
f6bc1314 279 int *type;
4efd8d38 280{
0c6d0430
KM
281 int mntsize, i;
282 struct statfs *mntbuf;
4efd8d38 283
52f4d3d5 284 if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
4efd8d38
KM
285 perror("umount");
286 return (0);
287 }
4efd8d38 288 for (i = 0; i < mntsize; i++) {
f6bc1314
KM
289 if (what == MNTON && !strcmp(mntbuf[i].f_mntfromname, name)) {
290 if (type)
291 *type = mntbuf[i].f_type;
4efd8d38 292 return (mntbuf[i].f_mntonname);
f6bc1314
KM
293 }
294 if (what == MNTFROM && !strcmp(mntbuf[i].f_mntonname, name)) {
295 if (type)
296 *type = mntbuf[i].f_type;
4efd8d38 297 return (mntbuf[i].f_mntfromname);
f6bc1314 298 }
4efd8d38
KM
299 }
300 fprintf(stderr, "%s: not currently mounted\n", name);
301 return (0);
302}
303
f6bc1314
KM
304static int skipvfs;
305
306badtype(type, typelist)
307 int type;
308 int *typelist;
309{
310 if (typelist == 0)
311 return(0);
312 while (*typelist) {
313 if (type == *typelist)
314 return(skipvfs);
315 typelist++;
316 }
317 return(!skipvfs);
318}
319
320int *
321maketypelist(fslist)
322 char *fslist;
323{
324 register char *nextcp;
325 register int *av, i;
f6bc1314
KM
326
327 if (fslist == NULL)
328 return(NULL);
329 if (fslist[0] == 'n' && fslist[1] == 'o') {
330 fslist += 2;
331 skipvfs = 1;
332 } else
333 skipvfs = 0;
334 for (i = 0, nextcp = fslist; *nextcp; nextcp++)
335 if (*nextcp == ',')
336 i++;
337 av = (int *)malloc((i+2) * sizeof(int));
338 if (av == NULL)
339 return(NULL);
340 for (i = 0; fslist; fslist = nextcp) {
341 if (nextcp = index(fslist, ','))
342 *nextcp++ = '\0';
343 if (strcmp(fslist, "ufs") == 0)
344 av[i++] = MOUNT_UFS;
345 else if (strcmp(fslist, "nfs") == 0)
346 av[i++] = MOUNT_NFS;
347 else if (strcmp(fslist, "mfs") == 0)
348 av[i++] = MOUNT_MFS;
349 else if (strcmp(fslist, "pc") == 0)
350 av[i++] = MOUNT_PC;
351 }
352 av[i++] = 0;
353 return(av);
354}
355
356#ifdef NFS
357namematch(hp, nfshost)
358 struct hostent *hp;
359 char *nfshost;
360{
361 register char *cp;
362 register char **np;
363
364 if (hp == NULL || nfshost == NULL)
365 return(1);
366 if (strcasecmp(nfshost, hp->h_name) == 0)
367 return(1);
368 if (cp = index(hp->h_name, '.')) {
369 *cp = '\0';
370 if (strcasecmp(nfshost, hp->h_name) == 0)
371 return(1);
372 }
373 for (np = hp->h_aliases; *np; np++) {
374 if (strcasecmp(nfshost, *np) == 0)
375 return(1);
376 if (cp = index(*np, '.')) {
377 *cp = '\0';
378 if (strcasecmp(nfshost, *np) == 0)
379 return(1);
380 }
381 }
382 return(0);
383}
384
71799463
KM
385/*
386 * xdr routines for mount rpc's
387 */
388xdr_dir(xdrsp, dirp)
389 XDR *xdrsp;
390 char *dirp;
391{
392 return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
393}
f6bc1314 394#endif /* NFS */