diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-07-05 17:13:27 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-08-28 23:15:26 +0200 |
commit | bcca1a329595eb98e12d83f32fc7f5f0fc0bd379 (patch) | |
tree | 26b93169eeba12444791242a58b5cf2a48ebc1b5 | |
parent | cc96e7a24e8d6ab074ee9023c99cc6ff88fe9d06 (diff) |
sutils: fix the semantic of -t, --types in fstab.c
The mount utility on both Linux and FreeBSD allows one to either
specify a whitelist or a blacklist of filesystem types to consider for
--all. Prefixing the list with "no" indicates that the list is a
blacklist. Furthermore, Linux' mount utility ignores a "no" prefix on
any entry in the given list.
Previously the Hurd variant first applied whitelist containing all
positive values given and then filtered the resulting list using all
negative values. But this makes little sense because each entry only
has one value for the filesystem type (mnt_type) and all values are
mutually exclusive.
This patch adjusts the fstab handling code so that our mount utility
behaves like the Linux mount utility. This code is used by both mount
and fsck. The same argumentation applies to fsck as well.
Like implemented in Linux mount, any "no" prefix is ignored to retain
compatibility with the old behavior.
* sutils/fstab.c (fstab_argp_create): Fix semantic of --types.
-rw-r--r-- | sutils/fstab.c | 103 |
1 files changed, 27 insertions, 76 deletions
diff --git a/sutils/fstab.c b/sutils/fstab.c index e2918a6c..ed591519 100644 --- a/sutils/fstab.c +++ b/sutils/fstab.c @@ -888,90 +888,41 @@ fstab_argp_create (struct fstab_argp_params *params, check = fstab; else { - struct fs *fs; - const char *tn; - unsigned int nonexclude_types; - err = fstab_create (types, &check); if (err) error (105, err, "fstab_create"); - /* For each excluded type (i.e. `-t notype'), clobber the - fstype entry's program with an empty string to mark it. */ - nonexclude_types = 0; - for (tn = params->types; tn; - tn = argz_next (params->types, params->types_len, tn)) - { - if (!strncasecmp (tn, "no", 2)) - { - struct fstype *type; - err = fstypes_get (types, &tn[2], &type); - if (err) - error (106, err, "fstypes_get"); - free (type->program); - type->program = strdup (""); - } - else - ++nonexclude_types; - } - - if (nonexclude_types != 0) - { - const char *tn; - struct fstypes *wanttypes; - - /* We will copy the types we want to include into a fresh - list in WANTTYPES. Since we specify no search formats, - `fstypes_get' applied to WANTTYPES can only create - elements with a null `program' field. */ - err = fstypes_create (0, 0, &wanttypes); - if (err) - error (102, err, "fstypes_create"); - - for (tn = params->types; tn; - tn = argz_next (params->types, params->types_len, tn)) - if (strncasecmp (tn, "no", 2)) - { - struct fstype *type; - err = fstypes_get (types, tn, &type); - if (err) - error (106, err, "fstypes_get"); - if (type->program == 0) - error (0, 0, - "requested filesystem type `%s' unknown", tn); - else - { - struct fstype *newtype = malloc (sizeof *newtype); - newtype->name = strdup (type->name); - newtype->program = strdup (type->program); - newtype->next = wanttypes->entries; - wanttypes->entries = newtype; - } - } - - /* fstypes_free (types); */ - types = wanttypes; - } + int blacklist = strncasecmp (params->types, "no", 2) == 0; + if (blacklist) + params->types += 2; /* Skip no. */ + struct fs *fs; for (fs = fstab->entries; fs; fs = fs->next) { - const char *ptn; - struct fstype *type; - - err = fs_type (fs, &type); - if (err || nonexclude_types) - { - err = fstypes_get (types, fs->mntent.mnt_type, &type); - if (err) - error (106, err, "fstypes_get"); - if (params->types != 0) - continue; - } - if (nonexclude_types && type->program == 0) - continue; /* Freshly created, was not in WANTTYPES. */ - if (type->program != 0 && type->program[0] == '\0') - continue; /* This type is marked as excluded. */ + if (strcmp (fs->mntent.mnt_type, MNTTYPE_SWAP) == 0) + continue; /* Ignore swap entries. */ + + const char *tn; + int matched = 0; + for (tn = params->types; tn; + tn = argz_next (params->types, params->types_len, tn)) + { + const char *type = fs->mntent.mnt_type; + if (strcmp (type, tn) == 0 + /* Skip no for compatibility. */ + || ((strncasecmp (type, "no", 2) == 0) + && strcmp (type, tn) == 0)) + { + matched = 1; + break; + } + } + + if (matched == blacklist) + continue; /* Either matched and types is a blacklist + or not matched and types is a whitelist */ + const char *ptn; for (ptn = params->exclude; ptn; ptn = argz_next (params->exclude, params->exclude_len, ptn)) if (fnmatch (ptn, fs->mntent.mnt_dir, 0) == 0) |