diff options
author | Karel Zak | 2016-12-20 15:31:33 +0100 |
---|---|---|
committer | Karel Zak | 2016-12-20 15:35:50 +0100 |
commit | db17f201b88903267175be4671efc6b7f71d9b88 (patch) | |
tree | 2c44614f6d4ae026f0d65826b224916a0c8ab6d5 /libmount/src/optstr.c | |
parent | tests: add findmnt tests (diff) | |
download | kernel-qcow2-util-linux-db17f201b88903267175be4671efc6b7f71d9b88.tar.gz kernel-qcow2-util-linux-db17f201b88903267175be4671efc6b7f71d9b88.tar.xz kernel-qcow2-util-linux-db17f201b88903267175be4671efc6b7f71d9b88.zip |
libmount: reimplement mnt_match_options()
Let's use optstr.c functions to parse pattern and options strings.
It's more robust that the old original mount(8) code and it supports
quotes in the options strings.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/optstr.c')
-rw-r--r-- | libmount/src/optstr.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/libmount/src/optstr.c b/libmount/src/optstr.c index 9dfab67f3..2aa6e8ccb 100644 --- a/libmount/src/optstr.c +++ b/libmount/src/optstr.c @@ -20,6 +20,7 @@ #include <selinux/context.h> #endif +#include "strutils.h" #include "mountP.h" /* @@ -1079,6 +1080,84 @@ int mnt_optstr_fix_user(char **optstr) return rc; } +/** + * mnt_match_options: + * @optstr: options string + * @pattern: comma delimited list of options + * + * The "no" could be used for individual items in the @options list. The "no" + * prefix does not have a global meaning. + * + * Unlike fs type matching, nonetdev,user and nonetdev,nouser have + * DIFFERENT meanings; each option is matched explicitly as specified. + * + * The "no" prefix interpretation could be disabled by the "+" prefix, for example + * "+noauto" matches if @optstr literally contains the "noauto" string. + * + * "xxx,yyy,zzz" : "nozzz" -> False + * + * "xxx,yyy,zzz" : "xxx,noeee" -> True + * + * "bar,zzz" : "nofoo" -> True (does not contain "foo") + * + * "nofoo,bar" : "nofoo" -> True (does not contain "foo") + * + * "nofoo,bar" : "+nofoo" -> True (contains "nofoo") + * + * "bar,zzz" : "+nofoo" -> False (does not contain "nofoo") + * + * + * Returns: 1 if pattern is matching, else 0. This function also returns 0 + * if @pattern is NULL and @optstr is non-NULL. + */ +int mnt_match_options(const char *optstr, const char *pattern) +{ + char *name, *pat = (char *) pattern; + char *buf; + size_t namesz = 0, valsz = 0; + int match = 1; + + if (!pattern && !optstr) + return 1; + if (!pattern) + return 0; + + buf = malloc(strlen(pattern) + 1); + if (!buf) + return 0; + + /* walk on pattern string + */ + while (match && !mnt_optstr_next_option(&pat, &name, &namesz, NULL, &valsz)) { + char *val; + size_t sz; + int no = 0; + + if (*name == '+') + name++, namesz--; + else if ((no = (startswith(name, "no") != NULL))) + name += 2, namesz -= 2; + + xstrncpy(buf, name, namesz + 1); + + switch (mnt_optstr_get_option(optstr, buf, &val, &sz)) { + case 0: /* found */ + match = no == 0 ? 1 : 0; + break; + case 1: /* not found */ + match = no == 1 ? 1 : 0; + break; + default: /* parse error */ + match = 0; + break; + } + + } + + free(buf); + return match; +} + #ifdef TEST_PROGRAM static int test_append(struct libmnt_test *ts, int argc, char *argv[]) |