=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/log.c,v retrieving revision 1.11 retrieving revision 1.11.2.3 diff -u -r1.11 -r1.11.2.3 --- src/usr.bin/ssh/log.c 2000/09/30 16:27:43 1.11 +++ src/usr.bin/ssh/log.c 2001/03/21 19:46:25 1.11.2.3 @@ -10,8 +10,6 @@ * called by a name other than "ssh" or "Secure Shell". */ /* - * Shared versions of debug(), log(), etc. - * * Copyright (c) 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,11 +34,78 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.11 2000/09/30 16:27:43 markus Exp $"); +RCSID("$OpenBSD: log.c,v 1.11.2.3 2001/03/21 19:46:25 jason Exp $"); -#include "ssh.h" +#include "log.h" #include "xmalloc.h" +#include + +static LogLevel log_level = SYSLOG_LEVEL_INFO; +static int log_on_stderr = 1; +static int log_facility = LOG_AUTH; +static char *argv0; + +extern char *__progname; + +/* textual representation of log-facilities/levels */ + +static struct { + const char *name; + SyslogFacility val; +} log_facilities[] = { + { "DAEMON", SYSLOG_FACILITY_DAEMON }, + { "USER", SYSLOG_FACILITY_USER }, + { "AUTH", SYSLOG_FACILITY_AUTH }, + { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, + { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, + { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, + { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, + { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, + { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, + { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, + { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, + { NULL, 0 } +}; + +static struct { + const char *name; + LogLevel val; +} log_levels[] = +{ + { "QUIET", SYSLOG_LEVEL_QUIET }, + { "FATAL", SYSLOG_LEVEL_FATAL }, + { "ERROR", SYSLOG_LEVEL_ERROR }, + { "INFO", SYSLOG_LEVEL_INFO }, + { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, + { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, + { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, + { NULL, 0 } +}; + +SyslogFacility +log_facility_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_facilities[i].name; i++) + if (strcasecmp(log_facilities[i].name, name) == 0) + return log_facilities[i].val; + return (SyslogFacility) - 1; +} + +LogLevel +log_level_number(char *name) +{ + int i; + if (name != NULL) + for (i = 0; log_levels[i].name; i++) + if (strcasecmp(log_levels[i].name, name) == 0) + return log_levels[i].val; + return (LogLevel) - 1; +} /* Fatal messages. This function never returns. */ void @@ -154,8 +219,8 @@ return; } } - fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", - (unsigned long) proc, (unsigned long) context); + fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx", + (u_long) proc, (u_long) context); } /* Cleanup and exit */ @@ -172,67 +237,143 @@ for (cu = fatal_cleanups; cu; cu = next_cu) { next_cu = cu->next; debug("Calling cleanup 0x%lx(0x%lx)", - (unsigned long) cu->proc, (unsigned long) cu->context); + (u_long) cu->proc, (u_long) cu->context); (*cu->proc) (cu->context); } exit(255); } -/* textual representation of log-facilities/levels */ -static struct { - const char *name; - SyslogFacility val; -} log_facilities[] = { - { "DAEMON", SYSLOG_FACILITY_DAEMON }, - { "USER", SYSLOG_FACILITY_USER }, - { "AUTH", SYSLOG_FACILITY_AUTH }, - { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, - { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, - { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, - { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, - { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, - { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, - { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, - { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, - { NULL, 0 } -}; +/* + * Initialize the log. + */ -static struct { - const char *name; - LogLevel val; -} log_levels[] = +void +log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) { - { "QUIET", SYSLOG_LEVEL_QUIET }, - { "FATAL", SYSLOG_LEVEL_FATAL }, - { "ERROR", SYSLOG_LEVEL_ERROR }, - { "INFO", SYSLOG_LEVEL_INFO }, - { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, - { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, - { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, - { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, - { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, - { NULL, 0 } -}; + argv0 = av0; -SyslogFacility -log_facility_number(char *name) -{ - int i; - if (name != NULL) - for (i = 0; log_facilities[i].name; i++) - if (strcasecmp(log_facilities[i].name, name) == 0) - return log_facilities[i].val; - return (SyslogFacility) - 1; + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG1: + case SYSLOG_LEVEL_DEBUG2: + case SYSLOG_LEVEL_DEBUG3: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int) level); + exit(1); + } + + log_on_stderr = on_stderr; + if (on_stderr) + return; + + switch (facility) { + case SYSLOG_FACILITY_DAEMON: + log_facility = LOG_DAEMON; + break; + case SYSLOG_FACILITY_USER: + log_facility = LOG_USER; + break; + case SYSLOG_FACILITY_AUTH: + log_facility = LOG_AUTH; + break; + case SYSLOG_FACILITY_LOCAL0: + log_facility = LOG_LOCAL0; + break; + case SYSLOG_FACILITY_LOCAL1: + log_facility = LOG_LOCAL1; + break; + case SYSLOG_FACILITY_LOCAL2: + log_facility = LOG_LOCAL2; + break; + case SYSLOG_FACILITY_LOCAL3: + log_facility = LOG_LOCAL3; + break; + case SYSLOG_FACILITY_LOCAL4: + log_facility = LOG_LOCAL4; + break; + case SYSLOG_FACILITY_LOCAL5: + log_facility = LOG_LOCAL5; + break; + case SYSLOG_FACILITY_LOCAL6: + log_facility = LOG_LOCAL6; + break; + case SYSLOG_FACILITY_LOCAL7: + log_facility = LOG_LOCAL7; + break; + default: + fprintf(stderr, + "Unrecognized internal syslog facility code %d\n", + (int) facility); + exit(1); + } } -LogLevel -log_level_number(char *name) +#define MSGBUFSIZ 1024 + +void +do_log(LogLevel level, const char *fmt, va_list args) { - int i; - if (name != NULL) - for (i = 0; log_levels[i].name; i++) - if (strcasecmp(log_levels[i].name, name) == 0) - return log_levels[i].val; - return (LogLevel) - 1; + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; + char *txt = NULL; + int pri = LOG_INFO; + + if (level > log_level) + return; + + switch (level) { + case SYSLOG_LEVEL_FATAL: + if (!log_on_stderr) + txt = "fatal"; + pri = LOG_CRIT; + break; + case SYSLOG_LEVEL_ERROR: + if (!log_on_stderr) + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_VERBOSE: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG1: + txt = "debug1"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG2: + txt = "debug2"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG3: + txt = "debug3"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; + } + if (txt != NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + } else { + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } + if (log_on_stderr) { + fprintf(stderr, "%s\r\n", msgbuf); + } else { + openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); + syslog(pri, "%.500s", msgbuf); + closelog(); + } }