The branch main has been updated by ivy:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7d4a177efc653bc60a496ba0adf5cb4e0560fa07

commit 7d4a177efc653bc60a496ba0adf5cb4e0560fa07
Author:     Lexi Winter <i...@freebsd.org>
AuthorDate: 2025-07-31 15:54:53 +0000
Commit:     Lexi Winter <i...@freebsd.org>
CommitDate: 2025-08-01 14:06:39 +0000

    ifconfig: Support variable-argument commands
    
    Add a new type of command, DEF_CMD_VARG, which takes an (argc, argv)
    pair instead of a fixed number of arguments.  This allows commands
    to do their own argument parsing and accept a variable number of
    arguments.
    
    Reviewed by:            kevans
    Differential Revision:  https://reviews.freebsd.org/D51243
---
 sbin/ifconfig/ifconfig.c |  7 +++++++
 sbin/ifconfig/ifconfig.h | 10 ++++++++++
 2 files changed, 17 insertions(+)

diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index a0680d09e54c..1a4d062253dd 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1209,6 +1209,13 @@ top:
                        argc -= 2, argv += 2;
                } else if (p->c_parameter == SPARAM && p->c_u.c_func3) {
                        p->c_u.c_func3(ctx, *argv, p->c_sparameter);
+               } else if (p->c_parameter == ARGVECTOR && p->c_u.c_funcv) {
+                       int argsdone;
+
+                       argsdone = p->c_u.c_funcv(ctx, argc - 1,
+                           (const char *const *)argv + 1);
+                       argc -= argsdone;
+                       argv += argsdone;
                } else if (p->c_u.c_func)
                        p->c_u.c_func(ctx, *argv, p->c_parameter);
                argc--, argv++;
diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h
index 555e7dbaca64..468c9b4e80da 100644
--- a/sbin/ifconfig/ifconfig.h
+++ b/sbin/ifconfig/ifconfig.h
@@ -67,6 +67,7 @@ typedef struct ifconfig_context if_ctx;
 typedef        void c_func(if_ctx *ctx, const char *cmd, int arg);
 typedef        void c_func2(if_ctx *ctx, const char *arg1, const char *arg2);
 typedef        void c_func3(if_ctx *ctx, const char *cmd, const char *arg);
+typedef        int  c_funcv(if_ctx *ctx, int argc, const char *const *argv);
 
 struct cmd {
        const char *c_name;
@@ -75,11 +76,13 @@ struct cmd {
 #define        NEXTARG2        0xfffffe        /* has 2 following args */
 #define        OPTARG          0xfffffd        /* has optional following arg */
 #define        SPARAM          0xfffffc        /* parameter is string 
c_sparameter */
+#define        ARGVECTOR       0xfffffb        /* takes argument vector */
        const char *c_sparameter;
        union {
                c_func  *c_func;
                c_func2 *c_func2;
                c_func3 *c_func3;
+               c_funcv *c_funcv;
        } c_u;
        int     c_iscloneop;
        struct cmd *c_next;
@@ -121,6 +124,13 @@ void       callback_register(callback_func *, void *);
     .c_iscloneop = 0,                          \
     .c_next = NULL,                            \
 }
+#define        DEF_CMD_VARG(name, func) {              \
+    .c_name = (name),                          \
+    .c_parameter = ARGVECTOR,                  \
+    .c_u = { .c_funcv = (func) },              \
+    .c_iscloneop = 0,                          \
+    .c_next = NULL,                            \
+}
 #define        DEF_CMD_SARG(name, sparam, func) {      \
     .c_name = (name),                          \
     .c_parameter = SPARAM,                     \

Reply via email to