summaryrefslogtreecommitdiffstats
path: root/sbin/umount/umount.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1997-06-16 11:20:05 +0000
committerbde <bde@FreeBSD.org>1997-06-16 11:20:05 +0000
commitf96e3b64ac8d0c826939e9971c5e98565c9a48e4 (patch)
treea635895371318ef30008ac61ca660d20f13c110b /sbin/umount/umount.c
parente7c620f4166bd12e6148a86e95549caf85f799be (diff)
downloadFreeBSD-src-f96e3b64ac8d0c826939e9971c5e98565c9a48e4.zip
FreeBSD-src-f96e3b64ac8d0c826939e9971c5e98565c9a48e4.tar.gz
Merge from Lite2.
- use new getvfsbyname() interface. - new -A option, like -a except only mounted file systems are unmounted. All non-cosmetic FreeBSD changes in umount.c, except ignoring of realpath() failures, went away because they are done better in Lite2. realpath() failures must be ignored so that non-pathnames like "<above>:/foo" and "host:/bar" get as far as mount(2). Reviewed by: dfr
Diffstat (limited to 'sbin/umount/umount.c')
-rw-r--r--sbin/umount/umount.c199
1 files changed, 80 insertions, 119 deletions
diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c
index 611bace..6c54b35 100644
--- a/sbin/umount/umount.c
+++ b/sbin/umount/umount.c
@@ -38,7 +38,7 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
+static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95";
#endif /* not lint */
#include <sys/param.h>
@@ -63,16 +63,16 @@ static char sccsid[] = "@(#)umount.c 8.3 (Berkeley) 2/20/94";
typedef enum { MNTON, MNTFROM } mntwhat;
-int fake, fflag, vflag, *typelist;
+int fake, fflag, vflag;
char *nfshost;
-int fsnametotype __P((char *));
-char *getmntname __P((char *, mntwhat, int *));
-void maketypelist __P((char *));
+int checkvfsname __P((const char *, char **));
+char *getmntname __P((char *, mntwhat, char **));
+char **makevfslist __P((char *));
int selected __P((int));
int namematch __P((struct hostent *));
-int umountall __P((void));
-int umountfs __P((char *));
+int umountall __P((char **));
+int umountfs __P((char *, char **));
void usage __P((void));
int xdr_dir __P((XDR *, char *));
@@ -81,14 +81,19 @@ main(argc, argv)
int argc;
char *argv[];
{
- int all, ch, errs;
+ int all, ch, errs, mnts;
+ char **typelist = NULL;
+ struct statfs *mntbuf;
/* Start disks transferring immediately. */
sync();
all = 0;
- while ((ch = getopt(argc, argv, "aFfh:t:v")) != -1)
+ while ((ch = getopt(argc, argv, "AaFfh:t:v")) != -1)
switch (ch) {
+ case 'A':
+ all = 2;
+ break;
case 'a':
all = 1;
break;
@@ -98,12 +103,14 @@ main(argc, argv)
case 'f':
fflag = MNT_FORCE;
break;
- case 'h': /* -h implies -a. */
- all = 1;
+ case 'h': /* -h implies -A. */
+ all = 2;
nfshost = optarg;
break;
case 't':
- maketypelist(optarg);
+ if (typelist != NULL)
+ errx(1, "only one -t option may be specified.");
+ typelist = makevfslist(optarg);
break;
case 'v':
vflag = 1;
@@ -120,24 +127,44 @@ main(argc, argv)
/* -h implies "-t nfs" if no -t flag. */
if ((nfshost != NULL) && (typelist == NULL))
- maketypelist("nfs");
+ typelist = makevfslist("nfs");
- if (all) {
+ switch (all) {
+ case 2:
+ if ((mnts = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+ warn("getmntinfo");
+ errs = 1;
+ break;
+ }
+ for (errs = 0, mnts--; mnts > 0; mnts--) {
+ if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
+ continue;
+ if (umountfs(mntbuf[mnts].f_mntonname, typelist) != 0)
+ errs = 1;
+ }
+ break;
+ case 1:
if (setfsent() == 0)
err(1, "%s", _PATH_FSTAB);
- errs = umountall();
- } else
+ errs = umountall(typelist);
+ break;
+ case 0:
for (errs = 0; *argv != NULL; ++argv)
- errs += umountfs(*argv);
+ if (umountfs(*argv, typelist) != 0)
+ errs = 1;
+ break;
+ }
exit(errs);
}
int
-umountall()
+umountall(typelist)
+ char **typelist;
{
struct fstab *fs;
int rval, type;
char *cp;
+ struct vfsconf vfc;
while ((fs = getfsent()) != NULL) {
/* Ignore the root. */
@@ -152,11 +179,11 @@ umountall()
strcmp(fs->fs_type, FSTAB_RQ))
continue;
/* If an unknown file system type, complain. */
- if ((type = fsnametotype(fs->fs_vfstype)) == MOUNT_NONE) {
+ if (getvfsbyname(fs->fs_vfstype, &vfc) < 0) {
warnx("%s: unknown mount type", fs->fs_vfstype);
continue;
}
- if (!selected(type))
+ if (checkvfsname(fs->fs_vfstype, typelist))
continue;
/*
@@ -167,16 +194,16 @@ umountall()
if ((cp = malloc((size_t)strlen(fs->fs_file) + 1)) == NULL)
err(1, NULL);
(void)strcpy(cp, fs->fs_file);
- rval = umountall();
- return (umountfs(cp) || rval);
+ rval = umountall(typelist);
+ return (umountfs(cp, typelist) || rval);
}
return (0);
}
-/* Returns 1 on failure, 0 on success */
int
-umountfs(name)
+umountfs(name, typelist)
char *name;
+ char **typelist;
{
enum clnt_stat clnt_stat;
struct hostent *hp;
@@ -184,8 +211,8 @@ umountfs(name)
struct stat sb;
struct timeval pertry, try;
CLIENT *clp;
- int so, type;
- char *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
+ int so;
+ char *type, *delimp, *hostp, *mntpt, rname[MAXPATHLEN];
if (realpath(name, rname) == NULL) {
/* Continue and let the system call check it... */
@@ -216,24 +243,27 @@ umountfs(name)
return (1);
}
- if (!selected(type))
- return (0);
+ if (checkvfsname(type, typelist))
+ return (1);
+
+ hp = NULL;
+ if (!strcmp(type, "nfs")) {
+ if ((delimp = strchr(name, '@')) != NULL) {
+ hostp = delimp + 1;
+ *delimp = '\0';
+ hp = gethostbyname(hostp);
+ *delimp = '@';
+ } else if ((delimp = strchr(name, ':')) != NULL) {
+ *delimp = '\0';
+ hostp = name;
+ hp = gethostbyname(hostp);
+ name = delimp + 1;
+ *delimp = ':';
+ }
+ }
- if ((delimp = strchr(name, '@')) != NULL && type == MOUNT_NFS) {
- hostp = delimp + 1;
- *delimp = '\0';
- hp = gethostbyname(hostp);
- *delimp = '@';
- } else if ((delimp = strchr(name, ':')) != NULL && type == MOUNT_NFS) {
- *delimp = '\0';
- hostp = name;
- hp = gethostbyname(hostp);
- name = delimp + 1;
- *delimp = ':';
- } else
- hp = NULL;
if (!namematch(hp))
- return (0);
+ return (1);
if (vflag)
(void)printf("%s: unmount from %s\n", name, mntpt);
@@ -278,101 +308,32 @@ char *
getmntname(name, what, type)
char *name;
mntwhat what;
- int *type;
+ char **type;
{
- struct statfs *mntbuf;
- int i, mntsize;
+ static struct statfs *mntbuf;
+ static int mntsize;
+ int i;
- if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
+ if (mntbuf == NULL &&
+ (mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
warn("getmntinfo");
return (NULL);
}
for (i = 0; i < mntsize; i++) {
if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
if (type)
- *type = mntbuf[i].f_type;
+ *type = mntbuf[i].f_fstypename;
return (mntbuf[i].f_mntonname);
}
if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
if (type)
- *type = mntbuf[i].f_type;
+ *type = mntbuf[i].f_fstypename;
return (mntbuf[i].f_mntfromname);
}
}
return (NULL);
}
-static enum { IN_LIST, NOT_IN_LIST } which;
-
-int
-selected(type)
- int type;
-{
- int *tmp_typelist;
-
- tmp_typelist=typelist;
- /* If no type specified, it's always selected. */
- if (tmp_typelist == NULL)
- return (1);
- for (; *tmp_typelist != MOUNT_NONE; ++tmp_typelist)
- if (type == *tmp_typelist)
- return (which == IN_LIST ? 1 : 0);
- return (which == IN_LIST ? 0 : 1);
-}
-
-void
-maketypelist(fslist)
- char *fslist;
-{
- int *av, i;
- char *nextcp;
-
- if ((fslist == NULL) || (fslist[0] == '\0'))
- errx(1, "empty type list");
-
- /*
- * XXX
- * Note: the syntax is "noxxx,yyy" for no xxx's and
- * no yyy's, not the more intuitive "noyyy,noyyy".
- */
- if (fslist[0] == 'n' && fslist[1] == 'o') {
- fslist += 2;
- which = NOT_IN_LIST;
- } else
- which = IN_LIST;
-
- /* Count the number of types. */
- for (i = 0, nextcp = fslist; *nextcp != NULL; ++nextcp)
- if (*nextcp == ',')
- i++;
-
- /* Build an array of that many types. */
- if ((av = typelist = malloc((i + 2) * sizeof(int))) == NULL)
- err(1, NULL);
- for (i = 0; fslist != NULL; fslist = nextcp, ++i) {
- if ((nextcp = strchr(fslist, ',')) != NULL)
- *nextcp++ = '\0';
- av[i] = fsnametotype(fslist);
- if (av[i] == MOUNT_NONE)
- errx(1, "%s: unknown mount type", fslist);
- }
- /* Terminate the array. */
- av[i++] = MOUNT_NONE;
-}
-
-int
-fsnametotype(name)
- char *name;
-{
- static char const *namelist[] = INITMOUNTNAMES;
- char const **cp;
-
- for (cp = namelist; *cp; ++cp)
- if (strcmp(name, *cp) == 0)
- return (cp - namelist);
- return (MOUNT_NONE);
-}
-
int
namematch(hp)
struct hostent *hp;
OpenPOWER on IntegriCloud