/* * Read /etc/mtab. If that fails, try /proc/mounts. * This produces a linked list. The list head mounttable is a dummy. * Return 0 on success. */ static void read_mounttable() { mntFILE *mfp; const char *fnam; struct mntentchn *mc = &mounttable; got_mtab = 1; mc->nxt = mc->prev = NULL; fnam = MOUNTED; mfp = nfs_setmntent (fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { int errsv = errno; fnam = PROC_MOUNTS; mfp = nfs_setmntent (fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { nfs_error(_("warning: can't open %s: %s"), MOUNTED, strerror (errsv)); return; } if (verbose) printf(_("%s: could not open %s; using %s instead\n"), progname, MOUNTED, PROC_MOUNTS); } read_mntentchn(mfp, fnam, mc); }
/* * Read /etc/mtab. If that fails, try /proc/mounts. * This produces a linked list. The list head mounttable is a dummy. * Return 0 on success. */ static void read_mounttable() { mntFILE *mfp; const char *fnam; struct mntentchn *mc = &mounttable; got_mtab = 1; mc->nxt = mc->prev = NULL; fnam = MOUNTED; mfp = my_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { int errsv = errno; fnam = PROC_MOUNTS; if (mfp != NULL) free(mfp); mfp = my_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { error("warning: can't open %s: %s", MOUNTED, strerror(errsv)); return; } if (mount_verbose) printf("mount: could not open %s - using %s instead\n", MOUNTED, PROC_MOUNTS); } read_mntentchn(mfp, fnam, mc); }
static void read_fstab() { mntFILE *mfp = NULL; const char *fnam; struct mntentchn *mc = &fstab; got_fstab = 1; mc->nxt = mc->prev = NULL; fnam = _PATH_FSTAB; mfp = my_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { error("warning: can't open %s: %s", _PATH_FSTAB, strerror(errno)); return; } read_mntentchn(mfp, fnam, mc); }
/* * Read /proc/mounts. * This produces a linked list. The list head procmounts is a dummy. * Return 0 on success. */ static void read_procmounts() { mntFILE *mfp; const char *fnam; struct mntentchn *mc = &procmounts; got_procmounts = 1; mc->nxt = mc->prev = NULL; fnam = PROC_MOUNTS; mfp = nfs_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { nfs_error(_("warning: can't open %s: %s"), PROC_MOUNTS, strerror (errno)); return; } read_mntentchn(mfp, fnam, mc); }
void update_mtab (const char *dir, struct 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_writable()) return; lock_mtab(); /* having locked mtab, read it again */ mc0 = mc = &mtabhead; mc->nxt = mc->prev = NULL; mfp = nfs_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { int errsv = errno; nfs_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 = nfs_setmntent (MOUNTED_TEMP, "w"); if (mftmp == NULL || mftmp->mntent_fp == NULL) { int errsv = errno; nfs_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 (nfs_addmntent(mftmp, &(mc->m)) == 1) { int errsv = errno; die (EX_FILEIO, _("error writing %s: %s"), MOUNTED_TEMP, strerror (errsv)); } } #if 0 /* the chain might have strings copied from 'instead', * so we cannot safely free it. * And there is no need anyway because we are going to exit * shortly. So just don't call discard_mntentchn.... */ discard_mntentchn(mc0); #endif if (fchmod (fileno (mftmp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { int errsv = errno; nfs_error(_("%s: error changing mode of %s: %s"), progname, MOUNTED_TEMP, strerror (errsv)); } nfs_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) { nfs_error(_("%s: error changing owner of %s: %s"), progname, MOUNTED_TEMP, strerror (errno)); } } } /* rename mtemp to mtab */ if (rename (MOUNTED_TEMP, MOUNTED) < 0) { int errsv = errno; nfs_error(_("%s: can't rename %s to %s: %s\n"), progname, MOUNTED_TEMP, MOUNTED, strerror(errsv)); } leave: unlock_mtab(); }
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) chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid); } /* 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(); }