From d5bea7eeeb61fa9c3696e575546cbfade40e4085 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Tue, 2 Mar 2021 22:27:17 +0100 Subject: [PATCH] Re-concatenate string arguments to commands, ugly patch This is quite possibly the ugliest pieces of code in this project. It is a quick fix to the problem with strtok() to split up the cmd into cmd + args[]. Without it wordexp() will later get very cranky about trying to expand `"Partial` strings from commands like this: /sbin/udhcpc-wrapper.sh -f -S -V "myOS v9.99" -t 8 -T 5 -A 10 -R -p \ /var/run/udhcpc-vlan1.pid -i vlan1 -x hostname:myos-12-34-50 -o \ -O 1 -O 3 -O 6 -O 7 -O 12 -O 15 -O 42 -O 121 -a Yes really. It's an obviously far from perfect solution. One might even start to question why we have an args[64[64] per svc_t and not just a cmd + arg? Well, there's a lot of improvement potential here, let's talk! Signed-off-by: Joachim Wiberg --- src/service.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index 6cefdc7c..c6ac3951 100644 --- a/src/service.c +++ b/src/service.c @@ -918,24 +918,56 @@ static void parse_name(svc_t *svc, char *arg) */ static void parse_cmdline_args(svc_t *svc, char *cmd) { - int i; + char sep = 0; char *arg; + int i = 0; - strlcpy(svc->args[0], cmd, sizeof(svc->args[0])); + strlcpy(svc->args[i++], cmd, sizeof(svc->args[0])); + + while (i < MAX_NUM_SVC_ARGS) + svc->args[i++][0] = 0; /* * Copy supplied args. Stop at MAX_NUM_SVC_ARGS-1 to allow the args * array to be zero-terminated. */ - for (i = 1; (arg = strtok(NULL, " ")) && i < (MAX_NUM_SVC_ARGS - 1); i++) - strlcpy(svc->args[i], arg, sizeof(svc->args[0])); + for (i = 1; (arg = strtok(NULL, " ")) && i < (MAX_NUM_SVC_ARGS - 1);) { + char ch = arg[0]; + size_t len; + + /* XXX: ugly string arg re-concatenation, fixme */ + if (ch == '"' || ch == '\'') + sep = ch; + else if (sep) + strlcat(svc->args[i], " ", sizeof(svc->args[0])); + + strlcat(svc->args[i], arg, sizeof(svc->args[0])); + + /* string arg contained already? */ + len = strlen(arg); + if (sep && len >= 1) { + ch = arg[len - 1]; + if (ch != sep) + continue; + } + + sep = 0; + i++; + } /* * Clear remaining args in case they were set earlier. * This also zero-terminates the args array. */ - for (; i < MAX_NUM_SVC_ARGS; i++) - svc->args[i][0] = 0; + while (i < MAX_NUM_SVC_ARGS) + svc->args[i++][0] = 0; +#if 0 + for (i = 0; i < MAX_NUM_SVC_ARGS; i++) { + if (!svc->args[i][0]) + break; + _d("%s ", svc->args[i]); + } +#endif }