void parselabel(void) { char *partname, *partduid; struct fstab *fsent; int i; i = asprintf(&partname, "/dev/%s%c", dkname, 'a'); if (i == -1) err(4, NULL); i = asprintf(&partduid, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.a", lab.d_uid[0], lab.d_uid[1], lab.d_uid[2], lab.d_uid[3], lab.d_uid[4], lab.d_uid[5], lab.d_uid[6], lab.d_uid[7]); if (i == -1) err(4, NULL); setfsent(); for (i = 0; i < MAXPARTITIONS; i++) { partname[strlen(dkname) + 5] = 'a' + i; partduid[strlen(partduid) - 1] = 'a' + i; fsent = getfsspec(partname); if (fsent == NULL) fsent = getfsspec(partduid); if (fsent) mountpoints[i] = strdup(fsent->fs_file); } endfsent(); free(partduid); free(partname); if (aflag) editor_allocspace(&lab); }
static void putfsent(const struct statfs *ent) { struct stat sb; struct fstab *fst; char *opts; opts = flags2opts(ent->f_flags); printf("%s\t%s\t%s %s", ent->f_mntfromname, ent->f_mntonname, ent->f_fstypename, opts); free(opts); /* * If fstab file is missing don't call getfsspec() or getfsfile() * at all, because the same warning will be printed twice for every * mounted filesystem. */ if (stat(_PATH_FSTAB, &sb) != -1) { if ((fst = getfsspec(ent->f_mntfromname))) printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); else if ((fst = getfsfile(ent->f_mntonname))) printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); else printdefvals(ent); } else { printdefvals(ent); } }
/* * Collect the requested quota information. */ static struct quotause * getprivs(long id, int quotatype) { struct quotause *qup, *quptail = NULL; struct fstab *fs; struct quotause *quphead; struct statfs *fst; int nfst, i; qup = quphead = NULL; nfst = getmntinfo(&fst, MNT_NOWAIT); if (nfst == 0) errx(2, "no filesystems mounted!"); setfsent(); for (i=0; i<nfst; i++) { if (qup == NULL) { if ((qup = (struct quotause *)malloc(sizeof *qup)) == NULL) errx(2, "out of memory"); } if (strcmp(fst[i].f_fstypename, "nfs") == 0) { if (lflag) continue; if (getnfsquota(&fst[i], qup, id, quotatype) == 0) continue; } else if (strcmp(fst[i].f_fstypename, "ufs") == 0) { /* * XXX * UFS filesystems must be in /etc/fstab, and must * indicate that they have quotas on (?!) This is quite * unlike SunOS where quotas can be enabled/disabled * on a filesystem independent of /etc/fstab, and it * will still print quotas for them. */ if ((fs = getfsspec(fst[i].f_mntfromname)) == NULL) continue; if (getufsquota(fs, qup, id, quotatype) == 0) continue; } else continue; strcpy(qup->fsname, fst[i].f_mntonname); if (quphead == NULL) quphead = qup; else quptail->next = qup; quptail = qup; quptail->next = 0; qup = NULL; } if (qup) free(qup); endfsent(); return (quphead); }
/* * Fetch requested disklabel into 'lab' using ioctl. */ void readlabel(int f) { char *partname, *partduid; struct fstab *fsent; int i; if (cflag && ioctl(f, DIOCRLDINFO) < 0) err(4, "ioctl DIOCRLDINFO"); if ((op == RESTORE) || dflag || aflag) { if (ioctl(f, DIOCGPDINFO, &lab) < 0) err(4, "ioctl DIOCGPDINFO"); } else { if (ioctl(f, DIOCGDINFO, &lab) < 0) err(4, "ioctl DIOCGDINFO"); } asprintf(&partname, "/dev/%s%c", dkname, 'a'); asprintf(&partduid, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx.a", lab.d_uid[0], lab.d_uid[1], lab.d_uid[2], lab.d_uid[3], lab.d_uid[4], lab.d_uid[5], lab.d_uid[6], lab.d_uid[7]); setfsent(); for (i = 0; i < MAXPARTITIONS; i++) { partname[strlen(dkname) + 5] = 'a' + i; partduid[strlen(partduid) - 1] = 'a' + i; fsent = getfsspec(partname); if (fsent == NULL) fsent = getfsspec(partduid); if (fsent) mountpoints[i] = strdup(fsent->fs_file); } endfsent(); free(partduid); free(partname); if (aflag) editor_allocspace(&lab); }
void putfsent(struct statfs *ent) { struct fstab *fst; char *opts, *rw; int l; opts = NULL; /* flags2opts() doesn't return the "rw" option. */ if ((ent->f_flags & MNT_RDONLY) != 0) rw = NULL; else rw = catopt(NULL, "rw"); opts = flags2opts(ent->f_flags); opts = catopt(rw, opts); if (strncmp(ent->f_mntfromname, "<below>", 7) == 0 || strncmp(ent->f_mntfromname, "<above>", 7) == 0) { strcpy(ent->f_mntfromname, (strnstr(ent->f_mntfromname, ":", 8) +1)); } l = strlen(ent->f_mntfromname); printf("%s%s%s%s", ent->f_mntfromname, l < 8 ? "\t" : "", l < 16 ? "\t" : "", l < 24 ? "\t" : " "); l = strlen(ent->f_mntonname); printf("%s%s%s%s", ent->f_mntonname, l < 8 ? "\t" : "", l < 16 ? "\t" : "", l < 24 ? "\t" : " "); printf("%s\t", ent->f_fstypename); l = strlen(opts); printf("%s%s", opts, l < 8 ? "\t" : " "); free(opts); if ((fst = getfsspec(ent->f_mntfromname))) printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); else if ((fst = getfsfile(ent->f_mntonname))) printf("\t%u %u\n", fst->fs_freq, fst->fs_passno); else if (strcmp(ent->f_fstypename, "ufs") == 0) { if (strcmp(ent->f_mntonname, "/") == 0) printf("\t1 1\n"); else printf("\t2 2\n"); } else printf("\t0 0\n"); }
gint32 Mono_Posix_Syscall_getfsspec (const char *special_file, struct Mono_Posix_Syscall__Fstab *fsbuf) { mph_fstab *fs; if (fsbuf == NULL) { errno = EFAULT; return -1; } fs = getfsspec (special_file); if (fs == NULL) return -1; if (copy_fstab (fsbuf, fs) == -1) { errno = ENOMEM; return -1; } return 0; }
int main(int argc, char *argv[]) { struct fstab *fs; int i, rval = 0; const char *vfstype = NULL; char globopt[3]; const char *etc_fstab; globopt[0] = '-'; globopt[2] = '\0'; TAILQ_INIT(&selhead); TAILQ_INIT(&opthead); etc_fstab = NULL; while ((i = getopt(argc, argv, "BCdvpfFnyl:t:T:c:")) != -1) switch (i) { case 'B': if (flags & CHECK_BACKGRD) errx(1, "Cannot specify -B and -F."); flags |= DO_BACKGRD; break; case 'd': flags |= CHECK_DEBUG; break; case 'v': flags |= CHECK_VERBOSE; break; case 'F': if (flags & DO_BACKGRD) errx(1, "Cannot specify -B and -F."); flags |= CHECK_BACKGRD; break; case 'p': flags |= CHECK_PREEN; /*FALLTHROUGH*/ case 'C': flags |= CHECK_CLEAN; /*FALLTHROUGH*/ case 'n': case 'y': globopt[1] = i; catopt(&options, globopt); break; case 'f': forceflag = 1; globopt[1] = i; catopt(&options, globopt); break; case 'l': warnx("Ignoring obsolete -l option\n"); 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 'c': etc_fstab = optarg; break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (etc_fstab != NULL) setfstab(etc_fstab); if (argc == 0) return checkfstab(flags, isok, checkfs); #define BADTYPE(type) \ (strcmp(type, FSTAB_RO) && \ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) for (; argc--; argv++) { const char *spec, *mntpt, *type, *cp; char device[MAXPATHLEN]; struct statfs *mntp; mntpt = NULL; spec = *argv; cp = strrchr(spec, '/'); if (cp == 0) { (void)snprintf(device, sizeof(device), "%s%s", _PATH_DEV, spec); spec = device; } mntp = getmntpt(spec); if (mntp != NULL) { spec = mntp->f_mntfromname; mntpt = mntp->f_mntonname; } if ((fs = getfsfile(spec)) == NULL && (fs = getfsspec(spec)) == NULL) { if (vfstype == NULL) vfstype = getfslab(spec); if (vfstype == NULL) errx(1, "Could not determine filesystem type"); type = vfstype; devcheck(spec); } else { spec = fs->fs_spec; type = fs->fs_vfstype; mntpt = fs->fs_file; if (BADTYPE(fs->fs_type)) errx(1, "%s has unknown file system type.", spec); } if ((flags & CHECK_BACKGRD) && checkfs(type, spec, mntpt, "-F", NULL) == 0) { printf("%s: DEFER FOR BACKGROUND CHECKING\n", *argv); continue; } if ((flags & DO_BACKGRD) && forceflag == 0 && checkfs(type, spec, mntpt, "-F", NULL) != 0) continue; rval |= checkfs(type, spec, mntpt, NULL, NULL); } return rval; }
int main(int argc, char *argv[]) { const char *mntfromname, **vfslist, *vfstype; struct fstab *fs; struct statfs *mntbuf; int all, ch, i, init_flags, late, failok, mntsize, rval, have_fstab, ro; int onlylate; char *cp, *ep, *options; all = init_flags = late = onlylate = 0; ro = 0; options = NULL; vfslist = NULL; vfstype = "ufs"; while ((ch = getopt(argc, argv, "adF:fLlno:prt:uvw")) != -1) switch (ch) { case 'a': all = 1; break; case 'd': debug = 1; break; case 'F': setfstab(optarg); break; case 'f': init_flags |= MNT_FORCE; break; case 'L': onlylate = 1; late = 1; break; case 'l': late = 1; break; case 'n': /* For compatibility with the Linux version of mount. */ break; case 'o': if (*optarg) { options = catopt(options, optarg); if (specified_ro(optarg)) ro = 1; } break; case 'p': fstab_style = 1; verbose = 1; break; case 'r': options = catopt(options, "ro"); ro = 1; break; case 't': if (vfslist != NULL) errx(1, "only one -t option may be specified"); vfslist = makevfslist(optarg); vfstype = optarg; break; case 'u': init_flags |= MNT_UPDATE; break; case 'v': verbose = 1; break; case 'w': options = catopt(options, "noro"); break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; #define BADTYPE(type) \ (strcmp(type, FSTAB_RO) && \ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) if ((init_flags & MNT_UPDATE) && (ro == 0)) options = catopt(options, "noro"); rval = 0; switch (argc) { case 0: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) err(1, "getmntinfo"); if (all) { while ((fs = getfsent()) != NULL) { if (BADTYPE(fs->fs_type)) continue; if (checkvfsname(fs->fs_vfstype, vfslist)) continue; if (hasopt(fs->fs_mntops, "noauto")) continue; if (!hasopt(fs->fs_mntops, "late") && onlylate) continue; if (hasopt(fs->fs_mntops, "late") && !late) continue; if (hasopt(fs->fs_mntops, "failok")) failok = 1; else failok = 0; if (!(init_flags & MNT_UPDATE) && ismounted(fs, mntbuf, mntsize)) continue; options = update_options(options, fs->fs_mntops, mntbuf->f_flags); if (mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops) && !failok) rval = 1; } } else if (fstab_style) { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; putfsent(&mntbuf[i]); } } else { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; if (!verbose && (mntbuf[i].f_flags & MNT_IGNORE) != 0) continue; prmount(&mntbuf[i]); } } exit(rval); case 1: if (vfslist != NULL) usage(); rmslashes(*argv, *argv); if (init_flags & MNT_UPDATE) { mntfromname = NULL; have_fstab = 0; if ((mntbuf = getmntpt(*argv)) == NULL) errx(1, "not currently mounted %s", *argv); /* * Only get the mntflags from fstab if both mntpoint * and mntspec are identical. Also handle the special * case where just '/' is mounted and 'spec' is not * identical with the one from fstab ('/dev' is missing * in the spec-string at boot-time). */ if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) { if (strcmp(fs->fs_spec, mntbuf->f_mntfromname) == 0 && strcmp(fs->fs_file, mntbuf->f_mntonname) == 0) { have_fstab = 1; mntfromname = mntbuf->f_mntfromname; } else if (argv[0][0] == '/' && argv[0][1] == '\0') { fs = getfsfile("/"); have_fstab = 1; mntfromname = fs->fs_spec; } } if (have_fstab) { options = update_options(options, fs->fs_mntops, mntbuf->f_flags); } else { mntfromname = mntbuf->f_mntfromname; options = update_options(options, NULL, mntbuf->f_flags); } rval = mountfs(mntbuf->f_fstypename, mntfromname, mntbuf->f_mntonname, init_flags, options, 0); break; } if ((fs = getfsfile(*argv)) == NULL && (fs = getfsspec(*argv)) == NULL) errx(1, "%s: unknown special file or file system", *argv); if (BADTYPE(fs->fs_type)) errx(1, "%s has unknown file system type", *argv); rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops); break; case 2: /* * If -t flag has not been specified, the path cannot be * found, spec contains either a ':' or a '@', then assume * that an NFS file system is being specified ala Sun. * Check if the hostname contains only allowed characters * to reduce false positives. IPv6 addresses containing * ':' will be correctly parsed only if the separator is '@'. * The definition of a valid hostname is taken from RFC 1034. */ if (vfslist == NULL && ((ep = strchr(argv[0], '@')) != NULL || (ep = strchr(argv[0], ':')) != NULL)) { if (*ep == '@') { cp = ep + 1; ep = cp + strlen(cp); } else cp = argv[0]; while (cp != ep) { if (!isdigit(*cp) && !isalpha(*cp) && *cp != '.' && *cp != '-' && *cp != ':') break; cp++; } if (cp == ep) vfstype = "nfs"; } rval = mountfs(vfstype, argv[0], argv[1], init_flags, options, NULL); break; default: usage(); /* NOTREACHED */ } /* * If the mount was successfully, and done by root, tell mountd the * good news. */ if (rval == 0 && getuid() == 0) restart_mountd(); exit(rval); }
int main(int argc, char **argv) { const char *mntfromname, **vfslist, *vfstype; struct fstab *fs; struct statfs *mntbuf; FILE *mountdfp; pid_t pid; int all, ch, i, init_flags, mntsize, rval, have_fstab; char *options; all = init_flags = 0; options = NULL; vfslist = NULL; vfstype = "ufs"; while ((ch = getopt(argc, argv, "adF:fo:prwt:uv")) != -1) { switch (ch) { case 'a': all = 1; break; case 'd': debug = 1; break; case 'F': setfstab(optarg); break; case 'f': init_flags |= MNT_FORCE; break; case 'o': if (*optarg) options = catopt(options, optarg); break; case 'p': fstab_style = 1; verbose = 1; break; case 'r': options = catopt(options, "ro"); break; case 't': if (vfslist != NULL) errx(1, "only one -t option may be specified"); vfslist = makevfslist(optarg); vfstype = optarg; break; case 'u': init_flags |= MNT_UPDATE; break; case 'v': verbose = 1; break; case 'w': options = catopt(options, "noro"); break; case '?': default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; #define BADTYPE(type) \ (strcmp(type, FSTAB_RO) && \ strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ)) rval = 0; switch (argc) { case 0: if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) err(1, "getmntinfo"); if (all) { while ((fs = getfsent()) != NULL) { if (BADTYPE(fs->fs_type)) continue; if (checkvfsname(fs->fs_vfstype, vfslist)) continue; if (hasopt(fs->fs_mntops, "noauto")) continue; if (!(init_flags & MNT_UPDATE) && ismounted(fs, mntbuf, mntsize)) continue; options = update_options(options, fs->fs_mntops, mntbuf->f_flags); if (mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops)) rval = 1; } } else if (fstab_style) { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; putfsent(&mntbuf[i]); } } else { for (i = 0; i < mntsize; i++) { if (checkvfsname(mntbuf[i].f_fstypename, vfslist)) continue; prmount(&mntbuf[i]); } } exit(rval); case 1: if (vfslist != NULL) usage(); rmslashes(*argv, *argv); if (init_flags & MNT_UPDATE) { mntfromname = NULL; have_fstab = 0; if ((mntbuf = getmntpt(*argv)) == NULL) errx(1, "not currently mounted %s", *argv); /* * Only get the mntflags from fstab if both mntpoint * and mntspec are identical. Also handle the special * case where just '/' is mounted and 'spec' is not * identical with the one from fstab ('/dev' is missing * in the spec-string at boot-time). */ if ((fs = getfsfile(mntbuf->f_mntonname)) != NULL) { if (strcmp(fs->fs_spec, mntbuf->f_mntfromname) == 0 && strcmp(fs->fs_file, mntbuf->f_mntonname) == 0) { have_fstab = 1; mntfromname = mntbuf->f_mntfromname; } else if (argv[0][0] == '/' && argv[0][1] == '\0') { fs = getfsfile("/"); have_fstab = 1; mntfromname = fs->fs_spec; } } if (have_fstab) { options = update_options(options, fs->fs_mntops, mntbuf->f_flags); } else { mntfromname = mntbuf->f_mntfromname; options = update_options(options, NULL, mntbuf->f_flags); } rval = mountfs(mntbuf->f_fstypename, mntfromname, mntbuf->f_mntonname, init_flags, options, 0); break; } if ((fs = getfsfile(*argv)) == NULL && (fs = getfsspec(*argv)) == NULL) errx(1, "%s: unknown special file or file system", *argv); if (BADTYPE(fs->fs_type)) errx(1, "%s has unknown file system type", *argv); rval = mountfs(fs->fs_vfstype, fs->fs_spec, fs->fs_file, init_flags, options, fs->fs_mntops); break; case 2: /* * If -t flag has not been specified, the path cannot be * found. * * If the spec is not a file and contains a ':' then assume * NFS. * * If the spec is a cdev attempt to extract the fstype from * the label. * * When all else fails ufs is assumed. */ if (vfslist == NULL) { if (strpbrk(argv[0], ":") != NULL && access(argv[0], 0) == -1) { vfstype = "nfs"; } else { checkdisklabel(argv[0], &vfstype); } } rval = mountfs(vfstype, getdevpath(argv[0], 0), argv[1], init_flags, options, NULL); break; default: usage(); /* NOTREACHED */ } /* * If the mount was successfully, and done by root, tell mountd the * good news. Pid checks are probably unnecessary, but don't hurt. */ if (rval == 0 && getuid() == 0 && (mountdfp = fopen(_PATH_MOUNTDPID, "r")) != NULL) { if (fscanf(mountdfp, "%d", &pid) == 1 && pid > 0 && kill(pid, SIGHUP) == -1 && errno != ESRCH) err(1, "signal mountd"); fclose(mountdfp); } exit(rval); }
int main(int argc, char *argv[]) { struct fstab *fs; int i, rval; const char *vfstype = NULL; char globopt[3]; int ret = FSCK_EXIT_OK; globopt[0] = '-'; globopt[2] = '\0'; TAILQ_INIT(&selhead); TAILQ_INIT(&opthead); while ((i = getopt(argc, argv, "dfl:nPpqT:t:vy")) != -1) { switch (i) { case 'd': flags |= CHECK_DEBUG; continue; case 'f': flags |= CHECK_FORCE; break; case 'n': flags |= CHECK_NOFIX; break; case 'p': flags |= CHECK_PREEN; break; case 'P': flags |= CHECK_PROGRESS; break; case 'q': break; case 'l': maxrun = atoi(optarg); continue; case 'T': if (*optarg) addoption(optarg); continue; case 't': if (TAILQ_FIRST(&selhead) != NULL) errx(1, "only one -t option may be specified."); maketypelist(optarg); vfstype = optarg; continue; case 'v': flags |= CHECK_VERBOSE; continue; case 'y': break; case '?': default: usage(); /* NOTREACHED */ } /* Pass option to fsck_xxxfs */ globopt[1] = i; catopt(&options, globopt); } /* Don't do progress meters if we're debugging. */ if (flags & CHECK_DEBUG) flags &= ~CHECK_PROGRESS; /* * If progress meters are being used, force max parallel to 1 * so the progress meter outputs don't interfere with one another. */ if (flags & CHECK_PROGRESS) maxrun = 1; 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++) { const char *spec, *type, *cp; char device[MAXPATHLEN]; spec = *argv; cp = strrchr(spec, '/'); if (cp == 0) { (void)snprintf(device, sizeof(device), "%s%s", _PATH_DEV, spec); spec = device; } if ((fs = getfsfile(spec)) == NULL && (fs = getfsspec(spec)) == NULL) { if (vfstype == NULL) vfstype = getfslab(spec); type = vfstype; } else { spec = fs->fs_spec; type = fs->fs_vfstype; if (BADTYPE(fs->fs_type)) errx(FSCK_EXIT_CHECK_FAILED, "%s has unknown file system type.", spec); } rval = checkfs(type, blockcheck(spec), *argv, NULL, NULL); if (rval > ret) ret = rval; } return ret; }
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; }
int this_was_main_int_mount_c (int argc, char *argv[]) { int c; int all = 0; string_list types = NULL; string_list options; struct mntentchn *mc, *fs; char *file; int result = 0; while ((c = getopt_long (argc, argv, "afhnrvVt:", longopts, NULL)) != EOF) switch (c) { case 'a': /* umount everything */ ++all; break; case 'f': /* force umount (needs kernel support) */ #if 0 ++force; #else die (2, "umount: forced umount not supported yet"); #endif break; case 'h': /* help */ usage (stdout, 0); break; case 'n': ++umount_nomtab; break; case 'r': /* remount read-only if umount fails */ ++remount; break; case 'v': /* make noise */ ++umount_verbose; break; case 'V': /* version */ printf ("umount: %s\n", version); exit (0); case 't': /* specify file system type */ types = parse_list (optarg); break; case 0: break; case '?': default: usage (stderr, 1); } if (getuid () != geteuid ()) { umount_suid = 1; if (all || types || umount_nomtab) die (2, "umount: only root can do that"); } argc -= optind; argv += optind; if (all) { if (types == NULL) types = parse_list(xstrdup("noproc")); result = umount_all (types); } else if (argc < 1) { usage (stderr, 2); } else while (argc--) { file = canonicalize (*argv); /* mtab paths are canonicalized */ if (umount_verbose > 1) printf("Trying to umount %s\n", file); mc = getmntfile (file); if (!mc && umount_verbose) printf("Could not find %s in mtab\n", file); if (umount_suid) { if (!mc) die (2, "umount: %s is not mounted (according to mtab)", file); if (!(fs = getfsspec (file)) && !(fs = getfsfile (file))) die (2, "umount: %s is not in the fstab (and you are not root)", file); if ((!streq (mc->mnt_fsname, fs->mnt_fsname) && !streq (mc->mnt_fsname, canonicalize (fs->mnt_fsname))) || (!streq (mc->mnt_dir, fs->mnt_dir) && !streq (mc->mnt_dir, canonicalize (fs->mnt_dir)))) { die (2, "umount: %s mount disagrees with the fstab", file); } options = parse_list (fs->mnt_opts); while (options) { if (streq (car (options), "user")) break; options = cdr (options); } if (!options) die (2, "umount: only root can unmount %s from %s", fs->mnt_fsname, fs->mnt_dir); } if (mc) result = umount_one (xstrdup(mc->mnt_fsname), xstrdup(mc->mnt_dir), xstrdup(mc->mnt_type), xstrdup(mc->mnt_opts)); else result = umount_one (*argv, *argv, *argv, *argv); argv++; } exit (result); }
int main (int argc, char *argv[]) { int c; int all = 0; string_list types = NULL; string_list options; struct mntentchn *mc, *fs; char *file; int result = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((c = getopt_long (argc, argv, "afhnrt:vV", longopts, NULL)) != EOF) switch (c) { case 'a': /* umount everything */ ++all; break; case 'f': /* force umount */ ++force; break; case 'h': /* help */ usage (stdout, 0); break; case 'n': /* do not write in /etc/mtab */ ++nomtab; break; case 'r': /* remount read-only if umount fails */ ++remount; break; case 'v': /* make noise */ ++verbose; break; case 'V': /* version */ printf ("umount: %s\n", version); exit (0); case 't': /* specify file system type */ types = parse_list (optarg); break; case 0: break; case '?': default: usage (stderr, 1); } if (getuid () != geteuid ()) { suid = 1; if (all || types || nomtab || force) die (2, _("umount: only root can do that")); } argc -= optind; argv += optind; if (all) { if (types == NULL) types = parse_list("noproc"); result = umount_all (types); } else if (argc < 1) { usage (stderr, 2); } else while (argc--) { file = canonicalize (*argv); /* mtab paths are canonicalized */ if (verbose > 1) printf(_("Trying to umount %s\n"), file); mc = getmntfilesbackward (file, NULL); if (!mc && verbose) printf(_("Could not find %s in mtab\n"), file); if (suid) { if (!mc) die (2, _("umount: %s is not mounted (according to mtab)"), file); if (getmntfilesbackward (file, mc)) die (2, _("umount: it seems %s is mounted multiple times"), file); /* If fstab contains the two lines /dev/sda1 /mnt/zip auto user,noauto 0 0 /dev/sda4 /mnt/zip auto user,noauto 0 0 then "mount /dev/sda4" followed by "umount /mnt/zip" used to fail. So, we must not look for file, but for the pair (spec,file) in fstab. */ fs = getfsspecfile(mc->mnt_fsname, mc->mnt_dir); if (!fs) { if (!getfsspec (file) && !getfsfile (file)) die (2, _("umount: %s is not in the fstab (and you are not root)"), file); else die (2, _("umount: %s mount disagrees with the fstab"), file); } /* User mounting and unmounting is allowed only if fstab contains the option `user' or `users' */ /* The option `users' allows arbitrary users to mount and unmount - this may be a security risk. */ /* The option `user' only allows unmounting by the user that mounted. */ /* The option `owner' only allows (un)mounting by the owner. */ /* A convenient side effect is that the user who mounted is visible in mtab. */ options = parse_list (fs->mnt_opts); while (options) { if (streq (car (options), "user") || streq (car (options), "users") || streq (car (options), "owner")) break; options = cdr (options); } if (!options) die (2, _("umount: only root can unmount %s from %s"), fs->mnt_fsname, fs->mnt_dir); if (streq (car (options), "user") || streq (car (options), "owner")) { char *user = getusername(); options = parse_list (mc->mnt_opts); while (options) { char *co = car (options); if (!strncmp(co, "user="******"umount: only %s can unmount %s from %s"), co+5, fs->mnt_fsname, fs->mnt_dir); break; } options = cdr (options); } } } if (mc) result = umount_one_bw (file, mc); else result = umount_one (*argv, *argv, *argv, *argv, NULL); argv++; } exit (result); }