1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#include "wantassert.h"
#include "leafnode.h"
#include "ln_log.h"
#include <stdarg.h>
#include <assert.h>
#include <syslog.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h> /* for getenv */
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
#include <signal.h> /* 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);
}
|