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