Example #1
0
int
main(int argc, char *argv[])
{
	struct fstab *fs;
	int i, rval = 0;
	char *vfstype = NULL;
	char *p, globopt[3];
	struct rlimit rl;

	/* Increase our data size to the max */
	if (getrlimit(RLIMIT_DATA, &rl) == 0) {
		if (geteuid() == 0)
			rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
		else
			rl.rlim_cur = rl.rlim_max;
		if (setrlimit(RLIMIT_DATA, &rl) < 0)
			warn("Can't get resource limit to max data size");
	} else
		warn("Can't get resource limit for data size");

	globopt[0] = '-';
	globopt[2] = '\0';

	TAILQ_INIT(&selhead);
	TAILQ_INIT(&opthead);

	while ((i = getopt(argc, argv, "dvpfnyb:l:T:t:")) != -1)
		switch (i) {
		case 'd':
			flags |= CHECK_DEBUG;
			break;

		case 'v':
			flags |= CHECK_VERBOSE;
			break;

		case 'p':
			flags |= CHECK_PREEN;
			/*FALLTHROUGH*/
		case 'n':
		case 'f':
		case 'y':
			globopt[1] = i;
			options = catopt(options, globopt, 1);
			break;

		case 'b':
			if (asprintf(&p, "-b %s", optarg) == -1)
				err(1, "malloc failed");
			options = catopt(options, p, 1);
			free(p);
			break;

		case 'l':
			maxrun = atoi(optarg);
			break;

		case 'T':
			if (*optarg)
				addoption(optarg);
			break;

		case 't':
			if (!TAILQ_EMPTY(&selhead))
				errx(1, "only one -t option may be specified.");

			maketypelist(optarg);
			vfstype = optarg;
			break;

		case '?':
		default:
			usage();
			/* NOTREACHED */
		}

	argc -= optind;
	argv += optind;

	if (argc == 0)
		return checkfstab(flags, maxrun, isok, checkfs);

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


	for (; argc--; argv++) {
		char *spec, *type;

		if ((strncmp(*argv, "/dev/", 5) == 0 || isduid(*argv, 0)) &&
		    (type = readlabelfs(*argv, 0))) {
			spec = *argv;
		} else if ((fs = getfsfile(*argv)) == NULL &&
		    (fs = getfsspec(*argv)) == NULL) {
			if (vfstype == NULL)
				errx(1,
				    "%s: unknown special file or file system.",
				    *argv);
			spec = *argv;
			type = vfstype;
		} else {
			spec = fs->fs_spec;
			type = fs->fs_vfstype;
			if (BADTYPE(fs->fs_type))
				errx(1, "%s has unknown file system type.",
				    *argv);
		}

		rval |= checkfs(type, blockcheck(spec), *argv, NULL, NULL);
	}

	return rval;
}
Example #2
0
/*
 * This routine is a generic rewrite of the original code found in
 * disklabel(8).
 */
int
opendev(const char *path, int oflags, int dflags, char **realpath)
{
	static char namebuf[PATH_MAX];
	struct dk_diskmap dm;
	char *slash, *prefix;
	int fd;

	/* Initial state */
	fd = -1;
	errno = ENOENT;

	if (dflags & OPENDEV_BLCK)
		prefix = "";			/* block device */
	else
		prefix = "r";			/* character device */

	if ((slash = strchr(path, '/'))) {
		strlcpy(namebuf, path, sizeof(namebuf));
		fd = open(namebuf, oflags);
	} else if (isduid(path, dflags)) {
		strlcpy(namebuf, path, sizeof(namebuf));
		if ((fd = open("/dev/diskmap", oflags)) != -1) {
			bzero(&dm, sizeof(struct dk_diskmap));
			dm.device = namebuf;
			dm.fd = fd;
			if (dflags & OPENDEV_PART)
				dm.flags |= DM_OPENPART;
			if (dflags & OPENDEV_BLCK)
				dm.flags |= DM_OPENBLCK;

			if (ioctl(fd, DIOCMAP, &dm) == -1) {
				close(fd);
				fd = -1;
				errno = ENOENT;
			}
		}
	}
	if (!slash && fd == -1 && errno == ENOENT) {
		if (dflags & OPENDEV_PART) {
			/*
			 * First try raw partition (for removable drives)
			 */
			if (snprintf(namebuf, sizeof(namebuf), "%s%s%s%c",
			    _PATH_DEV, prefix, path, 'a' + getrawpartition())
			    < sizeof(namebuf)) {
				fd = open(namebuf, oflags);
			} else
				errno = ENAMETOOLONG;
		}
		if (fd == -1 && errno == ENOENT) {
			if (snprintf(namebuf, sizeof(namebuf), "%s%s%s",
			    _PATH_DEV, prefix, path) < sizeof(namebuf)) {
				fd = open(namebuf, oflags);
			} else
				errno = ENAMETOOLONG;
		}
	}
	if (realpath)
		*realpath = namebuf;

	return (fd);
}
Example #3
0
/*
 * Try to get a disklabel for the specified device, and return mount_xxx
 * style filesystem type name for the specified partition.
 */
