commit e4923aa: [Rework] Rewrite rspamc in C++
Vsevolod Stakhov
vsevolod at rspamd.com
Tue Jun 7 21:14:03 UTC 2022
Author: Vsevolod Stakhov
Date: 2022-06-07 19:32:04 +0100
URL: https://github.com/rspamd/rspamd/commit/e4923aaaea977ff84425aace57058d94dd51568d
[Rework] Rewrite rspamc in C++
---
src/client/CMakeLists.txt | 2 +-
src/client/rspamc.c | 2129 ---------------------------------------------
src/client/rspamc.cxx | 2088 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 2089 insertions(+), 2130 deletions(-)
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
index 60e422dbd..edf3cc1c4 100644
--- a/src/client/CMakeLists.txt
+++ b/src/client/CMakeLists.txt
@@ -2,7 +2,7 @@
SET(LIBRSPAMDCLIENTSRC rspamdclient.c)
# rspamc
-SET(RSPAMCSRC rspamc.c)
+SET(RSPAMCSRC rspamc.cxx)
ADD_EXECUTABLE(rspamc ${RSPAMCSRC} ${LIBRSPAMDCLIENTSRC})
SET_TARGET_PROPERTIES(rspamc PROPERTIES COMPILE_FLAGS "-I${CMAKE_SOURCE_DIR}/lib")
diff --git a/src/client/rspamc.c b/src/client/rspamc.c
deleted file mode 100644
index 20886f933..000000000
--- a/src/client/rspamc.c
+++ /dev/null
@@ -1,2129 +0,0 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include "config.h"
-#include "libutil/util.h"
-#include "libserver/http/http_connection.h"
-#include "libserver/http/http_private.h"
-#include "libserver/cfg_file.h"
-#include "rspamdclient.h"
-#include "utlist.h"
-#include "unix-std.h"
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-
-#define DEFAULT_PORT 11333
-#define DEFAULT_CONTROL_PORT 11334
-
-static gchar *connect_str = "localhost";
-static gchar *password = NULL;
-static gchar *ip = NULL;
-static gchar *from = NULL;
-static gchar *deliver_to = NULL;
-static gchar **rcpts = NULL;
-static gchar *user = NULL;
-static gchar *helo = NULL;
-static gchar *hostname = NULL;
-static gchar *classifier = NULL;
-static gchar *local_addr = NULL;
-static gchar *execute = NULL;
-static gchar *sort = NULL;
-static gchar **http_headers = NULL;
-static gchar **exclude_patterns = NULL;
-static gint weight = 0;
-static gint flag = 0;
-static gchar *fuzzy_symbol = NULL;
-static gchar *dictionary = NULL;
-static gint max_requests = 8;
-static gdouble timeout = 10.0;
-static gboolean pass_all;
-static gboolean tty = FALSE;
-static gboolean verbose = FALSE;
-static gboolean print_commands = FALSE;
-static gboolean json = FALSE;
-static gboolean compact = FALSE;
-static gboolean headers = FALSE;
-static gboolean raw = FALSE;
-static gboolean ucl_reply = FALSE;
-static gboolean extended_urls = FALSE;
-static gboolean mime_output = FALSE;
-static gboolean empty_input = FALSE;
-static gboolean compressed = FALSE;
-static gboolean profile = FALSE;
-static gboolean skip_images = FALSE;
-static gboolean skip_attachments = FALSE;
-static gchar *key = NULL;
-static gchar *user_agent = "rspamc";
-static GList *children;
-static GPatternSpec **exclude_compiled = NULL;
-static struct rspamd_http_context *http_ctx;
-
-static gint retcode = EXIT_SUCCESS;
-
-#define ADD_CLIENT_HEADER(o, n, v) do { \
- struct rspamd_http_client_header *nh; \
- nh = g_malloc (sizeof (*nh)); \
- nh->name = g_strdup (n); \
- nh->value = g_strdup (v); \
- g_queue_push_tail ((o), nh); \
-} while (0)
-
-#define ADD_CLIENT_FLAG(str, n) do { \
- g_string_append ((str), n ","); \
-} while (0)
-
-static gboolean rspamc_password_callback (const gchar *option_name,
- const gchar *value,
- gpointer data,
- GError **error);
-
-static GOptionEntry entries[] =
-{
- { "connect", 'h', 0, G_OPTION_ARG_STRING, &connect_str,
- "Specify host and port", NULL },
- { "password", 'P', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK,
- &rspamc_password_callback, "Specify control password", NULL },
- { "classifier", 'c', 0, G_OPTION_ARG_STRING, &classifier,
- "Classifier to learn spam or ham", NULL },
- { "weight", 'w', 0, G_OPTION_ARG_INT, &weight,
- "Weight for fuzzy operations", NULL },
- { "flag", 'f', 0, G_OPTION_ARG_INT, &flag, "Flag for fuzzy operations",
- NULL },
- { "pass-all", 'p', 0, G_OPTION_ARG_NONE, &pass_all, "Pass all filters",
- NULL },
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "More verbose output",
- NULL },
- { "ip", 'i', 0, G_OPTION_ARG_STRING, &ip,
- "Emulate that message was received from specified ip address",
- NULL },
- { "user", 'u', 0, G_OPTION_ARG_STRING, &user,
- "Emulate that message was received from specified authenticated user", NULL },
- { "deliver", 'd', 0, G_OPTION_ARG_STRING, &deliver_to,
- "Emulate that message is delivered to specified user (for LDA/statistics)", NULL },
- { "from", 'F', 0, G_OPTION_ARG_STRING, &from,
- "Emulate that message has specified SMTP FROM address", NULL },
- { "rcpt", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &rcpts,
- "Emulate that message has specified SMTP RCPT address", NULL },
- { "helo", 0, 0, G_OPTION_ARG_STRING, &helo,
- "Imitate SMTP HELO passing from MTA", NULL },
- { "hostname", 0, 0, G_OPTION_ARG_STRING, &hostname,
- "Imitate hostname passing from MTA", NULL },
- { "timeout", 't', 0, G_OPTION_ARG_DOUBLE, &timeout,
- "Time in seconds to wait for a reply", NULL },
- { "bind", 'b', 0, G_OPTION_ARG_STRING, &local_addr,
- "Bind to specified ip address", NULL },
- { "commands", 0, 0, G_OPTION_ARG_NONE, &print_commands,
- "List available commands", NULL },
- { "json", 'j', 0, G_OPTION_ARG_NONE, &json, "Output json reply", NULL },
- { "compact", '\0', 0, G_OPTION_ARG_NONE, &compact, "Output compact json reply", NULL},
- { "headers", 0, 0, G_OPTION_ARG_NONE, &headers, "Output HTTP headers",
- NULL },
- { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "Input is a raw file, not an email file",
- NULL },
- { "ucl", 0, 0, G_OPTION_ARG_NONE, &ucl_reply, "Output ucl reply from rspamd",
- NULL },
- { "max-requests", 'n', 0, G_OPTION_ARG_INT, &max_requests,
- "Maximum count of parallel requests to rspamd", NULL },
- { "extended-urls", 0, 0, G_OPTION_ARG_NONE, &extended_urls,
- "Output urls in extended format", NULL },
- { "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 and pass output to it", NULL },
- { "mime", 'm', 0, G_OPTION_ARG_NONE, &mime_output,
- "Write mime body of message with headers instead of just a scan's result", NULL },
- {"header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &http_headers,
- "Add custom HTTP header to query (can be repeated)", NULL},
- {"exclude", 0, 0, G_OPTION_ARG_STRING_ARRAY, &exclude_patterns,
- "Exclude specific glob patterns in file names (can be repeated)", NULL},
- {"sort", 0, 0, G_OPTION_ARG_STRING, &sort,
- "Sort output in a specific order (name, weight, frequency, hits)", NULL},
- { "empty", 'E', 0, G_OPTION_ARG_NONE, &empty_input,
- "Allow empty input instead of reading from stdin", NULL },
- { "fuzzy-symbol", 'S', 0, G_OPTION_ARG_STRING, &fuzzy_symbol,
- "Learn the specified fuzzy symbol", NULL },
- { "compressed", 'z', 0, G_OPTION_ARG_NONE, &compressed,
- "Enable zstd compression", NULL },
- { "profile", '\0', 0, G_OPTION_ARG_NONE, &profile,
- "Profile symbols execution time", NULL },
- { "dictionary", 'D', 0, G_OPTION_ARG_FILENAME, &dictionary,
- "Use dictionary to compress data", NULL },
- { "skip-images", '\0', 0, G_OPTION_ARG_NONE, &skip_images,
- "Skip images when learning/unlearning fuzzy", NULL },
- { "skip-attachments", '\0', 0, G_OPTION_ARG_NONE, &skip_attachments,
- "Skip attachments when learning/unlearning fuzzy", NULL },
- { "user-agent", 'U', 0, G_OPTION_ARG_STRING, &user_agent,
- "Use specific User-Agent instead of \"rspamc\"", NULL },
- { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
-};
-
-static void rspamc_symbols_output (FILE *out, ucl_object_t *obj);
-static void rspamc_uptime_output (FILE *out, ucl_object_t *obj);
-static void rspamc_counters_output (FILE *out, ucl_object_t *obj);
-static void rspamc_stat_output (FILE *out, ucl_object_t *obj);
-
-enum rspamc_command_type {
- RSPAMC_COMMAND_UNKNOWN = 0,
- RSPAMC_COMMAND_CHECK,
- RSPAMC_COMMAND_SYMBOLS,
- RSPAMC_COMMAND_LEARN_SPAM,
- RSPAMC_COMMAND_LEARN_HAM,
- RSPAMC_COMMAND_FUZZY_ADD,
- RSPAMC_COMMAND_FUZZY_DEL,
- RSPAMC_COMMAND_FUZZY_DELHASH,
- RSPAMC_COMMAND_STAT,
- RSPAMC_COMMAND_STAT_RESET,
- RSPAMC_COMMAND_COUNTERS,
- RSPAMC_COMMAND_UPTIME,
- RSPAMC_COMMAND_ADD_SYMBOL,
- RSPAMC_COMMAND_ADD_ACTION
-};
-
-struct rspamc_command {
- enum rspamc_command_type cmd;
- const char *name;
- const char *description;
- const char *path;
- gboolean is_controller;
- gboolean is_privileged;
- gboolean need_input;
- void (*command_output_func)(FILE *, ucl_object_t *obj);
-} rspamc_commands[] = {
- {
- .cmd = RSPAMC_COMMAND_SYMBOLS,
- .name = "symbols",
- .path = "checkv2",
- .description = "scan message and show symbols (default command)",
- .is_controller = FALSE,
- .is_privileged = FALSE,
- .need_input = TRUE,
- .command_output_func = rspamc_symbols_output
- },
- {
- .cmd = RSPAMC_COMMAND_LEARN_SPAM,
- .name = "learn_spam",
- .path = "learnspam",
- .description = "learn message as spam",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = TRUE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_LEARN_HAM,
- .name = "learn_ham",
- .path = "learnham",
- .description = "learn message as ham",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = TRUE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_FUZZY_ADD,
- .name = "fuzzy_add",
- .path = "fuzzyadd",
- .description =
- "add hashes from a message to the fuzzy storage (check -f and -w options for this command)",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = TRUE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_FUZZY_DEL,
- .name = "fuzzy_del",
- .path = "fuzzydel",
- .description =
- "delete hashes from a message from the fuzzy storage (check -f option for this command)",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = TRUE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_FUZZY_DELHASH,
- .name = "fuzzy_delhash",
- .path = "fuzzydelhash",
- .description =
- "delete a hash from fuzzy storage (check -f option for this command)",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = FALSE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_STAT,
- .name = "stat",
- .path = "stat",
- .description = "show rspamd statistics",
- .is_controller = TRUE,
- .is_privileged = FALSE,
- .need_input = FALSE,
- .command_output_func = rspamc_stat_output,
- },
- {
- .cmd = RSPAMC_COMMAND_STAT_RESET,
- .name = "stat_reset",
- .path = "statreset",
- .description = "show and reset rspamd statistics (useful for graphs)",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = FALSE,
- .command_output_func = rspamc_stat_output
- },
- {
- .cmd = RSPAMC_COMMAND_COUNTERS,
- .name = "counters",
- .path = "counters",
- .description = "display rspamd symbols statistics",
- .is_controller = TRUE,
- .is_privileged = FALSE,
- .need_input = FALSE,
- .command_output_func = rspamc_counters_output
- },
- {
- .cmd = RSPAMC_COMMAND_UPTIME,
- .name = "uptime",
- .path = "auth",
- .description = "show rspamd uptime",
- .is_controller = TRUE,
- .is_privileged = FALSE,
- .need_input = FALSE,
- .command_output_func = rspamc_uptime_output
- },
- {
- .cmd = RSPAMC_COMMAND_ADD_SYMBOL,
- .name = "add_symbol",
- .path = "addsymbol",
- .description = "add or modify symbol settings in rspamd",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = FALSE,
- .command_output_func = NULL
- },
- {
- .cmd = RSPAMC_COMMAND_ADD_ACTION,
- .name = "add_action",
- .path = "addaction",
- .description = "add or modify action settings",
- .is_controller = TRUE,
- .is_privileged = TRUE,
- .need_input = FALSE,
- .command_output_func = NULL
- }
-};
-
-struct rspamc_callback_data {
- struct rspamc_command *cmd;
- gchar *filename;
-};
-
-gboolean
-rspamc_password_callback (const gchar *option_name,
- const gchar *value,
- gpointer data,
- GError **error)
-{
- guint plen = 8192;
- guint8 *map, *end;
- gsize sz;
-
- if (value != NULL) {
- if (value[0] == '/' || value[0] == '.') {
- /* Try to open file */
- map = rspamd_file_xmap (value, PROT_READ, &sz, 0);
-
- if (map == NULL) {
- /* Just use it as a string */
- password = g_strdup (value);
- }
- else {
- /* Strip trailing spaces */
- g_assert (sz > 0);
- end = map + sz - 1;
-
- while (g_ascii_isspace (*end) && end > map) {
- end --;
- }
-
- end ++;
- password = g_malloc (end - map + 1);
- rspamd_strlcpy (password, map, end - map + 1);
- munmap (map, sz);
- }
- }
- else {
- password = g_strdup (value);
- }
- }
- else {
- /* Read password from console */
- password = g_malloc0 (plen);
- plen = rspamd_read_passphrase (password, plen, 0, NULL);
- }
-
- if (plen == 0) {
- rspamd_fprintf (stderr, "Invalid password\n");
- exit (EXIT_FAILURE);
- }
-
- return TRUE;
-}
-
-/*
- * Parse command line
- */
-static void
-read_cmd_line (gint *argc, gchar ***argv)
-{
- GError *error = NULL;
- GOptionContext *context;
-
- /* Prepare parser */
- context = g_option_context_new ("- run rspamc client");
- g_option_context_set_summary (context,
- "Summary:\n Rspamd client version " RVERSION "\n Release id: " RID);
- g_option_context_add_main_entries (context, entries, NULL);
-
- /* Parse options */
- if (!g_option_context_parse (context, argc, argv, &error)) {
- fprintf (stderr, "option parsing failed: %s\n", error->message);
- g_option_context_free (context);
- exit (EXIT_FAILURE);
- }
-
- if (json || compact) {
- ucl_reply = TRUE;
- }
- /* Argc and argv are shifted after this function */
- g_option_context_free (context);
-}
-
-static gboolean
-rspamd_action_from_str_rspamc (const gchar *data, gint *result)
-{
- if (strcmp (data, "reject") == 0) {
- *result = METRIC_ACTION_REJECT;
- }
- else if (strcmp (data, "greylist") == 0) {
- *result = METRIC_ACTION_GREYLIST;
- }
- else if (strcmp (data, "add_header") == 0) {
- *result = METRIC_ACTION_ADD_HEADER;
- }
- else if (strcmp (data, "rewrite_subject") == 0) {
- *result = METRIC_ACTION_REWRITE_SUBJECT;
- }
- else if (strcmp (data, "add header") == 0) {
- *result = METRIC_ACTION_ADD_HEADER;
- }
- else if (strcmp (data, "rewrite subject") == 0) {
- *result = METRIC_ACTION_REWRITE_SUBJECT;
- }
- else if (strcmp (data, "soft_reject") == 0) {
- *result = METRIC_ACTION_SOFT_REJECT;
- }
- else if (strcmp (data, "soft reject") == 0) {
- *result = METRIC_ACTION_SOFT_REJECT;
- }
- else if (strcmp (data, "no_action") == 0) {
- *result = METRIC_ACTION_NOACTION;
- }
- else if (strcmp (data, "no action") == 0) {
- *result = METRIC_ACTION_NOACTION;
- }
- else {
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Check rspamc command from string (used for arguments parsing)
- */
-static struct rspamc_command *
-check_rspamc_command (const gchar *cmd)
-{
- enum rspamc_command_type ct = 0;
- guint i;
-
- if (g_ascii_strcasecmp (cmd, "SYMBOLS") == 0 ||
- g_ascii_strcasecmp (cmd, "CHECK") == 0 ||
- g_ascii_strcasecmp (cmd, "REPORT") == 0) {
- /* These all are symbols, don't use other commands */
- ct = RSPAMC_COMMAND_SYMBOLS;
- }
- else if (g_ascii_strcasecmp (cmd, "LEARN_SPAM") == 0) {
- ct = RSPAMC_COMMAND_LEARN_SPAM;
- }
- else if (g_ascii_strcasecmp (cmd, "LEARN_HAM") == 0) {
- ct = RSPAMC_COMMAND_LEARN_HAM;
- }
- else if (g_ascii_strcasecmp (cmd, "FUZZY_ADD") == 0) {
- ct = RSPAMC_COMMAND_FUZZY_ADD;
- }
- else if (g_ascii_strcasecmp (cmd, "FUZZY_DEL") == 0) {
- ct = RSPAMC_COMMAND_FUZZY_DEL;
- }
- else if (g_ascii_strcasecmp (cmd, "FUZZY_DELHASH") == 0) {
- ct = RSPAMC_COMMAND_FUZZY_DELHASH;
- }
- else if (g_ascii_strcasecmp (cmd, "STAT") == 0) {
- ct = RSPAMC_COMMAND_STAT;
- }
- else if (g_ascii_strcasecmp (cmd, "STAT_RESET") == 0) {
- ct = RSPAMC_COMMAND_STAT_RESET;
- }
- else if (g_ascii_strcasecmp (cmd, "COUNTERS") == 0) {
- ct = RSPAMC_COMMAND_COUNTERS;
- }
- else if (g_ascii_strcasecmp (cmd, "UPTIME") == 0) {
- ct = RSPAMC_COMMAND_UPTIME;
- }
- else if (g_ascii_strcasecmp (cmd, "ADD_SYMBOL") == 0) {
- ct = RSPAMC_COMMAND_ADD_SYMBOL;
- }
- else if (g_ascii_strcasecmp (cmd, "ADD_ACTION") == 0) {
- ct = RSPAMC_COMMAND_ADD_ACTION;
- }
-
- for (i = 0; i < G_N_ELEMENTS (rspamc_commands); i++) {
- if (rspamc_commands[i].cmd == ct) {
- return &rspamc_commands[i];
- }
- }
-
- return NULL;
-}
-
-static void
-print_commands_list (void)
-{
- guint i;
- guint cmd_len = 0;
- gchar fmt_str[32];
-
- rspamd_fprintf (stdout, "Rspamc commands summary:\n");
-
- for (i = 0; i < G_N_ELEMENTS (rspamc_commands); i++) {
- gsize clen = strlen (rspamc_commands[i].name);
-
- if (clen > cmd_len) {
- cmd_len = clen;
- }
- }
-
- rspamd_snprintf (fmt_str, sizeof (fmt_str), " %%%ds (%%7s%%1s)\t%%s\n",
- cmd_len);
-
- for (i = 0; i < G_N_ELEMENTS (rspamc_commands); i++) {
- fprintf (stdout,
- fmt_str,
- rspamc_commands[i].name,
- rspamc_commands[i].is_controller ? "control" : "normal",
- rspamc_commands[i].is_privileged ? "*" : "",
- rspamc_commands[i].description);
- }
-
- rspamd_fprintf (stdout,
- "\n* is for privileged commands that may need password (see -P option)\n");
- rspamd_fprintf (stdout,
- "control commands use port 11334 while normal use 11333 by default (see -h option)\n");
-}
-
-static void
-add_options (GQueue *opts)
-{
- GString *numbuf;
- gchar **hdr, **rcpt;
- GString *flagbuf = g_string_new (NULL);
-
- if (ip != NULL) {
- rspamd_inet_addr_t *addr = NULL;
-
- if (!rspamd_parse_inet_address (&addr, ip, strlen (ip),
- RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) {
- /* Try to resolve */
- struct addrinfo hints, *res, *cur;
- gint r;
-
- memset (&hints, 0, sizeof (hints));
- hints.ai_socktype = SOCK_STREAM; /* Type of the socket */
-#ifdef AI_IDN
- hints.ai_flags = AI_NUMERICSERV|AI_IDN;
-#else
- hints.ai_flags = AI_NUMERICSERV;
-#endif
- hints.ai_family = AF_UNSPEC;
-
- if ((r = getaddrinfo (ip, "25", &hints, &res)) == 0) {
-
- cur = res;
- while (cur) {
- addr = rspamd_inet_address_from_sa (cur->ai_addr,
- cur->ai_addrlen);
-
- if (addr != NULL) {
- ip = g_strdup (rspamd_inet_address_to_string (addr));
- rspamd_inet_address_free (addr);
- break;
- }
-
- cur = cur->ai_next;
- }
-
- freeaddrinfo (res);
- }
- else {
- rspamd_fprintf (stderr, "address resolution for %s failed: %s\n",
- ip,
- gai_strerror (r));
- }
- }
- else {
- rspamd_inet_address_free (addr);
- }
-
- ADD_CLIENT_HEADER (opts, "Ip", ip);
- }
-
- if (from != NULL) {
- ADD_CLIENT_HEADER (opts, "From", from);
- }
-
- if (user != NULL) {
- ADD_CLIENT_HEADER (opts, "User", user);
- }
-
- if (rcpts != NULL) {
-
- for (rcpt = rcpts; *rcpt != NULL; rcpt ++) {
- ADD_CLIENT_HEADER (opts, "Rcpt", *rcpt);
- }
- }
-
- if (deliver_to != NULL) {
- ADD_CLIENT_HEADER (opts, "Deliver-To", deliver_to);
- }
-
- if (helo != NULL) {
- ADD_CLIENT_HEADER (opts, "Helo", helo);
- }
-
- if (hostname != NULL) {
- ADD_CLIENT_HEADER (opts, "Hostname", hostname);
- }
-
- if (password != NULL) {
- ADD_CLIENT_HEADER (opts, "Password", password);
- }
-
- if (pass_all) {
- ADD_CLIENT_FLAG (flagbuf, "pass_all");
- }
-
- if (raw) {
- ADD_CLIENT_HEADER (opts, "Raw", "yes");
- }
-
- if (classifier) {
- ADD_CLIENT_HEADER (opts, "Classifier", classifier);
- }
-
- if (weight != 0) {
- numbuf = g_string_sized_new (8);
- rspamd_printf_gstring (numbuf, "%d", weight);
- ADD_CLIENT_HEADER (opts, "Weight", numbuf->str);
- g_string_free (numbuf, TRUE);
- }
-
- if (fuzzy_symbol != NULL) {
- ADD_CLIENT_HEADER (opts, "Symbol", fuzzy_symbol);
- }
-
- if (flag != 0) {
- numbuf = g_string_sized_new (8);
- rspamd_printf_gstring (numbuf, "%d", flag);
- ADD_CLIENT_HEADER (opts, "Flag", numbuf->str);
- g_string_free (numbuf, TRUE);
- }
-
- if (extended_urls) {
- ADD_CLIENT_HEADER (opts, "URL-Format", "extended");
- }
-
- if (profile) {
*** OUTPUT TRUNCATED, 3554 LINES SKIPPED ***
More information about the Commits
mailing list