Преглед изворни кода

[Fix] Deal with fmtlib exceptions properly

tags/3.7.2
Vsevolod Stakhov пре 8 месеци
родитељ
комит
9873ef954f
No account linked to committer's email address
1 измењених фајлова са 166 додато и 139 уклоњено
  1. 166
    139
      src/client/rspamc.cxx

+ 166
- 139
src/client/rspamc.cxx Прегледај датотеку

} }
}; };


template<typename... T>
static inline void rspamc_print(std::FILE *f, fmt::format_string<T...> fmt, T &&...args)
{
static auto try_print_exception = 1;
try {
fmt::print(f, fmt, std::forward<T>(args)...);
} catch (const fmt::format_error &err) {
if (try_print_exception) {
if (fprintf(f, "Format error: %s\n", err.what()) < 0) {
try_print_exception = 0;
}
}
} catch (std::system_error &err) {
if (try_print_exception) {
if (fprintf(f, "System error: %s\n", err.what()) < 0) {
try_print_exception = 0;
}
}
} catch (...) {
if (try_print_exception) {
if (fprintf(f, "Unknown format error\n") < 0) {
try_print_exception = 0;
}
}
}
}

using sort_lambda = std::function<int(const ucl_object_t *, const ucl_object_t *)>; 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>({ 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 { {"name", [](const ucl_object_t *o1, const ucl_object_t *o2) -> int {
processed_passwd.resize(plen, '\0'); processed_passwd.resize(plen, '\0');
plen = rspamd_read_passphrase(processed_passwd.data(), plen, 0, nullptr); plen = rspamd_read_passphrase(processed_passwd.data(), plen, 0, nullptr);
if (plen == 0) { if (plen == 0) {
fmt::print(stderr, "Invalid password\n");
rspamc_print(stderr, "Invalid password\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
processed_passwd.resize(plen); processed_passwd.resize(plen);


/* Parse options */ /* Parse options */
if (!g_option_context_parse(context, argc, argv, &error)) { if (!g_option_context_parse(context, argc, argv, &error)) {
fmt::print(stderr, "option parsing failed: {}\n", error->message);
rspamc_print(stderr, "option parsing failed: {}\n", error->message);
g_option_context_free(context); g_option_context_free(context);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
{ {
guint cmd_len = 0; guint cmd_len = 0;


fmt::print(stdout, "Rspamc commands summary:\n");
rspamc_print(stdout, "Rspamc commands summary:\n");


for (const auto &cmd: rspamc_commands) { for (const auto &cmd: rspamc_commands) {
auto clen = strlen(cmd.name); auto clen = strlen(cmd.name);
} }


for (const auto &cmd: rspamc_commands) { 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);
}
fmt::print(stdout,
"\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");
rspamc_print(stdout,
" {:>{}} ({:7}{:1})\t{}\n",
cmd.name,
cmd_len,
cmd.is_controller ? "control" : "normal",
cmd.is_privileged ? "*" : "",
cmd.description);
}
rspamc_print(stdout,
"\n* is for privileged commands that may need password (see -P option)\n");
rspamc_print(stdout,
"control commands use port 11334 while normal use 11333 by default (see -h option)\n");
} }


static void static void
freeaddrinfo(res); freeaddrinfo(res);
} }
else { else {
fmt::print(stderr, "address resolution for {} failed: {}\n",
ip,
gai_strerror(r));
rspamc_print(stderr, "address resolution for {} failed: {}\n",
ip,
gai_strerror(r));
} }
} }
else { else {
} }
} }
if (indent && pos) { if (indent && pos) {
fmt::print(out, "{:>{}}", " ", indent);
rspamc_print(out, "{:>{}}", " ", indent);
} }
fmt::print(out, "{}\n", s);
rspamc_print(out, "{}\n", s);
pos = line.find_first_not_of(whitespace, pos + s.size());//skip leading whitespace pos = line.find_first_not_of(whitespace, pos + s.size());//skip leading whitespace
} }
} }
{ {
auto first = true; auto first = true;


fmt::print(out, "Symbol: {} ", ucl_object_key(obj));
rspamc_print(out, "Symbol: {} ", ucl_object_key(obj));
const auto *val = ucl_object_lookup(obj, "score"); const auto *val = ucl_object_lookup(obj, "score");


if (val != nullptr) { if (val != nullptr) {
fmt::print(out, "({:.2f})", ucl_object_todouble(val));
rspamc_print(out, "({:.2f})", ucl_object_todouble(val));
} }
val = ucl_object_lookup(obj, "options"); val = ucl_object_lookup(obj, "options");
if (val != nullptr && ucl_object_type(val) == UCL_ARRAY) { if (val != nullptr && ucl_object_type(val) == UCL_ARRAY) {
ucl_object_iter_t it = nullptr; ucl_object_iter_t it = nullptr;
const ucl_object_t *cur; const ucl_object_t *cur;


fmt::print(out, "[");
rspamc_print(out, "[");


while ((cur = ucl_object_iterate(val, &it, true)) != nullptr) { while ((cur = ucl_object_iterate(val, &it, true)) != nullptr) {
if (first) { if (first) {
fmt::print(out, "{}", ucl_object_tostring(cur));
rspamc_print(out, "{}", ucl_object_tostring(cur));
first = false; first = false;
} }
else { else {
fmt::print(out, ", {}", ucl_object_tostring(cur));
rspamc_print(out, ", {}", ucl_object_tostring(cur));
} }
} }
fmt::print(out, "]");
rspamc_print(out, "]");
} }
fmt::print(out, "\n");
rspamc_print(out, "\n");
} }


