[PATCH] ip(6)tables-multi: unify subcommand handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I found the subcommand handling and naming done by iptables-multi and
ip6tables-multi very confusing and complicated; this patch reorganizes
the subcommands in a single table, allowing both variants of them to be
used (iptables/main) and also prints a list of the allowed commands if
an unknown command is entered by the user.
The selection and execution of the desired subcommand is handled by the
code placed in subcmd-multi.h, which is now included by iptables-multi.c
and ip6tables-multi.c containing the needed mapping tables.

Signed-off-by: Stefan Tomanek <stefan.tomanek@xxxxxxxxxxxxx>
---
 ip6tables-multi.c |   46 ++++++++++++--------------------------------
 iptables-multi.c  |   52 ++++++++++++++------------------------------------
 subcmd-multi.h    |   54 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 70 deletions(-)
 create mode 100644 subcmd-multi.h

diff --git a/ip6tables-multi.c b/ip6tables-multi.c
index 671558c..11fc6e7 100644
--- a/ip6tables-multi.c
+++ b/ip6tables-multi.c
@@ -3,43 +3,23 @@
 #include <string.h>
 #include <libgen.h>
 
+#include "subcmd-multi.h"
+
 int ip6tables_main(int argc, char **argv);
 int ip6tables_save_main(int argc, char **argv);
 int ip6tables_restore_main(int argc, char **argv);
 
+subcmd_cb subcommands[] = {
+	{ "ip6tables",		&ip6tables_main },
+	{ "main",		&ip6tables_main },
+	{ "ip6tables-save",	&ip6tables_save_main },
+	{ "save",		&ip6tables_save_main },
+	{ "ip6tables-restore",	&ip6tables_restore_main },
+	{ "restore",		&ip6tables_restore_main },
+	{ NULL,			NULL }
+};
+
 int main(int argc, char **argv)
 {
-	char *progname;
-
-	if (argc < 1) {
-		fprintf(stderr, "ERROR: This should not happen.\n");
-		exit(EXIT_FAILURE);
-	}
-
-	progname = basename(argv[0]);
-	if (strcmp(progname, "ip6tables") == 0)
-		return ip6tables_main(argc, argv);
-	if (strcmp(progname, "ip6tables-save") == 0)
-		return ip6tables_save_main(argc, argv);
-	if (strcmp(progname, "ip6tables-restore") == 0)
-		return ip6tables_restore_main(argc, argv);
-
-	++argv;
-	--argc;
-	if (argc < 1) {
-		fprintf(stderr, "ERROR: No subcommand given.\n");
-		exit(EXIT_FAILURE);
-	}
-
-	progname = basename(argv[0]);
-	if (strcmp(progname, "main") == 0)
-		return ip6tables_main(argc, argv);
-	if (strcmp(progname, "save") == 0)
-		return ip6tables_save_main(argc, argv);
-	if (strcmp(progname, "restore") == 0)
-		return ip6tables_restore_main(argc, argv);
-
-	fprintf(stderr, "ip6tables multi-purpose version: "
-	        "unknown subcommand \"%s\"\n", progname);
-	exit(EXIT_FAILURE);
+	return subcmd_main(argc, argv, subcommands);
 }
diff --git a/iptables-multi.c b/iptables-multi.c
index 4dcc26d..bba36b7 100644
--- a/iptables-multi.c
+++ b/iptables-multi.c
@@ -3,48 +3,26 @@
 #include <string.h>
 #include <libgen.h>
 
+#include "subcmd-multi.h"
+
 int iptables_main(int argc, char **argv);
 int iptables_save_main(int argc, char **argv);
 int iptables_restore_main(int argc, char **argv);
 int iptables_xml_main(int argc, char **argv);
 
+subcmd_cb subcommands[] = {
+	{ "iptables",		&iptables_main },
+	{ "main",		&iptables_main },
+	{ "iptables-save",	&iptables_save_main },
+	{ "save",		&iptables_save_main },
+	{ "iptables-restore",	&iptables_restore_main },
+	{ "restore",		&iptables_restore_main },
+	{ "iptables-xml",	&iptables_xml_main },
+	{ "xml",		&iptables_xml_main },
+	{ NULL,			NULL }
+};
+
 int main(int argc, char **argv)
 {
-	char *progname;
-
-	if (argc < 1) {
-		fprintf(stderr, "ERROR: This should not happen.\n");
-		exit(EXIT_FAILURE);
-	}
-
-	progname = basename(argv[0]);
-	if (strcmp(progname, "iptables") == 0)
-		return iptables_main(argc, argv);
-	if (strcmp(progname, "iptables-save") == 0)
-		return iptables_save_main(argc, argv);
-	if (strcmp(progname, "iptables-restore") == 0)
-		return iptables_restore_main(argc, argv);
-	if (strcmp(progname, "iptables-xml") == 0)
-		return iptables_xml_main(argc, argv);
-
-	++argv;
-	--argc;
-	if (argc < 1) {
-		fprintf(stderr, "ERROR: No subcommand given.\n");
-		exit(EXIT_FAILURE);
-	}
-
-	progname = basename(argv[0]);
-	if (strcmp(progname, "main") == 0)
-		return iptables_main(argc, argv);
-	if (strcmp(progname, "save") == 0)
-		return iptables_save_main(argc, argv);
-	if (strcmp(progname, "restore") == 0)
-		return iptables_restore_main(argc, argv);
-	if (strcmp(progname, "xml") == 0)
-		return iptables_xml_main(argc, argv);
-
-	fprintf(stderr, "iptables multi-purpose version: "
-	        "unknown subcommand \"%s\"\n", progname);
-	exit(EXIT_FAILURE);
+	return subcmd_main(argc, argv, subcommands);
 }
diff --git a/subcmd-multi.h b/subcmd-multi.h
new file mode 100644
index 0000000..3f3e914
--- /dev/null
+++ b/subcmd-multi.h
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+
+typedef int(*mainfunc)(int, char**);
+typedef struct { char *name; mainfunc main; } subcmd_cb;
+
+mainfunc get_subcommand(char *cmd, subcmd_cb cbs[]);
+int subcmd_main(int argc, char **argv, subcmd_cb cbs[]);
+
+mainfunc get_subcommand(char *cmd, subcmd_cb cbs[])
+{
+	int i = 0;
+	while ( cbs[i].name ) {
+		if ( strcmp(cmd, cbs[i].name) == 0 ) {
+			return cbs[i].main;
+		}
+		i++;
+	}
+	return NULL;
+}
+
+int subcmd_main(int argc, char **argv, subcmd_cb cbs[])
+{
+	if (argc < 1) {
+		fprintf(stderr, "ERROR: This should not happen.\n");
+		exit(EXIT_FAILURE);
+	}
+	char *cmd = basename(argv[0]);
+	mainfunc f = get_subcommand(cmd, cbs);
+
+	/* Unable to find a main method for our command name?
+	 * Let's try again with the first argument!
+	 */
+	if (! f && argc > 0) {
+		argv++; argc--;
+		cmd = argv[0];
+		f = get_subcommand(cmd, cbs);
+	}
+
+	/* now we should have a valid function pointer */
+	if (f) {
+		return f(argc, argv);
+	} else {
+		fprintf(stderr, "ERROR: No valid subcommand given.\nValid subcommands:\n");
+		int i = 0;
+		while ( cbs[i].name ) {
+			fprintf(stderr, " * %s\n", cbs[i].name);
+			i++;
+		}
+		exit(EXIT_FAILURE);
+	}
+}
-- 
1.7.2.3
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux