1 /* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * 6 * As far as I am concerned, the code I have written for this software 7 * can be used freely for any purpose. Any derived versions of this 8 * software must be clearly marked as such, and if the derived work is 9 * incompatible with the protocol description in the RFC file, it must be 10 * called by a name other than "ssh" or "Secure Shell". 11 */ 12 /* 13 * Shared versions of debug(), log(), etc. 14 * 15 * Copyright (c) 2000 Markus Friedl. All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include "includes.h" 39 RCSID("$OpenBSD: log.c,v 1.9 2000/09/07 21:13:37 markus Exp $"); 40 41 #include "ssh.h" 42 #include "xmalloc.h" 43 44 /* Fatal messages. This function never returns. */ 45 46 void 47 fatal(const char *fmt,...) 48 { 49 va_list args; 50 va_start(args, fmt); 51 do_log(SYSLOG_LEVEL_FATAL, fmt, args); 52 va_end(args); 53 fatal_cleanup(); 54 } 55 56 /* Error messages that should be logged. */ 57 58 void 59 error(const char *fmt,...) 60 { 61 va_list args; 62 va_start(args, fmt); 63 do_log(SYSLOG_LEVEL_ERROR, fmt, args); 64 va_end(args); 65 } 66 67 /* Log this message (information that usually should go to the log). */ 68 69 void 70 log(const char *fmt,...) 71 { 72 va_list args; 73 va_start(args, fmt); 74 do_log(SYSLOG_LEVEL_INFO, fmt, args); 75 va_end(args); 76 } 77 78 /* More detailed messages (information that does not need to go to the log). */ 79 80 void 81 verbose(const char *fmt,...) 82 { 83 va_list args; 84 va_start(args, fmt); 85 do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); 86 va_end(args); 87 } 88 89 /* Debugging messages that should not be logged during normal operation. */ 90 91 void 92 debug(const char *fmt,...) 93 { 94 va_list args; 95 va_start(args, fmt); 96 do_log(SYSLOG_LEVEL_DEBUG, fmt, args); 97 va_end(args); 98 } 99 100 /* Fatal cleanup */ 101 102 struct fatal_cleanup { 103 struct fatal_cleanup *next; 104 void (*proc) (void *); 105 void *context; 106 }; 107 108 static struct fatal_cleanup *fatal_cleanups = NULL; 109 110 /* Registers a cleanup function to be called by fatal() before exiting. */ 111 112 void 113 fatal_add_cleanup(void (*proc) (void *), void *context) 114 { 115 struct fatal_cleanup *cu; 116 117 cu = xmalloc(sizeof(*cu)); 118 cu->proc = proc; 119 cu->context = context; 120 cu->next = fatal_cleanups; 121 fatal_cleanups = cu; 122 } 123 124 /* Removes a cleanup frunction to be called at fatal(). */ 125 126 void 127 fatal_remove_cleanup(void (*proc) (void *context), void *context) 128 { 129 struct fatal_cleanup **cup, *cu; 130 131 for (cup = &fatal_cleanups; *cup; cup = &cu->next) { 132 cu = *cup; 133 if (cu->proc == proc && cu->context == context) { 134 *cup = cu->next; 135 xfree(cu); 136 return; 137 } 138 } 139 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n", 140 (unsigned long) proc, (unsigned long) context); 141 } 142 143 /* Cleanup and exit */ 144 void 145 fatal_cleanup(void) 146 { 147 struct fatal_cleanup *cu, *next_cu; 148 static int called = 0; 149 150 if (called) 151 exit(255); 152 called = 1; 153 /* Call cleanup functions. */ 154 for (cu = fatal_cleanups; cu; cu = next_cu) { 155 next_cu = cu->next; 156 debug("Calling cleanup 0x%lx(0x%lx)", 157 (unsigned long) cu->proc, (unsigned long) cu->context); 158 (*cu->proc) (cu->context); 159 } 160 exit(255); 161 } 162 163 /* textual representation of log-facilities/levels */ 164 165 static struct { 166 const char *name; 167 SyslogFacility val; 168 } log_facilities[] = { 169 { "DAEMON", SYSLOG_FACILITY_DAEMON }, 170 { "USER", SYSLOG_FACILITY_USER }, 171 { "AUTH", SYSLOG_FACILITY_AUTH }, 172 { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, 173 { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, 174 { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, 175 { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, 176 { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, 177 { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, 178 { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, 179 { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, 180 { NULL, 0 } 181 }; 182 183 static struct { 184 const char *name; 185 LogLevel val; 186 } log_levels[] = 187 { 188 { "QUIET", SYSLOG_LEVEL_QUIET }, 189 { "FATAL", SYSLOG_LEVEL_FATAL }, 190 { "ERROR", SYSLOG_LEVEL_ERROR }, 191 { "INFO", SYSLOG_LEVEL_INFO }, 192 { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, 193 { "DEBUG", SYSLOG_LEVEL_DEBUG }, 194 { NULL, 0 } 195 }; 196 197 SyslogFacility 198 log_facility_number(char *name) 199 { 200 int i; 201 if (name != NULL) 202 for (i = 0; log_facilities[i].name; i++) 203 if (strcasecmp(log_facilities[i].name, name) == 0) 204 return log_facilities[i].val; 205 return (SyslogFacility) - 1; 206 } 207 208 LogLevel 209 log_level_number(char *name) 210 { 211 int i; 212 if (name != NULL) 213 for (i = 0; log_levels[i].name; i++) 214 if (strcasecmp(log_levels[i].name, name) == 0) 215 return log_levels[i].val; 216 return (LogLevel) - 1; 217 } 218