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