From 99505d9a8d888dd4ae2a17a65db59bf3e5dd5d77 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Thu, 2 Apr 2009 17:12:14 -0700 Subject: [PATCH] cfg-mod: Add new --del-match option. --- lib/cfg.c | 21 +++++++++++++++++++++ lib/cfg.h | 1 + utilities/cfg-mod.8.in | 6 ++++++ utilities/cfg-mod.c | 13 ++++++++++++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/lib/cfg.c b/lib/cfg.c index 4495f670..203880d2 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -539,6 +540,26 @@ cfg_del_section(const char *section_, ...) dirty = true; } +void +cfg_del_match(const char *pattern_, ...) +{ + char *pattern; + char **p; + + FORMAT_KEY(pattern_, pattern); + + for (p = cfg.names; *p; p++) { + if (!fnmatch(pattern, *p, 0)) { + free(*p); + *p = NULL; + } + } + svec_compact(&cfg); + svec_terminate(&cfg); + + free(pattern); + dirty = true; +} /* Fills 'svec' with all of the key-value pairs that have sections that * begin with 'section'. The caller must first initialize 'svec'. */ diff --git a/lib/cfg.h b/lib/cfg.h index 8ecace94..8b21922e 100644 --- a/lib/cfg.h +++ b/lib/cfg.h @@ -70,6 +70,7 @@ void cfg_register(const char *key_spec, enum cfg_flags); void cfg_add_entry(const char *key, ...) PRINTF_FORMAT(1, 2); void cfg_del_entry(const char *key, ...) PRINTF_FORMAT(1, 2); void cfg_del_section(const char *key, ...) PRINTF_FORMAT(1, 2); +void cfg_del_match(const char *pattern, ...) PRINTF_FORMAT(1, 2); void cfg_get_section(struct svec *svec, const char *key, ...) PRINTF_FORMAT(2, 3); diff --git a/utilities/cfg-mod.8.in b/utilities/cfg-mod.8.in index 224fcc47..1cb8d6d9 100644 --- a/utilities/cfg-mod.8.in +++ b/utilities/cfg-mod.8.in @@ -51,6 +51,12 @@ that matches \fIentry\fR. . Delete section \fIkey\fR from \fIfile\fR. +.IP "\fB--del-match=\fIpattern\fR" +Deletes every entry that matches the given shell glob \fIpattern\fR. +For example, \fB--del-match=bridge.*.port=*\fR deletes all the ports +from every bridge, and \fB--del-match=bonding.bond0.*\fR is equivalent +to \fB--del-section=bonding.bond0\fR. + .TP \fB-q\fR \fIkey\fR, \fB--query=\fIkey\fR . diff --git a/utilities/cfg-mod.c b/utilities/cfg-mod.c index f7d0b634..5cb1767a 100644 --- a/utilities/cfg-mod.c +++ b/utilities/cfg-mod.c @@ -49,6 +49,7 @@ usage(char *prog_name, int exit_code) " -a, --add=ENTRY add ENTRY\n" " -d, --del-entry=ENTRY delete ENTRY\n" " -D, --del-section=KEY delete section matching KEY\n" + " --del-match=PATTERN delete entries matching shell PATTERN\n" " -q, --query=KEY return all entries matching KEY \n", prog_name); exit(exit_code); @@ -87,11 +88,15 @@ print_vals(char *key) int main(int argc, char *argv[]) { + enum { + OPT_DEL_MATCH = UCHAR_MAX + 1, + }; static const struct option long_options[] = { {"config-file", required_argument, 0, 'F'}, {"add", required_argument, 0, 'a'}, {"del-entry", required_argument, 0, 'd'}, {"del-section", required_argument, 0, 'D'}, + {"del-match", required_argument, 0, OPT_DEL_MATCH}, {"query", required_argument, 0, 'q'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}, @@ -112,7 +117,8 @@ int main(int argc, char *argv[]) break; } - if (!strchr("Fh?", option) && config_set == false) { + if ((option > UCHAR_MAX || !strchr("Fh?", option)) + && config_set == false) { ofp_fatal(0, "no config file specified (use --help for help)"); } @@ -137,6 +143,11 @@ int main(int argc, char *argv[]) modified = true; break; + case OPT_DEL_MATCH: + cfg_del_match("%s", optarg); + modified = true; + break; + case 'q': print_vals(optarg); break; -- 2.30.2