diff options
author | Florian Dold <florian@dold.me> | 2024-10-24 17:04:58 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-10-24 17:05:07 +0200 |
commit | 454b47fce9e7a8de12fa3d587de29ff30b1ec47a (patch) | |
tree | b1c765942ae07a8b7385a8409a57a0ee83022a57 /src/kyclogic | |
parent | 0ea6f1ee4df9b9868fa32b3b25174dc63a385892 (diff) |
kyc: split command before invoking AML programs
This behavior is useful for testing, especially with taler-harness. The
splitting is very primitive, but probably good enough.
Diffstat (limited to 'src/kyclogic')
-rw-r--r-- | src/kyclogic/kyclogic_api.c | 115 |
1 files changed, 105 insertions, 10 deletions
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c index 366c6fdb0..910f98c62 100644 --- a/src/kyclogic/kyclogic_api.c +++ b/src/kyclogic/kyclogic_api.c @@ -1340,6 +1340,88 @@ TALER_KYCLOGIC_rule2priority ( /** + * Perform very primitive word splitting of a command. + * + * @args command command to split + * @args extra_args extra arguments to append after the word + * @returns NULL-terminated array of words + */ +static char ** +split_words (const char *command, const char **extra_args) +{ + unsigned int i = 0; + unsigned int j = 0; + unsigned int n = 0; + char **res = NULL; + + /* Result is always NULL-terminated */ + GNUNET_array_append (res, n, NULL); + + /* Split command into words */ + while (1) + { + char *c; + + /* Skip initial whitespace before word */ + while (' ' == command[i]) + i++; + + /* Start of new word */ + j = i; + + /* Scan to end of word */ + while ( (0 != command[j]) && (' ' != command[j]) ) + j++; + + /* No new word found */ + if (i == j) + break; + + /* Append word to result */ + c = GNUNET_malloc (j - i + 1); + memcpy (c, &command[i], j - i); + c[j - i] = 0; + res[n - 1] = c; + GNUNET_array_append (res, n, NULL); + + /* Continue at end of word */ + i = j; + } + + /* Append extra args */ + if (NULL != extra_args) + { + for (const char **m = extra_args; *m; m++) + { + res[n - 1] = GNUNET_strdup (*m); + GNUNET_array_append (res, n, NULL); + } + } + + return res; +} + + +/** + * Free arguments allocated with split_words. + * + * @param args NULL-terminated array of strings to free. + */ +static void +destroy_words (char **args) +{ + if (NULL == args) + return; + for (char **m = args; *m; m++) + { + GNUNET_free (*m); + *m = NULL; + } + GNUNET_free (args); +} + + +/** * Run @a command with @a argument and return the * respective output from stdout. * @@ -1357,6 +1439,12 @@ command_output (const char *command, ssize_t ret; int sout[2]; pid_t chld; + const char *extra_args[] = { + argument, + "-c", + cfg_filename, + NULL, + }; if (0 != pipe (sout)) { @@ -1373,6 +1461,11 @@ command_output (const char *command, } if (0 == chld) { + char **argv; + + argv = split_words (command, + extra_args); + GNUNET_break (0 == close (sout[0])); GNUNET_break (0 == @@ -1382,12 +1475,9 @@ command_output (const char *command, STDOUT_FILENO)); GNUNET_break (0 == close (sout[1])); - execlp (command, - command, - argument, - "-c", - cfg_filename, - NULL); + execvp (argv[0], + argv); + destroy_words (argv); GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "exec", command); @@ -3750,13 +3840,14 @@ TALER_KYCLOGIC_run_aml_program2 ( { json_t *input; - const char *args[] = { - prog->command, + const char *extra_args[] = { "-c", cfg_filename, NULL, }; + char **args; + input = GNUNET_JSON_PACK ( GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_incref ("context", @@ -3771,6 +3862,9 @@ TALER_KYCLOGIC_run_aml_program2 ( GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running AML program %s\n", prog->command); + args = split_words (prog->command, extra_args); + GNUNET_assert (NULL != args); + GNUNET_assert (NULL != args[0]); json_dumpf (input, stderr, JSON_INDENT (2)); @@ -3778,8 +3872,9 @@ TALER_KYCLOGIC_run_aml_program2 ( input, &handle_aml_output, aprh, - prog->command, - args); + args[0], + (const char **) args); + destroy_words (args); json_decref (input); } return aprh; |