version 1.15, 2001/01/21 19:05:51 |
version 1.16, 2001/03/03 23:59:34 |
|
|
* called by a name other than "ssh" or "Secure Shell". |
* called by a name other than "ssh" or "Secure Shell". |
*/ |
*/ |
/* |
/* |
* Shared versions of debug(), log(), etc. |
|
* |
|
* Copyright (c) 2000 Markus Friedl. All rights reserved. |
* Copyright (c) 2000 Markus Friedl. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
|
|
#include "log.h" |
#include "log.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
|
|
|
#include <syslog.h> |
|
|
|
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. */ |
/* Fatal messages. This function never returns. */ |
|
|
void |
void |
|
|
} |
} |
} |
} |
fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", |
fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", |
(u_long) proc, (u_long) context); |
(u_long) proc, (u_long) context); |
} |
} |
|
|
/* Cleanup and exit */ |
/* Cleanup and exit */ |
|
|
exit(255); |
exit(255); |
} |
} |
|
|
/* textual representation of log-facilities/levels */ |
|
|
|
static struct { |
/* |
const char *name; |
* Initialize the log. |
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 { |
void |
const char *name; |
log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) |
LogLevel val; |
|
} log_levels[] = |
|
{ |
{ |
{ "QUIET", SYSLOG_LEVEL_QUIET }, |
argv0 = av0; |
{ "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 |
switch (level) { |
log_facility_number(char *name) |
case SYSLOG_LEVEL_QUIET: |
{ |
case SYSLOG_LEVEL_FATAL: |
int i; |
case SYSLOG_LEVEL_ERROR: |
if (name != NULL) |
case SYSLOG_LEVEL_INFO: |
for (i = 0; log_facilities[i].name; i++) |
case SYSLOG_LEVEL_VERBOSE: |
if (strcasecmp(log_facilities[i].name, name) == 0) |
case SYSLOG_LEVEL_DEBUG1: |
return log_facilities[i].val; |
case SYSLOG_LEVEL_DEBUG2: |
return (SyslogFacility) - 1; |
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 |
#define MSGBUFSIZ 1024 |
log_level_number(char *name) |
|
|
void |
|
do_log(LogLevel level, const char *fmt, va_list args) |
{ |
{ |
int i; |
char msgbuf[MSGBUFSIZ]; |
if (name != NULL) |
char fmtbuf[MSGBUFSIZ]; |
for (i = 0; log_levels[i].name; i++) |
char *txt = NULL; |
if (strcasecmp(log_levels[i].name, name) == 0) |
int pri = LOG_INFO; |
return log_levels[i].val; |
|
return (LogLevel) - 1; |
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(); |
|
} |
} |
} |