static void static void
auto *elt = ucl_object_lookup(obj, ucl_name); auto *elt = ucl_object_lookup(obj, ucl_name);
if (elt) { if (elt) {
if (humanreport) { if (humanreport) {
fmt::print(out, ",{}={}", output_message, emphasis_argument(ucl_object_tostring(elt)));
rspamc_print(out, ",{}={}", output_message, emphasis_argument(ucl_object_tostring(elt)));
} }
else { else {
fmt::print(out, "{}: {}\n", output_message, emphasis_argument(ucl_object_tostring(elt)));
rspamc_print(out, "{}: {}\n", output_message, emphasis_argument(ucl_object_tostring(elt)));
} }
} }
}; };


if (!humanreport) { if (!humanreport) {
fmt::print(out, "[Metric: default]\n");
rspamc_print(out, "[Metric: default]\n");
} }


const auto *elt = ucl_object_lookup(obj, "required_score"); const auto *elt = ucl_object_lookup(obj, "required_score");




if (humanreport) { if (humanreport) {
fmt::print(out,
"{}/{}/{}/{}",
emphasis_argument(score, 2),
emphasis_argument(greylist_score, 2),
emphasis_argument(addheader_score, 2),
emphasis_argument(required_score, 2));
rspamc_print(out,
"{}/{}/{}/{}",
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"); elt = ucl_object_lookup(obj, "action");
if (act.has_value()) { if (act.has_value()) {
if (!tty) { if (!tty) {
if (humanreport) { if (humanreport) {
fmt::print(out, ",action={}:{}", act.value(), ucl_object_tostring(elt));
rspamc_print(out, ",action={}:{}", act.value(), ucl_object_tostring(elt));
} }
else { else {
print_protocol_string("action", "Action"); print_protocol_string("action", "Action");
} }


if (humanreport) { if (humanreport) {
fmt::print(out, ",action={}:{}", act.value(), colorized_action);
rspamc_print(out, ",action={}:{}", act.value(), colorized_action);
} }
else { else {
fmt::print(out, "Action: {}\n", colorized_action);
rspamc_print(out, "Action: {}\n", colorized_action);
} }
} }


is_spam = act.value() < METRIC_ACTION_GREYLIST ? true : false; is_spam = act.value() < METRIC_ACTION_GREYLIST ? true : false;
if (!humanreport) { if (!humanreport) {
fmt::print(out, "Spam: {}\n", is_spam ? "true" : "false");
rspamc_print(out, "Spam: {}\n", is_spam ? "true" : "false");
} }
} }
else { else {
if (humanreport) { if (humanreport) {
fmt::print(out, ",action={}:{}", METRIC_ACTION_NOACTION, ucl_object_tostring(elt));
rspamc_print(out, ",action={}:{}", METRIC_ACTION_NOACTION, ucl_object_tostring(elt));
} }
else { else {
print_protocol_string("action", "Action"); print_protocol_string("action", "Action");
is_skipped = 1; is_skipped = 1;
} }


fmt::print(out, ",spam={},skipped={}\n", is_spam ? 1 : 0, is_skipped);
rspamc_print(out, ",spam={},skipped={}\n", is_spam ? 1 : 0, is_skipped);
} }
else if (got_scores == 2) { else if (got_scores == 2) {
fmt::print(out,
"Score: {} / {}\n",
emphasis_argument(score, 2),
emphasis_argument(required_score, 2));
rspamc_print(out,
"Score: {} / {}\n",
emphasis_argument(score, 2),
emphasis_argument(required_score, 2));
} }


if (humanreport) { if (humanreport) {
fmt::print(out, "Content analysis details: ({} points, {} required)\n\n",
emphasis_argument(score, 2),
emphasis_argument(addheader_score, 2));
fmt::print(out, " pts rule name description\n");
fmt::print(out, "---- ---------------------- --------------------------------------------------\n");
rspamc_print(out, "Content analysis details: ({} points, {} required)\n\n",
emphasis_argument(score, 2),
emphasis_argument(addheader_score, 2));
rspamc_print(out, " pts rule name description\n");
rspamc_print(out, "---- ---------------------- --------------------------------------------------\n");
} }


elt = ucl_object_lookup(obj, "symbols"); elt = ucl_object_lookup(obj, "symbols");
} }
} }
if (humanreport) { if (humanreport) {
fmt::print(out, "\n");
rspamc_print(out, "\n");
} }
} }


}); });


