]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add mnt_optstr_deduplicate_option()
authorKarel Zak <kzak@redhat.com>
Wed, 1 Aug 2012 15:51:43 +0000 (17:51 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 1 Aug 2012 15:51:43 +0000 (17:51 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/optstr.c

index dc6aeabf5d97eef83c8e80373f2ff5f99fcb6a89..e0f899471792ef7e7e4526e2697349512ce7de00 100644 (file)
@@ -250,6 +250,7 @@ MNT_NOHLPS
 <FILE>optstr</FILE>
 mnt_optstr_append_option
 mnt_optstr_apply_flags
+mnt_optstr_deduplicate_option
 mnt_optstr_get_flags
 mnt_optstr_get_option
 mnt_optstr_get_options
index 326588feccf82c4989ec1c5e11eae31cd559713f..43646ac8aa4a920e611573966023da9936f996ea 100644 (file)
@@ -183,6 +183,7 @@ extern int mnt_optstr_get_option(const char *optstr, const char *name,
 extern int mnt_optstr_set_option(char **optstr, const char *name,
                                const char *value);
 extern int mnt_optstr_remove_option(char **optstr, const char *name);
+extern int mnt_optstr_deduplicate_option(char **optstr, const char *name);
 
 extern int mnt_split_optstr(const char *optstr,
                            char **user, char **vfs, char **fs,
@@ -196,6 +197,7 @@ extern int mnt_optstr_get_flags(const char *optstr, unsigned long *flags,
 extern int mnt_optstr_apply_flags(char **optstr, unsigned long flags,
                                 const struct libmnt_optmap *map);
 
+
 /* iter.c */
 enum {
 
index 260642d4d7043739f24ef6d0c137aa11e7855a4f..9e0f2c45de7ba751826841cded721c9279665c89 100644 (file)
@@ -228,22 +228,23 @@ global:
 
 MOUNT_2.22 {
 global:
-       mnt_fs_streq_target;
-       mnt_fs_streq_srcpath;
-       mnt_context_tab_applied;
+       mnt_context_disable_swapmatch;
        mnt_context_get_options;
        mnt_context_is_loopdel;
        mnt_context_is_nocanonicalize;
        mnt_context_is_nohelpers;
-       mnt_table_find_devno;
-       mnt_table_parse_swaps;
-       mnt_get_mountpoint;
-       mnt_get_swaps_path;
+       mnt_context_is_swapmatch;
+       mnt_context_tab_applied;
        mnt_fs_get_priority;
        mnt_fs_get_size;
        mnt_fs_get_swaptype;
        mnt_fs_get_tid;
        mnt_fs_get_usedsize;
-       mnt_context_is_swapmatch;
-       mnt_context_disable_swapmatch;
+       mnt_fs_streq_srcpath;
+       mnt_fs_streq_target;
+       mnt_get_mountpoint;
+       mnt_get_swaps_path;
+       mnt_optstr_deduplicate_option;
+       mnt_table_find_devno;
+       mnt_table_parse_swaps;
 } MOUNT_2.21;
index 08c12150eb20e3392beb1b527de1f7ed97881149..16d6d13a24f5db11681e5886e75f1350a105b177 100644 (file)
@@ -290,6 +290,48 @@ int mnt_optstr_get_option(const char *optstr, const char *name,
        return rc;
 }
 
+/**
+ * mnt_optstr_deduplicate_option:
+ * @optstr: string with comma separated list of options
+ * @name: requested option name
+ *
+ * Removes all instances of @name except the last one.
+ *
+ * Returns: 0 on success, 1 when not found the @name or negative number in case
+ * of error.
+ */
+int mnt_optstr_deduplicate_option(char **optstr, const char *name)
+{
+       int rc;
+       char *begin = NULL, *end = NULL, *opt = *optstr;
+
+       do {
+               struct libmnt_optloc ol;
+
+               mnt_init_optloc(&ol);
+
+               rc = mnt_optstr_locate_option(opt, name, &ol);
+               if (!rc) {
+                       if (begin) {
+                               /* remove previous instance */
+                               size_t shift = strlen(*optstr);
+
+                               mnt_optstr_remove_option_at(optstr, begin, end);
+
+                               /* now all offset are not valied anymore - recount */
+                               shift -= strlen(*optstr);
+                               ol.begin -= shift;
+                               ol.end -= shift;
+                       }
+                       begin = ol.begin;
+                       end = ol.end;
+                       opt = end && *end ? end + 1 : NULL;
+               }
+       } while (rc == 0 && opt && *opt);
+
+       return rc < 0 ? rc : begin ? 0 : 1;
+}
+
 /*
  * The result never starts or ends with comma or contains two commas
  *    (e.g. ",aaa,bbb" or "aaa,,bbb" or "aaa,")
@@ -1187,6 +1229,24 @@ int test_remove(struct libmnt_test *ts, int argc, char *argv[])
        return rc;
 }
 
+int test_dedup(struct libmnt_test *ts, int argc, char *argv[])
+{
+       const char *name;
+       char *optstr;
+       int rc;
+
+       if (argc < 3)
+               return -EINVAL;
+       optstr = strdup(argv[1]);
+       name = argv[2];
+
+       rc = mnt_optstr_deduplicate_option(&optstr, name);
+       if (!rc)
+               printf("result: >%s<\n", optstr);
+       free(optstr);
+       return rc;
+}
+
 int test_fix(struct libmnt_test *ts, int argc, char *argv[])
 {
        char *optstr;
@@ -1230,6 +1290,7 @@ int main(int argc, char *argv[])
                { "--set",    test_set,    "<optstr> <name> [<value>]  (un)set value" },
                { "--get",    test_get,    "<optstr> <name>            search name in optstr" },
                { "--remove", test_remove, "<optstr> <name>            remove name in optstr" },
+               { "--dedup",  test_dedup,  "<optstr> <name>            deduplicate name in optstr" },
                { "--split",  test_split,  "<optstr>                   split into FS, VFS and userspace" },
                { "--flags",  test_flags,  "<optstr>                   convert options to MS_* flags" },
                { "--apply",  test_apply,  "--{linux,user} <optstr> <mask>    apply mask to optstr" },