log.c revision 1.4
1/* 2 3Shared versions of debug(), log(), etc. 4 5*/ 6 7#include "includes.h" 8RCSID("$OpenBSD: log.c,v 1.4 1999/11/23 22:25:54 markus Exp $"); 9 10#include "ssh.h" 11#include "xmalloc.h" 12 13/* Fatal messages. This function never returns. */ 14 15void 16fatal(const char *fmt,...) 17{ 18 va_list args; 19 va_start(args, fmt); 20 do_log(SYSLOG_LEVEL_FATAL, fmt, args); 21 va_end(args); 22 fatal_cleanup(); 23} 24 25/* Error messages that should be logged. */ 26 27void 28error(const char *fmt,...) 29{ 30 va_list args; 31 va_start(args, fmt); 32 do_log(SYSLOG_LEVEL_ERROR, fmt, args); 33 va_end(args); 34} 35 36/* Log this message (information that usually should go to the log). */ 37 38void 39log(const char *fmt,...) 40{ 41 va_list args; 42 va_start(args, fmt); 43 do_log(SYSLOG_LEVEL_INFO, fmt, args); 44 va_end(args); 45} 46 47/* More detailed messages (information that does not need to go to the log). */ 48 49void 50verbose(const char *fmt,...) 51{ 52 va_list args; 53 va_start(args, fmt); 54 do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); 55 va_end(args); 56} 57 58/* Debugging messages that should not be logged during normal operation. */ 59 60void 61debug(const char *fmt,...) 62{ 63 va_list args; 64 va_start(args, fmt); 65 do_log(SYSLOG_LEVEL_DEBUG, fmt, args); 66 va_end(args); 67} 68 69/* Fatal cleanup */ 70 71struct fatal_cleanup { 72 struct fatal_cleanup *next; 73 void (*proc) (void *); 74 void *context; 75}; 76 77static struct fatal_cleanup *fatal_cleanups = NULL; 78 79/* Registers a cleanup function to be called by fatal() before exiting. */ 80 81void 82fatal_add_cleanup(void (*proc) (void *), void *context) 83{ 84 struct fatal_cleanup *cu; 85 86 cu = xmalloc(sizeof(*cu)); 87 cu->proc = proc; 88 cu->context = context; 89 cu->next = fatal_cleanups; 90 fatal_cleanups = cu; 91} 92 93/* Removes a cleanup frunction to be called at fatal(). */ 94 95void 96fatal_remove_cleanup(void (*proc) (void *context), void *context) 97{ 98 struct fatal_cleanup **cup, *cu; 99 100 for (cup = &fatal_cleanups; *cup; cup = &cu->next) { 101 cu = *cup; 102 if (cu->proc == proc && cu->context == context) { 103 *cup = cu->next; 104 xfree(cu); 105 return; 106 } 107 } 108 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", 109 (unsigned long) proc, (unsigned long) context); 110} 111 112/* Cleanup and exit */ 113void 114fatal_cleanup(void) 115{ 116 struct fatal_cleanup *cu, *next_cu; 117 static int called = 0; 118 119 if (called) 120 exit(255); 121 called = 1; 122 /* Call cleanup functions. */ 123 for (cu = fatal_cleanups; cu; cu = next_cu) { 124 next_cu = cu->next; 125 debug("Calling cleanup 0x%lx(0x%lx)", 126 (unsigned long) cu->proc, (unsigned long) cu->context); 127 (*cu->proc) (cu->context); 128 } 129 exit(255); 130} 131 132/* textual representation of log-facilities/levels */ 133 134static struct { 135 const char *name; 136 SyslogFacility val; 137} log_facilities[] = { 138 { "DAEMON", SYSLOG_FACILITY_DAEMON }, 139 { "USER", SYSLOG_FACILITY_USER }, 140 { "AUTH", SYSLOG_FACILITY_AUTH }, 141 { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, 142 { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, 143 { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, 144 { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, 145 { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, 146 { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, 147 { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, 148 { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, 149 { NULL, 0 } 150}; 151 152static struct { 153 const char *name; 154 LogLevel val; 155} log_levels[] = 156{ 157 { "QUIET", SYSLOG_LEVEL_QUIET }, 158 { "FATAL", SYSLOG_LEVEL_FATAL }, 159 { "ERROR", SYSLOG_LEVEL_ERROR }, 160 { "INFO", SYSLOG_LEVEL_INFO }, 161 { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, 162 { "DEBUG", SYSLOG_LEVEL_DEBUG }, 163 { NULL, 0 } 164}; 165 166SyslogFacility 167log_facility_number(char *name) 168{ 169 int i; 170 if (name != NULL) 171 for (i = 0; log_facilities[i].name; i++) 172 if (strcasecmp(log_facilities[i].name, name) == 0) 173 return log_facilities[i].val; 174 return (SyslogFacility) - 1; 175} 176 177LogLevel 178log_level_number(char *name) 179{ 180 int i; 181 if (name != NULL) 182 for (i = 0; log_levels[i].name; i++) 183 if (strcasecmp(log_levels[i].name, name) == 0) 184 return log_levels[i].val; 185 return (LogLevel) - 1; 186} 187