for (const auto *cur_elt: ar) { for (const auto *cur_elt: ar) {
fmt::print(out, "\t{}: {:3} usec\n",
ucl_object_key(cur_elt), ucl_object_todouble(cur_elt));
rspamc_print(out, "\t{}: {:3} usec\n",
ucl_object_key(cur_elt), ucl_object_todouble(cur_elt));
} }
} }


auto print_protocol_string = [&](const char *ucl_name, const char *output_message) { auto print_protocol_string = [&](const char *ucl_name, const char *output_message) {
auto *elt = ucl_object_lookup(obj, ucl_name); auto *elt = ucl_object_lookup(obj, ucl_name);
if (elt) { if (elt) {
fmt::print(out, "{}: {}\n", output_message, ucl_object_tostring(elt));
rspamc_print(out, "{}: {}\n", output_message, ucl_object_tostring(elt));
} }
}; };


} }
} }
else { else {
fmt::print(out, "Urls: {}\n", emitted);
rspamc_print(out, "Urls: {}\n", emitted);
} }
free(emitted); free(emitted);
} }
} }
} }
else { else {
fmt::print(out, "Emails: {}\n", emitted);
rspamc_print(out, "Emails: {}\n", emitted);
} }
free(emitted); free(emitted);
} }


while ((cmesg = ucl_object_iterate(elt, &mit, true)) != nullptr) { while ((cmesg = ucl_object_iterate(elt, &mit, true)) != nullptr) {
if (ucl_object_type(cmesg) == UCL_STRING) { if (ucl_object_type(cmesg) == UCL_STRING) {
fmt::print(out, "Message - {}: {}\n",
ucl_object_key(cmesg), ucl_object_tostring(cmesg));
rspamc_print(out, "Message - {}: {}\n",
ucl_object_key(cmesg), ucl_object_tostring(cmesg));
} }
else { else {
char *rendered_message; char *rendered_message;
rendered_message = (char *) ucl_object_emit(cmesg, UCL_EMIT_JSON_COMPACT); rendered_message = (char *) ucl_object_emit(cmesg, UCL_EMIT_JSON_COMPACT);
fmt::print(out, "Message - {}: {:.60}\n",
ucl_object_key(cmesg), rendered_message);
rspamc_print(out, "Message - {}: {:.60}\n",
ucl_object_key(cmesg), rendered_message);
free(rendered_message); free(rendered_message);
} }
} }


