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(); }
static void read_mntentchn(mntFILE * mfp, const char *fnam, struct mntentchn *mc0) { struct mntentchn *mc = mc0; struct mntent *mnt; while ((mnt = my_getmntent(mfp)) != NULL && !streq(mnt->mnt_type, MNTTYPE_IGNORE)) { mc->nxt = (struct mntentchn *)xmalloc(sizeof(*mc)); mc->nxt->prev = mc; mc = mc->nxt; mc->mnt_fsname = mnt->mnt_fsname; mc->mnt_dir = mnt->mnt_dir; mc->mnt_type = mnt->mnt_type; mc->mnt_opts = mnt->mnt_opts; mc->nxt = NULL; } mc0->prev = mc; if (ferror(mfp->mntent_fp)) { error("warning: error reading %s: %s", fnam, strerror(errno)); mc0->nxt = mc0->prev = NULL; } my_endmntent(mfp); }
static void read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) { struct mntentchn *mc = mc0; struct my_mntent *mnt; while ((mnt = my_getmntent(mfp)) != NULL) { if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) { mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc)); mc->nxt->prev = mc; mc = mc->nxt; mc->m = *mnt; mc->nxt = mc0; } } mc0->prev = mc; if (ferror(mfp->mntent_fp)) { int errsv = errno; error(_("warning: error reading %s: %s"), fnam, strerror (errsv)); mc0->nxt = mc0->prev = NULL; } my_endmntent(mfp); }