log.c revision 1.3
1/* 2 3Shared versions of debug(), log(), etc. 4 5*/ 6 7#include "includes.h" 8RCSID("$OpenBSD: log.c,v 1.3 1999/11/22 21:02:38 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{ 73 struct fatal_cleanup *next; 74 void (*proc)(void *); 75 void *context; 76}; 77 78static struct fatal_cleanup *fatal_cleanups = NULL; 79 80/* Registers a cleanup function to be called by fatal() before exiting. */ 81 82void 83fatal_add_cleanup(void (*proc)(void *), void *context) 84{ 85 struct fatal_cleanup *cu; 86 87 cu = xmalloc(sizeof(*cu)); 88 cu->proc = proc; 89 cu->context = context; 90 cu->next = fatal_cleanups; 91 fatal_cleanups = cu; 92} 93 94/* Removes a cleanup frunction to be called at fatal(). */ 95 96void 97fatal_remove_cleanup(void (*proc)(void *context), void *context) 98{ 99 struct fatal_cleanup **cup, *cu; 100 101 for (cup = &fatal_cleanups; *cup; cup = &cu->next) 102 { 103 cu = *cup; 104 if (cu->proc == proc && cu->context == context) 105 { 106 *cup = cu->next; 107 xfree(cu); 108 return; 109 } 110 } 111 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", 112 (unsigned long)proc, (unsigned long)context); 113} 114 115/* Cleanup and exit */ 116void 117fatal_cleanup(void) 118{ 119 struct fatal_cleanup *cu, *next_cu; 120 static int called = 0; 121 if (called) 122 exit(255); 123 called = 1; 124 125 /* Call cleanup functions. */ 126 for (cu = fatal_cleanups; cu; cu = next_cu) 127 { 128 next_cu = cu->next; 129 debug("Calling cleanup 0x%lx(0x%lx)", 130 (unsigned long)cu->proc, (unsigned long)cu->context); 131 (*cu->proc)(cu->context); 132 } 133 134 exit(255); 135} 136 137/* textual representation of log-facilities/levels */ 138 139 140static struct 141{ 142 const char *name; 143 SyslogFacility val; 144} log_facilities[] = 145{ 146 { "DAEMON", SYSLOG_FACILITY_DAEMON }, 147 { "USER", SYSLOG_FACILITY_USER }, 148 { "AUTH", SYSLOG_FACILITY_AUTH }, 149 { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, 150 { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, 151 { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, 152 { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, 153 { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, 154 { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, 155 { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, 156 { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, 157 { NULL, 0 } 158}; 159 160static struct 161{ 162 const char *name; 163 LogLevel val; 164} log_levels[] = 165{ 166 { "QUIET", SYSLOG_LEVEL_QUIET }, 167 { "FATAL", SYSLOG_LEVEL_FATAL }, 168 { "ERROR", SYSLOG_LEVEL_ERROR }, 169 { "INFO", SYSLOG_LEVEL_INFO }, 170 { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, 171 { "DEBUG", SYSLOG_LEVEL_DEBUG }, 172 { NULL, 0 } 173}; 174 175SyslogFacility 176log_facility_number(char *name) 177{ 178 int i; 179 if (name != NULL) 180 for (i = 0; log_facilities[i].name; i++) 181 if (strcasecmp(log_facilities[i].name, name) == 0) 182 return log_facilities[i].val; 183 return (SyslogFacility)-1; 184} 185 186LogLevel 187log_level_number(char *name) 188{ 189 int i; 190 if (name != NULL) 191 for (i = 0; log_levels[i].name; i++) 192 if (strcasecmp(log_levels[i].name, name) == 0) 193 return log_levels[i].val; 194 return (LogLevel)-1; 195} 196