elt = ucl_object_lookup(obj, "dkim-signature"); elt = ucl_object_lookup(obj, "dkim-signature");
if (elt && elt->type == UCL_STRING) { if (elt && elt->type == UCL_STRING) {
fmt::print(out, "DKIM-Signature: {}\n", ucl_object_tostring(elt));
rspamc_print(out, "DKIM-Signature: {}\n", ucl_object_tostring(elt));
} }
else if (elt && elt->type == UCL_ARRAY) { else if (elt && elt->type == UCL_ARRAY) {
ucl_object_iter_t it = nullptr; ucl_object_iter_t it = nullptr;
const ucl_object_t *cur; const ucl_object_t *cur;


while ((cur = ucl_object_iterate(elt, &it, true)) != nullptr) { while ((cur = ucl_object_iterate(elt, &it, true)) != nullptr) {
fmt::print(out, "DKIM-Signature: {}\n", ucl_object_tostring(cur));
rspamc_print(out, "DKIM-Signature: {}\n", ucl_object_tostring(cur));
} }
} }


elt = ucl_object_lookup(obj, "profile"); elt = ucl_object_lookup(obj, "profile");


if (elt) { if (elt) {
fmt::print(out, "Profile data:\n");
rspamc_print(out, "Profile data:\n");
rspamc_profile_output(out, elt); rspamc_profile_output(out, elt);
} }
} }


const auto *elt = ucl_object_lookup(obj, "version"); const auto *elt = ucl_object_lookup(obj, "version");
if (elt != nullptr) { if (elt != nullptr) {
fmt::print(out, "Rspamd version: {}\n", ucl_object_tostring(elt));
rspamc_print(out, "Rspamd version: {}\n", ucl_object_tostring(elt));
} }


