diff options
author | Amish <contact@via.aur> | 2023-01-21 16:10:21 +0530 |
---|---|---|
committer | Amish <contact@via.aur> | 2023-01-21 16:10:21 +0530 |
commit | 42e1c8d507f72adc2a7390ac4baf1248067cf40b (patch) | |
tree | 677ca0096b15afe8aeca74bc0e0ec719ea38db3c | |
parent | 0df00b6af6775d67d92b15f71b9a485297deeb80 (diff) | |
download | rspamd-42e1c8d507f72adc2a7390ac4baf1248067cf40b.tar.gz rspamd-42e1c8d507f72adc2a7390ac4baf1248067cf40b.zip |
rspamc: add action number in first line and improve code
-rw-r--r-- | doc/rspamc.1 | 10 | ||||
-rw-r--r-- | doc/rspamc.1.md | 3 | ||||
-rw-r--r-- | src/client/rspamc.cxx | 152 |
3 files changed, 127 insertions, 38 deletions
diff --git a/doc/rspamc.1 b/doc/rspamc.1 index 8989f98b2..0f823e64b 100644 --- a/doc/rspamc.1 +++ b/doc/rspamc.1 @@ -150,7 +150,15 @@ Bind to specified ip address .RE .TP .B \-R, \-\-human -Output human readable report +Output human readable report. +The first line of the output contains the message score and three +threshold scores, in this format: +.IP +.nf +\f[C] + score/greylist/addheader/reject,action=N:ACTION,spam=0|1,skipped=0|1 +\f[] +.fi .RS .RE .TP diff --git a/doc/rspamc.1.md b/doc/rspamc.1.md index c6baa939c..335c22513 100644 --- a/doc/rspamc.1.md +++ b/doc/rspamc.1.md @@ -87,7 +87,8 @@ requires input. : Bind to specified ip address -R, \--human -: Output human readable report +: Output human readable report. The first line of the output contains the message score and three threshold scores, in this format: +: score/greylist/addheader/reject,action=N:ACTION,spam=0|1,skipped=0|1 -j, \--json : Output formatted JSON diff --git a/src/client/rspamc.cxx b/src/client/rspamc.cxx index 57505cf66..5bb75ef38 100644 --- a/src/client/rspamc.cxx +++ b/src/client/rspamc.cxx @@ -826,14 +826,18 @@ add_options(GQueue *opts) } static void -print_indented_line(FILE *out, std::string line, size_t maxlen, size_t indent) +print_indented_line(FILE *out, std::string_view line, size_t maxlen, size_t indent) { - if (maxlen < 1) return; + if (maxlen < 1) { + return; + } - std::string s; - for (size_t pos = 0; pos < line.length(); pos += s.length()) { + 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); + if (indent && pos) { + fmt::print(out, "{:>{}}", " ", indent); + } fmt::print(out, "{}\n", s); } } @@ -842,21 +846,27 @@ static void rspamc_symbol_human_output(FILE *out, const ucl_object_t *obj) { auto first = true; - double score = 0; - const char *key = nullptr, *desc = nullptr; + auto score = 0.0; + const char *desc = nullptr; + const auto *key = ucl_object_key(obj); const auto *val = ucl_object_lookup(obj, "score"); - if (val != nullptr) score = ucl_object_todouble(val); + if (val != nullptr) { + score = ucl_object_todouble(val); + } - key = ucl_object_key(obj); val = ucl_object_lookup(obj, "description"); - if (val != nullptr) desc = ucl_object_tostring(val); + if (val != nullptr) { + desc = ucl_object_tostring(val); + } - std::string line = fmt::format("{:>4.1f} {:<22} ", score, key); - if (desc != nullptr) line += desc; + auto line = fmt::format("{:>4.1f} {:<22} ", score, key); + if (desc != nullptr) { + line += desc; + } val = ucl_object_lookup(obj, "options"); - if (val != nullptr && val->type == UCL_ARRAY) { + if (val != nullptr && ucl_object_type(val) == UCL_ARRAY) { ucl_object_iter_t it = nullptr; const ucl_object_t *cur; @@ -873,7 +883,9 @@ rspamc_symbol_human_output(FILE *out, const ucl_object_t *obj) } line += ']'; } - else if (desc == nullptr) line += '\n'; + else if (desc == nullptr) { + line += '\n'; + } print_indented_line(out, line, 78, 28); } @@ -890,7 +902,7 @@ rspamc_symbol_output(FILE *out, const ucl_object_t *obj) fmt::print(out, "({:.2f})", ucl_object_todouble(val)); } val = ucl_object_lookup(obj, "options"); - if (val != nullptr && val->type == UCL_ARRAY) { + if (val != nullptr && ucl_object_type(val) == UCL_ARRAY) { ucl_object_iter_t it = nullptr; const ucl_object_t *cur; @@ -913,37 +925,56 @@ rspamc_symbol_output(FILE *out, const ucl_object_t *obj) static void rspamc_metric_output(FILE *out, const ucl_object_t *obj) { - double score = 0, required_score = 0; int got_scores = 0; + bool is_spam = false, is_skipped = false; + double score = 0, required_score = 0, greylist_score =0, addheader_score = 0; auto print_protocol_string = [&](const char *ucl_name, const char *output_message) { auto *elt = ucl_object_lookup(obj, ucl_name); if (elt) { - fmt::print(out, fmt::runtime(humanreport ? ",{}={}" : "{}: {}\n"), output_message, - emphasis_argument(ucl_object_tostring(elt))); + if (humanreport) { + fmt::print(out, ",{}={}", output_message, emphasis_argument(ucl_object_tostring(elt))); + } + else { + fmt::print(out, "{}: {}\n", output_message, emphasis_argument(ucl_object_tostring(elt))); + } } }; - if (!humanreport) fmt::print(out, "[Metric: default]\n"); + if (!humanreport) { + fmt::print(out, "[Metric: default]\n"); + } const auto *elt = ucl_object_lookup(obj, "required_score"); - if (elt) { required_score = ucl_object_todouble(elt); got_scores++; } elt = ucl_object_lookup(obj, "score"); - if (elt) { score = ucl_object_todouble(elt); got_scores++; } + /* XXX: greylist_score is not yet in checkv2 */ + elt = ucl_object_lookup(obj, "greylist_score"); + if (elt) { + greylist_score = ucl_object_todouble(elt); + } + + /* XXX: addheader_score is not yet in checkv2 */ + elt = ucl_object_lookup(obj, "addheader_score"); + if (elt) { + addheader_score = ucl_object_todouble(elt); + } + if (humanreport) { fmt::print(out, - "{}/{}", + "{}/{}/{}/{}", emphasis_argument(score, 2), + emphasis_argument(greylist_score, 2), + emphasis_argument(addheader_score, 2), emphasis_argument(required_score, 2)); } @@ -953,7 +984,12 @@ rspamc_metric_output(FILE *out, const ucl_object_t *obj) if (act.has_value()) { if (!tty) { - print_protocol_string("action", "Action"); + if (humanreport) { + fmt::print(out, ",action={}:{}", act.value(), ucl_object_tostring(elt)); + } + else { + print_protocol_string("action", "Action"); + } } else { /* Colorize action type */ @@ -977,21 +1013,48 @@ rspamc_metric_output(FILE *out, const ucl_object_t *obj) colorized_action = fmt::format(fmt::emphasis::bold, ucl_object_tostring(elt)); break; } - fmt::print(out, fmt::runtime(humanreport ? ",Action={}" : "Action: {}\n"), colorized_action); + + if (humanreport) { + fmt::print(out, ",action={}:{}", act.value(), colorized_action); + } + else { + fmt::print(out, "Action: {}\n", colorized_action); + } } - fmt::print(out, fmt::runtime(humanreport ? ",Spam={}" : "Spam: {}\n"), - emphasis_argument(act.value() < METRIC_ACTION_GREYLIST ? - "true" : "false")); + is_spam = act.value() < METRIC_ACTION_GREYLIST ? true : false; + if (!humanreport) { + fmt::print(out, "Spam: {}\n", is_spam ? "true" : "false"); + } } else { - print_protocol_string("action", "Action"); + if (humanreport) { + fmt::print(out, ",action={}:{}", METRIC_ACTION_NOACTION, ucl_object_tostring(elt)); + } + else { + print_protocol_string("action", "Action"); + } } } - if (!humanreport) print_protocol_string("subject", "Subject"); + if (!humanreport) { + print_protocol_string("subject", "Subject"); + } + + if (humanreport) { + /* XXX: why checkv2 does not provide "is_spam"? */ + elt = ucl_object_lookup(obj, "is_spam"); + if (elt) { + is_spam = ucl_object_toboolean(elt); + } + + elt = ucl_object_lookup(obj, "is_skipped"); + if (elt) { + is_skipped = ucl_object_toboolean(elt); + } - if (humanreport) fmt::print(out, "\n"); + fmt::print(out, ",spam={},skipped={}\n", is_spam ? 1 : 0, is_skipped ? 1 : 0); + } else if (got_scores == 2) { fmt::print(out, "Score: {} / {}\n", @@ -1021,11 +1084,12 @@ rspamc_metric_output(FILE *out, const ucl_object_t *obj) sort_ucl_container_with_default(symbols, "name"); for (const auto *sym_obj : symbols) { - if (humanreport) rspamc_symbol_human_output(out, sym_obj); - else rspamc_symbol_output(out, sym_obj); + humanreport ? rspamc_symbol_human_output(out, sym_obj) : rspamc_symbol_output(out, sym_obj); } } - if (humanreport) fmt::print(out, "\n"); + if (humanreport) { + fmt::print(out, "\n"); + } } static void @@ -1079,7 +1143,14 @@ rspamc_symbols_output(FILE *out, ucl_object_t *obj) emitted = (char *)ucl_object_emit(elt, UCL_EMIT_JSON); } - if (emitted && strcmp(emitted, "[]")) fmt::print(out, "Urls: {}\n", emitted); + if (humanreport) { + if (emitted && strcmp(emitted, "[]")) { + print_indented_line(out, fmt::format("Domains found: {}", emitted), 78, 4); + } + } + else { + fmt::print(out, "Urls: {}\n", emitted); + } free(emitted); } @@ -1094,12 +1165,21 @@ rspamc_symbols_output(FILE *out, ucl_object_t *obj) emitted = (char *)ucl_object_emit(elt, UCL_EMIT_JSON); } - if (emitted && strcmp(emitted, "[]")) fmt::print(out, "Emails: {}\n", emitted); + if (humanreport) { + if (emitted && strcmp(emitted, "[]")) { + print_indented_line(out, fmt::format("Emails found: {}", emitted), 78, 4); + } + } + else { + fmt::print(out, "Emails: {}\n", emitted); + } free(emitted); } print_protocol_string("error", "Scan error"); - if (humanreport) return; + if (humanreport) { + return; + } elt = ucl_object_lookup(obj, "messages"); if (elt && elt->type == UCL_OBJECT) { |