From b65925bd0cf5565d7c49112cc19c592cc9511d91 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sun, 12 Mar 2023 01:41:48 +1100
Subject: [PATCH] fix cmdline parsing

---
 src/66/66.c                             |   3 -
 src/lib66/exec/ssexec_scandir_wrapper.c | 193 ++++++++++--------------
 2 files changed, 81 insertions(+), 115 deletions(-)

diff --git a/src/66/66.c b/src/66/66.c
index 4058bf95..7049e8f6 100644
--- a/src/66/66.c
+++ b/src/66/66.c
@@ -352,9 +352,6 @@ int main(int argc, char const *const *argv)
 
         PROG = "scandir" ;
         nargv[n++] = PROG ;
-        info.prog = PROG ;
-        info.help = help_scandir_wrapper ;
-        info.usage = usage_scandir_wrapper ;
         func = &ssexec_scandir_wrapper ;
 
     } else {
diff --git a/src/lib66/exec/ssexec_scandir_wrapper.c b/src/lib66/exec/ssexec_scandir_wrapper.c
index ba6dac36..1420ace3 100644
--- a/src/lib66/exec/ssexec_scandir_wrapper.c
+++ b/src/lib66/exec/ssexec_scandir_wrapper.c
@@ -35,202 +35,171 @@ int ssexec_scandir_wrapper(int argc, char const *const *argv, ssexec_t *info)
 
     int r, n = 0, i = 0 ;
     uid_t owner = -1 ;
+    uint8_t ctl = 0 ;
     ssexec_func_t_ref func = 0 ;
     char const *nargv[argc + 1] ;
 
-    if (!strcmp(argv[1], "create")) {
+    if (argv[1][0] == '-') {
 
-        nargv[n++] = PROG ;
+        ctl++ ;
+        subgetopt l = SUBGETOPT_ZERO ;
+
+        for (;;) {
+
+            int opt = subgetopt_r(argc, argv, "ho:", &l) ;
+            if (opt == -1) break ;
+
+            switch (opt) {
+
+                case 'h' :
+
+                    info_help(help_scandir_wrapper, usage_scandir_wrapper) ;
+                    return 0 ;
+
+                case 'o' :
+
+                    if (MYUID)
+                        log_die(LOG_EXIT_USER, "only root can use -o option") ;
+
+                    if (!youruid(&owner,l.arg))
+                        log_dieusys(LOG_EXIT_SYS, "get uid of: ", l.arg) ;
+
+                    info->owner = owner ;
+                    info->ownerlen = uid_fmt(info->ownerstr, info->owner) ;
+                    info->ownerstr[info->ownerlen] = 0 ;
+
+                    info->scandir.len = 0 ;
+                    if (!auto_stra(&info->scandir, info->live.s, SS_SCANDIR, "/", info->ownerstr))
+                        log_die_nomem("stralloc") ;
+
+                    break ;
+
+                default:
+
+                    log_usage(usage_scandir_wrapper, "\n", help_scandir_wrapper) ;
+
+            }
+        }
+        argc -= l.ind ; argv += l.ind ;
+    }
+
+    if (!ctl) {
+        argc-- ;
+        argv++ ;
+    }
+
+    if (!strcmp(argv[0], "create")) {
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_create ;
         info->usage = usage_scandir_create ;
         func = &ssexec_scandir_create ;
 
-    } else if (!strcmp(argv[1], "remove")) {
+    } else if (!strcmp(argv[0], "remove")) {
 
-        nargv[n++] = PROG ;
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_remove ;
         info->usage = usage_scandir_remove ;
         func = &ssexec_scandir_remove ;
 
-    } else if (!strcmp(argv[1], "start")) {
+    } else if (!strcmp(argv[0], "start")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_start ;
         info->usage = usage_scandir_start ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "stop")) {
+    } else if (!strcmp(argv[0], "stop")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_stop ;
         info->usage = usage_scandir_stop ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "reconfigure")) {
+    } else if (!strcmp(argv[0], "reconfigure")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_reconfigure ;
         info->usage = usage_scandir_reconfigure ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "rescan")) {
+    } else if (!strcmp(argv[0], "rescan")) {
 
         nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_rescan ;
         info->usage = usage_scandir_rescan ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "quit")) {
+    } else if (!strcmp(argv[0], "quit")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_quit ;
         info->usage = usage_scandir_quit ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "halt")) {
+    } else if (!strcmp(argv[0], "halt")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_halt ;
         info->usage = usage_scandir_halt ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "abort")) {
+    } else if (!strcmp(argv[0], "abort")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_abort ;
         info->usage = usage_scandir_abort ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "nuke")) {
+    } else if (!strcmp(argv[0], "nuke")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_nuke ;
         info->usage = usage_scandir_nuke ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "annihilate")) {
+    } else if (!strcmp(argv[0], "annihilate")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_annihilate ;
         info->usage = usage_scandir_annihilate ;
         func = &ssexec_scandir_signal ;
 
-    } else if (!strcmp(argv[1], "zombies")) {
+    } else if (!strcmp(argv[0], "zombies")) {
 
-        nargv[n++] = PROG ;
-        nargv[n++] = argv[1] ;
+        nargv[n++] = argv[0] ;
         info->prog = PROG ;
         info->help = help_scandir_zombies ;
         info->usage = usage_scandir_zombies ;
         func = &ssexec_scandir_signal ;
 
-    } else {
-
-        if (!strcmp(argv[1], "-h")) {
-            info_help(help_scandir_wrapper, usage_scandir_wrapper) ;
-            return 0 ;
-        }
-
-        log_usage(usage_scandir_wrapper, "\n", help_scandir_wrapper) ;
     }
 
     argc-- ;
     argv++ ;
 
