public inbox for b.a.t.m.a.n@lists.open-mesh.org
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: [B.A.T.M.A.N.] [PATCH 12/38] batctl: Use getopt to parse main options
Date: Mon, 22 Oct 2018 00:54:58 +0200	[thread overview]
Message-ID: <20181021225524.8155-13-sven@narfation.org> (raw)
In-Reply-To: <20181021225524.8155-1-sven@narfation.org>

The handwritten option parser is rather fragile and doesn't support all
features of a normal commandline option parser. Instead use getopt to
handle the most critical parts and keep it more flexible.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 main.c | 95 ++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 56 insertions(+), 39 deletions(-)

diff --git a/main.c b/main.c
index fa4371c..f5df477 100644
--- a/main.c
+++ b/main.c
@@ -22,6 +22,7 @@
 
 
 
+#include <getopt.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -87,6 +88,25 @@ static void print_usage(void)
 #endif
 }
 
+static void version(void)
+{
+	int ret;
+
+	printf("batctl %s [batman-adv: ", SOURCE_VERSION);
+
+	ret = read_file("", module_ver_path, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0);
+	if ((line_ptr) && (line_ptr[strlen(line_ptr) - 1] == '\n'))
+		line_ptr[strlen(line_ptr) - 1] = '\0';
+
+	if (ret == EXIT_SUCCESS)
+		printf("%s]\n", line_ptr);
+	else
+		printf("module not loaded]\n");
+
+	free(line_ptr);
+	exit(EXIT_SUCCESS);
+}
+
 static const struct command *find_command(const char *name)
 {
 	const struct command **p;
@@ -109,53 +129,48 @@ int main(int argc, char **argv)
 	const struct command *cmd;
 	int i, ret = EXIT_FAILURE;
 	char *mesh_iface = mesh_dfl_iface;
-
-	if ((argc > 1) && (strcmp(argv[1], "-m") == 0)) {
-		if (argc < 3) {
-			fprintf(stderr, "Error - the option '-m' needs a parameter\n");
+	int opt;
+
+	while ((opt = getopt(argc, argv, "+hm:v")) != -1) {
+		switch (opt) {
+		case 'h':
+			print_usage();
+			exit(EXIT_SUCCESS);
+			break;
+		case 'm':
+			if (mesh_iface != mesh_dfl_iface) {
+				fprintf(stderr,
+					"Error - multiple mesh interfaces specified\n");
+				goto err;
+			}
+
+			mesh_iface = argv[2];
+			break;
+		case 'v':
+			version();
+			break;
+		default:
 			goto err;
 		}
-
-		mesh_iface = argv[2];
-
-		argv += 2;
-		argc -= 2;
 	}
 
-	if (argc < 2) {
+	if (optind >= argc) {
 		fprintf(stderr, "Error - no command specified\n");
 		goto err;
 	}
 
-	if (strcmp(argv[1], "-h") == 0) {
-		print_usage();
-		exit(EXIT_SUCCESS);
-	}
-
-	if (strcmp(argv[1], "-v") == 0) {
-		printf("batctl %s [batman-adv: ", SOURCE_VERSION);
-
-		ret = read_file("", module_ver_path, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0);
-		if ((line_ptr) && (line_ptr[strlen(line_ptr) - 1] == '\n'))
-			line_ptr[strlen(line_ptr) - 1] = '\0';
-
-		if (ret == EXIT_SUCCESS)
-			printf("%s]\n", line_ptr);
-		else
-			printf("module not loaded]\n");
-
-		free(line_ptr);
-		exit(EXIT_SUCCESS);
-	}
+	argv += optind;
+	argc -= optind;
+	optind = 0;
 
-	if ((cmd = find_command(argv[1]))) {
+	if ((cmd = find_command(argv[0]))) {
 		if (cmd->flags & COMMAND_FLAG_MESH_IFACE &&
 		    check_mesh_iface(mesh_iface) < 0) {
 			fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface);
 			exit(EXIT_FAILURE);
 		}
 
-		ret = cmd->handler(mesh_iface, argc - 1, argv + 1);
+		ret = cmd->handler(mesh_iface, argc, argv);
 	} else {
 		if (check_mesh_iface(mesh_iface) < 0) {
 			fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface);
@@ -163,24 +178,26 @@ int main(int argc, char **argv)
 		}
 
 		for (i = 0; i < BATCTL_SETTINGS_NUM; i++) {
-			if ((strcmp(argv[1], batctl_settings[i].opt_long) != 0) &&
-			    (strcmp(argv[1], batctl_settings[i].opt_short) != 0))
+			if ((strcmp(argv[0], batctl_settings[i].opt_long) != 0) &&
+			    (strcmp(argv[0], batctl_settings[i].opt_short) != 0))
 				continue;
 
-			ret = handle_sys_setting(mesh_iface, i, argc - 1, argv + 1);
+			ret = handle_sys_setting(mesh_iface, i, argc, argv);
 			goto out;
 		}
 
 		for (i = 0; i < BATCTL_TABLE_NUM; i++) {
-			if ((strcmp(argv[1], batctl_debug_tables[i].opt_long) != 0) &&
-			    (strcmp(argv[1], batctl_debug_tables[i].opt_short) != 0))
+			if ((strcmp(argv[0], batctl_debug_tables[i].opt_long) != 0) &&
+			    (strcmp(argv[0], batctl_debug_tables[i].opt_short) != 0))
 				continue;
 
-			ret = handle_debug_table(mesh_iface, i, argc - 1, argv + 1);
+			ret = handle_debug_table(mesh_iface, i, argc, argv);
 			goto out;
 		}
 
-		fprintf(stderr, "Error - no valid command or debug table specified: %s\n", argv[1]);
+		fprintf(stderr,
+			"Error - no valid command or debug table specified: %s\n",
+			argv[0]);
 		print_usage();
 	}
 
-- 
2.19.1


  parent reply	other threads:[~2018-10-21 22:54 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-21 22:54 [B.A.T.M.A.N.] [PATCH 00/38] batctl: pre-netlink restructuring, part 1 Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 01/38] batctl: Drop unused define SOCKET_PATH_FMT Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 02/38] batctl: Use common code organization for statistics Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 03/38] batctl: Drop legacy vis_* related warning messages Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 04/38] batctl: Move loglevel command to separate file Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 05/38] batctl: Move log " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 06/38] batctl: Move gw_mode " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 07/38] batctl: Move routing_algo " Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 08/38] batctl: Rename tp_meter to throughputmeter Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 09/38] batctl: Introduce datastructure for subcommands Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 10/38] batctl: Add per command flags Sven Eckelmann
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 11/38] batctl: Use command structure for remaining subcommands Sven Eckelmann
2018-10-21 22:54 ` Sven Eckelmann [this message]
2018-10-21 22:54 ` [B.A.T.M.A.N.] [PATCH 13/38] batctl: Store usage line next to command Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 14/38] batctl: Prepare command infrastructure for shared functions Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 15/38] batctl: Add type to command to structure usage output Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 16/38] batctl: Convert debug table to command infrastructure Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 17/38] batctl: Convert sysfs settings " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 18/38] batctl: Move backbonetable debug table to own file Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 19/38] batctl: Move claimtable " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 20/38] batctl: Move dat_cache " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 21/38] batctl: Move gateways " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 22/38] batctl: Move mcast_flags " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 23/38] batctl: Move nc_nodes " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 24/38] batctl: Move neighbors " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 25/38] batctl: Move originators " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 26/38] batctl: Move transglobal " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 27/38] batctl: Move translocal " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 28/38] batctl: Move aggregation setting " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 29/38] batctl: Move bonding " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 30/38] batctl: Move bridge_loop_avoidance " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 31/38] batctl: Move distributed_arp_table " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 32/38] batctl: Move fragmentation " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 33/38] batctl: Move isolation_mark " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 34/38] batctl: Move multicast_mode " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 35/38] batctl: Move network_coding " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 36/38] batctl: Move orig_interval " Sven Eckelmann
2018-10-21 23:02   ` [B.A.T.M.A.N.] [PATCH v2 " Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 37/38] batctl: Use external netlink socket for debug tables Sven Eckelmann
2018-10-21 22:55 ` [B.A.T.M.A.N.] [PATCH 38/38] batctl: Add command to monitor for netlink events Sven Eckelmann
2018-10-22 16:42 ` [B.A.T.M.A.N.] [PATCH 00/38] batctl: pre-netlink restructuring, part 1 Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181021225524.8155-13-sven@narfation.org \
    --to=sven@narfation.org \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox