version 1.52, 2020/07/03 06:46:41 |
version 1.53, 2020/10/16 13:24:45 |
|
|
#include <vis.h> |
#include <vis.h> |
|
|
#include "log.h" |
#include "log.h" |
|
#include "match.h" |
|
|
static LogLevel log_level = SYSLOG_LEVEL_INFO; |
static LogLevel log_level = SYSLOG_LEVEL_INFO; |
static int log_on_stderr = 1; |
static int log_on_stderr = 1; |
|
|
static char *argv0; |
static char *argv0; |
static log_handler_fn *log_handler; |
static log_handler_fn *log_handler; |
static void *log_handler_ctx; |
static void *log_handler_ctx; |
|
static char **log_verbose; |
|
static size_t nlog_verbose; |
extern char *__progname; |
extern char *__progname; |
|
|
/* textual representation of log-facilities/levels */ |
/* textual representation of log-facilities/levels */ |
|
|
return NULL; |
return NULL; |
} |
} |
|
|
/* Error messages that should be logged. */ |
|
|
|
void |
void |
error(const char *fmt,...) |
log_verbose_add(const char *s) |
{ |
{ |
va_list args; |
char **tmp; |
|
|
va_start(args, fmt); |
/* Ignore failures here */ |
do_log(SYSLOG_LEVEL_ERROR, fmt, args); |
if ((tmp = recallocarray(log_verbose, nlog_verbose, nlog_verbose + 1, |
va_end(args); |
sizeof(*log_verbose))) != NULL) { |
|
log_verbose = tmp; |
|
if ((log_verbose[nlog_verbose] = strdup(s)) != NULL) |
|
nlog_verbose++; |
|
} |
} |
} |
|
|
void |
void |
sigdie(const char *fmt,...) |
log_verbose_reset(void) |
{ |
{ |
va_list args; |
size_t i; |
|
|
va_start(args, fmt); |
for (i = 0; i < nlog_verbose; i++) |
do_log(SYSLOG_LEVEL_FATAL, fmt, args); |
free(log_verbose[i]); |
va_end(args); |
free(log_verbose); |
_exit(1); |
log_verbose = NULL; |
|
nlog_verbose = 0; |
} |
} |
|
|
void |
|
logdie(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_INFO, fmt, args); |
|
va_end(args); |
|
cleanup_exit(255); |
|
} |
|
|
|
/* Log this message (information that usually should go to the log). */ |
|
|
|
void |
|
logit(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_INFO, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
/* More detailed messages (information that does not need to go to the log). */ |
|
|
|
void |
|
verbose(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
/* Debugging messages that should not be logged during normal operation. */ |
|
|
|
void |
|
debug(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
void |
|
debug2(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
void |
|
debug3(const char *fmt,...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
/* |
/* |
* Initialize the log. |
* Initialize the log. |
*/ |
*/ |
|
|
log_handler_ctx = ctx; |
log_handler_ctx = ctx; |
} |
} |
|
|
void |
static void |
do_log2(LogLevel level, const char *fmt,...) |
do_log(const char *file, const char *func, int line, LogLevel level, |
|
int force, const char *fmt, va_list args) |
{ |
{ |
va_list args; |
|
|
|
va_start(args, fmt); |
|
do_log(level, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
void |
|
do_log(LogLevel level, const char *fmt, va_list args) |
|
{ |
|
struct syslog_data sdata = SYSLOG_DATA_INIT; |
struct syslog_data sdata = SYSLOG_DATA_INIT; |
char msgbuf[MSGBUFSIZ]; |
char msgbuf[MSGBUFSIZ]; |
char fmtbuf[MSGBUFSIZ]; |
char fmtbuf[MSGBUFSIZ]; |
|
|
int saved_errno = errno; |
int saved_errno = errno; |
log_handler_fn *tmp_handler; |
log_handler_fn *tmp_handler; |
|
|
if (level > log_level) |
if (!force && level > log_level) |
return; |
return; |
|
|
switch (level) { |
switch (level) { |
|
|
/* Avoid recursion */ |
/* Avoid recursion */ |
tmp_handler = log_handler; |
tmp_handler = log_handler; |
log_handler = NULL; |
log_handler = NULL; |
tmp_handler(level, fmtbuf, log_handler_ctx); |
tmp_handler(file, func, line, level, fmtbuf, log_handler_ctx); |
log_handler = tmp_handler; |
log_handler = tmp_handler; |
} else if (log_on_stderr) { |
} else if (log_on_stderr) { |
snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n", |
snprintf(msgbuf, sizeof msgbuf, "%.*s\r\n", |
|
|
closelog_r(&sdata); |
closelog_r(&sdata); |
} |
} |
errno = saved_errno; |
errno = saved_errno; |
|
} |
|
|
|
void |
|
sshlog(const char *file, const char *func, int line, int showfunc, |
|
LogLevel level, const char *fmt, ...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
sshlogv(file, func, line, showfunc, level, fmt, args); |
|
va_end(args); |
|
} |
|
|
|
void |
|
sshlogdie(const char *file, const char *func, int line, const char *fmt, ...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
sshlogv(file, func, line, 0, SYSLOG_LEVEL_INFO, fmt, args); |
|
va_end(args); |
|
cleanup_exit(255); |
|
} |
|
|
|
void |
|
sshsigdie(const char *file, const char *func, int line, const char *fmt, ...) |
|
{ |
|
va_list args; |
|
|
|
va_start(args, fmt); |
|
sshlogv(file, func, line, 0, SYSLOG_LEVEL_FATAL, fmt, args); |
|
va_end(args); |
|
_exit(1); |
|
} |
|
|
|
void |
|
sshlogv(const char *file, const char *func, int line, int showfunc, |
|
LogLevel level, const char *fmt, va_list args) |
|
{ |
|
char tag[128], fmt2[MSGBUFSIZ + 128]; |
|
int forced = 0; |
|
const char *cp; |
|
size_t i; |
|
|
|
snprintf(tag, sizeof(tag), "%.48s:%.48s():%d", |
|
(cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line); |
|
for (i = 0; i < nlog_verbose; i++) { |
|
if (match_pattern_list(tag, log_verbose[i], 0) == 1) { |
|
forced = 1; |
|
break; |
|
} |
|
} |
|
|
|
if (log_handler == NULL && forced) |
|
snprintf(fmt2, sizeof(fmt2), "%s: %s", tag, fmt); |
|
else if (showfunc) |
|
snprintf(fmt2, sizeof(fmt2), "%s: %s", func, fmt); |
|
else |
|
strlcpy(fmt2, fmt, sizeof(fmt2)); |
|
|
|
do_log(file, func, line, level, forced, fmt2, args); |
} |
} |