As a load from file support preparation, introduce a ct_cmd_list, which represents a list of ct_cmd elements. Currently only a single entry is generated for the command line processing. Signed-off-by: Mikhail Sennikovsky <mikhail.sennikovskii@xxxxxxxxx> --- src/conntrack.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) diff --git a/src/conntrack.c b/src/conntrack.c index 4bc340f..6040828 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -102,6 +102,7 @@ struct ct_tmpl { static struct ct_tmpl *cur_tmpl; struct ct_cmd { + struct list_head list_entry; unsigned int command; unsigned int cmd; unsigned int type; @@ -113,6 +114,10 @@ struct ct_cmd { struct ct_tmpl tmpl; }; +struct ct_cmd_list { + struct list_head list; +}; + static int alloc_tmpl_objects(struct ct_tmpl *tmpl) { tmpl->ct = nfct_new(); @@ -2823,6 +2828,8 @@ static void do_parse(struct ct_cmd *ct_cmd, int argc, char *argv[]) /* disable explicit missing arguments error output from getopt_long */ opterr = 0; + /* reset optind, for the case do_parse is called multiple times */ + optind = 0; while ((c = getopt_long(argc, argv, getopt_str, opts, NULL)) != -1) { switch(c) { @@ -3543,9 +3550,65 @@ try_proc: return EXIT_SUCCESS; } +static int ct_cmd_process(struct ct_cmd *ct_cmd, const char *progname) +{ + int res; + + res = do_command_ct(progname, ct_cmd); + if (res < 0) + return res; + + return print_stats(ct_cmd); +} + +static struct ct_cmd *ct_cmd_create(int argc, char *argv[]) +{ + struct ct_cmd *ct_cmd; + + ct_cmd = calloc(1, sizeof(*ct_cmd)); + if (!ct_cmd) + exit_error(OTHER_PROBLEM, "cmd alloc failed!!"); + + do_parse(ct_cmd, argc, argv); + + return ct_cmd; +} + +static void ct_cmd_list_init(struct ct_cmd_list *list) +{ + memset(list, 0, sizeof(*list)); + INIT_LIST_HEAD(&list->list); +} + +static void ct_cmd_list_add(struct ct_cmd_list *list, struct ct_cmd *cmd) +{ + list_add_tail(&cmd->list_entry, &list->list); +} + +static int ct_cmd_list_apply(struct ct_cmd_list *list, const char *progname) +{ + int res = 0; + struct ct_cmd *cmd, *tmp; + + list_for_each_entry_safe(cmd, tmp, &list->list, list_entry) { + list_del(&cmd->list_entry); + res |= ct_cmd_process(cmd, progname); + + free(cmd); + } + + return res; +} + +static void ct_cmd_list_parse_argv(struct ct_cmd_list *list, + int argc, char *argv[]) +{ + ct_cmd_list_add(list, ct_cmd_create(argc, argv)); +} + int main(int argc, char *argv[]) { - struct ct_cmd _cmd = {}, *cmd = &_cmd; + struct ct_cmd_list list; register_tcp(); register_udp(); @@ -3557,10 +3620,11 @@ int main(int argc, char *argv[]) register_gre(); register_unknown(); - do_parse(cmd, argc, argv); - do_command_ct(argv[0], cmd); + ct_cmd_list_init(&list); + + ct_cmd_list_parse_argv(&list, argc, argv); - if (print_stats(cmd) < 0) + if (ct_cmd_list_apply(&list, argv[0]) < 0) return EXIT_FAILURE; return EXIT_SUCCESS; -- 2.25.1