diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-07-31 17:13:28 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-07-31 17:13:28 +0100 |
commit | e432433904daa712ee302c87bd61da9e54a23940 (patch) | |
tree | 6d282691dae2a22bdada92d2aa5d75c2844dd625 /src/client/rspamc.c | |
parent | 7b63780d69a4495ca90819c47c6e5fd16ca76ca0 (diff) | |
download | rspamd-e432433904daa712ee302c87bd61da9e54a23940.tar.gz rspamd-e432433904daa712ee302c87bd61da9e54a23940.zip |
Initial support of processes execution.
Diffstat (limited to 'src/client/rspamc.c')
-rw-r--r-- | src/client/rspamc.c | 116 |
1 files changed, 93 insertions, 23 deletions
diff --git a/src/client/rspamc.c b/src/client/rspamc.c index 37ac68dcd..2a49bc35b 100644 --- a/src/client/rspamc.c +++ b/src/client/rspamc.c @@ -58,6 +58,7 @@ static gboolean json = FALSE; static gboolean headers = FALSE; static gboolean raw = FALSE; static gboolean extended_urls = FALSE; +static gboolean mime_output = FALSE; static gchar *key = NULL; static GOptionEntry entries[] = @@ -111,7 +112,9 @@ static GOptionEntry entries[] = { "key", 0, 0, G_OPTION_ARG_STRING, &key, "Use specified pubkey to encrypt request", NULL }, { "exec", 'e', 0, G_OPTION_ARG_STRING, &execute, - "Execute the specified command with the message filtered", NULL }, + "Execute the specified command and pass output to it", NULL }, + { "mime", 'e', 0, G_OPTION_ARG_NONE, &mime_output, + "Execute the specified command and pass output to it", NULL }, { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; @@ -784,6 +787,64 @@ rspamc_output_headers (FILE *out, struct rspamd_http_message *msg) } static void +rspamc_client_execute_cmd (struct rspamc_command *cmd, ucl_object_t *result, + GString *input) +{ + gchar **eargv; + gint eargc, infd, outfd, errfd; + GError *err = NULL; + GPid cld; + FILE *out; + gchar *ucl_out; + + if (!g_shell_parse_argv (execute, &eargc, &eargv, &err)) { + rspamd_fprintf (stderr, "Cannot execute %s: %e", execute, err); + g_error_free (err); + + return; + } + + if (!g_spawn_async_with_pipes (NULL, eargv, NULL, + G_SPAWN_SEARCH_PATH|G_SPAWN_DEFAULT, NULL, NULL, &cld, + &infd, &outfd, &errfd, &err)) { + + rspamd_fprintf (stderr, "Cannot execute %s: %e", execute, err); + g_error_free (err); + } + else { + out = fdopen (infd, "w"); + + if (result != NULL) { + if (raw || cmd->command_output_func == NULL) { + if (json) { + ucl_out = ucl_object_emit (result, UCL_EMIT_JSON); + } + else { + ucl_out = ucl_object_emit (result, UCL_EMIT_CONFIG); + } + rspamd_fprintf (out, "%s", ucl_out); + free (ucl_out); + } + else { + cmd->command_output_func (out, result); + } + + ucl_object_unref (result); + } + else if (err != NULL) { + rspamd_fprintf (out, "%s\n", err->message); + } + + rspamd_fprintf (out, "\n"); + fflush (out); + + fclose (out); + } + + g_strfreev (eargv); +} + +static void rspamc_client_cb (struct rspamd_client_connection *conn, struct rspamd_http_message *msg, const gchar *name, ucl_object_t *result, GString *input, @@ -795,39 +856,48 @@ rspamc_client_cb (struct rspamd_client_connection *conn, FILE *out = stdout; cmd = cbdata->cmd; - if (cmd->need_input) { - rspamd_fprintf (out, "Results for file: %s\n", cbdata->filename); + + if (execute) { + /* Pass all to the external command */ + rspamc_client_execute_cmd (cmd, result, input); } else { - rspamd_fprintf (out, "Results for command: %s\n", cmd->name); - } - if (result != NULL) { - if (headers && msg != NULL) { - rspamc_output_headers (out, msg); + if (cmd->need_input) { + rspamd_fprintf (out, "Results for file: %s\n", cbdata->filename); + } + else { + rspamd_fprintf (out, "Results for command: %s\n", cmd->name); } - if (raw || cmd->command_output_func == NULL) { - if (json) { - ucl_out = ucl_object_emit (result, UCL_EMIT_JSON); + + + if (result != NULL) { + if (headers && msg != NULL) { + rspamc_output_headers (out, msg); + } + if (raw || cmd->command_output_func == NULL) { + if (json) { + ucl_out = ucl_object_emit (result, UCL_EMIT_JSON); + } + else { + ucl_out = ucl_object_emit (result, UCL_EMIT_CONFIG); + } + rspamd_fprintf (out, "%s", ucl_out); + free (ucl_out); } else { - ucl_out = ucl_object_emit (result, UCL_EMIT_CONFIG); + cmd->command_output_func (out, result); } - rspamd_fprintf (out, "%s", ucl_out); - free (ucl_out); + + ucl_object_unref (result); } - else { - cmd->command_output_func (out, result); + else if (err != NULL) { + rspamd_fprintf (out, "%s\n", err->message); } - ucl_object_unref (result); - } - else if (err != NULL) { - rspamd_fprintf (out, "%s\n", err->message); + rspamd_fprintf (out, "\n"); + fflush (out); } - rspamd_fprintf (out, "\n"); - fflush (out); - rspamd_client_destroy (conn); g_free (cbdata->filename); g_slice_free1 (sizeof (struct rspamc_callback_data), cbdata); |