}
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);
}
}
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;
}
line += ']';
}
- else if (desc == nullptr) line += '\n';
+ else if (desc == nullptr) {
+ line += '\n';
+ }
print_indented_line(out, line, 78, 28);
}
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;
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));
}
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 */
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",
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
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);
}
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) {