-    {
-        subgetopt l = SUBGETOPT_ZERO ;
-
-        int f = 0 ;
-        for (;;) {
-
-            int opt = subgetopt_r(argc, argv, OPTS_SCANDIR_WRAPPER, &l) ;
-            if (opt == -1) break ;
-            switch (opt) {
-
-                case 'h' :
-
-                    info_help(info->help, info->usage) ;
-                    return 0 ;
-
-                case 'o' :
-
-                    if (MYUID)
-                        log_die(LOG_EXIT_USER, "only root can use -o option") ;
-
-                    if (!youruid(&owner,l.arg))
-                        log_dieusys(LOG_EXIT_SYS, "get uid of: ", l.arg) ;
-
-                    info->owner = owner ;
-                    info->ownerlen = uid_fmt(info->ownerstr, info->owner) ;
-                    info->ownerstr[info->ownerlen] = 0 ;
-
-                    info->scandir.len = 0 ;
-                    if (!auto_stra(&info->scandir, info->live.s, SS_SCANDIR, "/", info->ownerstr))
-                        log_die_nomem("stralloc") ;
-
-                default:
-
-                    for (i = 0 ; i < n ; i++) {
-
-                        if (!argv[l.ind])
-                            log_usage(info->usage) ;
-
-                        if (l.arg) {
-
-                            if (!strcmp(nargv[i],argv[l.ind - 2]) || !strcmp(nargv[i],l.arg))
-                                f = 1 ;
-
-                        } else {
-
-                            if (!strcmp(nargv[i],argv[l.ind]))
-                                f = 1 ;
-                        }
-                    }
-
-                    if (!f) {
-
-                        if (l.arg) {
-                            // distinction between e.g -enano and -e nano
-                            if (argv[l.ind - 1][0] != '-')
-                                nargv[n++] = argv[l.ind - 2] ;
-
-                            nargv[n++] = argv[l.ind - 1] ;
-
-                        } else {
-
-                            nargv[n++] = argv[l.ind] ;
-                        }
-                    }
-                    f = 0 ;
-                    break ;
-            }
-        }
-        argc -= l.ind ; argv += l.ind ;
-    }
-
     for (i = 0 ; i < argc ; i++ , argv++)
         nargv[n++] = *argv ;
 
+    nargv[n++] = nargv[0] ;
     nargv[n] = 0 ;
 
     r = (*func)(n, nargv, info) ;
-- 
GitLab