#include "wantassert.h" #include "leafnode.h" #include "ln_log.h" #include #include #include #include #include #include #include /* for getenv */ #ifdef WITH_DMALLOC #include #endif #include /* for raise */ /* add LOG_NEWS where it doesn't exist */ #if !defined(LOG_NEWS) #define LOG_NEWS LOG_DAEMON #endif /* if LOG_CONS isn't supported, do without */ #if !defined(LOG_CONS) #define LOG_CONS 0 #endif static int maylog_console = 1; /* if 0, ln_log* stuff will not log to consoles */ void ln_log_use_console(int en) { maylog_console = en; } static void vln_log_core(int slg, FILE /*@null@*/ * console, int severity, int context, const char *format, va_list ap); /* log to syslog if slg != 0 * log to stream console if console != 0 * ctx to have verbosity like context * other arguments like syslog */ static void vln_log_core(int slg, FILE * console, int severity, int context, const char *format, va_list ap) { char buf[2048], fmt[2048], *y; const char *x; int errno_save = errno; assert(severity >= LNLOG_SMIN); assert(context >= 0); assert(verbose >= 0); /* support %m */ for (x = format, y = fmt; *x && y < fmt + sizeof(fmt) - 2; x++) { if (*x == '%') { x++; if (*x == '%') { *y++ = *x; *y++ = *x; } else if (*x == 'm') { const char *z = strerror(errno_save); while (*z && y < fmt + sizeof(fmt)) { if (*z == '%') *(y++) = *z; *(y++) = *(z++); } } else { *y++ = '%'; *y++ = *x; } } else { *y++ = *x; } } *y = '\0'; vsnprintf(buf, sizeof(buf), fmt, ap); #ifndef TESTMODE if (slg != 0 && (severity < LNLOG_SDEBUG || debugmode)) { syslog(severity, "%s", buf); } #endif /* not TESTMODE */ if (severity <= LNLOG_SERR) { /* check if environment demands kill on first error */ char *k = getenv("LN_LOG_ABORT_ON_ERROR"); if (k) abort(); } if (console && maylog_console) { /* always log LNLOG_SERR and more severe, regardless of verbosity */ if (context <= verbose+1 || severity <= LNLOG_SERR) { (void)fputs(buf, console); (void)fputc('\n', console); } } } void ln_log(int sev, int ctx, const char *format, ...) { va_list ap; va_start(ap, format); vln_log_core(1, stderr, sev, ctx, format, ap); va_end(ap); } void ln_log_so(int sev, int ctx, const char *format, ...) { va_list ap; va_start(ap, format); vln_log_core(1, stdout, sev, ctx, format, ap); va_end(ap); } void ln_log_prt(int sev, int ctx, const char *format, ...) { va_list ap; va_start(ap, format); vln_log_core(0, stderr, sev, ctx, format, ap); va_end(ap); } void ln_log_sys(int sev, int ctx, const char *format, ...) { va_list ap; va_start(ap, format); vln_log_core(1, NULL, sev, ctx, format, ap); va_end(ap); }