elt = ucl_object_lookup(obj, "uptime"); elt = ucl_object_lookup(obj, "uptime");
if (elt != nullptr) { if (elt != nullptr) {
fmt::print("Uptime: ");
rspamc_print(out, "Uptime: ");
seconds = ucl_object_toint(elt); seconds = ucl_object_toint(elt);
if (seconds >= 2 * 3600) { if (seconds >= 2 * 3600) {
days = seconds / 86400; days = seconds / 86400;
hours = seconds / 3600 - days * 24; hours = seconds / 3600 - days * 24;
minutes = seconds / 60 - hours * 60 - days * 1440; 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" : "");
rspamc_print(out, "{} day{} {} hour{} {} minute{}\n", days,
days > 1 ? "s" : "", hours, hours > 1 ? "s" : "",
minutes, minutes > 1 ? "s" : "");
} }
/* If uptime is less than 1 minute print only seconds */ /* If uptime is less than 1 minute print only seconds */
else if (seconds / 60 == 0) { else if (seconds / 60 == 0) {
fmt::print("{} second{}\n", seconds,
seconds > 1 ? "s" : "");
rspamc_print(out, "{} second{}\n", seconds,
seconds > 1 ? "s" : "");
} }
/* Else print the minutes and seconds. */ /* Else print the minutes and seconds. */
else { else {
hours = seconds / 3600; hours = seconds / 3600;
minutes = seconds / 60 - hours * 60; minutes = seconds / 60 - hours * 60;
seconds -= hours * 3600 + minutes * 60; seconds -= hours * 3600 + minutes * 60;
fmt::print("{} hour {} minute{} {} second{}\n", hours,
minutes, minutes > 1 ? "s" : "",
seconds, seconds > 1 ? "s" : "");
rspamc_print(out, "{} hour {} minute{} {} second{}\n", hours,
minutes, minutes > 1 ? "s" : "",
seconds, seconds > 1 ? "s" : "");
} }
} }
} }
rspamc_counters_output(FILE *out, ucl_object_t *obj) rspamc_counters_output(FILE *out, ucl_object_t *obj)
{ {
if (obj->type != UCL_ARRAY) { if (obj->type != UCL_ARRAY) {
fmt::print(out, "Bad output\n");
rspamc_print(out, "Bad output\n");
return; return;
} }


memset(dash_buf, '-', dashes + max_len); memset(dash_buf, '-', dashes + max_len);
dash_buf[dashes + max_len] = '\0'; dash_buf[dashes + max_len] = '\0';


fmt::print(out, "Symbols cache\n");
fmt::print(out, " {} \n", emphasis_argument(dash_buf));
fmt::print(out,
"| {:<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", "");
rspamc_print(out, "Symbols cache\n");
rspamc_print(out, " {} \n", emphasis_argument(dash_buf));
rspamc_print(out,
"| {:<4} | {:<{}} | {:^7} | {:^13} | {:^7} |\n",
"Pri",
"Symbol",
max_len,
"Weight",
"Frequency",
"Hits");
rspamc_print(out, " {} \n", emphasis_argument(dash_buf));
rspamc_print(out, "| {:<4} | {:<{}} | {:^7} | {:^13} | {:^7} |\n", "",
"", max_len,
"", "hits/min", "");


for (const auto [i, cur]: rspamd::enumerate(counters_vec)) { for (const auto [i, cur]: rspamd::enumerate(counters_vec)) {
fmt::print(out, " {} \n", dash_buf);
rspamc_print(out, " {} \n", dash_buf);
const auto *sym = ucl_object_lookup(cur, "symbol"); const auto *sym = ucl_object_lookup(cur, "symbol");
const auto *weight = ucl_object_lookup(cur, "weight"); const auto *weight = ucl_object_lookup(cur, "weight");
const auto *freq = ucl_object_lookup(cur, "frequency"); const auto *freq = ucl_object_lookup(cur, "frequency");
sym_name = ucl_object_tostring(sym); sym_name = ucl_object_tostring(sym);
} }


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));
rspamc_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));
} }
} }
fmt::print(out, " {} \n", dash_buf);
rspamc_print(out, " {} \n", dash_buf);
} }


static void static void
fmt::format_to(std::back_inserter(out_str), "Total learns: {}\n", 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());
rspamc_print(out, "{}", out_str.c_str());
} }


static void static void
struct rspamd_http_header *h; struct rspamd_http_header *h;


kh_foreach_value(msg->headers, h, { 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});
rspamc_print(out, "{}: {}\n", std::string_view{h->name.begin, h->name.len},
std::string_view{h->value.begin, h->value.len});
}); });


fmt::print(out, "\n");
rspamc_print(out, "\n");
} }


static void static void
auto headers_pos = rspamd_string_find_eoh(input, nullptr); auto headers_pos = rspamd_string_find_eoh(input, nullptr);


if (headers_pos == -1) { if (headers_pos == -1) {
fmt::print(stderr, "cannot find end of headers position");
rspamc_print(stderr, "cannot find end of headers position");
return; return;
} }




/* Write message */ /* Write message */
/* Original headers */ /* Original headers */
fmt::print(out, "{}", std::string_view{input->str, (std::size_t) headers_pos});
rspamc_print(out, "{}", std::string_view{input->str, (std::size_t) headers_pos});
/* Added headers */ /* Added headers */
fmt::print(out, "{}", added_headers);
rspamc_print(out, "{}", added_headers);
/* Message body */ /* Message body */
fmt::print(out, "{}", input->str + headers_pos);
rspamc_print(out, "{}", input->str + headers_pos);
} }


