From cefe7db730cae80133c7811cf34b83985857ab25 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 20 Oct 2010 16:20:37 +0200 Subject: Make nl-qdisc-delete installable Fixes nl_cli_confirm() and adds a check enforcing --yes before deleting all qdiscs on all devices. --- src/Makefile.am | 3 +-- src/lib/utils.c | 34 ++++++++++++++++++++--------- src/nl-qdisc-delete.c | 59 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 1287c21..1c0bcc4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = -Wall -I${top_srcdir}/include -I${top_builddir}/include -D_GNU_SO AM_LDFLAGS = -L${top_builddir}/lib -L${top_builddir}/src/lib -lnl-cli sbin_PROGRAMS = \ - nl-qdisc-add nl-qdisc-list \ + nl-qdisc-add nl-qdisc-list nl-qdisc-delete \ nl-class-add \ nl-classid-lookup @@ -17,7 +17,6 @@ noinst_PROGRAMS = \ nl-link-list nl-link-set nl-link-stats \ nl-link-ifindex2name nl-link-name2ifindex \ nl-neigh-add nl-neigh-delete nl-neigh-list \ - nl-qdisc-delete \ nl-rule-list \ nl-neightbl-list \ nl-monitor \ diff --git a/src/lib/utils.c b/src/lib/utils.c index ef76c84..78ad260 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -134,20 +134,34 @@ int nl_cli_parse_dumptype(const char *str) int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params, int default_yes) { - int answer; - nl_object_dump(obj, params); - printf("Delete? (%c/%c) ", - default_yes ? 'Y' : 'y', - default_yes ? 'n' : 'N'); - do { - answer = tolower(getchar()); - if (answer == '\n') + for (;;) { + char buf[32] = { 0 }; + int answer; + + printf("Delete? (%c/%c) ", + default_yes ? 'Y' : 'y', + default_yes ? 'n' : 'N'); + + if (!fgets(buf, sizeof(buf), stdin)) { + fprintf(stderr, "Error while reading\n."); + continue; + } + + switch ((answer = tolower(buf[0]))) { + case '\n': answer = default_yes ? 'y' : 'n'; - } while (answer != 'y' && answer != 'n'); + case 'y': + case 'n': + return answer == 'y'; + } + + fprintf(stderr, "Invalid input, try again.\n"); + } + + return 0; - return answer == 'y'; } struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name, diff --git a/src/nl-qdisc-delete.c b/src/nl-qdisc-delete.c index 5cb7aa3..24424a7 100644 --- a/src/nl-qdisc-delete.c +++ b/src/nl-qdisc-delete.c @@ -6,7 +6,7 @@ * License as published by the Free Software Foundation version 2.1 * of the License. * - * Copyright (c) 2003-2009 Thomas Graf + * Copyright (c) 2003-2010 Thomas Graf */ #include @@ -21,17 +21,16 @@ static void print_usage(void) printf( "Usage: nl-qdisc-delete [OPTION]... [QDISC]\n" "\n" - "Options\n" - " -i, --interactive Run interactively\n" - " --yes Set default answer to yes\n" - " -q, --quiet Do not print informal notifications\n" - " -h, --help Show this help\n" - " -v, --version Show versioning information\n" + "OPTIONS\n" + " --interactive Run interactively.\n" + " --yes Set default answer to yes.\n" + " -q, --quiet Do not print informal notifications.\n" + " -h, --help Show this help text and exit.\n" + " -v, --version Show versioning information and exit.\n" "\n" - "QDisc Options\n" - " -d, --dev=DEV Device the qdisc is attached to\n" - " -p, --parent=HANDLE Identifier of parent qdisc\n" - " -H, --handle=HANDLE Identifier\n" + " -d, --dev=DEV Device the qdisc is attached to.\n" + " -p, --parent=ID Identifier of parent qdisc/class.\n" + " -i, --id=ID Identifier\n" " -k, --kind=NAME Kind of qdisc (e.g. pfifo_fast)\n" ); @@ -65,6 +64,7 @@ int main(int argc, char *argv[]) { struct rtnl_qdisc *qdisc; struct nl_cache *link_cache, *qdisc_cache; + int nfilter = 0; sock = nl_cli_alloc_socket(); nl_cli_connect(sock, NETLINK_ROUTE); @@ -76,37 +76,58 @@ int main(int argc, char *argv[]) int c, optidx = 0; enum { ARG_YES = 257, + ARG_INTERACTIVE = 258, }; static struct option long_opts[] = { - { "interactive", 0, 0, 'i' }, + { "interactive", 0, 0, ARG_INTERACTIVE }, { "yes", 0, 0, ARG_YES }, { "quiet", 0, 0, 'q' }, { "help", 0, 0, 'h' }, { "version", 0, 0, 'v' }, { "dev", 1, 0, 'd' }, { "parent", 1, 0, 'p' }, - { "handle", 1, 0, 'H' }, + { "id", 1, 0, 'i' }, { "kind", 1, 0, 'k' }, { 0, 0, 0, 0 } }; - c = getopt_long(argc, argv, "iqhvd:p:H:k:", long_opts, &optidx); + c = getopt_long(argc, argv, "qhvd:p:i:k:", long_opts, &optidx); if (c == -1) break; switch (c) { - case 'i': interactive = 1; break; + case '?': nl_cli_fatal(EINVAL, "Invalid options"); + case ARG_INTERACTIVE: interactive = 1; break; case ARG_YES: default_yes = 1; break; case 'q': quiet = 1; break; case 'h': print_usage(); break; case 'v': nl_cli_print_version(); break; - case 'd': nl_cli_qdisc_parse_dev(qdisc, link_cache, optarg); break; - case 'p': nl_cli_qdisc_parse_parent(qdisc, optarg); break; - case 'H': nl_cli_qdisc_parse_handle(qdisc, optarg); break; - case 'k': nl_cli_qdisc_parse_kind(qdisc, optarg); break; + case 'd': + nfilter++; + nl_cli_qdisc_parse_dev(qdisc, link_cache, optarg); + break; + case 'p': + nfilter++; + nl_cli_qdisc_parse_parent(qdisc, optarg); + break; + case 'i': + nfilter++; + nl_cli_qdisc_parse_handle(qdisc, optarg); + break; + case 'k': + nfilter++; + nl_cli_qdisc_parse_kind(qdisc, optarg); + break; } } + if (nfilter == 0 && !interactive && !default_yes) { + nl_cli_fatal(EINVAL, + "You are attempting to delete all qdiscs on all devices.\n" + "If you want to proceed, run nl-qdisc-delete --yes.\n" + "Aborting..."); + } + nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(qdisc), delete_cb, NULL); if (!quiet) -- cgit v0.12