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 <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2021-03-02 22:33:41 +01:00
parent 5da0a460fe
commit d5bea7eeeb
+38 -6
View File
@@ -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
}