diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-01-21 14:22:57 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2023-01-21 14:22:57 +0000 |
commit | 057df47a8d35a4cfd96fa23afe3f73ba6cbebd65 (patch) | |
tree | af7822efee721677e603d1b068b0bee4c3876d1e /src/client/rspamc.cxx | |
parent | 4445807558c29aa5c376b19fcb81528141ec3571 (diff) | |
download | rspamd-057df47a8d35a4cfd96fa23afe3f73ba6cbebd65.tar.gz rspamd-057df47a8d35a4cfd96fa23afe3f73ba6cbebd65.zip |
[Minor] Some style fixes + reformat
Diffstat (limited to 'src/client/rspamc.cxx')
-rw-r--r-- | src/client/rspamc.cxx | 907 |
1 files changed, 456 insertions, 451 deletions
diff --git a/src/client/rspamc.cxx b/src/client/rspamc.cxx index 5bb75ef38..1a425b881 100644 --- a/src/client/rspamc.cxx +++ b/src/client/rspamc.cxx @@ -84,7 +84,7 @@ static gboolean compressed = FALSE; static gboolean profile = FALSE; static gboolean skip_images = FALSE; static gboolean skip_attachments = FALSE; -static const char *key = nullptr; +static const char *pubkey = nullptr; static const char *user_agent = "rspamc"; std::vector<GPid> children; @@ -99,85 +99,85 @@ static gboolean rspamc_password_callback(const gchar *option_name, GError **error); static GOptionEntry entries[] = - { - {"connect", 'h', 0, G_OPTION_ARG_STRING, &connect_str, - "Specify host and port", nullptr}, - {"password", 'P', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, - (void *) &rspamc_password_callback, "Specify control password", nullptr}, - {"classifier", 'c', 0, G_OPTION_ARG_STRING, &classifier, - "Classifier to learn spam or ham", nullptr}, - {"weight", 'w', 0, G_OPTION_ARG_INT, &weight, - "Weight for fuzzy operations", nullptr}, - {"flag", 'f', 0, G_OPTION_ARG_INT, &flag, "Flag for fuzzy operations", - nullptr}, - {"pass-all", 'p', 0, G_OPTION_ARG_NONE, &pass_all, "Pass all filters", - nullptr}, - {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "More verbose output", - nullptr}, - {"ip", 'i', 0, G_OPTION_ARG_STRING, &ip, - "Emulate that message was received from specified ip address", - nullptr}, - {"user", 'u', 0, G_OPTION_ARG_STRING, &user, - "Emulate that message was received from specified authenticated user", nullptr}, - {"deliver", 'd', 0, G_OPTION_ARG_STRING, &deliver_to, - "Emulate that message is delivered to specified user (for LDA/statistics)", nullptr}, - {"from", 'F', 0, G_OPTION_ARG_STRING, &from, - "Emulate that message has specified SMTP FROM address", nullptr}, - {"rcpt", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &rcpts, - "Emulate that message has specified SMTP RCPT address", nullptr}, - {"helo", 0, 0, G_OPTION_ARG_STRING, &helo, - "Imitate SMTP HELO passing from MTA", nullptr}, - {"hostname", 0, 0, G_OPTION_ARG_STRING, &hostname, - "Imitate hostname passing from MTA", nullptr}, - {"timeout", 't', 0, G_OPTION_ARG_DOUBLE, &timeout, - "Time in seconds to wait for a reply", nullptr}, - {"bind", 'b', 0, G_OPTION_ARG_STRING, &local_addr, - "Bind to specified ip address", nullptr}, - {"commands", 0, 0, G_OPTION_ARG_NONE, &print_commands, - "List available commands", nullptr}, - {"human", 'R', 0, G_OPTION_ARG_NONE, &humanreport, "Output human readable report", nullptr}, - {"json", 'j', 0, G_OPTION_ARG_NONE, &json, "Output json reply", nullptr}, - {"compact", '\0', 0, G_OPTION_ARG_NONE, &compact, "Output compact json reply", nullptr}, - {"headers", 0, 0, G_OPTION_ARG_NONE, &headers, "Output HTTP headers", - nullptr}, - {"raw", 0, 0, G_OPTION_ARG_NONE, &raw, "Input is a raw file, not an email file", - nullptr}, - {"ucl", 0, 0, G_OPTION_ARG_NONE, &ucl_reply, "Output ucl reply from rspamd", - nullptr}, - {"max-requests", 'n', 0, G_OPTION_ARG_INT, &max_requests, - "Maximum count of parallel requests to rspamd", nullptr}, - {"extended-urls", 0, 0, G_OPTION_ARG_NONE, &extended_urls, - "Output urls in extended format", nullptr}, - {"key", 0, 0, G_OPTION_ARG_STRING, &key, - "Use specified pubkey to encrypt request", nullptr}, - {"exec", 'e', 0, G_OPTION_ARG_STRING, &execute, - "Execute the specified command and pass output to it", nullptr}, - {"mime", 'm', 0, G_OPTION_ARG_NONE, &mime_output, - "Write mime body of message with headers instead of just a scan's result", nullptr}, - {"header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &http_headers, - "Add custom HTTP header to query (can be repeated)", nullptr}, - {"exclude", 0, 0, G_OPTION_ARG_STRING_ARRAY, &exclude_patterns, - "Exclude specific glob patterns in file names (can be repeated)", nullptr}, - {"sort", 0, 0, G_OPTION_ARG_STRING, &sort, - "Sort output in a specific order (name, weight, frequency, hits)", nullptr}, - {"empty", 'E', 0, G_OPTION_ARG_NONE, &empty_input, - "Allow empty input instead of reading from stdin", nullptr}, - {"fuzzy-symbol", 'S', 0, G_OPTION_ARG_STRING, &fuzzy_symbol, - "Learn the specified fuzzy symbol", nullptr}, - {"compressed", 'z', 0, G_OPTION_ARG_NONE, &compressed, - "Enable zstd compression", nullptr}, - {"profile", '\0', 0, G_OPTION_ARG_NONE, &profile, - "Profile symbols execution time", nullptr}, - {"dictionary", 'D', 0, G_OPTION_ARG_FILENAME, &dictionary, - "Use dictionary to compress data", nullptr}, - {"skip-images", '\0', 0, G_OPTION_ARG_NONE, &skip_images, - "Skip images when learning/unlearning fuzzy", nullptr}, - {"skip-attachments", '\0', 0, G_OPTION_ARG_NONE, &skip_attachments, - "Skip attachments when learning/unlearning fuzzy", nullptr}, - {"user-agent", 'U', 0, G_OPTION_ARG_STRING, &user_agent, - "Use specific User-Agent instead of \"rspamc\"", nullptr}, - {nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr} - }; + { + {"connect", 'h', 0, G_OPTION_ARG_STRING, &connect_str, + "Specify host and port", nullptr}, + {"password", 'P', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + (void *) &rspamc_password_callback, "Specify control password", nullptr}, + {"classifier", 'c', 0, G_OPTION_ARG_STRING, &classifier, + "Classifier to learn spam or ham", nullptr}, + {"weight", 'w', 0, G_OPTION_ARG_INT, &weight, + "Weight for fuzzy operations", nullptr}, + {"flag", 'f', 0, G_OPTION_ARG_INT, &flag, "Flag for fuzzy operations", + nullptr}, + {"pass-all", 'p', 0, G_OPTION_ARG_NONE, &pass_all, "Pass all filters", + nullptr}, + {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "More verbose output", + nullptr}, + {"ip", 'i', 0, G_OPTION_ARG_STRING, &ip, + "Emulate that message was received from specified ip address", + nullptr}, + {"user", 'u', 0, G_OPTION_ARG_STRING, &user, + "Emulate that message was received from specified authenticated user", nullptr}, + {"deliver", 'd', 0, G_OPTION_ARG_STRING, &deliver_to, + "Emulate that message is delivered to specified user (for LDA/statistics)", nullptr}, + {"from", 'F', 0, G_OPTION_ARG_STRING, &from, + "Emulate that message has specified SMTP FROM address", nullptr}, + {"rcpt", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &rcpts, + "Emulate that message has specified SMTP RCPT address", nullptr}, + {"helo", 0, 0, G_OPTION_ARG_STRING, &helo, + "Imitate SMTP HELO passing from MTA", nullptr}, + {"hostname", 0, 0, G_OPTION_ARG_STRING, &hostname, + "Imitate hostname passing from MTA", nullptr}, + {"timeout", 't', 0, G_OPTION_ARG_DOUBLE, &timeout, + "Time in seconds to wait for a reply", nullptr}, + {"bind", 'b', 0, G_OPTION_ARG_STRING, &local_addr, + "Bind to specified ip address", nullptr}, + {"commands", 0, 0, G_OPTION_ARG_NONE, &print_commands, + "List available commands", nullptr}, + {"human", 'R', 0, G_OPTION_ARG_NONE, &humanreport, "Output human readable report", nullptr}, + {"json", 'j', 0, G_OPTION_ARG_NONE, &json, "Output json reply", nullptr}, + {"compact", '\0', 0, G_OPTION_ARG_NONE, &compact, "Output compact json reply", nullptr}, + {"headers", 0, 0, G_OPTION_ARG_NONE, &headers, "Output HTTP headers", + nullptr}, + {"raw", 0, 0, G_OPTION_ARG_NONE, &raw, "Input is a raw file, not an email file", + nullptr}, + {"ucl", 0, 0, G_OPTION_ARG_NONE, &ucl_reply, "Output ucl reply from rspamd", + nullptr}, + {"max-requests", 'n', 0, G_OPTION_ARG_INT, &max_requests, + "Maximum count of parallel requests to rspamd", nullptr}, + {"extended-urls", 0, 0, G_OPTION_ARG_NONE, &extended_urls, + "Output urls in extended format", nullptr}, + {"key", 0, 0, G_OPTION_ARG_STRING, &pubkey, + "Use specified pubkey to encrypt request", nullptr}, + {"exec", 'e', 0, G_OPTION_ARG_STRING, &execute, + "Execute the specified command and pass output to it", nullptr}, + {"mime", 'm', 0, G_OPTION_ARG_NONE, &mime_output, + "Write mime body of message with headers instead of just a scan's result", nullptr}, + {"header", 0, 0, G_OPTION_ARG_STRING_ARRAY, &http_headers, + "Add custom HTTP header to query (can be repeated)", nullptr}, + {"exclude", 0, 0, G_OPTION_ARG_STRING_ARRAY, &exclude_patterns, + "Exclude specific glob patterns in file names (can be repeated)", nullptr}, + {"sort", 0, 0, G_OPTION_ARG_STRING, &sort, + "Sort output in a specific order (name, weight, frequency, hits)", nullptr}, + {"empty", 'E', 0, G_OPTION_ARG_NONE, &empty_input, + "Allow empty input instead of reading from stdin", nullptr}, + {"fuzzy-symbol", 'S', 0, G_OPTION_ARG_STRING, &fuzzy_symbol, + "Learn the specified fuzzy symbol", nullptr}, + {"compressed", 'z', 0, G_OPTION_ARG_NONE, &compressed, + "Enable zstd compression", nullptr}, + {"profile", '\0', 0, G_OPTION_ARG_NONE, &profile, + "Profile symbols execution time", nullptr}, + {"dictionary", 'D', 0, G_OPTION_ARG_FILENAME, &dictionary, + "Use dictionary to compress data", nullptr}, + {"skip-images", '\0', 0, G_OPTION_ARG_NONE, &skip_images, + "Skip images when learning/unlearning fuzzy", nullptr}, + {"skip-attachments", '\0', 0, G_OPTION_ARG_NONE, &skip_attachments, + "Skip attachments when learning/unlearning fuzzy", nullptr}, + {"user-agent", 'U', 0, G_OPTION_ARG_STRING, &user_agent, + "Use specific User-Agent instead of \"rspamc\"", nullptr}, + {nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr} + }; static void rspamc_symbols_output(FILE *out, ucl_object_t *obj); @@ -217,129 +217,129 @@ struct rspamc_command { }; static const constexpr auto rspamc_commands = rspamd::array_of( - rspamc_command{ - .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 - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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, - }, - rspamc_command{ - .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 - }, - rspamc_command{ - .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 - }, - rspamc_command{ - .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 - }, - rspamc_command{ - .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 = nullptr - }, - rspamc_command{ - .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 = nullptr - } + rspamc_command{ + .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 + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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, + }, + rspamc_command{ + .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 + }, + rspamc_command{ + .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 + }, + rspamc_command{ + .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 + }, + rspamc_command{ + .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 = nullptr + }, + rspamc_command{ + .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 = nullptr + } ); struct rspamc_callback_data { @@ -367,66 +367,66 @@ static constexpr auto emphasis_argument(const T &arg, int precision) -> auto { using sort_lambda = std::function<int(const ucl_object_t *, const ucl_object_t *)>; static const auto sort_map = frozen::make_unordered_map<frozen::string, sort_lambda>({ - {"name", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "symbol"); - const auto *elt2 = ucl_object_lookup(o2, "symbol"); - - if (elt1 && elt2) { - return strcmp(ucl_object_tostring(elt1), - ucl_object_tostring(elt2)); - } - else if (ucl_object_key(o1) != nullptr && ucl_object_key(o2) != nullptr) { - return strcmp(ucl_object_key(o1), - ucl_object_key(o2)); - } - return 0; - }}, - {"weight", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "weight"); - const auto *elt2 = ucl_object_lookup(o2, "weight"); - - if (elt1 && elt2) { - return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; - } - return 0; - }}, - {"score", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "score"); - const auto *elt2 = ucl_object_lookup(o2, "score"); - - if (elt1 && elt2) { - return std::fabs(ucl_object_todouble(elt2)) * 1000.0 - - std::fabs(ucl_object_todouble(elt1)) * 1000.0; - } - return 0; - }}, - {"time", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "time"); - const auto *elt2 = ucl_object_lookup(o2, "time"); - - if (elt1 && elt2) { - return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; - } - return 0; - }}, - {"frequency", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "frequency"); - const auto *elt2 = ucl_object_lookup(o2, "frequency"); - - if (elt1 && elt2) { - return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; - } - return 0; - }}, - {"hits", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - const auto *elt1 = ucl_object_lookup(o1, "hits"); - const auto *elt2 = ucl_object_lookup(o2, "hits"); - - if (elt1 && elt2) { - return ucl_object_toint(elt2) - ucl_object_toint(elt1); - } - return 0; - }}, + {"name", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "symbol"); + const auto *elt2 = ucl_object_lookup(o2, "symbol"); + + if (elt1 && elt2) { + return strcmp(ucl_object_tostring(elt1), + ucl_object_tostring(elt2)); + } + else if (ucl_object_key(o1) != nullptr && ucl_object_key(o2) != nullptr) { + return strcmp(ucl_object_key(o1), + ucl_object_key(o2)); + } + return 0; + }}, + {"weight", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "weight"); + const auto *elt2 = ucl_object_lookup(o2, "weight"); + + if (elt1 && elt2) { + return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; + } + return 0; + }}, + {"score", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "score"); + const auto *elt2 = ucl_object_lookup(o2, "score"); + + if (elt1 && elt2) { + return std::fabs(ucl_object_todouble(elt2)) * 1000.0 - + std::fabs(ucl_object_todouble(elt1)) * 1000.0; + } + return 0; + }}, + {"time", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "time"); + const auto *elt2 = ucl_object_lookup(o2, "time"); + + if (elt1 && elt2) { + return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; + } + return 0; + }}, + {"frequency", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "frequency"); + const auto *elt2 = ucl_object_lookup(o2, "frequency"); + + if (elt1 && elt2) { + return ucl_object_todouble(elt2) * 1000.0 - ucl_object_todouble(elt1) * 1000.0; + } + return 0; + }}, + {"hits", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + const auto *elt1 = ucl_object_lookup(o1, "hits"); + const auto *elt2 = ucl_object_lookup(o2, "hits"); + + if (elt1 && elt2) { + return ucl_object_toint(elt2) - ucl_object_toint(elt1); + } + return 0; + }}, }); /* TODO: remove once migrate to C++20 standard */ @@ -452,11 +452,11 @@ auto sort_ucl_container_with_default(T &cont, const char *default_sort, const auto sort_functor = sort_map.find(sort_view); if (sort_functor != sort_map.end()) { std::stable_sort(std::begin(cont), std::end(cont), - [&](const ucl_object_t *o1, const ucl_object_t *o2) -> int { - auto order = sort_functor->second(o1, o2); + [&](const ucl_object_t *o1, const ucl_object_t *o2) -> int { + auto order = sort_functor->second(o1, o2); - return inverse ? order > 0 : order < 0; - }); + return inverse ? order > 0 : order < 0; + }); } } } @@ -533,7 +533,7 @@ read_cmd_line(gint *argc, gchar ***argv) /* 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); + "Summary:\n Rspamd client version " RVERSION "\n Release id: " RID); g_option_context_add_main_entries(context, entries, nullptr); /* Parse options */ @@ -577,7 +577,7 @@ rspamd_string_tolower(const char *inp) -> std::string { std::string s{inp}; std::transform(std::begin(s), std::end(s), std::begin(s), - [](unsigned char c) { return std::tolower(c); }); + [](unsigned char c) { return std::tolower(c); }); return s; } @@ -585,16 +585,16 @@ static auto rspamd_action_from_str_rspamc(const char *data) -> std::optional<int> { static constexpr const auto str_map = frozen::make_unordered_map<frozen::string, int>({ - {"reject", METRIC_ACTION_REJECT}, - {"greylist", METRIC_ACTION_GREYLIST}, - {"add_header", METRIC_ACTION_ADD_HEADER}, - {"add header", METRIC_ACTION_ADD_HEADER}, - {"rewrite_subject", METRIC_ACTION_REWRITE_SUBJECT}, - {"rewrite subject", METRIC_ACTION_REWRITE_SUBJECT}, - {"soft_reject", METRIC_ACTION_SOFT_REJECT}, - {"soft reject", METRIC_ACTION_SOFT_REJECT}, - {"no_action", METRIC_ACTION_NOACTION}, - {"no action", METRIC_ACTION_NOACTION}, + {"reject", METRIC_ACTION_REJECT}, + {"greylist", METRIC_ACTION_GREYLIST}, + {"add_header", METRIC_ACTION_ADD_HEADER}, + {"add header", METRIC_ACTION_ADD_HEADER}, + {"rewrite_subject", METRIC_ACTION_REWRITE_SUBJECT}, + {"rewrite subject", METRIC_ACTION_REWRITE_SUBJECT}, + {"soft_reject", METRIC_ACTION_SOFT_REJECT}, + {"soft reject", METRIC_ACTION_SOFT_REJECT}, + {"no_action", METRIC_ACTION_NOACTION}, + {"no action", METRIC_ACTION_NOACTION}, }); auto st_lower = rspamd_string_tolower(data); @@ -608,18 +608,18 @@ static auto check_rspamc_command(const char *cmd) -> std::optional<rspamc_command> { static constexpr const auto str_map = frozen::make_unordered_map<frozen::string, int>({ - {"symbols", RSPAMC_COMMAND_SYMBOLS}, - {"check", RSPAMC_COMMAND_SYMBOLS}, - {"report", RSPAMC_COMMAND_SYMBOLS}, - {"learn_spam", RSPAMC_COMMAND_LEARN_SPAM}, - {"learn_ham", RSPAMC_COMMAND_LEARN_HAM}, - {"fuzzy_add", RSPAMC_COMMAND_FUZZY_ADD}, - {"fuzzy_del", RSPAMC_COMMAND_FUZZY_DEL}, - {"fuzzy_delhash", RSPAMC_COMMAND_FUZZY_DELHASH}, - {"stat", RSPAMC_COMMAND_STAT}, - {"stat_reset", RSPAMC_COMMAND_STAT_RESET}, - {"counters", RSPAMC_COMMAND_COUNTERS}, - {"uptime", RSPAMC_COMMAND_UPTIME}, + {"symbols", RSPAMC_COMMAND_SYMBOLS}, + {"check", RSPAMC_COMMAND_SYMBOLS}, + {"report", RSPAMC_COMMAND_SYMBOLS}, + {"learn_spam", RSPAMC_COMMAND_LEARN_SPAM}, + {"learn_ham", RSPAMC_COMMAND_LEARN_HAM}, + {"fuzzy_add", RSPAMC_COMMAND_FUZZY_ADD}, + {"fuzzy_del", RSPAMC_COMMAND_FUZZY_DEL}, + {"fuzzy_delhash", RSPAMC_COMMAND_FUZZY_DELHASH}, + {"stat", RSPAMC_COMMAND_STAT}, + {"stat_reset", RSPAMC_COMMAND_STAT_RESET}, + {"counters", RSPAMC_COMMAND_COUNTERS}, + {"uptime", RSPAMC_COMMAND_UPTIME}, }); std::string cmd_lc = rspamd_string_tolower(cmd); @@ -653,18 +653,18 @@ print_commands_list() for (const auto &cmd: rspamc_commands) { fmt::print(stdout, - " {:>{}} ({:7}{:1})\t{}\n", - cmd.name, - cmd_len, - cmd.is_controller ? "control" : "normal", - cmd.is_privileged ? "*" : "", - cmd.description); + " {:>{}} ({:7}{:1})\t{}\n", + cmd.name, + cmd_len, + cmd.is_controller ? "control" : "normal", + cmd.is_privileged ? "*" : "", + cmd.description); } fmt::print(stdout, - "\n* is for privileged commands that may need password (see -P option)\n"); + "\n* is for privileged commands that may need password (see -P option)\n"); fmt::print(stdout, - "control commands use port 11334 while normal use 11333 by default (see -h option)\n"); + "control commands use port 11334 while normal use 11333 by default (see -h option)\n"); } static void @@ -676,7 +676,7 @@ add_options(GQueue *opts) rspamd_inet_addr_t *addr = nullptr; if (!rspamd_parse_inet_address(&addr, ip, strlen(ip), - RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) { + RSPAMD_INET_ADDRESS_PARSE_DEFAULT)) { /* Try to resolve */ struct addrinfo hints, *res, *cur; int r; @@ -695,7 +695,7 @@ add_options(GQueue *opts) cur = res; while (cur) { addr = rspamd_inet_address_from_sa(cur->ai_addr, - cur->ai_addrlen); + cur->ai_addrlen); if (addr != nullptr) { ip = g_strdup(rspamd_inet_address_to_string(addr)); @@ -710,8 +710,8 @@ add_options(GQueue *opts) } else { fmt::print(stderr, "address resolution for {} failed: {}\n", - ip, - gai_strerror(r)); + ip, + gai_strerror(r)); } } else { @@ -809,8 +809,8 @@ add_options(GQueue *opts) } else { add_client_header(opts, - hdr_view.substr(0, std::distance(std::begin(hdr_view), delim_pos)), - hdr_view.substr(std::distance(std::begin(hdr_view), delim_pos) + 1)); + hdr_view.substr(0, std::distance(std::begin(hdr_view), delim_pos)), + hdr_view.substr(std::distance(std::begin(hdr_view), delim_pos) + 1)); } hdr++; @@ -826,23 +826,6 @@ add_options(GQueue *opts) } static void -print_indented_line(FILE *out, std::string_view line, size_t maxlen, size_t indent) -{ - if (maxlen < 1) { - return; - } - - std::string_view s; - for (size_t pos = 0; pos < line.size(); pos += s.size()) { - s = line.substr(pos, pos ? (maxlen-indent) : maxlen); - if (indent && pos) { - fmt::print(out, "{:>{}}", " ", indent); - } - fmt::print(out, "{}\n", s); - } -} - -static void rspamc_symbol_human_output(FILE *out, const ucl_object_t *obj) { auto first = true; @@ -887,7 +870,21 @@ rspamc_symbol_human_output(FILE *out, const ucl_object_t *obj) line += '\n'; } - print_indented_line(out, line, 78, 28); + auto print_indented_line = [&](size_t maxlen, size_t indent) { + if (maxlen < 1 || maxlen < indent) { + return; + } + for (size_t pos = 0; pos < line.size(); ) { + auto s = line.substr(pos, pos ? (maxlen-indent) : maxlen); + if (indent && pos) { + fmt::print(out, "{:>{}}", " ", indent); + } + fmt::print(out, "{}\n", s); + pos += s.size(); + } + }; + + print_indented_line(78, 28); } static void @@ -971,11 +968,11 @@ rspamc_metric_output(FILE *out, const ucl_object_t *obj) if (humanreport) { fmt::print(out, - "{}/{}/{}/{}", - emphasis_argument(score, 2), - emphasis_argument(greylist_score, 2), - emphasis_argument(addheader_score, 2), - emphasis_argument(required_score, 2)); + "{}/{}/{}/{}", + emphasis_argument(score, 2), + emphasis_argument(greylist_score, 2), + emphasis_argument(addheader_score, 2), + emphasis_argument(required_score, 2)); } elt = ucl_object_lookup(obj, "action"); @@ -1057,15 +1054,15 @@ rspamc_metric_output(FILE *out, const ucl_object_t *obj) } else if (got_scores == 2) { fmt::print(out, - "Score: {} / {}\n", - emphasis_argument(score, 2), - emphasis_argument(required_score, 2)); + "Score: {} / {}\n", + emphasis_argument(score, 2), + emphasis_argument(required_score, 2)); } if (humanreport) { fmt::print(out, "Content analysis details: ({} points, {} required)\n\n", - emphasis_argument(score, 2), - emphasis_argument(required_score, 2)); + emphasis_argument(score, 2), + emphasis_argument(required_score, 2)); fmt::print(out, " pts rule name description\n"); fmt::print(out, "---- ---------------------- --------------------------------------------------\n"); } @@ -1104,13 +1101,13 @@ rspamc_profile_output(FILE *out, const ucl_object_t *obj) ar.push_back(cur); } std::stable_sort(std::begin(ar), std::end(ar), - [](const ucl_object_t *u1, const ucl_object_t *u2) -> int { - return ucl_object_compare(u1, u2); - }); + [](const ucl_object_t *u1, const ucl_object_t *u2) -> int { + return ucl_object_compare(u1, u2); + }); for (const auto *cur_elt : ar) { fmt::print(out, "\t{}: {:3} usec\n", - ucl_object_key(cur_elt), ucl_object_todouble(cur_elt)); + ucl_object_key(cur_elt), ucl_object_todouble(cur_elt)); } } @@ -1144,9 +1141,13 @@ rspamc_symbols_output(FILE *out, ucl_object_t *obj) } if (humanreport) { - if (emitted && strcmp(emitted, "[]")) { - print_indented_line(out, fmt::format("Domains found: {}", emitted), 78, 4); - } + if (emitted && strcmp(emitted, "[]") != 0) { + auto folded_line = rspamd_header_value_fold("Domains found: ", sizeof("Domains found: ") - 1, + emitted, strlen(emitted), 78, + RSPAMD_TASK_NEWLINES_LF, nullptr); + fmt::print("Domains found: {}\n", folded_line->str); + g_string_free(folded_line, true); + } } else { fmt::print(out, "Urls: {}\n", emitted); @@ -1166,8 +1167,12 @@ rspamc_symbols_output(FILE *out, ucl_object_t *obj) } if (humanreport) { - if (emitted && strcmp(emitted, "[]")) { - print_indented_line(out, fmt::format("Emails found: {}", emitted), 78, 4); + if (emitted && strcmp(emitted, "[]") != 0) { + auto folded_line = rspamd_header_value_fold("Emails found: ", sizeof("Emails found: ") - 1, + emitted, strlen(emitted), 78, + RSPAMD_TASK_NEWLINES_LF, nullptr); + fmt::print("Emails found: {}\n", folded_line->str); + g_string_free(folded_line, true); } } else { @@ -1189,12 +1194,12 @@ rspamc_symbols_output(FILE *out, ucl_object_t *obj) while ((cmesg = ucl_object_iterate (elt, &mit, true)) != nullptr) { if (ucl_object_type(cmesg) == UCL_STRING) { fmt::print(out, "Message - {}: {}\n", - ucl_object_key(cmesg), ucl_object_tostring(cmesg)); + ucl_object_key(cmesg), ucl_object_tostring(cmesg)); } else { char *rendered_message; rendered_message = (char *)ucl_object_emit(cmesg, UCL_EMIT_JSON_COMPACT); fmt::print(out, "Message - {}: {:.60}\n", - ucl_object_key(cmesg), rendered_message); + ucl_object_key(cmesg), rendered_message); free(rendered_message); } } @@ -1229,7 +1234,7 @@ rspamc_uptime_output(FILE *out, ucl_object_t *obj) const auto *elt = ucl_object_lookup(obj, "version"); if (elt != nullptr) { fmt::print(out, "Rspamd version: %s\n", ucl_object_tostring( - elt)); + elt)); } elt = ucl_object_lookup(obj, "uptime"); @@ -1241,13 +1246,13 @@ rspamc_uptime_output(FILE *out, ucl_object_t *obj) hours = seconds / 3600 - days * 24; minutes = seconds / 60 - hours * 60 - days * 1440; fmt::print("{} day{} {} hour{} {} minute{}\n", days, - days > 1 ? "s" : "", hours, hours > 1 ? "s" : "", - minutes, minutes > 1 ? "s" : ""); + days > 1 ? "s" : "", hours, hours > 1 ? "s" : "", + minutes, minutes > 1 ? "s" : ""); } /* If uptime is less than 1 minute print only seconds */ else if (seconds / 60 == 0) { fmt::print("{} second%s\n", seconds, - (gint) seconds > 1 ? "s" : ""); + (gint) seconds > 1 ? "s" : ""); } /* Else print the minutes and seconds. */ else { @@ -1255,8 +1260,8 @@ rspamc_uptime_output(FILE *out, ucl_object_t *obj) minutes = seconds / 60 - hours * 60; seconds -= hours * 3600 + minutes * 60; fmt::print("{} hour {} minute{} {} second{}\n", hours, - minutes, minutes > 1 ? "s" : "", - seconds, seconds > 1 ? "s" : ""); + minutes, minutes > 1 ? "s" : "", + seconds, seconds > 1 ? "s" : ""); } } } @@ -1300,17 +1305,17 @@ rspamc_counters_output(FILE *out, ucl_object_t *obj) fmt::print(out, " {} \n", emphasis_argument(dash_buf)); fmt::print(out, - "| {:<4} | {:<{}} | {:^7} | {:^13} | {:^7} |\n", - "Pri", - "Symbol", - max_len, - "Weight", - "Frequency", - "Hits"); + "| {:<4} | {:<{}} | {:^7} | {:^13} | {:^7} |\n", + "Pri", + "Symbol", + max_len, + "Weight", + "Frequency", + "Hits"); fmt::print(out, " {} \n", emphasis_argument(dash_buf)); fmt::print(out, "| {:<4} | {:<{}} | {:^7} | {:^13} | {:^7} |\n", "", - "", max_len, - "", "hits/min", ""); + "", max_len, + "", "hits/min", ""); for (const auto [i, cur] : rspamd::enumerate(counters_vec)) { fmt::print(out, " {} \n", dash_buf); @@ -1325,7 +1330,7 @@ rspamc_counters_output(FILE *out, ucl_object_t *obj) if (sym->len > max_len) { rspamd_snprintf(sym_buf, sizeof(sym_buf), "%*s...", - (max_len - 3), ucl_object_tostring(sym)); + (max_len - 3), ucl_object_tostring(sym)); sym_name = sym_buf; } else { @@ -1333,12 +1338,12 @@ rspamc_counters_output(FILE *out, ucl_object_t *obj) } fmt::print(out, "| {:<4} | {:<{}} | {:^7.1f} | {:^6.3f}({:^5.3f}) | {:^7} |\n", i, - sym_name, - max_len, - ucl_object_todouble(weight), - ucl_object_todouble(freq) * 60.0, - ucl_object_todouble(freq_dev) * 60.0, - (std::uintmax_t)ucl_object_toint(nhits)); + sym_name, + max_len, + ucl_object_todouble(weight), + ucl_object_todouble(freq) * 60.0, + ucl_object_todouble(freq_dev) * 60.0, + (std::uintmax_t)ucl_object_toint(nhits)); } } fmt::print(out, " {} \n", dash_buf); @@ -1355,19 +1360,19 @@ rspamc_stat_actions(ucl_object_t *obj, std::string &out, std::int64_t scanned) while ((cur = ucl_object_iterate (actions, &iter, true)) != nullptr) { auto cnt = ucl_object_toint(cur); fmt::format_to(std::back_inserter(out), "Messages with action {}: {}, {:.2f}%\n", - ucl_object_key(cur), emphasis_argument(cnt), - ((double) cnt / (double) scanned) * 100.); + ucl_object_key(cur), emphasis_argument(cnt), + ((double) cnt / (double) scanned) * 100.); } } auto spam = ucl_object_toint(ucl_object_lookup(obj, "spam_count")); auto ham = ucl_object_toint(ucl_object_lookup(obj, "ham_count")); fmt::format_to(std::back_inserter(out), "Messages treated as spam: {}, {:.2f}%\n", - emphasis_argument(spam), - ((double) spam / (double) scanned) * 100.); + emphasis_argument(spam), + ((double) spam / (double) scanned) * 100.); fmt::format_to(std::back_inserter(out), "Messages treated as ham: {}, {:.2f}%\n", - emphasis_argument(ham), - ((double) ham / (double) scanned) * 100.); + emphasis_argument(ham), + ((double) ham / (double) scanned) * 100.); } } @@ -1386,18 +1391,18 @@ rspamc_stat_statfile(const ucl_object_t *obj, std::string &out) if (label) { fmt::format_to(std::back_inserter(out), "Statfile: {} <{}> type: {}; ", symbol, - label, type); + label, type); } else { fmt::format_to(std::back_inserter(out), "Statfile: {} type: {}; ", symbol, type); } fmt::format_to(std::back_inserter(out), "length: {}; free blocks: {}; total blocks: {}; " - "free: {:.2f}%; learned: {}; users: {}; languages: {}\n", - size, - blocks - used_blocks, blocks, - blocks > 0 ? (blocks - used_blocks) * 100.0 / (double) blocks : 0, - version, - nusers, nlanguages); + "free: {:.2f}%; learned: {}; users: {}; languages: {}\n", + size, + blocks - used_blocks, blocks, + blocks > 0 ? (blocks - used_blocks) * 100.0 / (double) blocks : 0, + version, + nusers, nlanguages); } static void @@ -1409,16 +1414,16 @@ rspamc_stat_output(FILE *out, ucl_object_t *obj) auto scanned = ucl_object_toint(ucl_object_lookup(obj, "scanned")); fmt::format_to(std::back_inserter(out_str), "Messages scanned: {}\n", - emphasis_argument(scanned)); + emphasis_argument(scanned)); rspamc_stat_actions(obj, out_str, scanned); fmt::format_to(std::back_inserter(out_str), "Messages learned: {}\n", - emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "learned")))); + emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "learned")))); fmt::format_to(std::back_inserter(out_str), "Connections count: {}\n", - emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "connections")))); + emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "connections")))); fmt::format_to(std::back_inserter(out_str), "Control connections count: {}\n", - emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "control_connections")))); + emphasis_argument(ucl_object_toint(ucl_object_lookup(obj, "control_connections")))); const auto *avg_time_obj = ucl_object_lookup(obj, "scan_times"); @@ -1438,26 +1443,26 @@ rspamc_stat_output(FILE *out, ucl_object_t *obj) if (cnt > 0) { auto sum = rspamd_sum_floats(nums.data(), &cnt); fmt::format_to(std::back_inserter(out_str), - "Average scan time: {} sec\n", - emphasis_argument(sum / cnt, 3)); + "Average scan time: {} sec\n", + emphasis_argument(sum / cnt, 3)); } } /* Pools */ fmt::format_to(std::back_inserter(out_str), "Pools allocated: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "pools_allocated"))); + ucl_object_toint(ucl_object_lookup(obj, "pools_allocated"))); fmt::format_to(std::back_inserter(out_str), "Pools freed: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "pools_freed"))); + ucl_object_toint(ucl_object_lookup(obj, "pools_freed"))); fmt::format_to(std::back_inserter(out_str), "Bytes allocated: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "bytes_allocated"))); + ucl_object_toint(ucl_object_lookup(obj, "bytes_allocated"))); fmt::format_to(std::back_inserter(out_str), "Memory chunks allocated: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "chunks_allocated"))); + ucl_object_toint(ucl_object_lookup(obj, "chunks_allocated"))); fmt::format_to(std::back_inserter(out_str), "Shared chunks allocated: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "shared_chunks_allocated"))); + ucl_object_toint(ucl_object_lookup(obj, "shared_chunks_allocated"))); fmt::format_to(std::back_inserter(out_str), "Chunks freed: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "chunks_freed"))); + ucl_object_toint(ucl_object_lookup(obj, "chunks_freed"))); fmt::format_to(std::back_inserter(out_str), "Oversized chunks: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "chunks_oversized"))); + ucl_object_toint(ucl_object_lookup(obj, "chunks_oversized"))); /* Fuzzy */ const auto *st = ucl_object_lookup(obj, "fuzzy_hashes"); @@ -1469,13 +1474,13 @@ rspamc_stat_output(FILE *out, ucl_object_t *obj) while ((cur = ucl_iterate_object (st, &it, true)) != nullptr) { auto num = ucl_object_toint(cur); fmt::format_to(std::back_inserter(out_str), "Fuzzy hashes in storage \"{}\": {}\n", - ucl_object_key(cur), - num); + ucl_object_key(cur), + num); stored += num; } fmt::format_to(std::back_inserter(out_str), "Fuzzy hashes stored: {}\n", - stored); + stored); } st = ucl_object_lookup(obj, "fuzzy_checked"); @@ -1516,7 +1521,7 @@ rspamc_stat_output(FILE *out, ucl_object_t *obj) } } fmt::format_to(std::back_inserter(out_str), "Total learns: {}\n", - ucl_object_toint(ucl_object_lookup(obj, "total_learns"))); + ucl_object_toint(ucl_object_lookup(obj, "total_learns"))); fmt::print(out, "{}", out_str.c_str()); } @@ -1528,7 +1533,7 @@ rspamc_output_headers(FILE *out, struct rspamd_http_message *msg) kh_foreach_value (msg->headers, h, { fmt::print(out, "{}: {}\n", std::string_view{h->name.begin, h->name.len}, - std::string_view{h->value.begin, h->value.len}); + std::string_view{h->value.begin, h->value.len}); }); fmt::print(out, "\n"); @@ -1593,9 +1598,9 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, } fmt::format_to(std::back_inserter(added_headers), "X-Spam-Scanner: {}{}", - "rspamc " RVERSION, line_end); + "rspamc " RVERSION, line_end); fmt::format_to(std::back_inserter(added_headers), "X-Spam-Scan-Time: {:.3}{}", - time, line_end); + time, line_end); /* * TODO: add milter_headers support here @@ -1605,9 +1610,9 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, } fmt::format_to(std::back_inserter(added_headers),"X-Spam-Action: {}{}", - action, line_end); + action, line_end); fmt::format_to(std::back_inserter(added_headers), "X-Spam-Score: {:.2f} / {:.2f}{}", - score, required_score, line_end); + score, required_score, line_end); /* SA style stars header */ std::string scorebuf; @@ -1618,7 +1623,7 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, } fmt::format_to(std::back_inserter(added_headers), "X-Spam-Level: {}{}", - scorebuf, line_end); + scorebuf, line_end); /* Short description of all symbols */ std::string symbuf; @@ -1637,23 +1642,23 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, } auto *folded_symbuf = rspamd_header_value_fold("X-Spam-Symbols", strlen("X-Spam-Symbols"), - symbuf.data(), symbuf.size(), - 0, nl_type, ","); + symbuf.data(), symbuf.size(), + 0, nl_type, ","); fmt::format_to(std::back_inserter(added_headers), "X-Spam-Symbols: {}{}", - folded_symbuf->str, line_end); + folded_symbuf->str, line_end); g_string_free(folded_symbuf, TRUE); res = ucl_object_lookup(result, "dkim-signature"); if (res && res->type == UCL_STRING) { fmt::format_to(std::back_inserter(added_headers), "DKIM-Signature: {}{}", - ucl_object_tostring(res), line_end); + ucl_object_tostring(res), line_end); } else if (res && res->type == UCL_ARRAY) { it = nullptr; while ((cur = ucl_object_iterate (res, &it, true)) != nullptr) { fmt::format_to(std::back_inserter(added_headers), "DKIM-Signature: {}{}", - ucl_object_tostring(cur), line_end); + ucl_object_tostring(cur), line_end); } } @@ -1662,19 +1667,19 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, /* We also append json data as a specific header */ if (json) { json_header = ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); } else { json_header = ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); } auto *json_header_encoded = rspamd_encode_base64_fold(json_header, - strlen((char *)json_header), 60, nullptr, nl_type); + strlen((char *)json_header), 60, nullptr, nl_type); free(json_header); fmt::format_to(std::back_inserter(added_headers), - "X-Spam-Result: {}{}", - json_header_encoded, line_end); + "X-Spam-Result: {}{}", + json_header_encoded, line_end); g_free(json_header_encoded); } @@ -1682,11 +1687,11 @@ rspamc_mime_output(FILE *out, ucl_object_t *result, GString *input, } else { fmt::format_to(std::back_inserter(added_headers), "X-Spam-Scanner: {}{}", - "rspamc " RVERSION, line_end); + "rspamc " RVERSION, line_end); fmt::format_to(std::back_inserter(added_headers), "X-Spam-Scan-Time: {:.3f}{}", - time, line_end); + time, line_end); fmt::format_to(std::back_inserter(added_headers), "X-Spam-Error: {}{}", - err->message, line_end); + err->message, line_end); } /* Write message */ @@ -1715,8 +1720,8 @@ rspamc_client_execute_cmd(const struct rspamc_command &cmd, ucl_object_t *result } if (!g_spawn_async_with_pipes(nullptr, eargv, nullptr, - static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD), nullptr, nullptr, &cld, - &infd, &outfd, &errfd, &exec_err)) { + static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD), nullptr, nullptr, &cld, + &infd, &outfd, &errfd, &exec_err)) { fmt::print(stderr, "Cannot execute {}: {}", execute, exec_err->message); g_error_free(exec_err); @@ -1736,11 +1741,11 @@ rspamc_client_execute_cmd(const struct rspamc_command &cmd, ucl_object_t *result if (json) { ucl_out = (char *)ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); } else { ucl_out = (char *)ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); } fmt::print(out, "{}", ucl_out); free(ucl_out); @@ -1805,13 +1810,13 @@ rspamc_client_cb(struct rspamd_client_connection *conn, if (cmd.need_input && !json) { if (!compact && !humanreport) { fmt::print(out, "Results for file: {} ({:.3} seconds)\n", - emphasis_argument(cbdata->filename), diff); + emphasis_argument(cbdata->filename), diff); } } else { if (!compact && !json && !humanreport) { fmt::print(out, "Results for command: {} ({:.3} seconds)\n", - emphasis_argument(cmd.name), diff); + emphasis_argument(cmd.name), diff); } } @@ -1822,25 +1827,25 @@ rspamc_client_cb(struct rspamd_client_connection *conn, if (ucl_reply || cmd.command_output_func == nullptr) { if (cmd.need_input) { ucl_object_insert_key(result, - ucl_object_fromstring(cbdata->filename.c_str()), - "filename", 0, - false); + ucl_object_fromstring(cbdata->filename.c_str()), + "filename", 0, + false); } ucl_object_insert_key(result, - ucl_object_fromdouble(diff), - "scan_time", 0, - false); + ucl_object_fromdouble(diff), + "scan_time", 0, + false); char *ucl_out; if (json) { ucl_out = (char *)ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_JSON); } else { ucl_out = (char *)ucl_object_emit(result, - compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); + compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); } fmt::print(out, "{}", ucl_out); @@ -1852,7 +1857,7 @@ rspamc_client_cb(struct rspamd_client_connection *conn, if (body) { fmt::print(out, "\nNew body:\n{}\n", - std::string_view{body, bodylen}); + std::string_view{body, bodylen}); } ucl_object_unref(result); @@ -1942,7 +1947,7 @@ rspamc_process_input(struct ev_loop *ev_base, const struct rspamc_command &cmd, } - conn = rspamd_client_init(http_ctx, ev_base, hostbuf.c_str(), port, timeout, key); + conn = rspamd_client_init(http_ctx, ev_base, hostbuf.c_str(), port, timeout, pubkey); if (conn != nullptr) { auto *cbdata = new rspamc_callback_data; @@ -1951,24 +1956,24 @@ rspamc_process_input(struct ev_loop *ev_base, const struct rspamc_command &cmd, if (cmd.need_input) { rspamd_client_command(conn, cmd.path, attrs, in, rspamc_client_cb, - cbdata, compressed, dictionary, cbdata->filename.c_str(), &err); + cbdata, compressed, dictionary, cbdata->filename.c_str(), &err); } else { rspamd_client_command(conn, - cmd.path, - attrs, - nullptr, - rspamc_client_cb, - cbdata, - compressed, - dictionary, - cbdata->filename.c_str(), - &err); + cmd.path, + attrs, + nullptr, + rspamc_client_cb, + cbdata, + compressed, + dictionary, + cbdata->filename.c_str(), + &err); } } else { fmt::print(stderr, "cannot connect to {}: {}\n", connect_str, - strerror(errno)); + strerror(errno)); exit(EXIT_FAILURE); } } @@ -1994,7 +1999,7 @@ rspamd_dirent_size(DIR *dirp) } # endif #else -# if defined(NAME_MAX) + # if defined(NAME_MAX) name_max = (NAME_MAX > 255) ? NAME_MAX : 255; # else # error "buffer size for readdir_r cannot be determined" @@ -2027,8 +2032,8 @@ rspamc_process_dir(struct ev_loop *ev_base, const struct rspamc_command &cmd, fpath.clear(); fmt::format_to(std::back_inserter(fpath), "{}{}{}", - name, G_DIR_SEPARATOR, - pentry->d_name); + name, G_DIR_SEPARATOR, + pentry->d_name); /* Check exclude */ auto **ex = exclude_compiled; @@ -2037,7 +2042,7 @@ rspamc_process_dir(struct ev_loop *ev_base, const struct rspamc_command &cmd, #if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 70 if (g_pattern_spec_match(*ex, fpath.size(), fpath.c_str(), nullptr)) { #else - if (g_pattern_match(*ex, fpath.size(), fpath.c_str(), nullptr)) { + if (g_pattern_match(*ex, fpath.size(), fpath.c_str(), nullptr)) { #endif skip = true; break; @@ -2059,7 +2064,7 @@ rspamc_process_dir(struct ev_loop *ev_base, const struct rspamc_command &cmd, /* Fallback to lstat */ if (lstat(fpath.c_str(), &st) == -1) { fmt::print(stderr, "cannot stat file {}: {}\n", - fpath, strerror(errno)); + fpath, strerror(errno)); continue; } @@ -2092,7 +2097,7 @@ rspamc_process_dir(struct ev_loop *ev_base, const struct rspamc_command &cmd, auto *in = fopen(fpath.c_str(), "r"); if (in == nullptr) { fmt::print(stderr, "cannot open file {}: {}\n", - fpath, strerror(errno)); + fpath, strerror(errno)); continue; } @@ -2158,7 +2163,7 @@ main(int argc, char **argv, char **env) if (exclude_compiled[i] == nullptr) { fmt::print(stderr, "Invalid glob pattern: {}\n", - exclude_patterns[i]); + exclude_patterns[i]); exit(EXIT_FAILURE); } } @@ -2173,7 +2178,7 @@ main(int argc, char **argv, char **env) http_config.kp_cache_size_server = 0; http_config.user_agent = user_agent; http_ctx = rspamd_http_context_create_config(&http_config, - event_loop, nullptr); + event_loop, nullptr); /* Ignore sigpipe */ struct sigaction sigpipe_act; @@ -2307,7 +2312,7 @@ main(int argc, char **argv, char **env) auto res = 0; if (waitpid(cld, &res, 0) == -1) { fmt::print(stderr, "Cannot wait for {}: {}", cld, - strerror(errno)); + strerror(errno)); ret = errno; } |