Beispiel #1
0
/*
 * Make a pass over the file system info in ``mntbuf'' filtering out
 * file system types not in vfslist and possibly re-stating to get
 * current (not cached) info.  Returns the new count of valid statfs bufs.
 */
static size_t
regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist)
{
	int error, i, j;
	struct statfs *mntbuf;

	if (vfslist == NULL)
		return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT));

	mntbuf = *mntbufp;
	for (j = 0, i = 0; i < mntsize; i++) {
		if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
			continue;
		/*
		 * XXX statfs(2) can fail for various reasons. It may be
		 * possible that the user does not have access to the
		 * pathname, if this happens, we will fall back on
		 * "stale" filesystem statistics.
		 */
		error = statfs(mntbuf[i].f_mntonname, &mntbuf[j]);
		if (nflag || error < 0)
			if (i != j) {
				if (error < 0)
					warnx("%s stats possibly stale",
					    mntbuf[i].f_mntonname);
				mntbuf[j] = mntbuf[i];
			}
		j++;
	}
	return (j);
}
Beispiel #2
0
/*
 * Make a pass over the filesystem info in ``mntbuf'' filtering out
 * filesystem types not in vfslist and possibly re-stating to get
 * current (not cached) info.  Returns the new count of valid statfs bufs.
 */
long
regetmntinfo(struct statfs **mntbufp, struct statvfs **mntvbufp, long mntsize, char **vfslist)
{
    int i, j;
    struct statfs *mntbuf;
    struct statvfs *mntvbuf;

    if (vfslist == NULL)
        return (nflag ? mntsize : getmntvinfo(mntbufp, mntvbufp, MNT_WAIT));

    mntbuf = *mntbufp;
    mntvbuf = *mntvbufp;
    for (j = 0, i = 0; i < mntsize; i++) {
        if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
            continue;
        if (!nflag) {
            statfs(mntbuf[i].f_mntonname,&mntbuf[j]);
            statvfs(mntbuf[i].f_mntonname,&mntvbuf[j]);
        } else if (i != j) {
            mntbuf[j] = mntbuf[i];
            mntvbuf[j] = mntvbuf[i];
        }
        j++;
    }
    return (j);
}
Beispiel #3
0
int
umountall(char **typelist)
{
	struct vfsconf vfc;
	struct fstab *fs;
	int rval;
	char *cp;
	static int firstcall = 1;

	if ((fs = getfsent()) != NULL)
		firstcall = 0;
	else if (firstcall)
		errx(1, "fstab reading failure");
	else
		return (0);
	do {
		/* Ignore the root. */
		if (strcmp(fs->fs_file, "/") == 0)
			continue;
		/*
		 * !!!
		 * Historic practice: ignore unknown FSTAB_* fields.
		 */
		if (strcmp(fs->fs_type, FSTAB_RW) &&
		    strcmp(fs->fs_type, FSTAB_RO) &&
		    strcmp(fs->fs_type, FSTAB_RQ))
			continue;
		/* If an unknown file system type, complain. */
		if (getvfsbyname(fs->fs_vfstype, &vfc) == -1) {
			warnx("%s: unknown mount type", fs->fs_vfstype);
			continue;
		}
		if (checkvfsname(fs->fs_vfstype, typelist))
			continue;

		/*
		 * We want to unmount the file systems in the reverse order
		 * that they were mounted.  So, we save off the file name
		 * in some allocated memory, and then call recursively.
		 */
		if ((cp = malloc((size_t)strlen(fs->fs_file) + 1)) == NULL)
			err(1, "malloc failed");
		(void)strcpy(cp, fs->fs_file);
		rval = umountall(typelist);
		rval = umountfs(cp, typelist) || rval;
		free(cp);
		return (rval);
	} while ((fs = getfsent()) != NULL);
	return (0);
}
  /*_________________---------------------------__________________
    _________________     regetmntinfo          __________________
    -----------------___________________________------------------
  */
  static size_t regetmntinfo(struct statfs **mntbufp, long mntsize, const char **vfslist)
  {
    int i, j;
    struct statfs *mntbuf;
    
    if (vfslist == NULL)
      return (getmntinfo(mntbufp, MNT_WAIT));
    
    mntbuf = *mntbufp;
    for (j = 0, i = 0; i < mntsize; i++) {
      if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
	continue;
      (void)statfs(mntbuf[i].f_mntonname,&mntbuf[j]);
      j++;
    }
    return (j);
  }
