コード例 #1
0
ファイル: umount.c プロジェクト: repos-holder/openbsd-patches
int
main(int argc, char *argv[])
{
	int all, ch, errs;

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

	all = 0;
	while ((ch = getopt(argc, argv, "afh:t:v")) != -1)
		switch (ch) {
		case 'a':
			all = 1;
			break;
		case 'f':
			fflag = MNT_FORCE;
			break;
		case 'h':	/* -h implies -a. */
			all = 1;
			nfshost = optarg;
			break;
		case 't':
			if (typelist != NULL)
				errx(1, "only one -t option may be specified.");
			maketypelist(optarg);
			break;
		case 'v':
			verbose = 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))
		maketypelist(MOUNT_NFS);

	if (all)
		errs = umountall();
	else
		for (errs = 0; *argv != NULL; ++argv)
			if (umountfs(*argv) != 0)
				errs = 1;
	return (errs);
}
コード例 #2
0
ファイル: umount.c プロジェクト: joshuabergeron/ClosedBSD
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);
}
コード例 #3
0
ファイル: umount.c プロジェクト: repos-holder/openbsd-patches
int
umountall(void)
{
	struct statfs *fs;
	int n;
	int rval;

	n = getmntinfo(&fs, MNT_NOWAIT);
	if (n == 0)
		err(1, NULL);

	rval = 0;
	while (--n >= 0) {
		/* Ignore the root. */
		if (strncmp(fs[n].f_mntonname, "/", MNAMELEN) == 0)
			continue;
		if (!selected(fs[n].f_fstypename))
			continue;
		if (umountfs(fs[n].f_mntonname))
			rval = 1;
	}
	return (rval);
}
コード例 #4
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);
}
コード例 #5
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));
}
コード例 #6
0
ファイル: umount.c プロジェクト: 2trill2spill/freebsd
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);
}
コード例 #7
0
ファイル: umount.c プロジェクト: joshuabergeron/ClosedBSD
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);
}