mount: add support for -O list. +44 bytes
Signed-off-by: Michael Abbott <michael@araneidae.co.uk> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
6dc0ace109
commit
6b5accbfc1
@ -1760,43 +1760,61 @@ static int singlemount(struct mntent *mp, int ignore_busy)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -O support
|
||||
* Unlike -t, -O should interpret "no" prefix differently:
|
||||
* -t noa,b,c = -t no(a,b,c) = mount all except fs'es with types a,b, and c
|
||||
* -O noa,b,c = -O noa,b,c = mount all with without option a,
|
||||
* or with option b or c.
|
||||
* But for now we do not support -O a,b,c at all (only -O a).
|
||||
*
|
||||
* Another difference from -t support (match_fstype) is that
|
||||
* we need to examine the _list_ of options in fsopt, not just a string.
|
||||
*/
|
||||
static int match_opt(const char *fs_opt, const char *O_opt)
|
||||
// -O support
|
||||
// -O interprets a list of filter options which select whether a mount
|
||||
// point will be mounted: only mounts with options matching *all* filtering
|
||||
// options will be selected.
|
||||
// By default each -O filter option must be present in the list of mount
|
||||
// options, but if it is prefixed by "no" then it must be absent.
|
||||
// For example,
|
||||
// -O a,nob,c matches -o a,c but fails to match -o a,b,c
|
||||
// (and also fails to match -o a because -o c is absent).
|
||||
//
|
||||
// It is different from -t in that each option is matched exactly; a leading
|
||||
// "no" at the beginning of one option does not negate the rest.
|
||||
static int match_opt(const char *fs_opt_in, const char *O_opt)
|
||||
{
|
||||
int match = 1;
|
||||
int len;
|
||||
|
||||
if (!O_opt)
|
||||
return match;
|
||||
return 1;
|
||||
|
||||
if (O_opt[0] == 'n' && O_opt[1] == 'o') {
|
||||
match--;
|
||||
O_opt += 2;
|
||||
}
|
||||
while (*O_opt) {
|
||||
const char *fs_opt = fs_opt_in;
|
||||
int O_len;
|
||||
int match;
|
||||
|
||||
len = strlen(O_opt);
|
||||
while (1) {
|
||||
if (strncmp(fs_opt, O_opt, len) == 0
|
||||
&& (fs_opt[len] == '\0' || fs_opt[len] == ',')
|
||||
) {
|
||||
return match;
|
||||
// If option begins with "no" then treat as an inverted match:
|
||||
// matching is a failure
|
||||
match = 0;
|
||||
if (O_opt[0] == 'n' && O_opt[1] == 'o') {
|
||||
match = 1;
|
||||
O_opt += 2;
|
||||
}
|
||||
fs_opt = strchr(fs_opt, ',');
|
||||
if (!fs_opt)
|
||||
// Isolate the current O option
|
||||
O_len = strchrnul(O_opt, ',') - O_opt;
|
||||
// Check for a match against existing options
|
||||
while (1) {
|
||||
if (strncmp(fs_opt, O_opt, O_len) == 0
|
||||
&& (fs_opt[O_len] == '\0' || fs_opt[O_len] == ',')
|
||||
) {
|
||||
if (match)
|
||||
return 0; // "no" prefix, but option found
|
||||
match = 1; // current O option found, go check next one
|
||||
break;
|
||||
}
|
||||
fs_opt = strchr(fs_opt, ',');
|
||||
if (!fs_opt)
|
||||
break;
|
||||
fs_opt++;
|
||||
}
|
||||
if (match == 0)
|
||||
return 0; // match wanted but not found
|
||||
if (O_opt[O_len] == '\0') // end?
|
||||
break;
|
||||
fs_opt++;
|
||||
// Step to the next O option
|
||||
O_opt += O_len + 1;
|
||||
}
|
||||
|
||||
return !match;
|
||||
// If we get here then everything matched
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parse options, if necessary parse fstab/mtab, and call singlemount for
|
||||
|
Loading…
Reference in New Issue
Block a user