Exemple #1
0
/* todo: there are some cases which options are not changed */
static void update_mtab(FILE *fp, char *mntpnt, int do_remount, int do_verbose)
{
	int err;
	long pos;
	FILE *ofp;
	struct mntent ent, *p;

	/* prohibit updating mount options for this mntpnt */
	au_plink_maint(mntpnt);
	err = au_proc_getmntent(mntpnt, &ent);
	if (err)
		AuFin("no such mount point");

	ofp = setmntent(MTab, "r");
	if (!ofp)
		AuFin(MTab);

	if (do_remount) {
		/* find the last one */
		pos = -1;
		while ((p = getmntent(ofp))) {
			if (!strcmp(p->mnt_dir, mntpnt))
				pos = ftell(ofp);
		}
		rewind(ofp);

		if (pos > 0) {
			while ((p = getmntent(ofp))) {
				if (ftell(ofp) == pos) {
					/* replace the line */
					p = &ent;
					pos = -1;
				}
				err = addmntent(fp, p);
				if (err)
					AuFin("addmntent");
			}
			if (pos > 0)
				AuFin("internal error");
		} else
			append_mtab(fp, ofp, &ent);
	} else
		append_mtab(fp, ofp, &ent);

	endmntent(ofp); /* ignore */
	au_plink_maint(NULL);
	if (do_verbose)
		au_print_ent(&ent);
}
Exemple #2
0
int main(int argc, char *argv[])
{
	int err, c, status;
	pid_t pid;
	unsigned char flags[LastOpt];
	struct mntent ent;
	char *dev, *mntpnt, *opts, *cwd;
	DIR *cur;

	if (argc < 3) {
		errno = EINVAL;
		AuFin(NULL);
	}

	memset(flags, 0, sizeof(flags));
	flags[Update] = 1;
	opts = NULL;

	/* mount(8) always passes the arguments in this order */
	dev = argv[1];
	mntpnt = argv[2];
	while ((c = getopt(argc - 2, argv + 2, "nvo:")) != -1) {
		switch (c) {
		case 'n':
			flags[Update] = 0;
			break;
		case 'v':
			flags[Verbose] = 1;
			break;
		case 'o':
			opts = optarg;
			break;
		case '?':
		case ':':
			errno = EINVAL;
			AuFin("internal error");
		}
	}

	cur = opendir(".");
	if (!cur)
		AuFin(".");
	err = chdir(mntpnt);
	if (err)
		AuFin(mntpnt);
	cwd = getcwd(NULL, 0); /* glibc */
	if (!cwd)
		AuFin("getcwd");
	err = fchdir(dirfd(cur));
	if (err)
		AuFin("fchdir");
	closedir(cur); /* ignore */

	if (opts)
		test_opts(opts, flags);

	if (!flags[Bind] && flags[Update]) {
		err = access(MTab, R_OK | W_OK);
		if (err)
			AuFin(MTab);
	}

	if (flags[Remount]) {
		errno = EINVAL;
		if (flags[Bind])
			AuFin("both of remount and bind are specified");
		flags[AuFlush] = test_flush(opts);
		if (flags[AuFlush]) {
			err = au_plink(cwd, AuPlink_FLUSH, 1, 1);
			if (err)
				AuFin(NULL);
		}
	}

	pid = fork();
	if (!pid) {
		/* actual mount operation */
		do_mount(dev, mntpnt, argc, argv, flags);
		return 0;
	} else if (pid < 0)
		AuFin("fork");

	err = waitpid(pid, &status, 0);
	if (err < 0)
		AuFin("child process");

	err = !WIFEXITED(status);
	if (!err)
		err = WEXITSTATUS(status);

	if (!err && !flags[Bind]) {
		if (flags[Update])
			err = au_update_mtab(cwd, flags[Remount],
					     flags[Verbose]);
		else if (flags[Verbose]) {
			/* withoug blocking plink */
			err = au_proc_getmntent(cwd, &ent);
			if (!err)
				au_print_ent(&ent);
			else
				AuFin("internal error");
		}
	}

	return err;
}