From: Alberto Leiva Popper Date: Mon, 29 Sep 2025 19:28:28 +0000 (-0600) Subject: Rethink logging for Fort 2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ac5bf9070d68c13368cc346e2717ee895339c4ac;p=thirdparty%2FFORT-validator.git Rethink logging for Fort 2 - Rename "operation logs" to just "logs" - Rename "validation logs" to "report" Rationale: Logging is meant for sysadmin consumption. Sysadmins don't care if some RPKI objects need to be thrown away. - Logs can be sent to std streams, files or syslog. Reports only go to files. Logs and reports go to different files (because they're different things). - Subdivide DEBUG into TRC, CLT and DBG. "TRC"s (traces) are algorithm steps as they happen. "CLT"s (clutters) are detailed information about what's happening. "DBG"s are just temporal debugging prints. - Rename CRIT into PANIC. - Subdivide ERR ento ERR and CRIT. "ERR"s are normal, expected errors. "CRIT"s (criticals) are unexpected (but recoverable) errors. - Apply #121: Redirect WRNs and ERRs to reports during validation cycles. Logs actually still get WRNs and ERRs, but they're downgraded to TRCs. Still TODO: - Configuration layer has not been updated - Reports don't print offending file names --- diff --git a/src/Makefile.am b/src/Makefile.am index f1e79c40..7f2a50dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,6 @@ fort_SOURCES += cachetmp.c cachetmp.h fort_SOURCES += common.c common.h fort_SOURCES += config/boolean.c config/boolean.h fort_SOURCES += config/curl_offset.c config/curl_offset.h -fort_SOURCES += config/filename_format.h config/filename_format.c fort_SOURCES += config/file_type.h config/file_type.c fort_SOURCES += config.h config.c fort_SOURCES += config/incidences.h config/incidences.c @@ -51,6 +50,7 @@ fort_SOURCES += output_printer.h output_printer.c fort_SOURCES += print_file.h print_file.c fort_SOURCES += prometheus.h prometheus.c fort_SOURCES += relax_ng.c relax_ng.h +fort_SOURCES += report.c report.h fort_SOURCES += resource/asn.h resource/asn.c fort_SOURCES += resource.h resource.c fort_SOURCES += resource/ip4.h resource/ip4.c diff --git a/src/config.c b/src/config.c index e898f355..ed9515b1 100644 --- a/src/config.c +++ b/src/config.c @@ -156,8 +156,6 @@ struct rpki_config { char *tag; /** Print ANSI color codes? */ bool color; - /** Format in which file names will be printed. */ - enum filename_format filename_format; /* Log level */ uint8_t level; /* Log output */ @@ -167,22 +165,8 @@ struct rpki_config { } log; struct { - /** Enables validation Logs **/ - bool enabled; - bool print_times; - /** String tag to identify validation logs **/ - char *tag; - /** Print ANSI color codes? */ - bool color; - /** Format in which file names will be printed. */ - enum filename_format filename_format; - /* Log level */ - uint8_t level; - /* Log output */ - enum log_output output; - /** facilities for syslog if output is syslog **/ - uint32_t facility; - } validation_log; + char *path; + } report; struct { /** File where the validated ROAs will be stored */ @@ -679,12 +663,6 @@ static const struct option_field options[] = { .type = >_log_facility, .offset = offsetof(struct rpki_config, log.facility), .doc = "Facility for syslog if output is syslog", - }, { - .id = 4005, - .name = "log.file-name-format", - .type = >_filename_format, - .offset = offsetof(struct rpki_config, log.filename_format), - .doc = "File name variant to print during debug/error messages", }, { .id = 'c', .name = "log.color-output", @@ -695,55 +673,9 @@ static const struct option_field options[] = { { .id = 4010, - .name = "validation-log.enabled", - .type = >_bool, - .offset = offsetof(struct rpki_config, validation_log.enabled), - .doc = "Enables validation logs", - }, { - .id = 4011, - .name = "validation-log.output", - .type = >_log_output, - .offset = offsetof(struct rpki_config, validation_log.output), - .doc = "Output where validation log messages will be printed", - }, { - .id = 4012, - .name = "validation-log.level", - .type = >_log_level, - .offset = offsetof(struct rpki_config, validation_log.level), - .doc = "Log level to print message of equal or higher importance", - }, { - .id = 4017, - .name = "validation-log.print-times", - .type = >_bool, - .offset = offsetof(struct rpki_config, validation_log.print_times), - .doc = "(Console output only)", - }, { - .id = 4013, - .name = "validation-log.tag", + .name = "report.path", .type = >_string, - .offset = offsetof(struct rpki_config, validation_log.tag), - .doc = "Text tag to identify validation logs", - .arg_doc = "", - .json_null_allowed = true, - }, { - .id = 4014, - .name = "validation-log.facility", - .type = >_log_facility, - .offset = offsetof(struct rpki_config, validation_log.facility), - .doc = "Facility for syslog if output is syslog", - }, { - .id = 4015, - .name = "validation-log.file-name-format", - .type = >_filename_format, - .offset = offsetof(struct rpki_config, - validation_log.filename_format), - .doc = "File name variant to print during debug/error messages", - }, { - .id = 4016, - .name = "validation-log.color-output", - .type = >_bool, - .offset = offsetof(struct rpki_config, validation_log.color), - .doc = "Print ANSI color codes", + .offset = offsetof(struct rpki_config, report.path), }, /* Incidences */ @@ -852,10 +784,9 @@ static const struct option_field options[] = { { 0 }, }; -/** +/* * Returns true if @field is the descriptor of one of the members of the * struct rpki_config structure, false otherwise. - * (Alternatively: Returns true if @field->offset is valid, false otherwise.) */ static bool is_rpki_config_field(struct option_field const *field) @@ -1042,18 +973,11 @@ set_default_values(void) rpki_config.log.enabled = true; rpki_config.log.tag = NULL; rpki_config.log.color = false; - rpki_config.log.filename_format = FNF_GLOBAL; rpki_config.log.level = LOG_WARNING; rpki_config.log.output = CONSOLE; rpki_config.log.facility = LOG_DAEMON; - rpki_config.validation_log.enabled = false; - rpki_config.validation_log.tag = pstrdup("Validation"); - rpki_config.validation_log.color = false; - rpki_config.validation_log.filename_format = FNF_GLOBAL; - rpki_config.validation_log.level = LOG_WARNING; - rpki_config.validation_log.output = CONSOLE; - rpki_config.validation_log.facility = LOG_DAEMON; + rpki_config.report.path = NULL; rpki_config.output.roa = NULL; rpki_config.output.bgpsec = NULL; @@ -1171,25 +1095,72 @@ handle_opt(int opt) return ESRCH; } +static void +become_absolute_path(char *cwd, char **_path) +{ + char *relative, *absolute; + + relative = *_path; + if (relative != NULL) { + absolute = path_join(cwd, relative); + free(relative); + *_path = absolute; + } +} + static int -become_absolute_path(char **_path) +become_absolute_paths(void) { - char *relative = *_path; - char *absolute; + char *buf, *cwd; + int error; - if (relative == NULL) - return 0; + buf = pmalloc(1024); + + cwd = getcwd(buf, 1024); + if (!cwd) { + error = errno; + pr_err("Cannot get the current directory: %s", strerror(error)); + free(buf); + return error; + } - absolute = realpath(relative, NULL); - if (!absolute) - return pr_err("Cannot resolve the absolute path of %s: %s", - relative, strerror(errno)); + become_absolute_path(cwd, &rpki_config.tal); + become_absolute_path(cwd, &rpki_config.report.path); + become_absolute_path(cwd, &rpki_config.slurm); + become_absolute_path(cwd, &rpki_config.http.ca_path); - free(relative); - *_path = absolute; + free(buf); return 0; } +static void +set_logger_syslog(void) +{ + struct log_listeners list = TAILQ_HEAD_INITIALIZER(list); + struct log_listener node = { 0 }; + + node.type = "syslog"; + node.level = "info"; + node.facility = LOG_DAEMON; + + TAILQ_INSERT_TAIL(&list, &node, lh); + log_init(&list); +} + +static void +set_logger_console(void) +{ + struct log_listeners list = TAILQ_HEAD_INITIALIZER(list); + struct log_listener node = { 0 }; + + node.type = "console"; + node.level = "info"; + node.color = true; + + TAILQ_INSERT_TAIL(&list, &node, lh); + log_init(&list); +} + int handle_flags_config(int argc, char **argv) { @@ -1219,13 +1190,7 @@ handle_flags_config(int argc, char **argv) if (error) goto end; - error = become_absolute_path(&rpki_config.tal); - if (error) - goto end; - error = become_absolute_path(&rpki_config.slurm); - if (error) - goto end; - error = become_absolute_path(&rpki_config.http.ca_path); + error = become_absolute_paths(); if (error) goto end; @@ -1242,14 +1207,12 @@ handle_flags_config(int argc, char **argv) if (rpki_config.daemon) { pr_inf("Executing as daemon, all logs will be sent to syslog."); - /* Send all logs to syslog */ - rpki_config.log.output = SYSLOG; - rpki_config.validation_log.output = SYSLOG; - error = daemonize(log_start); - goto end; + set_logger_syslog(); /* XXX hardcoded */ + error = daemonize(); + } else { + set_logger_console(); /* XXX hardcoded */ } - log_start(); end: if (error) { free_rpki_config(); @@ -1261,7 +1224,6 @@ end: free(long_opts); free(short_opts); return error; - } struct option_field const * @@ -1385,12 +1347,6 @@ config_get_op_log_color_output(void) return rpki_config.log.color; } -enum filename_format -config_get_op_log_file_format(void) -{ - return rpki_config.log.filename_format; -} - uint8_t config_get_op_log_level(void) { @@ -1409,60 +1365,10 @@ config_get_op_log_facility(void) return rpki_config.log.facility; } -bool -config_get_val_log_enabled(void) -{ - return rpki_config.validation_log.enabled; -} - -bool -config_get_val_print_times(void) -{ - return rpki_config.validation_log.print_times; -} - -char const * -config_get_val_log_tag(void) -{ - return rpki_config.validation_log.tag; -} - -bool -config_get_val_log_color_output(void) -{ - return rpki_config.validation_log.color; -} - -enum filename_format -config_get_val_log_file_format(void) -{ - return rpki_config.validation_log.filename_format; -} - -char const * -logv_filename(char const *path) -{ - return (rpki_config.validation_log.filename_format == FNF_NAME) - ? path_filename(path) - : path; -} - -uint8_t -config_get_val_log_level(void) -{ - return rpki_config.validation_log.level; -} - -enum log_output -config_get_val_log_output(void) -{ - return rpki_config.validation_log.output; -} - -uint32_t -config_get_val_log_facility(void) +char * +config_get_report(void) { - return rpki_config.validation_log.facility; + return rpki_config.report.path; } bool diff --git a/src/config.h b/src/config.h index 68aaaf2c..637e8e59 100644 --- a/src/config.h +++ b/src/config.h @@ -10,7 +10,6 @@ #include #include "config/file_type.h" -#include "config/filename_format.h" #include "config/log_conf.h" #include "config/mode.h" #include "config/output_format.h" @@ -66,20 +65,11 @@ bool config_get_op_log_enabled(void); bool config_get_op_print_times(void); char const * config_get_op_log_tag(void); bool config_get_op_log_color_output(void); -enum filename_format config_get_op_log_file_format(void); uint8_t config_get_op_log_level(void); enum log_output config_get_op_log_output(void); uint32_t config_get_op_log_facility(void); -bool config_get_val_log_enabled(void); -bool config_get_val_print_times(void); -char const * config_get_val_log_tag(void); -bool config_get_val_log_color_output(void); -enum filename_format config_get_val_log_file_format(void); -char const *logv_filename(char const *); -uint8_t config_get_val_log_level(void); -enum log_output config_get_val_log_output(void); -uint32_t config_get_val_log_facility(void); +char *config_get_report(void); /* Public, so --work-offline can override them. */ void config_set_rsync_enabled(bool); diff --git a/src/config/filename_format.c b/src/config/filename_format.c deleted file mode 100644 index 25d27a6f..00000000 --- a/src/config/filename_format.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "config/filename_format.h" - -#include -#include - -#include "config/str.h" -#include "log.h" - -#define FNF_VALUE_GLOBAL "global-url" -#define FNF_VALUE_LOCAL "local-path" -#define FNF_VALUE_NAME "file-name" - -#define DEREFERENCE(void_value) (*((enum filename_format *) void_value)) - -static void -print_filename_format(struct option_field const *field, void *value) -{ - char const *str = ""; - - switch (DEREFERENCE(value)) { - case FNF_GLOBAL: - str = FNF_VALUE_GLOBAL; - break; - case FNF_LOCAL: - str = FNF_VALUE_LOCAL; - break; - case FNF_NAME: - str = FNF_VALUE_NAME; - break; - } - - pr_inf("%s: %s", field->name, str); -} - -static int -parse_argv_filename_format(struct option_field const *field, char const *str, - void *result) -{ - if (strcmp(str, FNF_VALUE_GLOBAL) == 0) - DEREFERENCE(result) = FNF_GLOBAL; - else if (strcmp(str, FNF_VALUE_LOCAL) == 0) - DEREFERENCE(result) = FNF_LOCAL; - else if (strcmp(str, FNF_VALUE_NAME) == 0) - DEREFERENCE(result) = FNF_NAME; - else - return pr_err("Unknown file name format %s: '%s'", - field->name, str); - - return 0; -} - -static int -parse_json_filename_format(struct option_field const *opt, json_t *json, - void *result) -{ - char const *string; - int error; - - error = parse_json_string(json, opt->name, &string); - return error ? error : parse_argv_filename_format(opt, string, result); -} - -const struct global_type gt_filename_format = { - .has_arg = required_argument, - .size = sizeof(enum filename_format), - .print = print_filename_format, - .parse.argv = parse_argv_filename_format, - .parse.json = parse_json_filename_format, - .arg_doc = FNF_VALUE_GLOBAL "|" FNF_VALUE_LOCAL "|" FNF_VALUE_NAME, -}; diff --git a/src/config/filename_format.h b/src/config/filename_format.h deleted file mode 100644 index 90748518..00000000 --- a/src/config/filename_format.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef SRC_CONFIG_FILENAME_FORMAT_H_ -#define SRC_CONFIG_FILENAME_FORMAT_H_ - -#include "config/types.h" - -enum filename_format { - /** Example: "rsync://repository.lacnic.net/rpki/foo/bar/baz.cer" */ - FNF_GLOBAL, - /** Example: "/tmp/repo/repository.lacnic.net/rpki/foo/bar/baz.cer" */ - FNF_LOCAL, - /** Example: "baz.cer" */ - FNF_NAME, -}; - -extern const struct global_type gt_filename_format; - -#endif /* SRC_CONFIG_FILENAME_FORMAT_H_ */ diff --git a/src/config/types.h b/src/config/types.h index 50152797..23d45360 100644 --- a/src/config/types.h +++ b/src/config/types.h @@ -92,7 +92,7 @@ struct global_type { int has_arg; /** * Number of bytes this data type uses in the rpki_config structure. - * Optional. Defaults to zero, obviously. + * Optional; Defaults to zero. */ size_t size; diff --git a/src/daemon.c b/src/daemon.c index b424620a..4ef7bda9 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -14,16 +14,13 @@ #include "log.h" /* - * Daemonize fort execution. The function "daemon()" from unistd header isn't - * utilized since isn't standardized (too bad). - * - * The logs must be sent to syslog before this call, the @log_cb is called to - * initialize logging after the first fork() call. + * Daemonize fort execution. "daemon()" from unistd.h isn't used since it's not + * portable. * * This function exits on any error once the first fork is successfully done. */ int -daemonize(daemon_log_cb log_cb) +daemonize(void) { char *pwd; pid_t pid; @@ -55,9 +52,6 @@ daemonize(daemon_log_cb log_cb) if (pid > 0) exit(0); - /* Activate logs */ - log_cb(); - /* Child goes on from here */ if (setsid() < 0) { error = errno; @@ -74,7 +68,7 @@ daemonize(daemon_log_cb log_cb) */ signal(SIGHUP, SIG_IGN); - /* Assure this is not a session leader */ + /* Ensure this is not a session leader */ pid = fork(); if (pid < 0) { error = errno; @@ -99,7 +93,7 @@ daemonize(daemon_log_cb log_cb) if (chdir(pwd) < 0) { error = errno; - pr_err("Couldn't chdir() of daemon, ending execution: %s", + pr_err("Couldn't chdir() daemon, ending execution: %s", strerror(error)); exit(error); } diff --git a/src/daemon.h b/src/daemon.h index 94e79671..6432b4db 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -1,7 +1,6 @@ #ifndef SRC_DAEMON_H_ #define SRC_DAEMON_H_ -typedef void (*daemon_log_cb)(void); -int daemonize(daemon_log_cb); +int daemonize(void); #endif /* SRC_DAEMON_H_ */ diff --git a/src/log.c b/src/log.c index 77295b1f..c5e9d14d 100644 --- a/src/log.c +++ b/src/log.c @@ -1,3 +1,5 @@ +#define _DEFAULT_SOURCE 1 + #include "log.h" #include @@ -12,514 +14,484 @@ #include #include "config.h" +#include "report.h" #include "thread_var.h" #include "types/path.h" struct level { - char const *label; + int id; + char const *tag; + char const *name; char const *color; - FILE *stream; + char const *rst; }; -static struct level DBG = { "DBG", PR_COLOR_DBG }; -static struct level INF = { "INF", PR_COLOR_INF }; -static struct level WRN = { "WRN", PR_COLOR_WRN }; -static struct level ERR = { "ERR", PR_COLOR_ERR }; -static struct level CRT = { "CRT", PR_COLOR_CRT }; -static struct level UNK = { "UNK", "" }; - -struct log_config { - bool fprintf_enabled; /* Print on the standard streams? */ - bool syslog_enabled; /* Print on syslog? */ - - uint8_t level; - bool print_times; - char const *tag; - bool color; - int facility; - bool rm_filepath; +#ifdef PR_CLUTTER_ENABLED +static struct level CLT = { LOG_DEBUG, "CLT", "clutter", CLR_CLT, CLR_RST }; +#endif +static struct level TRC = { LOG_DEBUG, "TRC", "trace", CLR_TRC, CLR_RST }; +static struct level INF = { LOG_INFO, "INF", "info", "", "" }; +static struct level WRN = { LOG_WARNING, "WRN", "warning", CLR_WRN, CLR_RST }; +static struct level ERR = { LOG_ERR, "ERR", "error", CLR_ERR, CLR_RST }; +static struct level CRT = { LOG_CRIT, "CRT", "critical", CLR_CRT, CLR_RST }; +static struct level PNC = { LOG_EMERG, "PNC", "panic", CLR_PNC, CLR_RST }; + +struct logger { + void (*cb)(struct logger *, struct level *, char const *, va_list); + + struct level *lvl; + FILE *stream; /* file only */ + bool print_times; /* console and file only */ + bool color; /* console and file only */ + int facility; /* syslog only */ + bool free; + + pthread_mutex_t *lock; /* console (except init) and file only */ + SLIST_ENTRY(logger) lh; }; -/* Configuration for the operation logs. */ -static struct log_config op_config; -/* Configuration for the validation logs. */ -static struct log_config val_config; +SLIST_HEAD(loggers, logger); -/* - * fprintf and syslog are rarely enabled at the same time, so I reused the - * mutex. - * - * "log" + "lock" = "logck" - */ -static pthread_mutex_t logck; +/* Constant after init */ +static struct loggers listeners = SLIST_HEAD_INITIALIZER(listeners); -/** - * Important: -rdynamic needs to be enabled, otherwise this does not print - * function names. See LDFLAGS_DEBUG in Makefile.am. - * Also: Only non-static functions will be labeled. - * - * The first printed entry is probably not meaningful. (But I'm printing - * everything anyway due to paranoia.) - * - * @title is allowed to be NULL. If you need locking, do it outside. (And be - * aware that pthread_mutex_lock() can return error codes, which shouldn't - * prevent critical stack traces from printing.) - */ static void -print_stack_trace(char const *title) +vcb(struct logger *lgr, struct level *lvl, char const *fmt, ...) { -#ifdef BACKTRACE_ENABLED -#define STACK_SIZE 64 + va_list vl; - void *array[STACK_SIZE]; - size_t size; - char **strings; - size_t i; - int fp; + va_start(vl, fmt); + lgr->cb(lgr, lvl, fmt, vl); + va_end(vl); +} - size = backtrace(array, STACK_SIZE); - strings = backtrace_symbols(array, size); +#ifdef BACKTRACE_ENABLED - if (op_config.fprintf_enabled) { - if (title != NULL) - fprintf(ERR.stream, "%s\n", title); - fprintf(ERR.stream, "Stack trace:\n"); - for (i = 0; i < size; i++) - fprintf(ERR.stream, " %s\n", strings[i]); - fprintf(ERR.stream, "(End of stack trace)\n"); - } +#define STACK_SIZE 64 - if (op_config.syslog_enabled) { - fp = LOG_ERR | op_config.facility; - if (title != NULL) - syslog(fp, "%s", title); - syslog(fp, "Stack trace:"); - for (i = 0; i < size; i++) - syslog(fp, " %s", strings[i]); - syslog(fp, "(End of stack trace)"); - } +/* + * Needs -rdynamic, otherwise function names don't show up. + * Only non-static functions can be labeled. + */ +static void +__pr_stack_trace(struct logger *lgr, struct level *lvl, + char const *title, size_t size, char **strings) +{ + size_t i; - free(strings); -#endif /* BACKTRACE_ENABLED */ + if (title != NULL) + vcb(lgr, lvl, "%s", title); + vcb(lgr, lvl, "Stack trace:"); + for (i = 0; i < size; i++) + vcb(lgr, lvl, " %s", strings[i]); + vcb(lgr, lvl, "(End of stack trace)"); } -static void init_config(struct log_config *cfg) -{ - cfg->fprintf_enabled = true; - cfg->syslog_enabled = true; - cfg->level = LOG_DEBUG; - cfg->print_times = true; - cfg->tag = NULL; - cfg->color = false; - cfg->facility = LOG_DAEMON; -} +#endif /* BACKTRACE_ENABLED */ -int -log_setup(void) +static void +init_mutex(struct logger *lgr) { - /* - * Remember not to use any actual logging functions until logging has - * been properly initialized. - */ - int error; - DBG.stream = stdout; - INF.stream = stdout; - WRN.stream = stderr; - ERR.stream = stderr; - CRT.stream = stderr; - UNK.stream = stdout; + lgr->lock = pmalloc(sizeof(pthread_mutex_t)); - init_config(&op_config); - init_config(&val_config); - - error = pthread_mutex_init(&logck, NULL); + error = pthread_mutex_init(lgr->lock, NULL); if (error) { - fprintf(ERR.stream, - "pthread_mutex_init() failure: %s\n", - strerror(error)); - syslog(LOG_ERR | op_config.facility, - "pthread_mutex_init() failure: %s", - strerror(error)); - return error; + pr_wrn("Cannot initialize logging mutex: %s. " + "Logs might overlap sometimes.", strerror(error)); + free(lgr->lock); + lgr->lock = NULL; } - - return 0; } static void -log_disable_syslog(void) +get_time(char *buf /* Must length 16 */) { - if (op_config.syslog_enabled || val_config.syslog_enabled) { - closelog(); - op_config.syslog_enabled = false; - val_config.syslog_enabled = false; - } + time_t now; + struct tm components; + + now = time(NULL); + if (now == ((time_t) -1)) + return; + if (localtime_r(&now, &components) == NULL) + return; + if (strftime(buf, sizeof(buf), "%m-%d %H:%M:%S ", &components) == 0) + buf[0] = 0; } -void -log_start(void) +static void +stream_print(FILE *out, struct logger *lgr, struct level *lvl, + char const *fmt, va_list vl) { - if (config_get_val_log_enabled()) { - switch (config_get_val_log_output()) { - case SYSLOG: - val_config.fprintf_enabled = false; - break; - case CONSOLE: - val_config.syslog_enabled = false; - break; - } - } else { - val_config.fprintf_enabled = false; - val_config.syslog_enabled = false; - } + char time[16]; - if (config_get_op_log_enabled()) { - switch (config_get_op_log_output()) { - case SYSLOG: - op_config.fprintf_enabled = false; - break; - case CONSOLE: - if (val_config.syslog_enabled) - op_config.syslog_enabled = false; - else - log_disable_syslog(); - break; - } - } else { - op_config.fprintf_enabled = false; - if (val_config.syslog_enabled) - op_config.syslog_enabled = false; - else - log_disable_syslog(); - } + time[0] = 0; + if (lgr->print_times) + get_time(time); - op_config.level = config_get_op_log_level(); - op_config.print_times = config_get_op_print_times(); - op_config.tag = config_get_op_log_tag(); - op_config.color = config_get_op_log_color_output(); - op_config.facility = config_get_op_log_facility(); - op_config.rm_filepath = config_get_op_log_file_format() == FNF_NAME; - val_config.level = config_get_val_log_level(); - val_config.print_times = config_get_val_print_times(); - val_config.tag = config_get_val_log_tag(); - val_config.color = config_get_val_log_color_output(); - val_config.facility = config_get_val_log_facility(); - val_config.rm_filepath = config_get_val_log_file_format() == FNF_NAME; -} + if (lgr->lock) + pthread_mutex_lock(lgr->lock); -void -log_teardown(void) -{ - log_disable_syslog(); - pthread_mutex_destroy(&logck); + fprintf(out, "%s%s%s: ", lgr->color ? lvl->color : "", time, lvl->tag); + vfprintf(out, fmt, vl); + fprintf(out, "%s\n", lgr->color ? lvl->rst : ""); + + if (lgr->lock) + pthread_mutex_unlock(lgr->lock); } -static struct level const * -level2struct(int level) +static void +console_cb(struct logger *lgr, struct level *lvl, char const *fmt, va_list vl) { - switch (level) { - case LOG_CRIT: - return &CRT; - case LOG_ERR: - return &ERR; - case LOG_WARNING: - return &WRN; - case LOG_INFO: - return &INF; - case LOG_DEBUG: - return &DBG; - } + FILE *stream; - return &UNK; + stream = (lvl->id <= LOG_ERR) ? stderr : stdout; + stream_print(stream, lgr, lvl, fmt, vl); + fflush(stream); } static void -lock_mutex(void) +file_cb(struct logger *lgr, struct level *lvl, char const *fmt, va_list vl) { - int error; - - error = pthread_mutex_lock(&logck); - if (error) { - /* - * Despite being supposed to be impossible, failing to lock the - * mutex is not fatal; it just means we might log some mixed - * messages, which is better than dying. - * - * Furthermore, this might have been called while logging - * another critical. We must absolutely not get in the way of - * that critical's print. - */ - print_stack_trace(strerror(error)); - } + stream_print(lgr->stream, lgr, lvl, fmt, vl); } static void -unlock_mutex(void) +syslog_cb(struct logger *lgr, struct level *lvl, char const *fmt, va_list vl) { - int error; - - error = pthread_mutex_unlock(&logck); - if (error) - print_stack_trace(strerror(error)); /* Same as above. */ + vsyslog(lvl->id | lgr->facility, fmt, vl); } -static void -print_time(struct level const *lvl) +void +log_setup(void) { - time_t now; - struct tm components; - char str[16]; + static struct logger init_node = { 0 }; - now = time(NULL); - if (now == ((time_t) -1)) - return; - if (localtime_r(&now, &components) == NULL) - return; - if (strftime(str, sizeof(str), "%m-%d %H:%M:%S", &components) == 0) - return; + init_node.cb = console_cb; + init_node.lvl = &INF; - fprintf(lvl->stream, "%s ", str); + SLIST_INSERT_HEAD(&listeners, &init_node, lh); } -static void -__vfprintf(int level, struct log_config *cfg, char const *format, va_list args) +static int +add_listener(struct loggers *list, struct log_listener *new) { - struct level const *lvl; - char const *file_name; - - lvl = level2struct(level); - - lock_mutex(); + struct logger *node; + + node = pzalloc(sizeof(struct logger)); + node->free = true; + + if (strcmp(new->level, ERR.name) == 0) + node->lvl = &ERR; + else if (strcmp(new->level, WRN.name) == 0) + node->lvl = &WRN; + else if (strcmp(new->level, INF.name) == 0) + node->lvl = &INF; + else if (strcmp(new->level, TRC.name) == 0) + node->lvl = &TRC; + else { + free(node); + return pr_err("Unknown log level: %s", new->level); + } - if (cfg->color) - fprintf(lvl->stream, "%s", lvl->color); + if (strcmp(new->type, "console") == 0) { + node->cb = console_cb; + node->print_times = new->print_times; + node->color = new->color; + init_mutex(node); + } else if (strcmp(new->type, "file") == 0) { + node->cb = file_cb; + node->stream = fopen(new->filename, "a"); + node->print_times = new->print_times; + node->color = new->color; + init_mutex(node); + } else if (strcmp(new->type, "syslog") == 0) { + node->cb = syslog_cb; + node->facility = new->facility; + } else { + free(node); + return pr_err("Unknown log type: %s", new->type); + } - if (cfg->print_times) - print_time(lvl); + SLIST_INSERT_HEAD(list, node, lh); + return 0; +} - fprintf(lvl->stream, "%s", lvl->label); - if (cfg->tag) - fprintf(lvl->stream, " [%s]", cfg->tag); - fprintf(lvl->stream, ": "); +static void +clear_loggers(struct loggers *list) +{ + struct logger *lgr; + + while ((lgr = SLIST_FIRST(list)) != NULL) { + if (lgr->stream) + fclose(lgr->stream); + if (lgr->lock) { + pthread_mutex_destroy(lgr->lock); + free(lgr->lock); + } - file_name = fnstack_peek(); - if (file_name != NULL) { - if (cfg->rm_filepath) - file_name = path_filename(file_name); - fprintf(lvl->stream, "%s: ", file_name); + SLIST_REMOVE_HEAD(list, lh); + if (lgr->free) + free(lgr); } +} - vfprintf(lvl->stream, format, args); +int +log_init(struct log_listeners *descriptors) +{ + struct loggers newlist; + struct log_listener *descriptor; + int error; - if (cfg->color) - fprintf(lvl->stream, PR_COLOR_RST); - fprintf(lvl->stream, "\n"); + SLIST_INIT(&newlist); + TAILQ_FOREACH(descriptor, descriptors, lh) { + error = add_listener(&newlist, descriptor); + if (error) { + clear_loggers(&newlist); + return error; + } + } - /* Force flush */ - if (lvl->stream == stdout) - fflush(lvl->stream); + clear_loggers(&listeners); + listeners = newlist; + return 0; +} - unlock_mutex(); +void +log_teardown(void) +{ + clear_loggers(&listeners); } -/* - * TODO (fine) Optimize. Notice the buffer is static, which seems to be the - * reason why it's (probably ill-advisedly) mutexing. - */ -#define MSG_LEN 512 +#ifdef PR_CLUTTER_ENABLED -static void -__syslog(int level, struct log_config *cfg, const char *format, va_list args) +void +pr_clutter(const char *fmt, ...) { - static char msg[MSG_LEN]; - char const *file; - int res; - - level |= cfg->facility; - file = fnstack_peek(); - if (file && cfg->rm_filepath) - file = path_filename(file); - - lock_mutex(); - - /* Can't use vsyslog(); it's not portable. */ - res = vsnprintf(msg, MSG_LEN, format, args); - if (res < 0) - goto end; - if (res >= MSG_LEN) - msg[MSG_LEN - 1] = '\0'; - - if (file != NULL) { - if (cfg->tag != NULL) - syslog(level, "[%s] %s: %s", cfg->tag, file, msg); - else - syslog(level, "%s: %s", file, msg); - } else { - if (cfg->tag != NULL) - syslog(level, "[%s] %s", cfg->tag, msg); - else - syslog(level, "%s", msg); + struct logger *lgr; + va_list args; + + SLIST_FOREACH(lgr, &listeners, lh) { + if (LOG_DEBUG <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, &CLT, fmt, args); + va_end(args); + } } - -end: unlock_mutex(); } -#define PR_SIMPLE(lvl, config) \ - do { \ - va_list args; \ - \ - if (lvl > config.level) \ - break; \ - \ - if (config.syslog_enabled) { \ - va_start(args, format); \ - __syslog(lvl, &config, format, args); \ - va_end(args); \ - } \ - \ - if (config.fprintf_enabled) { \ - va_start(args, format); \ - __vfprintf(lvl, &config, format, args); \ - va_end(args); \ - } \ - } while (0) +#endif void -pr_trc(const char *format, ...) +pr_trc(const char *fmt, ...) { - PR_SIMPLE(LOG_DEBUG, op_config); + struct logger *lgr; + va_list args; + + SLIST_FOREACH(lgr, &listeners, lh) { + if (LOG_DEBUG <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, &TRC, fmt, args); + va_end(args); + } + } } void -pr_inf(const char *format, ...) +pr_inf(const char *fmt, ...) { - PR_SIMPLE(LOG_INFO, op_config); + struct logger *lgr; + va_list args; + + SLIST_FOREACH(lgr, &listeners, lh) { + if (LOG_INFO <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, &INF, fmt, args); + va_end(args); + } + } } -/** - * Always returs 0. (So you can interrupt whatever you're doing without failing - * validation.) - */ int -pr_wrn(const char *format, ...) +pr_wrn(const char *fmt, ...) { - PR_SIMPLE(LOG_WARNING, op_config); + struct level *lvl = &WRN; + struct logger *lgr; + va_list args; + + if (report_enabled()) { + va_start(args, fmt); + report(lvl->tag, fmt, args); + va_end(args); + lvl = &TRC; + } + + SLIST_FOREACH(lgr, &listeners, lh) { + if (lvl->id <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, lvl, fmt, args); + va_end(args); + } + } + return 0; } int -pr_err(const char *format, ...) +pr_err(const char *fmt, ...) { - PR_SIMPLE(LOG_ERR, op_config); - return EINVAL; -} + struct level *lvl = &ERR; + struct logger *lgr; + va_list args; + + if (report_enabled()) { + va_start(args, fmt); + report(lvl->tag, fmt, args); + va_end(args); + lvl = &TRC; + } + + SLIST_FOREACH(lgr, &listeners, lh) { + if (lvl->id <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, lvl, fmt, args); + va_end(args); + } + } -int -pr_crit(const char *format, ...) -{ - PR_SIMPLE(LOG_ERR, op_config); - lock_mutex(); - print_stack_trace(NULL); - unlock_mutex(); return EINVAL; } -struct crypto_cb_arg { - unsigned int stack_size; - int (*error_fn)(const char *, ...); -}; - static int -log_crypto_error(const char *str, size_t len, void *_arg) +log_crypto_error(const char *str, size_t len, void *_stack_size) { - struct crypto_cb_arg *arg = _arg; - arg->error_fn("-> %s", str); - arg->stack_size++; + unsigned int *stack_size = _stack_size; + pr_err("-> %s", str); + (*stack_size)++; return 1; } -static int -crypto_err(struct log_config *cfg, int (*error_fn)(const char *, ...)) -{ - struct crypto_cb_arg arg; - - error_fn("libcrypto error stack:"); - - arg.stack_size = 0; - arg.error_fn = error_fn; - ERR_print_errors_cb(log_crypto_error, &arg); - if (arg.stack_size == 0) - error_fn(" "); - else - error_fn("End of libcrypto stack."); - - return EINVAL; -} - /** - * This is like pr_err() and pr_errno(), except meant to log an error made - * during a libcrypto routine. + * This is like pr_err(), except meant to log an error made during a libcrypto + * routine. * * This differs from usual printf-like functions: * * - It returns EINVAL, not bytes written. * - It prints a newline. * - Also prints the cryptolib's error message stack. - * - * Always appends a newline at the end. */ int -pr_crypto_err(const char *format, ...) +pr_crypto_err(const char *fmt, ...) +{ + struct level *lvl = &ERR; + struct logger *lgr; + va_list args; + unsigned int stack_size; + + if (report_enabled()) { + va_start(args, fmt); + report(lvl->tag, fmt, args); + va_end(args); + lvl = &TRC; + } + + SLIST_FOREACH(lgr, &listeners, lh) { + if (lvl->id <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, lvl, fmt, args); + va_end(args); + } + } + + pr_err("libcrypto error stack:"); + stack_size = 0; + ERR_print_errors_cb(log_crypto_error, &stack_size); + if (stack_size == 0) + pr_err(" "); + else + pr_err("End of libcrypto stack."); + + return EINVAL; +} + +int +pr_crit(const char *fmt, ...) { - PR_SIMPLE(LOG_ERR, op_config); - return crypto_err(&op_config, pr_err); + struct logger *lgr; + va_list args; + +#ifdef BACKTRACE_ENABLED + void *array[STACK_SIZE]; + size_t size; + char **strings; + + size = backtrace(array, STACK_SIZE); + strings = backtrace_symbols(array, size); +#endif + + SLIST_FOREACH(lgr, &listeners, lh) { + if (CRT.id <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, &CRT, fmt, args); + va_end(args); + +#ifdef BACKTRACE_ENABLED + __pr_stack_trace(lgr, &CRT, NULL, size, strings); +#endif + } + } + +#ifdef BACKTRACE_ENABLED + free(strings); +#endif + + return EINVAL; } __dead void -enomem_panic(void) +pr_panic(const char *fmt, ...) { - static char const *ENOMEM_MSG = "Out of memory.\n"; - ssize_t garbage; - - /* - * I'm not using PR_SIMPLE and friends, because those allocate. - * We want to minimize allocations after a memory allocation failure. - */ - - if (LOG_ERR > op_config.level) - goto done; - - if (op_config.fprintf_enabled) { - lock_mutex(); - /* - * write() is AS-Safe, which implies it doesn't allocate, - * unlike printf(). - * - * "garbage" prevents write()'s warn_unused_result (compiler - * warning). - */ - garbage = write(STDERR_FILENO, ENOMEM_MSG, strlen(ENOMEM_MSG)); - unlock_mutex(); - /* Prevents "set but not used" warning. */ - garbage += garbage; - } + struct logger *lgr; + va_list args; + +#ifdef BACKTRACE_ENABLED + void *array[STACK_SIZE]; + size_t size; + char **strings; + + size = backtrace(array, STACK_SIZE); + strings = backtrace_symbols(array, size); +#endif - if (op_config.syslog_enabled) { - lock_mutex(); - /* This allocates, but I don't think I have more options. */ - syslog(LOG_ERR | op_config.facility, "Out of memory."); - unlock_mutex(); + SLIST_FOREACH(lgr, &listeners, lh) { + if (LOG_CRIT <= lgr->lvl->id) { + va_start(args, fmt); + lgr->cb(lgr, &PNC, fmt, args); + va_end(args); + +#ifdef BACKTRACE_ENABLED + __pr_stack_trace(lgr, &PNC, NULL, size, strings); +#endif + } } -done: exit(ENOMEM); +#ifdef BACKTRACE_ENABLED + free(strings); +#endif + + exit(-1); } __dead void -pr_panic(const char *format, ...) +enomem_panic(void) { - PR_SIMPLE(LOG_ERR, op_config); - print_stack_trace(NULL); - exit(-1); + struct logger *lgr; + + SLIST_FOREACH(lgr, &listeners, lh) + if (LOG_CRIT <= lgr->lvl->id) + vcb(lgr, &CRT, "Out of memory"); + + exit(ENOMEM); } diff --git a/src/log.h b/src/log.h index fc82c8e7..59a5cb77 100644 --- a/src/log.h +++ b/src/log.h @@ -3,15 +3,16 @@ #include #include +#include -#define PR_COLOR_DBG "\x1B[36m" /* Cyan */ -#define PR_COLOR_CLT "\x1B[34m" /* Blue */ -#define PR_COLOR_TRC "\x1B[32m" /* Green */ -#define PR_COLOR_INF "\x1B[37m" /* White */ -#define PR_COLOR_WRN "\x1B[33m" /* Yellow */ -#define PR_COLOR_ERR "\x1B[31m" /* Red */ -#define PR_COLOR_CRT "\x1B[35m" /* Purple */ -#define PR_COLOR_RST "\x1B[0m" +#define CLR_DBG "\x1B[36m" /* Cyan */ +#define CLR_CLT "\x1B[34m" /* Blue */ +#define CLR_TRC "\x1B[32m" /* Green */ +#define CLR_WRN "\x1B[33m" /* Yellow */ +#define CLR_ERR "\x1B[31m" /* Red */ +#define CLR_CRT "\x1B[35m" /* Magenta */ +#define CLR_PNC "\x1B[35m" /* Magenta */ +#define CLR_RST "\x1B[0m" /* * According to BSD style, __dead is supposed to be defined in sys/cdefs.h, @@ -31,21 +32,64 @@ #define CHECK_FORMAT(str, args) /* Nothing */ #endif +struct log_listener { + char const *type; + char const *level; + char const *filename; /* file only */ + bool print_times; /* console and file only */ + bool color; /* console and file only */ + int facility; /* syslog only */ + + TAILQ_ENTRY(log_listener) lh; +}; + +TAILQ_HEAD(log_listeners, log_listener); + +void log_setup(void); /* Enables pr_* functions */ +int log_init(struct log_listeners *); /* Loads configuration */ +void log_teardown(void); + /* - * Only call this group of functions while you know there's only one thread. + * DBG (Debug) = Dirty lazy (debuggerless) bug hunting prints. + * These should be removed after the fix, and are always purged during releases. + * They go straight to standard output, bypassing listeners (and their levels). + * + * CLT (Clutter) = Low-level "I'm doing this now." + * TRC (Trace) = High-level "I'm doing this now." + * TRCs contextualize errors; CLTs give detailed information once the dev + * understands the context. + * TRCs are permanent; CLTs need to be compiled in. This is because I've + * extremely rarely found CLTs useful, even when debugging, and I got tired of + * them. + * In syslog, both are mapped to LOG_DEBUG. + * + * INF (Info) = Rare significant benign event. * - * log_setup() is an incomplete initialization meant to be called when the - * program starts. Logging can be performed after log_setup(), but it will use - * default values. - * log_init() finishes initialization by loading the user's intended config. - * log_teardown() reverts initialization. + * WRN (Warning) = Weirdness found, object not rejected, validation recovers. + * Means "this doesn't look rational, but I'll humor you anyway." + * + * ERR (Error) = Error, object rejected, validation recovers. + * Typical nonfatal expected error. A "checked exception," if you will. + * + * CRIT (Critical) = Apalling error, object rejected, validation recovers. + * A somehow nonfatal programming error. + * These include stack traces, and are not meant for reports. + * + * PNC (Panic) = Crippling error, validation dies. + * This is what CRIT used to be; Fort dies on the spot. Also includes a stack + * trace. Mapped to LOG_EMERG. + * With the exception of ENOMEMs, PNCs should never happen in production. + * + * WRNs and ERRs are redirected to reports during validations. */ -int log_setup(void); -void log_start(void); -void log_teardown(void); +#ifdef PR_CLUTTER_ENABLED +#define pr_clutter_enabled() true +void pr_clutter(const char *, ...) CHECK_FORMAT(1, 2); +#else #define pr_clutter_enabled() false #define pr_clutter(...) +#endif void pr_trc(const char *, ...) CHECK_FORMAT(1, 2); void pr_inf(const char *, ...) CHECK_FORMAT(1, 2); @@ -57,11 +101,15 @@ int pr_crit(const char *format, ...) CHECK_FORMAT(1, 2); __dead void pr_panic(const char *, ...) CHECK_FORMAT(1, 2); __dead void enomem_panic(void); /* Out of memory */ -#define PR_DBG(msg, ...) \ - printf(PR_COLOR_DBG "%s:%d (%s()): " msg PR_COLOR_RST "\n", \ - __FILE__, __LINE__, __func__, ##__VA_ARGS__) -#define PR_HELLO \ - printf(PR_COLOR_DBG "%s:%d (%s())" PR_COLOR_RST "\n", \ - __FILE__, __LINE__, __func__) +#define PR_DBG(msg, ...) do { \ + printf(CLR_DBG "%s:%d (%s()): " msg CLR_RST "\n", \ + __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ + fflush(stdout); \ + } while (0) +#define PR_HELLO do { \ + printf(CLR_DBG "%s:%d (%s())" CLR_RST "\n", \ + __FILE__, __LINE__, __func__); \ + fflush(stdout); \ + } while (0) #endif /* SRC_LOG_H_ */ diff --git a/src/main.c b/src/main.c index 3ebef412..2d5fe535 100644 --- a/src/main.c +++ b/src/main.c @@ -121,9 +121,7 @@ main(int argc, char **argv) /* Initializations */ /* (Do not start any threads until after rsync_setup() has forked.) */ - error = log_setup(); - if (error) - goto just_quit; + log_setup(); error = handle_flags_config(argc, argv); if (error) goto revert_log; @@ -206,6 +204,5 @@ revert_config: free_rpki_config(); revert_log: log_teardown(); -just_quit: return convert_to_result(error); } diff --git a/src/object/certificate.c b/src/object/certificate.c index b8559d6b..393a9d33 100644 --- a/src/object/certificate.c +++ b/src/object/certificate.c @@ -935,6 +935,9 @@ pr_clutter_x509_dates(X509 *x509) { char *nb, *na; + if (!pr_clutter_enabled()) + return; + nb = asn1time2str(X509_get0_notBefore(x509)); na = asn1time2str(X509_get0_notAfter(x509)); @@ -1023,8 +1026,7 @@ validate_chain(struct rpki_certificate *cert) } X509_STORE_CTX_set0_crls(ctx, crls); - if (pr_clutter_enabled()) - pr_clutter_x509_dates(cert->x509); + pr_clutter_x509_dates(cert->x509); /* * HERE'S THE MEAT OF LIBCRYPTO'S VALIDATION. diff --git a/src/object/tal.c b/src/object/tal.c index aa4447d4..4d601fef 100644 --- a/src/object/tal.c +++ b/src/object/tal.c @@ -7,6 +7,7 @@ #include "file.h" #include "log.h" #include "object/certificate.h" +#include "report.h" #include "task.h" #include "thread_var.h" #include "types/path.h" @@ -283,13 +284,16 @@ perform_standalone_validation(void) error = cache_prepare(); if (error) return error; - fnstack_init(); - task_start(); + task_start(); error = foreach_file(config_get_tal(), ".tal", true, queue_tal, NULL); if (error) goto end; + error = report_enable(); + if (error) + goto end; + /* * From now on, the trees should be considered valid, even if subsequent * certificates fail. @@ -310,6 +314,8 @@ perform_standalone_validation(void) t, strerror(error)); } + report_disable(); + // // FIXME // stats_set_tal_vrps(thread->tal_file, "ipv4", // db_table_roa_count_v4(thread->db)); diff --git a/src/report.c b/src/report.c new file mode 100644 index 00000000..5b53107a --- /dev/null +++ b/src/report.c @@ -0,0 +1,66 @@ +#include "report.h" + +#include +#include +#include + +#include "common.h" +#include "config.h" +#include "log.h" + +static FILE *stream; /* Constant during multithreaded */ +static bool enabled; +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +int +report_enable(void) +{ + char const *path; + int error; + + path = config_get_report(); + if (!path) + /* Will not write report, but pr_wrn & pr_err still need to + * be sent to TRC */ + goto done; + + stream = fopen(path, "wb"); + if (!stream) { + error = errno; + if (error != EEXIST) + return pr_err("fopen(%s): %s", path, strerror(error)); + } + +done: enabled = true; + return 0; +} + +bool +report_enabled(void) +{ + return enabled; +} + +void +report(char const *tag, char const *fmt, va_list vl) +{ + if (!stream) + return; + + mutex_lock(&lock); + fprintf(stream, "Severity: %s\n", tag); + fprintf(stream, "File: %s\n", ""); // XXX + vfprintf(stream, fmt, vl); + fprintf(stream, "\n\n"); + mutex_unlock(&lock); +} + +void +report_disable(void) +{ + if (stream) { + fclose(stream); + stream = NULL; + } + enabled = false; +} diff --git a/src/report.h b/src/report.h new file mode 100644 index 00000000..3c984c17 --- /dev/null +++ b/src/report.h @@ -0,0 +1,12 @@ +#ifndef SRC_REPORT_H_ +#define SRC_REPORT_H_ + +#include +#include + +int report_enable(void); /* pr_wrn and pr_errs now send to report */ +bool report_enabled(void); +void report(char const *, char const *, va_list); +void report_disable(void); /* pr_wrn and pr_errs go back to logs */ + +#endif /* SRC_REPORT_H_ */ diff --git a/src/thread_var.c b/src/thread_var.c index 45de81e6..ae80d5b4 100644 --- a/src/thread_var.c +++ b/src/thread_var.c @@ -127,7 +127,7 @@ fnstack_push(char const *file) void fnstack_push_map(struct cache_mapping const *map) { - fnstack_push(map_val_get_printable(map)); + fnstack_push(uri_str(&map->url)); } /* Returns the file name on the top of the file name stack. */ diff --git a/src/types/map.c b/src/types/map.c index 76820fda..a840c63b 100644 --- a/src/types/map.c +++ b/src/types/map.c @@ -1,37 +1,5 @@ #include "types/map.h" -#include "config.h" -#include "log.h" -#include "types/path.h" - -static char const * -map_get_printable(struct cache_mapping const *map, enum filename_format format) -{ - switch (format) { - case FNF_GLOBAL: - return uri_str(&map->url); - case FNF_LOCAL: - return map->path; - case FNF_NAME: - return path_filename(uri_str(&map->url)); - } - - pr_panic("Unknown file name format: %u", format); - return NULL; -} - -char const * -map_val_get_printable(struct cache_mapping const *map) -{ - return map_get_printable(map, config_get_val_log_file_format()); -} - -char const * -map_op_get_printable(struct cache_mapping const *map) -{ - return map_get_printable(map, config_get_op_log_file_format()); -} - void map_copy(struct cache_mapping *dst, struct cache_mapping const *src) { diff --git a/src/types/map.h b/src/types/map.h index 4dac978c..9ee59e76 100644 --- a/src/types/map.h +++ b/src/types/map.h @@ -10,9 +10,6 @@ struct cache_mapping { char *path; }; -char const *map_val_get_printable(struct cache_mapping const *); -char const *map_op_get_printable(struct cache_mapping const *); - void map_copy(struct cache_mapping *, struct cache_mapping const *); void map_cleanup(struct cache_mapping *); diff --git a/test/mock.c b/test/mock.c index 7d4676eb..ff32f988 100644 --- a/test/mock.c +++ b/test/mock.c @@ -77,31 +77,25 @@ log_crypto_error(const char *str, size_t len, void *_arg) return 1; } -static int -crypto_err(int (*error_fn)(const char *, ...)) +int +pr_crypto_err(const char *format, ...) { struct crypto_cb_arg arg; - error_fn("libcrypto error stack:"); + MOCK_PRINT(PR_COLOR_ERR); + pr_err("libcrypto error stack:"); arg.stack_size = 0; - arg.error_fn = error_fn; + arg.error_fn = pr_err; ERR_print_errors_cb(log_crypto_error, &arg); if (arg.stack_size == 0) - error_fn(" "); + pr_err(" "); else - error_fn("End of libcrypto stack."); + pr_err("End of libcrypto stack."); return EINVAL; } -int -pr_crypto_err(const char *format, ...) -{ - MOCK_PRINT(PR_COLOR_ERR); - return crypto_err(pr_err); -} - void enomem_panic(void) { @@ -164,7 +158,6 @@ MOCK_VOID(free_rpki_config, void) MOCK_VOID(fnstack_init, void) MOCK_VOID(fnstack_push, char const *file) -MOCK_VOID(fnstack_push_map, struct cache_mapping const *map) MOCK_VOID(fnstack_pop, void) MOCK_VOID(fnstack_cleanup, void)