Exemplo n.º 1
0
void update_mtab(const char *dir, struct mntent *instead)
{
	struct mntent *mnt;
	struct mntent *next;
	struct mntent remnt;
	int added = 0;
	mntFILE *mfp, *mftmp;

	if (mtab_does_not_exist() || mtab_is_a_symlink())
		return;

	lock_mtab();

	mfp = my_setmntent(MOUNTED, "r");
	if (mfp == NULL || mfp->mntent_fp == NULL) {
		error("cannot open %s (%s) - mtab not updated", MOUNTED, strerror(errno));
		goto leave;
	}

	mftmp = my_setmntent(MOUNTED_TEMP, "w");
	if (mftmp == NULL || mftmp->mntent_fp == NULL) {
		error("can't open %s (%s) - mtab not updated", MOUNTED_TEMP, strerror(errno));
		goto leave;
	}

	while ((mnt = my_getmntent(mfp))) {
		if (streq(mnt->mnt_dir, dir)) {
			added++;
			if (instead) {	/* a remount */
				remnt = *instead;
				next = &remnt;
				remnt.mnt_fsname = mnt->mnt_fsname;
				remnt.mnt_type = mnt->mnt_type;
				if (instead->mnt_fsname && !streq(mnt->mnt_fsname, instead->mnt_fsname))
					printf("mount: warning: cannot change " "mounted device with a remount\n");
				else if (instead->mnt_type && !streq(instead->mnt_type, "unknown")
					 && !streq(mnt->mnt_type, instead->mnt_type))
					printf("mount: warning: cannot change " "filesystem type with a remount\n");
			} else
				next = NULL;
		} else
			next = mnt;
		if (next && my_addmntent(mftmp, next) == 1)
			die(EX_FILEIO, "error writing %s: %s", MOUNTED_TEMP, strerror(errno));
	}
	if (instead && !added && my_addmntent(mftmp, instead) == 1)
		die(EX_FILEIO, "error writing %s: %s", MOUNTED_TEMP, strerror(errno));

	my_endmntent(mfp);
	if (fchmod(fileno(mftmp->mntent_fp), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)
		fprintf(stderr, "error changing mode of %s: %s\n", MOUNTED_TEMP, strerror(errno));
	my_endmntent(mftmp);

	if (rename(MOUNTED_TEMP, MOUNTED) < 0)
		fprintf(stderr, "can't rename %s to %s: %s\n", MOUNTED_TEMP, MOUNTED, strerror(errno));

 leave:
	unlock_mtab();
}
Exemplo n.º 2
0
/*
 * based on similar function in util-linux-2.12r/mount/mount.c
 */
static void
update_mtab_entry(const char *spec, const char *node, const char *type,
		  const char *opts, int freq, int pass, int addnew)
{
	struct my_mntent mnt;

	mnt.mnt_fsname = canonicalize (spec);
	mnt.mnt_dir = canonicalize (node);
	mnt.mnt_type = xstrdup(type);
	mnt.mnt_opts = xstrdup(opts);
	mnt.mnt_freq = freq;
	mnt.mnt_passno = pass;

	/* We get chatty now rather than after the update to mtab since the
	   mount succeeded, even if the write to /etc/mtab should fail.  */
	if (verbose)
		print_one (&mnt);

	if (!addnew)
		update_mtab (mnt.mnt_dir, &mnt);
	else {
		mntFILE *mfp;

		lock_mtab();
		mfp = my_setmntent(MOUNTED, "a+");
		if (mfp == NULL || mfp->mntent_fp == NULL) {
			int errsv = errno;
			error(_("%s: can't open %s, %s"),
			      progname, MOUNTED, strerror(errsv));
		} else {
			if ((my_addmntent (mfp, &mnt)) == 1) {
				int errsv = errno;
				error(_("%s: error writing %s, %s"),
				      progname, MOUNTED, strerror(errsv));
			}
		}
		my_endmntent(mfp);
		unlock_mtab();
	}
	my_free(mnt.mnt_fsname);
	my_free(mnt.mnt_dir);
	my_free(mnt.mnt_type);
	my_free(mnt.mnt_opts);
}
Exemplo n.º 3
0
/*
 * Code based on similar function in util-linux-2.12p/mount/mount.c
 *
 */
static void update_mtab_entry(char *spec, char *node, char *type, char *opts,
			      int flags, int freq, int pass)
{
	struct my_mntent mnt;

	mnt.mnt_fsname = canonicalize (spec);
	mnt.mnt_dir = canonicalize (node);
	mnt.mnt_type = type;
	mnt.mnt_opts = opts;
	mnt.mnt_freq = freq;
	mnt.mnt_passno = pass;
      
	/* We get chatty now rather than after the update to mtab since the
	   mount succeeded, even if the write to /etc/mtab should fail.  */
	if (verbose)
		print_one (&mnt);

	if (!nomtab && mtab_is_writable()) {
		if (flags & MS_REMOUNT)
			update_mtab (mnt.mnt_dir, &mnt);
		else {
			mntFILE *mfp;

			lock_mtab();

			mfp = my_setmntent(MOUNTED, "a+");
			if (mfp == NULL || mfp->mntent_fp == NULL) {
				com_err(progname, OCFS2_ET_IO, "%s, %s",
					MOUNTED, strerror(errno));
			} else {
				if ((my_addmntent (mfp, &mnt)) == 1) {
					com_err(progname, OCFS2_ET_IO, "%s, %s",
						MOUNTED, strerror(errno));
				}
			}
			my_endmntent(mfp);
			unlock_mtab();
		}
	}
	my_free(mnt.mnt_fsname);
	my_free(mnt.mnt_dir);
}
Exemplo n.º 4
0
void
update_mtab (const char *dir, struct my_mntent *instead) {
	mntFILE *mfp, *mftmp;
	const char *fnam = MOUNTED;
	struct mntentchn mtabhead;	/* dummy */
	struct mntentchn *mc, *mc0, *absent = NULL;

	if (mtab_does_not_exist() || mtab_is_a_symlink())
		return;

	lock_mtab();

	/* having locked mtab, read it again */
	mc0 = mc = &mtabhead;
	mc->nxt = mc->prev = NULL;

	mfp = my_setmntent(fnam, "r");
	if (mfp == NULL || mfp->mntent_fp == NULL) {
		int errsv = errno;
		error (_("cannot open %s (%s) - mtab not updated"),
		       fnam, strerror (errsv));
		goto leave;
	}

	read_mntentchn(mfp, fnam, mc);

	/* find last occurrence of dir */
	for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
		if (streq(mc->m.mnt_dir, dir))
			break;
	if (mc && mc != mc0) {
		if (instead == NULL) {
			/* An umount - remove entry */
			if (mc && mc != mc0) {
				mc->prev->nxt = mc->nxt;
				mc->nxt->prev = mc->prev;
				free(mc);
			}
		} else {
			/* A remount */
			mc->m.mnt_opts = instead->mnt_opts;
		}
	} else if (instead) {
		/* not found, add a new entry */
		absent = xmalloc(sizeof(*absent));
		absent->m = *instead;
		absent->nxt = mc0;
		absent->prev = mc0->prev;
		mc0->prev = absent;
		if (mc0->nxt == NULL)
			mc0->nxt = absent;
	}

	/* write chain to mtemp */
	mftmp = my_setmntent (MOUNTED_TEMP, "w");
	if (mftmp == NULL || mftmp->mntent_fp == NULL) {
		int errsv = errno;
		error (_("cannot open %s (%s) - mtab not updated"),
		       MOUNTED_TEMP, strerror (errsv));
		goto leave;
	}

	for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
		if (my_addmntent(mftmp, &(mc->m)) == 1) {
			int errsv = errno;
			die (EX_FILEIO, _("error writing %s: %s"),
			     MOUNTED_TEMP, strerror (errsv));
		}
	}

	discard_mntentchn(mc0);

	if (fchmod (fileno (mftmp->mntent_fp),
		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
		int errsv = errno;
		fprintf(stderr, _("error changing mode of %s: %s\n"),
			MOUNTED_TEMP, strerror (errsv));
	}
	my_endmntent (mftmp);

	{ /*
	   * If mount is setuid and some non-root user mounts sth,
	   * then mtab.tmp might get the group of this user. Copy uid/gid
	   * from the present mtab before renaming.
	   */
	    struct stat sbuf;
	    if (stat (MOUNTED, &sbuf) == 0)
		if (chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid) < 0) {
			int errsv = errno;
			fprintf(stderr, _("error changing ownership of %s: %s\n"),
				MOUNTED_TEMP, strerror (errsv));
		}
	}

	/* rename mtemp to mtab */
	if (rename (MOUNTED_TEMP, MOUNTED) < 0) {
		int errsv = errno;
		fprintf(stderr, _("can't rename %s to %s: %s\n"),
			MOUNTED_TEMP, MOUNTED, strerror(errsv));
	}

 leave:
	unlock_mtab();
}