X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/d83ebe4ab0cf26a110ffa181a567e5c0f456d7a8..HEAD:/log.c diff --git a/log.c b/log.c index 5a28438f..4a8239b9 100644 --- a/log.c +++ b/log.c @@ -1,3 +1,4 @@ +/* $OpenBSD: log.c,v 1.41 2008/06/10 04:50:25 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,12 +35,22 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.27 2003/05/18 23:22:01 deraadt Exp $"); -#include "log.h" -#include "xmalloc.h" +#include +#include +#include +#include +#include #include +#include +#include +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +# include +#endif + +#include "xmalloc.h" +#include "log.h" static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 1; @@ -48,6 +59,9 @@ static char *argv0; extern char *__progname; +#define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) +#define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) + /* textual representation of log-facilities/levels */ static struct { @@ -100,6 +114,17 @@ log_facility_number(char *name) return SYSLOG_FACILITY_NOT_SET; } +const char * +log_facility_name(SyslogFacility facility) +{ + u_int i; + + for (i = 0; log_facilities[i].name; i++) + if (log_facilities[i].val == facility) + return log_facilities[i].name; + return NULL; +} + LogLevel log_level_number(char *name) { @@ -112,6 +137,17 @@ log_level_number(char *name) return SYSLOG_LEVEL_NOT_SET; } +const char * +log_level_name(LogLevel level) +{ + u_int i; + + for (i = 0; log_levels[i].name != NULL; i++) + if (log_levels[i].val == level) + return log_levels[i].name; + return NULL; +} + /* Error messages that should be logged. */ void @@ -124,6 +160,20 @@ error(const char *fmt,...) va_end(args); } +void +sigdie(const char *fmt,...) +{ +#ifdef DO_LOG_SAFE_IN_SIGHAND + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); +#endif + _exit(1); +} + + /* Log this message (information that usually should go to the log). */ void @@ -180,83 +230,6 @@ debug3(const char *fmt,...) va_end(args); } -/* Fatal cleanup */ - -struct fatal_cleanup { - struct fatal_cleanup *next; - void (*proc) (void *); - void *context; -}; - -static struct fatal_cleanup *fatal_cleanups = NULL; - -/* Registers a cleanup function to be called by fatal() before exiting. */ - -void -fatal_add_cleanup(void (*proc) (void *), void *context) -{ - struct fatal_cleanup *cu; - - cu = xmalloc(sizeof(*cu)); - cu->proc = proc; - cu->context = context; - cu->next = fatal_cleanups; - fatal_cleanups = cu; -} - -/* Removes a cleanup frunction to be called at fatal(). */ - -void -fatal_remove_cleanup(void (*proc) (void *context), void *context) -{ - struct fatal_cleanup **cup, *cu; - - for (cup = &fatal_cleanups; *cup; cup = &cu->next) { - cu = *cup; - if (cu->proc == proc && cu->context == context) { - *cup = cu->next; - xfree(cu); - return; - } - } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx", - (u_long) proc, (u_long) context); -} - -/* Remove all cleanups, to be called after fork() */ -void -fatal_remove_all_cleanups(void) -{ - struct fatal_cleanup *cu, *next_cu; - - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - xfree(cu); - } - fatal_cleanups = NULL; -} - -/* Cleanup and exit */ -void -fatal_cleanup(void) -{ - struct fatal_cleanup *cu, *next_cu; - static int called = 0; - - if (called) - exit(255); - called = 1; - /* Call cleanup functions. */ - for (cu = fatal_cleanups; cu; cu = next_cu) { - next_cu = cu->next; - debug("Calling cleanup 0x%lx(0x%lx)", - (u_long) cu->proc, (u_long) cu->context); - (*cu->proc) (cu->context); - } - exit(255); -} - - /* * Initialize the log. */ @@ -264,6 +237,10 @@ fatal_cleanup(void) void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + struct syslog_data sdata = SYSLOG_DATA_INIT; +#endif + argv0 = av0; switch (level) { @@ -332,6 +309,19 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) (int) facility); exit(1); } + + /* + * If an external library (eg libwrap) attempts to use syslog + * immediately after reexec, syslog may be pointing to the wrong + * facility, so we force an open/close of syslog here. + */ +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); + closelog_r(&sdata); +#else + openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); + closelog(); +#endif } #define MSGBUFSIZ 1024 @@ -339,13 +329,14 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) void do_log(LogLevel level, const char *fmt, va_list args) { -#ifdef OPENLOG_R +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) struct syslog_data sdata = SYSLOG_DATA_INIT; #endif char msgbuf[MSGBUFSIZ]; char fmtbuf[MSGBUFSIZ]; char *txt = NULL; int pri = LOG_INFO; + int saved_errno = errno; if (level > log_level) return; @@ -390,16 +381,15 @@ do_log(LogLevel level, const char *fmt, va_list args) } else { vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); } - /* Escape magic chars in output. */ - strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), VIS_SAFE|VIS_OCTAL); - + strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), + log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS); if (log_on_stderr) { - snprintf(fmtbuf, sizeof fmtbuf, "%s\r\n", msgbuf); - write(STDERR_FILENO, fmtbuf, strlen(fmtbuf)); + snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); + write(STDERR_FILENO, msgbuf, strlen(msgbuf)); } else { -#ifdef OPENLOG_R +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); - syslog_r(pri, &sdata, "%.500s", msgbuf); + syslog_r(pri, &sdata, "%.500s", fmtbuf); closelog_r(&sdata); #else openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); @@ -407,4 +397,5 @@ do_log(LogLevel level, const char *fmt, va_list args) closelog(); #endif } + errno = saved_errno; }