Beispiel #5
0
int
main(int argc, char *argv[])
{
	struct stat stbuf;
	struct statfs statfsbuf, totalbuf;
	struct maxwidths maxwidths;
	struct statfs *mntbuf;
	const char *fstype;
	char *mntpath, *mntpt;
	const char **vfslist;
	int i, mntsize;
	int ch, rv;

	fstype = "ufs";

	memset(&totalbuf, 0, sizeof(totalbuf));
	totalbuf.f_bsize = DEV_BSIZE;
	strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN);
	vfslist = NULL;
	while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1)
		switch (ch) {
		case 'a':
			aflag = 1;
			break;
		case 'b':
				/* FALLTHROUGH */
		case 'P':
			/*
			 * POSIX specifically discusses the behavior of
			 * both -k and -P. It states that the blocksize should
			 * be set to 1024. Thus, if this occurs, simply break
			 * rather than clobbering the old blocksize.
			 */
			if (kflag)
				break;
			setenv("BLOCKSIZE", "512", 1);
			hflag = 0;
			break;
		case 'c':
			cflag = 1;
			break;
		case 'g':
			setenv("BLOCKSIZE", "1g", 1);
			hflag = 0;
			break;
		case 'H':
			hflag = UNITS_SI;
			break;
		case 'h':
			hflag = UNITS_2;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			kflag++;
			setenv("BLOCKSIZE", "1024", 1);
			hflag = 0;
			break;
		case 'l':
			if (vfslist != NULL)
				errx(1, "-l and -t are mutually exclusive.");
			vfslist = makevfslist(makenetvfslist());
			lflag = 1;
			break;
		case 'm':
			setenv("BLOCKSIZE", "1m", 1);
			hflag = 0;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			if (lflag)
				errx(1, "-l and -t are mutually exclusive.");
			if (vfslist != NULL)
				errx(1, "only one -t option may be specified");
			fstype = optarg;
			vfslist = makevfslist(optarg);
			break;
		case 'T':
			Tflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	rv = 0;
	if (!*argv) {
		/* everything (modulo -t) */
		mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
		mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
	} else {
		/* just the filesystems specified on the command line */
		mntbuf = malloc(argc * sizeof(*mntbuf));
		if (mntbuf == 0)
			err(1, "malloc()");
		mntsize = 0;
		/* continued in for loop below */
	}

	/* iterate through specified filesystems */
	for (; *argv; argv++) {
		if (stat(*argv, &stbuf) < 0) {
			if ((mntpt = getmntpt(*argv)) == 0) {
				warn("%s", *argv);
				rv = 1;
				continue;
			}
		} else if (S_ISCHR(stbuf.st_mode)) {
			if ((mntpt = getmntpt(*argv)) == 0) {
				mdev.fspec = *argv;
				mntpath = strdup("/tmp/df.XXXXXX");
				if (mntpath == NULL) {
					warn("strdup failed");
					rv = 1;
					continue;
				}
				mntpt = mkdtemp(mntpath);
				if (mntpt == NULL) {
					warn("mkdtemp(\"%s\") failed", mntpath);
					rv = 1;
					free(mntpath);
					continue;
				}
				if (mount(fstype, mntpt, MNT_RDONLY,
				    &mdev) != 0) {
					warn("%s", *argv);
					rv = 1;
					(void)rmdir(mntpt);
					free(mntpath);
					continue;
				} else if (statfs(mntpt, &statfsbuf) == 0) {
					statfsbuf.f_mntonname[0] = '\0';
					prtstat(&statfsbuf, &maxwidths);
					if (cflag)
						addstat(&totalbuf, &statfsbuf);
				} else {
					warn("%s", *argv);
					rv = 1;
				}
				(void)unmount(mntpt, 0);
				(void)rmdir(mntpt);
				free(mntpath);
				continue;
			}
		} else
			mntpt = *argv;

		/*
		 * Statfs does not take a `wait' flag, so we cannot
		 * implement nflag here.
		 */
		if (statfs(mntpt, &statfsbuf) < 0) {
			warn("%s", mntpt);
			rv = 1;
			continue;
		}

		/*
		 * Check to make sure the arguments we've been given are
		 * satisfied.  Return an error if we have been asked to
		 * list a mount point that does not match the other args
		 * we've been given (-l, -t, etc.).
		 */
		if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
			rv = 1;
			continue;
		}

		/* the user asked for it, so ignore the ignore flag */
		statfsbuf.f_flags &= ~MNT_IGNORE;

		/* add to list */
		mntbuf[mntsize++] = statfsbuf;
	}

	bzero(&maxwidths, sizeof(maxwidths));
	for (i = 0; i < mntsize; i++) {
		if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) {
			update_maxwidths(&maxwidths, &mntbuf[i]);
			if (cflag)
				addstat(&totalbuf, &mntbuf[i]);
		}
	}
	for (i = 0; i < mntsize; i++)
		if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
			prtstat(&mntbuf[i], &maxwidths);
	if (cflag)
		prtstat(&totalbuf, &maxwidths);
	return (rv);
}
Beispiel #6
0
int
main(int argc, char *argv[])
{
	struct stat stbuf;
	struct statfs statfsbuf, *mntbuf;
	struct maxwidths maxwidths;
	char *mntpt, **vfslist;
	long mntsize;
	int ch, i, rv, tflag = 0, kludge_tflag = 0;
	int kflag = 0;
	const char *options = "abgHhiklmnPt:T:";
	if (COMPAT_MODE("bin/df", "unix2003")) {
		/* Unix2003 requires -t be "include total capacity". which df
		  already does, but it conflicts with the old -t so we need to
		  *not* expect a string after -t (we provide -T in both cases
		  to cover the old use of -t) */
		options = "abgHhiklmnPtT:";
		iflag = 1;
	}

	vfslist = NULL;
	while ((ch = getopt(argc, argv, options)) != -1)
		switch (ch) {
		case 'a':
			aflag = 1;
			break;
		case 'b':
				/* FALLTHROUGH */
		case 'P':
			if (COMPAT_MODE("bin/df", "unix2003")) {
				if (!kflag) {
					/* -k overrides -P */
					putenv("BLOCKSIZE=512");
				}
				iflag = 0;
			} else {
				putenv("BLOCKSIZE=512");
			}
			hflag = 0;
			break;
		case 'g':
			putenv("BLOCKSIZE=1g");
			hflag = 0;
			break;
		case 'H':
			hflag = UNITS_SI;
			valp = vals_si;
			break;
		case 'h':
			hflag = UNITS_2;
			valp = vals_base2;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			if (COMPAT_MODE("bin/df", "unix2003")) {
				putenv("BLOCKSIZE=1024");
			} else {
				putenv("BLOCKSIZE=1k");
			}
			kflag = 1;
			hflag = 0;
			break;
		case 'l':
			if (tflag)
				errx(1, "-l and -T are mutually exclusive.");
			if (vfslist != NULL)
				break;
			vfslist = makevfslist(makenetvfslist());
			break;
		case 'm':
			putenv("BLOCKSIZE=1m");
			hflag = 0;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			/* Unix2003 uses -t for something we do by default */
			if (COMPAT_MODE("bin/df", "unix2003")) {
			    kludge_tflag = 1;
			    break;
			}
		case 'T':
			if (vfslist != NULL) {
				if (tflag)
					errx(1, "only one -%c option may be specified", ch);
				else
					errx(1, "-l and -%c are mutually exclusive.", ch);
			}
			tflag++;
			vfslist = makevfslist(optarg);
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	/* If we are in unix2003 mode, have seen a -t but no -T and the first
	  non switch arg isn't a file, let's pretend they used -T on it.
	  This makes the Lexmark printer installer happy (PR-3918471) */
	if (tflag == 0 && kludge_tflag && *argv && stat(*argv, &stbuf) < 0
	  && errno == ENOENT) {
	    vfslist = makevfslist(*argv++);
	}

	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
	bzero(&maxwidths, sizeof(maxwidths));
	for (i = 0; i < mntsize; i++)
		update_maxwidths(&maxwidths, &mntbuf[i]);

	rv = 0;
	if (!*argv) {
		mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
		bzero(&maxwidths, sizeof(maxwidths));
		for (i = 0; i < mntsize; i++)
			update_maxwidths(&maxwidths, &mntbuf[i]);
		for (i = 0; i < mntsize; i++) {
			if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
				prtstat(&mntbuf[i], &maxwidths);
		}
		exit(rv);
	}

	for (; *argv; argv++) {
		if (stat(*argv, &stbuf) < 0) {
			if ((mntpt = getmntpt(*argv)) == 0) {
				warn("%s", *argv);
				rv = 1;
				continue;
			}
		} else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) {
			warnx("%s: Raw devices not supported", *argv);
			rv = 1;
			continue;
		} else
			mntpt = *argv;
		/*
		 * Statfs does not take a `wait' flag, so we cannot
		 * implement nflag here.
		 */
		if (statfs(mntpt, &statfsbuf) < 0) {
			warn("%s", mntpt);
			rv = 1;
			continue;
		}
		/* Check to make sure the arguments we've been
		 * given are satisfied.  Return an error if we
		 * have been asked to list a mount point that does
		 * not match the other args we've been given (-l, -t, etc.)
		 */
		if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
			rv++;
			continue;
		}

		if (argc == 1) {
		        bzero(&maxwidths, sizeof(maxwidths));
			update_maxwidths(&maxwidths, &statfsbuf);
		}
		prtstat(&statfsbuf, &maxwidths);
	}
	return (rv);
}
Beispiel #7
0
int
main(int argc, char *argv[])
{
	const char *mntfromname, **vfslist, *vfstype;
	struct fstab *fs;
	struct statfs *mntbuf;
	int all, ch, i, init_flags, late, failok, mntsize, rval, have_fstab, ro;
	int onlylate;
	char *cp, *ep, *options;

	all = init_flags = late = onlylate = 0;
	ro = 0;
	options = NULL;
	vfslist = NULL;
	vfstype = "ufs";
	while ((ch = getopt(argc, argv, "adF:fLlno:prt:uvw")) != -1)
		switch (ch) {
		case 'a':
			all = 1;
			break;
		case 'd':
			debug = 1;
			break;
		case 'F':
			setfstab(optarg);
			break;
		case 'f':
			init_flags |= MNT_FORCE;
			break;
		case 'L':
			onlylate = 1;
			late = 1;
			break;
		case 'l':
			late = 1;
			break;
		case 'n':
			/* For compatibility with the Linux version of mount. */
			break;
		case 'o':
			if (*optarg) {
				options = catopt(options, optarg);
				if (specified_ro(optarg))
					ro = 1;
			}
			break;
		case 'p':
			fstab_style = 1;
			verbose = 1;
			break;
		case 'r':
			options = catopt(options, "ro");
			ro = 1;
			break;
		case 't':
			if (vfslist != NULL)
				errx(1, "only one -t option may be specified");
			vfslist = makevfslist(optarg);
			vfstype = optarg;
			break;
		case 'u':
			init_flags |= MNT_UPDATE;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'w':
			options = catopt(options, "noro");
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

#define	BADTYPE(type)							\
	(strcmp(type, FSTAB_RO) &&					\
	    strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))

	if ((init_flags & MNT_UPDATE) && (ro == 0))
		options = catopt(options, "noro");

	rval = 0;
	switch (argc) {
	case 0:
		if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
			err(1, "getmntinfo");
		if (all) {
			while ((fs = getfsent()) != NULL) {
				if (BADTYPE(fs->fs_type))
					continue;
				if (checkvfsname(fs->fs_vfstype, vfslist))
					continue;
				if (hasopt(fs->fs_mntops, "noauto"))
					continue;
				if (!hasopt(fs->fs_mntops, "late") && onlylate)
					continue;
				if (hasopt(fs->fs_mntops, "late") && !late)
					continue;
				if (hasopt(fs->fs_mntops, "failok"))
					failok = 1;
				else
					failok = 0;
				if (!(init_flags & MNT_UPDATE) &&
				    ismounted(fs, mntbuf, mntsize))
					continue;
				options = update_options(options, fs->fs_mntops,
				    mntbuf->f_flags);
				if (mountfs(fs->fs_vfstype, fs->fs_spec,
				    fs->fs_file, init_flags, options,
				    fs->fs_mntops) && !failok)
					rval = 1;
			}
		} else if (fstab_style) {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
					continue;
				putfsent(&mntbuf[i]);
			}
		} else {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename,
				    vfslist))
					continue;
				if (!verbose &&
				    (mntbuf[i].f_flags & MNT_IGNORE) != 0)
					continue;
				prmount(&mntbuf[i]);
			}
		}
		exit(rval);
	case 1:
		if (vfslist != NULL)
			usage();

		rmslashes(*argv, *argv);
		if (init_flags & MNT_UPDATE) {
			mntfromname = NULL;
			have_fstab = 0;
			if ((mntbuf = getmntpt(*argv)) == NULL)
				errx(1, "not currently mounted %s", *argv);
			/*
			 * Only get the mntflags from fstab if both mntpoint
			 * and mntspec are identical. Also handle the special
			 * case where just '/' is mounted and 'spec' is not
			 * identical with the one from fstab ('/dev' is missing
			 * in the spec-string at boot-time).
			 */
			if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) {
				if (strcmp(fs->fs_spec,
				    mntbuf->f_mntfromname) == 0 &&
				    strcmp(fs->fs_file,
				    mntbuf->f_mntonname) == 0) {
					have_fstab = 1;
					mntfromname = mntbuf->f_mntfromname;
				} else if (argv[0][0] == '/' &&
				    argv[0][1] == '\0') {
					fs = getfsfile("/");
					have_fstab = 1;
					mntfromname = fs->fs_spec;
				}
			}
			if (have_fstab) {
				options = update_options(options, fs->fs_mntops,
				    mntbuf->f_flags);
			} else {
				mntfromname = mntbuf->f_mntfromname;
				options = update_options(options, NULL,
				    mntbuf->f_flags);
			}
			rval = mountfs(mntbuf->f_fstypename, mntfromname,
			    mntbuf->f_mntonname, init_flags, options, 0);
			break;
		}
		if ((fs = getfsfile(*argv)) == NULL &&
		    (fs = getfsspec(*argv)) == NULL)
			errx(1, "%s: unknown special file or file system",
			    *argv);
		if (BADTYPE(fs->fs_type))
			errx(1, "%s has unknown file system type",
			    *argv);
		rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file,
		    init_flags, options, fs->fs_mntops);
		break;
	case 2:
		/*
		 * If -t flag has not been specified, the path cannot be
		 * found, spec contains either a ':' or a '@', then assume
		 * that an NFS file system is being specified ala Sun.
		 * Check if the hostname contains only allowed characters
		 * to reduce false positives.  IPv6 addresses containing
		 * ':' will be correctly parsed only if the separator is '@'.
		 * The definition of a valid hostname is taken from RFC 1034.
		 */
		if (vfslist == NULL && ((ep = strchr(argv[0], '@')) != NULL ||
		    (ep = strchr(argv[0], ':')) != NULL)) {
			if (*ep == '@') {
				cp = ep + 1;
				ep = cp + strlen(cp);
			} else
				cp = argv[0];
			while (cp != ep) {
				if (!isdigit(*cp) && !isalpha(*cp) &&
				    *cp != '.' && *cp != '-' && *cp != ':')
					break;
				cp++;
			}
			if (cp == ep)
				vfstype = "nfs";
		}
		rval = mountfs(vfstype,
		    argv[0], argv[1], init_flags, options, NULL);
		break;
	default:
		usage();
		/* NOTREACHED */
	}

	/*
	 * If the mount was successfully, and done by root, tell mountd the
	 * good news.
	 */
	if (rval == 0 && getuid() == 0)
		restart_mountd();

	exit(rval);
}
int
mntlistmain()
{
	
	/* NCurses Stuff */
	
	app_init(); /* INIT Ncurses Stuff not needed when becomes part of SMIT*/
	
	const char  **vfslist, *vfstype;
	struct fstab *fs;
	struct statfs *mntbuf;
	int all, i, init_flags, late, failok, mntsize, rval, ro;
	int onlylate;
	char *options;

	all = init_flags = late = onlylate = 0;
	ro = 0;
	options = NULL;
	vfslist = NULL;
	vfstype = "ufs";

// Leave there


#define	BADTYPE(type)							\
	(strcmp(type, FSTAB_RO) &&					\
	    strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))

	rval = 0;
		/* Might be what I want */

		if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
			err(1, "getmntinfo");
		if (all) {
			while ((fs = getfsent()) != NULL) {
				if (BADTYPE(fs->fs_type))
					continue;
				if (checkvfsname(fs->fs_vfstype, vfslist))
					continue;
				if (hasopt(fs->fs_mntops, "noauto"))
					continue;
				if (!hasopt(fs->fs_mntops, "late") && onlylate)
					continue;
				if (hasopt(fs->fs_mntops, "late") && !late)
					continue;
				if (hasopt(fs->fs_mntops, "failok"))
					failok = 1;
				else
					failok = 0;
				if (!(init_flags & MNT_UPDATE) &&
				    ismounted(fs, mntbuf, mntsize))
					continue;
		
			}
				
		} else if (fstab_style) {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
					continue;
			}
		} else {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename,
				    vfslist))
					continue;
				prmount(&mntbuf[i]);
				wmove(FS_LIST, ctr++, 2);
			}
		}
		wgetch(FS_LIST);
		
		ctr = 1; // Reset the Counter
		return (rval);


}
Beispiel #9
0
int
main(int argc, char **argv)
{
	const char *mntfromname, **vfslist, *vfstype;
	struct fstab *fs;
	struct statfs *mntbuf;
	FILE *mountdfp;
	pid_t pid;
	int all, ch, i, init_flags, mntsize, rval, have_fstab;
	char *options;

	all = init_flags = 0;
	options = NULL;
	vfslist = NULL;
	vfstype = "ufs";
	while ((ch = getopt(argc, argv, "adF:fo:prwt:uv")) != -1) {
		switch (ch) {
		case 'a':
			all = 1;
			break;
		case 'd':
			debug = 1;
			break;
		case 'F':
			setfstab(optarg);
			break;
		case 'f':
			init_flags |= MNT_FORCE;
			break;
		case 'o':
			if (*optarg)
				options = catopt(options, optarg);
			break;
		case 'p':
			fstab_style = 1;
			verbose = 1;
			break;
		case 'r':
			options = catopt(options, "ro");
			break;
		case 't':
			if (vfslist != NULL)
				errx(1, "only one -t option may be specified");
			vfslist = makevfslist(optarg);
			vfstype = optarg;
			break;
		case 'u':
			init_flags |= MNT_UPDATE;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'w':
			options = catopt(options, "noro");
			break;
		case '?':
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

#define	BADTYPE(type)							\
	(strcmp(type, FSTAB_RO) &&					\
	    strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))

	rval = 0;
	switch (argc) {
	case 0:
		if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
			err(1, "getmntinfo");
		if (all) {
			while ((fs = getfsent()) != NULL) {
				if (BADTYPE(fs->fs_type))
					continue;
				if (checkvfsname(fs->fs_vfstype, vfslist))
					continue;
				if (hasopt(fs->fs_mntops, "noauto"))
					continue;
				if (!(init_flags & MNT_UPDATE) &&
				    ismounted(fs, mntbuf, mntsize))
					continue;
				options = update_options(options,
				    fs->fs_mntops, mntbuf->f_flags);
				if (mountfs(fs->fs_vfstype, fs->fs_spec,
				    fs->fs_file, init_flags, options,
				    fs->fs_mntops))
					rval = 1;
			}
		} else if (fstab_style) {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename, vfslist))
					continue;
				putfsent(&mntbuf[i]);
			}
		} else {
			for (i = 0; i < mntsize; i++) {
				if (checkvfsname(mntbuf[i].f_fstypename,
				    vfslist))
					continue;
				prmount(&mntbuf[i]);
			}
		}
		exit(rval);
	case 1:
		if (vfslist != NULL)
			usage();

		rmslashes(*argv, *argv);

		if (init_flags & MNT_UPDATE) {
			mntfromname = NULL;
			have_fstab = 0;
			if ((mntbuf = getmntpt(*argv)) == NULL)
				errx(1, "not currently mounted %s", *argv);
			/*
			 * Only get the mntflags from fstab if both mntpoint
			 * and mntspec are identical. Also handle the special
			 * case where just '/' is mounted and 'spec' is not
			 * identical with the one from fstab ('/dev' is missing
			 * in the spec-string at boot-time).
			 */
			if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) {
				if (strcmp(fs->fs_spec,
				    mntbuf->f_mntfromname) == 0 &&
				    strcmp(fs->fs_file,
				    mntbuf->f_mntonname) == 0) {
					have_fstab = 1;
					mntfromname = mntbuf->f_mntfromname;
				} else if (argv[0][0] == '/' &&
				    argv[0][1] == '\0') {
					fs = getfsfile("/");
					have_fstab = 1;
					mntfromname = fs->fs_spec;
				}
			}
			if (have_fstab) {
				options = update_options(options, fs->fs_mntops,
				    mntbuf->f_flags);
			} else {
				mntfromname = mntbuf->f_mntfromname;
				options = update_options(options, NULL,
				    mntbuf->f_flags);
			}
			rval = mountfs(mntbuf->f_fstypename, mntfromname,
			    mntbuf->f_mntonname, init_flags, options, 0);
			break;
		}
		if ((fs = getfsfile(*argv)) == NULL &&
		    (fs = getfsspec(*argv)) == NULL)
			errx(1, "%s: unknown special file or file system",
			    *argv);
		if (BADTYPE(fs->fs_type))
			errx(1, "%s has unknown file system type",
			    *argv);
		rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file,
		    init_flags, options, fs->fs_mntops);
		break;
	case 2:
		/*
		 * If -t flag has not been specified, the path cannot be
		 * found.
		 *
		 * If the spec is not a file and contains a ':' then assume
		 * NFS.
		 *
		 * If the spec is a cdev attempt to extract the fstype from
		 * the label.
		 *
		 * When all else fails ufs is assumed.
		 */
		if (vfslist == NULL) {
			if (strpbrk(argv[0], ":") != NULL &&
			    access(argv[0], 0) == -1) {
				vfstype = "nfs";
			} else {
				checkdisklabel(argv[0], &vfstype);
			}
		}

		rval = mountfs(vfstype, getdevpath(argv[0], 0), argv[1],
			       init_flags, options, NULL);
		break;
	default:
		usage();
		/* NOTREACHED */
	}

	/*
	 * If the mount was successfully, and done by root, tell mountd the
	 * good news.  Pid checks are probably unnecessary, but don't hurt.
	 */
	if (rval == 0 && getuid() == 0 &&
	    (mountdfp = fopen(_PATH_MOUNTDPID, "r")) != NULL) {
		if (fscanf(mountdfp, "%d", &pid) == 1 &&
		     pid > 0 && kill(pid, SIGHUP) == -1 && errno != ESRCH)
			err(1, "signal mountd");
		fclose(mountdfp);
	}

	exit(rval);
}
Beispiel #10
0
int
main(int argc, char *argv[])
{
	int all, errs, ch, mntsize, error;
	char **typelist = NULL;
	struct statfs *mntbuf, *sfs;
	struct addrinfo hints;

	all = errs = 0;
	while ((ch = getopt(argc, argv, "AaF:fh:t:v")) != -1)
		switch (ch) {
		case 'A':
			all = 2;
			break;
		case 'a':
			all = 1;
			break;
		case 'F':
			setfstab(optarg);
			break;
		case 'f':
			fflag = MNT_FORCE;
			break;
		case 'h':	/* -h implies -A. */
			all = 2;
			nfshost = optarg;
			break;
		case 't':
			if (typelist != NULL)
				err(1, "only one -t option may be specified");
			typelist = makevfslist(optarg);
			break;
		case 'v':
			vflag = 1;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

	/* Start disks transferring immediately. */
	if ((fflag & MNT_FORCE) == 0)
		sync();

	if ((argc == 0 && !all) || (argc != 0 && all))
		usage();

	/* -h implies "-t nfs" if no -t flag. */
	if ((nfshost != NULL) && (typelist == NULL))
		typelist = makevfslist("nfs");

	if (nfshost != NULL) {
		memset(&hints, 0, sizeof hints);
		error = getaddrinfo(nfshost, NULL, &hints, &nfshost_ai);
		if (error)
			errx(1, "%s: %s", nfshost, gai_strerror(error));
	}

	switch (all) {
	case 2:
		if ((mntsize = mntinfo(&mntbuf)) <= 0)
			break;
		/*
		 * We unmount the nfs-mounts in the reverse order
		 * that they were mounted.
		 */
		for (errs = 0, mntsize--; mntsize > 0; mntsize--) {
			sfs = &mntbuf[mntsize];
			if (checkvfsname(sfs->f_fstypename, typelist))
				continue;
			if (strcmp(sfs->f_mntonname, "/dev") == 0)
				continue;
			if (umountfs(sfs) != 0)
				errs = 1;
		}
		free(mntbuf);
		break;
	case 1:
		if (setfsent() == 0)
			err(1, "%s", getfstab());
		errs = umountall(typelist);
		break;
	case 0:
		for (errs = 0; *argv != NULL; ++argv)
			if (checkname(*argv, typelist) != 0)
				errs = 1;
		break;
	}
	exit(errs);
}
Beispiel #11
0
/*
 * Do magic checks on mountpoint/device/fsid, and then call unmount(2).
 */
int
checkname(char *mntname, char **typelist)
{
	char buf[MAXPATHLEN];
	struct statfs sfsbuf;
	struct stat sb;
	struct statfs *sfs;
	char *delimp;
	dev_t dev;
	int len;

	/*
	 * 1. Check if the name exists in the mounttable.
	 */
	sfs = checkmntlist(mntname);
	/*
	 * 2. Remove trailing slashes if there are any. After that
	 * we look up the name in the mounttable again.
	 */
	if (sfs == NULL) {
		len = strlen(mntname);
		while (len > 1 && mntname[len - 1] == '/')
			mntname[--len] = '\0';
		sfs = checkmntlist(mntname);
	}
	/*
	 * 3. Check if the deprecated NFS syntax with an '@' has been used
	 * and translate it to the ':' syntax. Look up the name in the
	 * mount table again.
	 */
	if (sfs == NULL && (delimp = strrchr(mntname, '@')) != NULL) {
		snprintf(buf, sizeof(buf), "%s:%.*s", delimp + 1,
		    (int)(delimp - mntname), mntname);
		len = strlen(buf);
		while (len > 1 && buf[len - 1] == '/')
			buf[--len] = '\0';
		sfs = checkmntlist(buf);
	}
	/*
	 * 4. Resort to a statfs(2) call. This is the last check so that
	 * hung NFS filesystems for example can be unmounted without
	 * potentially blocking forever in statfs() as long as the
	 * filesystem is specified unambiguously. This covers all the
	 * hard cases such as symlinks and mismatches between the
	 * mount list and reality.
	 * We also do this if an ambiguous mount point was specified.
	 */
	if (sfs == NULL || (getmntentry(NULL, mntname, NULL, FIND) != NULL &&
	    getmntentry(NULL, mntname, NULL, CHECKUNIQUE) == NULL)) {
		if (statfs(mntname, &sfsbuf) != 0) {
			warn("%s: statfs", mntname);
		} else if (stat(mntname, &sb) != 0) {
			warn("%s: stat", mntname);
		} else if (S_ISDIR(sb.st_mode)) {
			/* Check that `mntname' is the root directory. */
			dev = sb.st_dev;
			snprintf(buf, sizeof(buf), "%s/..", mntname);
			if (stat(buf, &sb) != 0) {
				warn("%s: stat", buf);
			} else if (sb.st_dev == dev) {
				warnx("%s: not a file system root directory",
				    mntname);
				return (1);
			} else
				sfs = &sfsbuf;
		}
	}
	if (sfs == NULL) {
		warnx("%s: unknown file system", mntname);
		return (1);
	}
	if (checkvfsname(sfs->f_fstypename, typelist))
		return (1);
	return (umountfs(sfs));
}
Beispiel #12
0
int
main(int argc, char **argv)
{
    struct stat stbuf;
    struct statfs statfsbuf, *mntbuf;
    struct statvfs statvfsbuf, *mntvbuf;
    struct maxwidths maxwidths;
    const char *fstype;
    char *mntpath, *mntpt, **vfslist;
    long mntsize;
    int ch, i, rv;

    fstype = "ufs";

    vfslist = NULL;
    while ((ch = getopt(argc, argv, "abgHhiklmnPt:")) != -1)
        switch (ch) {
        case 'a':
            aflag = 1;
            break;
        case 'b':
        /* FALLTHROUGH */
        case 'P':
            if (setenv("BLOCKSIZE", "512", 1) != 0)
                warn("setenv: cannot set BLOCKSIZE=512");
            hflag = 0;
            break;
        case 'g':
            if (setenv("BLOCKSIZE", "1g", 1) != 0)
                warn("setenv: cannot set BLOCKSIZE=1g");
            hflag = 0;
            break;
        case 'H':
            hflag = UNITS_SI;
            break;
        case 'h':
            hflag = UNITS_2;
            break;
        case 'i':
            iflag = 1;
            break;
        case 'k':
            if (setenv("BLOCKSIZE", "1k", 1) != 0)
                warn("setenv: cannot set BLOCKSIZE=1k");
            hflag = 0;
            break;
        case 'l':
            if (vfslist != NULL)
                errx(1, "-l and -t are mutually exclusive.");
            vfslist = makevfslist(makenetvfslist());
            break;
        case 'm':
            if (setenv("BLOCKSIZE", "1m", 1) != 0)
                warn("setenv: cannot set BLOCKSIZE=1m");
            hflag = 0;
            break;
        case 'n':
            nflag = 1;
            break;
        case 't':
            if (vfslist != NULL)
                errx(1, "only one -t option may be specified");
            fstype = optarg;
            vfslist = makevfslist(optarg);
            break;
        case '?':
        default:
            usage();
        }
    argc -= optind;
    argv += optind;

    mntsize = getmntvinfo(&mntbuf, &mntvbuf, MNT_NOWAIT);
    bzero(&maxwidths, sizeof(maxwidths));
    for (i = 0; i < mntsize; i++)
        update_maxwidths(&maxwidths, &mntbuf[i], &mntvbuf[i]);

    rv = 0;
    if (!*argv) {
        mntsize = regetmntinfo(&mntbuf, &mntvbuf, mntsize, vfslist);
        bzero(&maxwidths, sizeof(maxwidths));
        for (i = 0; i < mntsize; i++)
            update_maxwidths(&maxwidths, &mntbuf[i], &mntvbuf[i]);
        for (i = 0; i < mntsize; i++) {
            if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
                prtstat(&mntbuf[i], &mntvbuf[i], &maxwidths);
        }
        exit(rv);
    }

    for (; *argv; argv++) {
        if (stat(*argv, &stbuf) < 0) {
            if ((mntpt = getmntpt(*argv)) == NULL) {
                warn("%s", *argv);
                rv = 1;
                continue;
            }
        } else if (S_ISCHR(stbuf.st_mode)) {
            if ((mntpt = getmntpt(*argv)) == NULL) {
                mdev.fspec = *argv;
                mntpath = strdup("/tmp/df.XXXXXX");
                if (mntpath == NULL) {
                    warn("strdup failed");
                    rv = 1;
                    continue;
                }
                mntpt = mkdtemp(mntpath);
                if (mntpt == NULL) {
                    warn("mkdtemp(\"%s\") failed", mntpath);
                    rv = 1;
                    free(mntpath);
                    continue;
                }
                if (mount(fstype, mntpt, MNT_RDONLY,
                          &mdev) != 0) {
                    rv = ufs_df(*argv, &maxwidths) || rv;
                    rmdir(mntpt);
                    free(mntpath);
                    continue;
                } else if (statfs(mntpt, &statfsbuf) == 0 &&
                           statvfs(mntpt, &statvfsbuf) == 0) {
                    statfsbuf.f_mntonname[0] = '\0';
                    prtstat(&statfsbuf, &statvfsbuf, &maxwidths);
                } else {
                    warn("%s", *argv);
                    rv = 1;
                }
                unmount(mntpt, 0);
                rmdir(mntpt);
                free(mntpath);
                continue;
            }
        } else
            mntpt = *argv;
        /*
         * Statfs does not take a `wait' flag, so we cannot
         * implement nflag here.
         */
        if (statfs(mntpt, &statfsbuf) < 0) {
            warn("%s", mntpt);
            rv = 1;
            continue;
        }
        if (statvfs(mntpt, &statvfsbuf) < 0) {
            warn("%s", mntpt);
            rv = 1;
            continue;
        }
        /*
         * Check to make sure the arguments we've been given are
         * satisfied. Return an error if we have been asked to
         * list a mount point that does not match the other args
         * we've been given (-l, -t, etc.).
         */
        if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
            rv = 1;
            continue;
        }

        if (argc == 1) {
            bzero(&maxwidths, sizeof(maxwidths));
            update_maxwidths(&maxwidths, &statfsbuf, &statvfsbuf);
        }
        prtstat(&statfsbuf, &statvfsbuf, &maxwidths);
    }
    return (rv);
}
Beispiel #13
0
int
main(int argc, char *argv[])
{
	int all, errs, ch, mntsize, error, nfsforce, ret;
	char **typelist = NULL;
	struct statfs *mntbuf, *sfs;
	struct addrinfo hints;

	nfsforce = all = errs = 0;
	while ((ch = getopt(argc, argv, "AaF:fh:Nnt:v")) != -1)
		switch (ch) {
		case 'A':
			all = 2;
			break;
		case 'a':
			all = 1;
			break;
		case 'F':
			setfstab(optarg);
			break;
		case 'f':
			fflag |= MNT_FORCE;
			break;
		case 'h':	/* -h implies -A. */
			all = 2;
			nfshost = optarg;
			break;
		case 'N':
			nfsforce = 1;
			break;
		case 'n':
			fflag |= MNT_NONBUSY;
			break;
		case 't':
			if (typelist != NULL)
				err(1, "only one -t option may be specified");
			typelist = makevfslist(optarg);
			break;
		case 'v':
			vflag = 1;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

	if ((fflag & MNT_FORCE) != 0 && (fflag & MNT_NONBUSY) != 0)
		err(1, "-f and -n are mutually exclusive");

	/* Start disks transferring immediately. */
	if ((fflag & (MNT_FORCE | MNT_NONBUSY)) == 0 && nfsforce == 0)
		sync();

	if ((argc == 0 && !all) || (argc != 0 && all))
		usage();

	if (nfsforce != 0 && (argc == 0 || nfshost != NULL || typelist != NULL))
		usage();

	/* -h implies "-t nfs" if no -t flag. */
	if ((nfshost != NULL) && (typelist == NULL))
		typelist = makevfslist("nfs");

	if (nfshost != NULL) {
		memset(&hints, 0, sizeof hints);
		error = getaddrinfo(nfshost, NULL, &hints, &nfshost_ai);
		if (error)
			errx(1, "%s: %s", nfshost, gai_strerror(error));
	}

	switch (all) {
	case 2:
		if ((mntsize = mntinfo(&mntbuf)) <= 0)
			break;
		/*
		 * We unmount the nfs-mounts in the reverse order
		 * that they were mounted.
		 */
		for (errs = 0, mntsize--; mntsize > 0; mntsize--) {
			sfs = &mntbuf[mntsize];
			if (checkvfsname(sfs->f_fstypename, typelist))
				continue;
			if (strcmp(sfs->f_mntonname, "/dev") == 0)
				continue;
			if (umountfs(sfs) != 0)
				errs = 1;
		}
		free(mntbuf);
		break;
	case 1:
		if (setfsent() == 0)
			err(1, "%s", getfstab());
		errs = umountall(typelist);
		break;
	case 0:
		for (errs = 0; *argv != NULL; ++argv)
			if (nfsforce != 0) {
				/*
				 * First do the nfssvc() syscall to shut down
				 * the mount point and then do the forced
				 * dismount.
				 */
				ret = nfssvc(NFSSVC_FORCEDISM, *argv);
				if (ret >= 0)
					ret = unmount(*argv, MNT_FORCE);
				if (ret < 0) {
					warn("%s", *argv);
					errs = 1;
				}
			} else if (checkname(*argv, typelist) != 0)
				errs = 1;
		break;
	}
	exit(errs);
}
Beispiel #14
0
int
main(int argc, char *argv[])
{
	int all, errs, ch, mntsize;
	char **typelist = NULL, *mntonname, *mntfromname;
	char *type, *mntfromnamerev, *mntonnamerev;
	struct statfs *mntbuf;

	/* Start disks transferring immediately. */
	sync();

	all = errs = 0;
	while ((ch = getopt(argc, argv, "Aafh:t:v")) != -1)
		switch (ch) {
		case 'A':
			all = 2;
			break;
		case 'a':
			all = 1;
			break;
		case 'f':
			fflag = MNT_FORCE;
			break;
		case 'h':	/* -h implies -A. */
			all = 2;
			nfshost = optarg;
			break;
		case 't':
			if (typelist != NULL)
				err(1, "only one -t option may be specified");
			typelist = makevfslist(optarg);
			break;
		case 'v':
			vflag = 1;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	argc -= optind;
	argv += optind;

	if ((argc == 0 && !all) || (argc != 0 && all))
		usage();

	/* -h implies "-t nfs" if no -t flag. */
	if ((nfshost != NULL) && (typelist == NULL))
		typelist = makevfslist("nfs");

	switch (all) {
	case 2:
		if ((mntsize = mntinfo(&mntbuf)) <= 0)
			break;
		/*
		 * We unmount the nfs-mounts in the reverse order
		 * that they were mounted.
		 */
		for (errs = 0, mntsize--; mntsize > 0; mntsize--) {
			if (checkvfsname(mntbuf[mntsize].f_fstypename,
			    typelist))
				continue;
			/*
			 * Check if a mountpoint is laid over by another mount.
			 * A warning will be printed to stderr if this is
			 * the case. The laid over mount remains unmounted.
			 */
			mntonname = mntbuf[mntsize].f_mntonname;
			mntfromname = mntbuf[mntsize].f_mntfromname;
			mntonnamerev = getmntname(getmntname(mntonname,
			    NULL, MNTFROM, &type, NAME), NULL,
			    MNTON, &type, NAME);

			mntfromnamerev = getmntname(mntonnamerev,
			    NULL, MNTFROM, &type, NAME);

			if (strcmp(mntonnamerev, mntonname) == 0 &&
			    strcmp(mntfromnamerev, mntfromname ) != 0)
				warnx("cannot umount %s, %s\n        "
				    "is mounted there, umount it first",
				    mntonname, mntfromnamerev);

			if (umountfs(mntbuf[mntsize].f_mntonname,
			    typelist) != 0)
				errs = 1;
		}
		free(mntbuf);
		break;
	case 1:
		if (setfsent() == 0)
			err(1, "%s", _PATH_FSTAB);
		errs = umountall(typelist);
		break;
	case 0:
		for (errs = 0; *argv != NULL; ++argv)
			if (umountfs(*argv, typelist) != 0)
				errs = 1;
		break;
	}
	(void)getmntname(NULL, NULL, NOTHING, NULL, FREE);
	exit(errs);
}
Beispiel #15
0
int
umountfs(char *name, char **typelist)
{
	enum clnt_stat clnt_stat;
	struct hostent *hp;
	struct mtablist *mtab;
	struct sockaddr_in saddr;
	struct timeval pertry, try;
	CLIENT *clp;
	size_t len;
	int so, speclen, do_rpc;
	char *mntonname, *mntfromname;
	char *mntfromnamerev;
	char *nfsdirname, *orignfsdirname;
	char *resolved, realname[MAXPATHLEN];
	char *type, *delimp, *hostp, *origname;

	len = 0;
	mtab = NULL;
	mntfromname = mntonname = delimp = hostp = orignfsdirname = NULL;

	/*
	 * 1. Check if the name exists in the mounttable.
	 */
	(void)checkmntlist(name, &mntfromname, &mntonname, &type);
	/*
	 * 2. Remove trailing slashes if there are any. After that
	 * we look up the name in the mounttable again.
	 */
	if (mntfromname == NULL && mntonname == NULL) {
		speclen = strlen(name);
		for (speclen = strlen(name); 
		    speclen > 1 && name[speclen - 1] == '/';
		    speclen--)
			name[speclen - 1] = '\0';
		(void)checkmntlist(name, &mntfromname, &mntonname, &type);
		resolved = name;
		/* Save off original name in origname */
		if ((origname = strdup(name)) == NULL)
			err(1, "strdup");
		/*
		 * 3. Check if the deprecated nfs-syntax with an '@'
		 * has been used and translate it to the ':' syntax.
		 * Look up the name in the mounttable again.
		 */
		if (mntfromname == NULL && mntonname == NULL) {
			if ((delimp = strrchr(name, '@')) != NULL) {
				hostp = delimp + 1;
				if (*hostp != '\0') {
					/*
					 * Make both '@' and ':'
					 * notations equal 
					 */
					char *host = strdup(hostp);
					len = strlen(hostp);
					if (host == NULL)
						err(1, "strdup");
					memmove(name + len + 1, name,
					    (size_t)(delimp - name));
					name[len] = ':';
					memmove(name, host, len);
					free(host);
				}
				for (speclen = strlen(name); 
				    speclen > 1 && name[speclen - 1] == '/';
				    speclen--)
					name[speclen - 1] = '\0';
				name[len + speclen + 1] = '\0';
				(void)checkmntlist(name, &mntfromname,
				    &mntonname, &type);
				resolved = name;
			}
			/*
			 * 4. Check if a relative mountpoint has been
			 * specified. This should happen as last check,
			 * the order is important. To prevent possible
			 * nfs-hangs, we just call realpath(3) on the
			 * basedir of mountpoint and add the dirname again.
			 * Check the name in mounttable one last time.
			 */
			if (mntfromname == NULL && mntonname == NULL) {
				(void)strcpy(name, origname);
				if ((getrealname(name, realname)) != NULL) {
					(void)checkmntlist(realname,
					    &mntfromname, &mntonname, &type);
					resolved = realname;
				}
				/*
				 * All tests failed, return to main()
				 */
				if (mntfromname == NULL && mntonname == NULL) {
					(void)strcpy(name, origname);
					warnx("%s: not currently mounted",
					    origname);
					free(origname);
					return (1);
				}
			}
		}
		free(origname);
	} else
		resolved = name;

	if (checkvfsname(type, typelist))
		return (1);

	hp = NULL;
	nfsdirname = NULL;
	if (!strcmp(type, "nfs")) {
		if ((nfsdirname = strdup(mntfromname)) == NULL)
			err(1, "strdup");
		orignfsdirname = nfsdirname;
		if ((delimp = strchr(nfsdirname, ':')) != NULL) {
			*delimp = '\0';
			hostp = nfsdirname;
			if ((hp = gethostbyname(hostp)) == NULL) {
				warnx("can't get net id for host");
			}
			nfsdirname = delimp + 1;
		}
	}
	/*
	 * Check if the reverse entrys of the mounttable are really the
	 * same as the normal ones.
	 */
	if ((mntfromnamerev = strdup(getmntname(getmntname(mntfromname,
	    NULL, MNTON, &type, NAME), NULL, MNTFROM, &type, NAME))) == NULL)
		err(1, "strdup");
	/*
	 * Mark the uppermost mount as unmounted.
	 */
	(void)getmntname(mntfromname, mntonname, NOTHING, &type, MARK);
	/*
	 * If several equal mounts are in the mounttable, check the order
	 * and warn the user if necessary.
	 */
	if (strcmp(mntfromnamerev, mntfromname ) != 0 &&
	    strcmp(resolved, mntonname) != 0) {
		warnx("cannot umount %s, %s\n        "
		    "is mounted there, umount it first",
		    mntonname, mntfromnamerev);

		/* call getmntname again to set mntcheck[i] to 0 */
		(void)getmntname(mntfromname, mntonname,
		    NOTHING, &type, UNMARK);
		return (1);
	}
	free(mntfromnamerev);
	/*
	 * Check if we have to start the rpc-call later.
	 * If there are still identical nfs-names mounted,
	 * we skip the rpc-call. Obviously this has to
	 * happen before unmount(2), but it should happen
	 * after the previous namecheck.
	 */
	if (strcmp(type, "nfs") == 0 && getmntname(mntfromname, NULL, NOTHING,
	    &type, COUNT) != NULL)
		do_rpc = 1;
	else
		do_rpc = 0;
	if (!namematch(hp))
		return (1);
	if (unmount(mntonname, fflag) != 0 ) {
		warn("unmount of %s failed", mntonname);
		return (1);
	}
	if (vflag)
		(void)printf("%s: unmount from %s\n", mntfromname, mntonname);
	/*
	 * Report to mountd-server which nfsname
	 * has been unmounted.
	 */
	if (hp != NULL && !(fflag & MNT_FORCE) && do_rpc) {
		memset(&saddr, 0, sizeof(saddr));
		saddr.sin_family = AF_INET;
		saddr.sin_port = 0;
		memmove(&saddr.sin_addr, hp->h_addr, 
		    MIN(hp->h_length, sizeof(saddr.sin_addr)));
		pertry.tv_sec = 3;
		pertry.tv_usec = 0;
		so = RPC_ANYSOCK;
		if ((clp = clntudp_create(&saddr,
		    RPCPROG_MNT, RPCMNT_VER1, pertry, &so)) == NULL) {
			clnt_pcreateerror("Cannot MNT PRC");
			return (1);
		}
		clp->cl_auth = authunix_create_default();
		try.tv_sec = 20;
		try.tv_usec = 0;
		clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir,
		    nfsdirname, xdr_void, (caddr_t)0, try);
		if (clnt_stat != RPC_SUCCESS) {
			clnt_perror(clp, "Bad MNT RPC");
			return (1);
		}
		/*
		 * Remove the unmounted entry from /var/db/mounttab.
		 */
		if (read_mtab(mtab)) {
			mtab = mtabhead;
			clean_mtab(hostp, nfsdirname);
			if(!write_mtab())
				warnx("cannot remove entry %s:%s",
				    hostp, nfsdirname);
			free_mtab();
		}
		free(orignfsdirname);
		auth_destroy(clp->cl_auth);
		clnt_destroy(clp);
	}