char *
readlabelfs(char *device, int verbose)
{
	char rpath[MAXPATHLEN];
	struct dk_diskmap dm;
	struct disklabel dk;
	char part, *type;
	struct stat sbuf;
	int fd = -1;

	/* Perform disk mapping if device is given as a DUID. */
	if (isduid(device, 0)) {
		if ((fd = open("/dev/diskmap", O_RDONLY)) != -1) {
			bzero(&dm, sizeof(struct dk_diskmap));
			strlcpy(rpath, device, sizeof(rpath));
			part = rpath[strlen(rpath) - 1];
			dm.device = rpath;
			dm.fd = fd;
			dm.flags = DM_OPENPART;
			if (ioctl(fd, DIOCMAP, &dm) == -1)
				close(fd);
			else
				goto disklabel;
		}
	}

	/* Assuming device is of the form /dev/??p, build a raw partition. */
	if (stat(device, &sbuf) < 0) {
		if (verbose)
			warn("%s", device);
		return (NULL);
	}
	switch (sbuf.st_mode & S_IFMT) {
	case S_IFCHR:
		/* Ok... already a raw device.  Hmm. */
		strlcpy(rpath, device, sizeof(rpath));

		/* Change partition name. */
		part = rpath[strlen(rpath) - 1];
		rpath[strlen(rpath) - 1] = 'a' + getrawpartition();
		break;
	case S_IFBLK:
		if (strlen(device) > sizeof(_PATH_DEV) - 1) {
			snprintf(rpath, sizeof(rpath), "%sr%s", _PATH_DEV,
			    &device[sizeof(_PATH_DEV) - 1]);
			/* Change partition name. */
			part = rpath[strlen(rpath) - 1];
			rpath[strlen(rpath) - 1] = 'a' + getrawpartition();
			break;
		}
		/* FALLTHROUGH */
	default:
		if (verbose)
			warnx("%s: not a device node", device);
		return (NULL);
	}

	/* If rpath doesn't exist, change that partition back. */
	fd = open(rpath, O_RDONLY);
	if (fd < 0) {
		if (errno == ENOENT) {
			rpath[strlen(rpath) - 1] = part;

			fd = open(rpath, O_RDONLY);
			if (fd < 0) {
				if (verbose)
					warn("%s", rpath);
				return (NULL);
			}
		} else {
			if (verbose)
				warn("%s", rpath);
			return (NULL);
		}
	}

disklabel:

	if (ioctl(fd, DIOCGDINFO, &dk) < 0) {
		if (verbose)
			warn("%s: couldn't read disklabel", rpath);
		close(fd);
		return (NULL);
	}
	close(fd);

	if (dk.d_partitions[part - 'a'].p_fstype >= FSMAXTYPES) {
		if (verbose)
			warnx("%s: bad filesystem type in label", rpath);
		return (NULL);
	}

	type = fstypesnames[dk.d_partitions[part - 'a'].p_fstype];
	return ((type[0] == '\0') ? NULL : type);
}
Example #4
0
void
do_fstab(void)
{
	struct	fstab *fp;
	char	*s;
	long	priority;
	struct	stat st;
	mode_t	rejecttype;
	int	gotone = 0;

	/*
	 * Select which mount point types to reject, depending on the
	 * value of the -t parameter.
	 */
	if (tflag != NULL) {
		if (strcmp(tflag, "blk") == 0)
			rejecttype = S_IFREG;
		else if (strcmp(tflag, "noblk") == 0)
			rejecttype = S_IFBLK;
	} else
		rejecttype = 0;

#define PRIORITYEQ	"priority="
#define NFSMNTPT	"nfsmntpt="
#define PATH_MOUNT	"/sbin/mount_nfs"
	while ((fp = getfsent()) != NULL) {
		const char *spec;

		if (strcmp(fp->fs_type, "sw") != 0)
			continue;

		spec = fp->fs_spec;

		if ((s = strstr(fp->fs_mntops, PRIORITYEQ)) != NULL) {
			s += sizeof(PRIORITYEQ) - 1;
			priority = atol(s);
		} else
			priority = pri;

		if ((s = strstr(fp->fs_mntops, NFSMNTPT)) != NULL) {
			char *t, cmd[sizeof(PATH_MOUNT)+PATH_MAX+1+PATH_MAX+1];
			int l;

			/*
			 * Skip this song and dance if we're only
			 * doing block devices.
			 */
			if (rejecttype == S_IFREG)
				continue;

			t = strpbrk(s, ",");
			if (t != 0)
				*t = '\0';
			spec = strdup(s + strlen(NFSMNTPT));
			if (spec == NULL)
				err(1, "strdup");

			if (t != 0)
				*t = ',';

			if (strlen(spec) == 0) {
				warnx("empty mountpoint");
				free((char *)spec);
				continue;
			}
			l = snprintf(cmd, sizeof(cmd), "%s %s %s",
			    PATH_MOUNT, fp->fs_spec, spec);
			if (l == -1 || l >= sizeof(cmd))
				errx(1, "path too long");
			if (system(cmd) != 0) {
				warnx("%s: mount failed", fp->fs_spec);
				free((char *)spec);
				continue;
			}
		} else if (isduid(spec, 0)) {
			if (rejecttype == S_IFBLK)
				continue;
		} else {
			/*
			 * Determine blk-ness.  Don't even consider a
			 * mountpoint outside /dev as a block device.
			 */
			if (rejecttype == S_IFREG) {
				if (strncmp("/dev/", spec, 5) != 0)
					continue;
			}
			if (stat(spec, &st) < 0) {
				warn("%s", spec);
				continue;
			}
			if ((st.st_mode & S_IFMT) == rejecttype)
				continue;

			/*
			 * Do not allow fancy objects to be swap areas.
			 */
			if (!S_ISREG(st.st_mode) &&
			    !S_ISBLK(st.st_mode))
				continue;
		}

		if (swapctl(SWAP_ON, spec, (int)priority) < 0) {
			if (errno != EBUSY)
				warn("%s", spec);
		} else {
			gotone = 1;
			printf("%s: adding %s as swap device at priority %d\n",
			    __progname, fp->fs_spec, (int)priority);
		}

		if (spec != fp->fs_spec)
			free((char *)spec);
	}
	if (gotone == 0)
		exit(1);
}