static void static void
GPid cld; GPid cld;


if (!g_shell_parse_argv(execute, &eargc, &eargv, &err)) { if (!g_shell_parse_argv(execute, &eargc, &eargv, &err)) {
fmt::print(stderr, "Cannot execute {}: {}", execute, err->message);
rspamc_print(stderr, "Cannot execute {}: {}", execute, err->message);
g_error_free(err); g_error_free(err);


return; return;
static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD), nullptr, nullptr, &cld, static_cast<GSpawnFlags>(G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD), nullptr, nullptr, &cld,
&infd, &outfd, &errfd, &exec_err)) { &infd, &outfd, &errfd, &exec_err)) {


fmt::print(stderr, "Cannot execute {}: {}", execute, exec_err->message);
rspamc_print(stderr, "Cannot execute {}: {}", execute, exec_err->message);
g_error_free(exec_err); g_error_free(exec_err);


exit(EXIT_FAILURE); exit(EXIT_FAILURE);
ucl_out = (char *) ucl_object_emit(result, 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);
rspamc_print(out, "{}", ucl_out);
free(ucl_out); free(ucl_out);
} }
else { else {
ucl_object_unref(result); ucl_object_unref(result);
} }
else { else {
fmt::print(out, "{}\n", err->message);
rspamc_print(out, "{}\n", err->message);
} }


fflush(out); fflush(out);
else { else {
if (cmd.need_input && !json) { if (cmd.need_input && !json) {
if (!compact && !humanreport) { if (!compact && !humanreport) {
fmt::print(out, "Results for file: {} ({:.3} seconds)\n",
emphasis_argument(cbdata->filename), diff);
rspamc_print(out, "Results for file: {} ({:.3} seconds)\n",
emphasis_argument(cbdata->filename), diff);
} }
} }
else { else {
if (!compact && !json && !humanreport) { if (!compact && !json && !humanreport) {
fmt::print(out, "Results for command: {} ({:.3} seconds)\n",
emphasis_argument(cmd.name), diff);
rspamc_print(out, "Results for command: {} ({:.3} seconds)\n",
emphasis_argument(cmd.name), diff);
} }
} }


compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG); compact ? UCL_EMIT_JSON_COMPACT : UCL_EMIT_CONFIG);
} }


fmt::print(out, "{}", ucl_out);
rspamc_print(out, "{}", ucl_out);
free(ucl_out); free(ucl_out);
} }
else { else {
} }


if (body) { if (body) {
fmt::print(out, "\nNew body:\n{}\n",
std::string_view{body, bodylen});
rspamc_print(out, "\nNew body:\n{}\n",
std::string_view{body, bodylen});
} }


ucl_object_unref(result); ucl_object_unref(result);
} }
else if (err != nullptr) { else if (err != nullptr) {
fmt::print(out, "{}\n", err->message);
rspamc_print(out, "{}\n", err->message);


if (json && msg != nullptr) { if (json && msg != nullptr) {
gsize rawlen; gsize rawlen;


if (raw_body) { if (raw_body) {
/* We can also output the resulting json */ /* We can also output the resulting json */
fmt::print(out, "{}\n", std::string_view{raw_body, (std::size_t)(rawlen - bodylen)});
rspamc_print(out, "{}\n", std::string_view{raw_body, (std::size_t)(rawlen - bodylen)});
} }
} }
} }
fmt::print(out, "\n");
rspamc_print(out, "\n");
} }


