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 <s...@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

Reply via email to