fflush(out); fflush(out);
} }
} }
else { else {
fmt::print(stderr, "cannot connect to {}: {}\n", connect_str,
strerror(errno));
rspamc_print(stderr, "cannot connect to {}: {}\n", connect_str,
strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
if (pentry->d_type == DT_UNKNOWN) { if (pentry->d_type == DT_UNKNOWN) {
/* Fallback to lstat */ /* Fallback to lstat */
if (lstat(fpath.c_str(), &st) == -1) { if (lstat(fpath.c_str(), &st) == -1) {
fmt::print(stderr, "cannot stat file {}: {}\n",
fpath, strerror(errno));
rspamc_print(stderr, "cannot stat file {}: {}\n",
fpath, strerror(errno));
continue; continue;
} }


} }
#else #else
if (lstat(fpath.c_str(), &st) == -1) { if (lstat(fpath.c_str(), &st) == -1) {
fmt::print(stderr, "cannot stat file {}: {}\n",
fpath, strerror(errno));
rspamc_print(stderr, "cannot stat file {}: {}\n",
fpath, strerror(errno));
continue; continue;
} }


else if (is_reg) { else if (is_reg) {
auto *in = fopen(fpath.c_str(), "r"); auto *in = fopen(fpath.c_str(), "r");
if (in == nullptr) { if (in == nullptr) {
fmt::print(stderr, "cannot open file {}: {}\n",
fpath, strerror(errno));
rspamc_print(stderr, "cannot open file {}: {}\n",
fpath, strerror(errno));
continue; continue;
} }


} }
} }
else { else {
fmt::print(stderr, "cannot open directory {}: {}\n", name, strerror(errno));
rspamc_print(stderr, "cannot open directory {}: {}\n", name, strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }


exclude_compiled[i] = g_pattern_spec_new(exclude_patterns[i]); exclude_compiled[i] = g_pattern_spec_new(exclude_patterns[i]);


if (exclude_compiled[i] == nullptr) { if (exclude_compiled[i] == nullptr) {
fmt::print(stderr, "Invalid glob pattern: {}\n",
exclude_patterns[i]);
rspamc_print(stderr, "Invalid glob pattern: {}\n",
exclude_patterns[i]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
/* In case of command read arguments starting from 2 */ /* In case of command read arguments starting from 2 */
if (cmd.cmd == RSPAMC_COMMAND_ADD_SYMBOL || cmd.cmd == RSPAMC_COMMAND_ADD_ACTION) { if (cmd.cmd == RSPAMC_COMMAND_ADD_SYMBOL || cmd.cmd == RSPAMC_COMMAND_ADD_ACTION) {
if (argc < 4 || argc > 5) { if (argc < 4 || argc > 5) {
fmt::print(stderr, "invalid arguments\n");
rspamc_print(stderr, "invalid arguments\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (argc == 5) { if (argc == 5) {
} }


if (!maybe_cmd.has_value()) { if (!maybe_cmd.has_value()) {
fmt::print(stderr, "invalid command\n");
rspamc_print(stderr, "invalid command\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }


struct stat st; struct stat st;


if (stat(argv[i], &st) == -1) { if (stat(argv[i], &st) == -1) {
fmt::print(stderr, "cannot stat file {}\n", argv[i]);
rspamc_print(stderr, "cannot stat file {}\n", argv[i]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (S_ISDIR(st.st_mode)) { if (S_ISDIR(st.st_mode)) {
else { else {
in = fopen(argv[i], "r"); in = fopen(argv[i], "r");
if (in == nullptr) { if (in == nullptr) {
fmt::print(stderr, "cannot open file {}\n", argv[i]);
rspamc_print(stderr, "cannot open file {}\n", argv[i]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
rspamc_process_input(event_loop, cmd, in, argv[i], kwattrs); rspamc_process_input(event_loop, cmd, in, argv[i], kwattrs);
for (auto cld: children) { for (auto cld: children) {
auto res = 0; auto res = 0;
if (waitpid(cld, &res, 0) == -1) { if (waitpid(cld, &res, 0) == -1) {
fmt::print(stderr, "Cannot wait for {}: {}", cld,
strerror(errno));
rspamc_print(stderr, "Cannot wait for {}: {}", cld,
strerror(errno));


ret = errno; ret = errno;
} }

Loading…
Откажи
Сачувај