blob: fce96b01dace6bf1360e2027784bcd0cd775235b [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
2
3log-server.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved
9
10Created: Mon Mar 20 21:19:30 1995 ylo
11
12Server-side versions of debug(), log(), etc. These normally send the output
13to the system log.
14
15*/
16
17#include "includes.h"
18RCSID("$Id: log-server.c,v 1.1 1999/10/27 03:42:44 damien Exp $");
19
20#include <syslog.h>
21#include "packet.h"
22#include "xmalloc.h"
23#include "ssh.h"
24
25static int log_debug = 0;
26static int log_quiet = 0;
27static int log_on_stderr = 0;
28
29/* Initialize the log.
30 av0 program name (should be argv[0])
31 on_stderr print also on stderr
32 debug send debugging messages to system log
33 quiet don\'t log anything
34 */
35
36void log_init(char *av0, int on_stderr, int debug, int quiet,
37 SyslogFacility facility)
38{
39 int log_facility;
40
41 switch (facility)
42 {
43 case SYSLOG_FACILITY_DAEMON:
44 log_facility = LOG_DAEMON;
45 break;
46 case SYSLOG_FACILITY_USER:
47 log_facility = LOG_USER;
48 break;
49 case SYSLOG_FACILITY_AUTH:
50 log_facility = LOG_AUTH;
51 break;
52 case SYSLOG_FACILITY_LOCAL0:
53 log_facility = LOG_LOCAL0;
54 break;
55 case SYSLOG_FACILITY_LOCAL1:
56 log_facility = LOG_LOCAL1;
57 break;
58 case SYSLOG_FACILITY_LOCAL2:
59 log_facility = LOG_LOCAL2;
60 break;
61 case SYSLOG_FACILITY_LOCAL3:
62 log_facility = LOG_LOCAL3;
63 break;
64 case SYSLOG_FACILITY_LOCAL4:
65 log_facility = LOG_LOCAL4;
66 break;
67 case SYSLOG_FACILITY_LOCAL5:
68 log_facility = LOG_LOCAL5;
69 break;
70 case SYSLOG_FACILITY_LOCAL6:
71 log_facility = LOG_LOCAL6;
72 break;
73 case SYSLOG_FACILITY_LOCAL7:
74 log_facility = LOG_LOCAL7;
75 break;
76 default:
77 fprintf(stderr, "Unrecognized internal syslog facility code %d\n",
78 (int)facility);
79 exit(1);
80 }
81
82 log_debug = debug;
83 log_quiet = quiet;
84 log_on_stderr = on_stderr;
85 closelog(); /* Close any previous log. */
86 openlog(av0, LOG_PID, log_facility);
87}
88
89#define MSGBUFSIZE 1024
90
91#define DECL_MSGBUF char msgbuf[MSGBUFSIZE]
92
93/* Log this message (information that usually should go to the log). */
94
95void log(const char *fmt, ...)
96{
97 va_list args;
98 DECL_MSGBUF;
99 if (log_quiet)
100 return;
101 va_start(args, fmt);
102 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
103 va_end(args);
104 if (log_on_stderr)
105 fprintf(stderr, "log: %s\n", msgbuf);
106 syslog(LOG_INFO, "log: %.500s", msgbuf);
107}
108
109/* Debugging messages that should not be logged during normal operation. */
110
111void debug(const char *fmt, ...)
112{
113 va_list args;
114 DECL_MSGBUF;
115 if (!log_debug || log_quiet)
116 return;
117 va_start(args, fmt);
118 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
119 va_end(args);
120 if (log_on_stderr)
121 fprintf(stderr, "debug: %s\n", msgbuf);
122 syslog(LOG_DEBUG, "debug: %.500s", msgbuf);
123}
124
125/* Error messages that should be logged. */
126
127void error(const char *fmt, ...)
128{
129 va_list args;
130 DECL_MSGBUF;
131 if (log_quiet)
132 return;
133 va_start(args, fmt);
134 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
135 va_end(args);
136 if (log_on_stderr)
137 fprintf(stderr, "error: %s\n", msgbuf);
138 syslog(LOG_ERR, "error: %.500s", msgbuf);
139}
140
141struct fatal_cleanup
142{
143 struct fatal_cleanup *next;
144 void (*proc)(void *);
145 void *context;
146};
147
148static struct fatal_cleanup *fatal_cleanups = NULL;
149
150/* Registers a cleanup function to be called by fatal() before exiting. */
151
152void fatal_add_cleanup(void (*proc)(void *), void *context)
153{
154 struct fatal_cleanup *cu;
155
156 cu = xmalloc(sizeof(*cu));
157 cu->proc = proc;
158 cu->context = context;
159 cu->next = fatal_cleanups;
160 fatal_cleanups = cu;
161}
162
163/* Removes a cleanup frunction to be called at fatal(). */
164
165void fatal_remove_cleanup(void (*proc)(void *context), void *context)
166{
167 struct fatal_cleanup **cup, *cu;
168
169 for (cup = &fatal_cleanups; *cup; cup = &cu->next)
170 {
171 cu = *cup;
172 if (cu->proc == proc && cu->context == context)
173 {
174 *cup = cu->next;
175 xfree(cu);
176 return;
177 }
178 }
179 fatal("fatal_remove_cleanup: no such cleanup function: 0x%lx 0x%lx\n",
180 (unsigned long)proc, (unsigned long)context);
181}
182
183/* Fatal messages. This function never returns. */
184
185void fatal(const char *fmt, ...)
186{
187 va_list args;
188 struct fatal_cleanup *cu, *next_cu;
189 static int fatal_called = 0;
190#if defined(KRB4)
191 extern char *ticket;
192#endif /* KRB4 */
193 DECL_MSGBUF;
194
195 if (log_quiet)
196 exit(1);
197 va_start(args, fmt);
198 vsnprintf(msgbuf, MSGBUFSIZE, fmt, args);
199 va_end(args);
200 if (log_on_stderr)
201 fprintf(stderr, "fatal: %s\n", msgbuf);
202 syslog(LOG_ERR, "fatal: %.500s", msgbuf);
203
204 if (fatal_called)
205 exit(1);
206 fatal_called = 1;
207
208 /* Call cleanup functions. */
209 for (cu = fatal_cleanups; cu; cu = next_cu)
210 {
211 next_cu = cu->next;
212 debug("Calling cleanup 0x%lx(0x%lx)",
213 (unsigned long)cu->proc, (unsigned long)cu->context);
214 (*cu->proc)(cu->context);
215 }
216#if defined(KRB4)
217 /* If you forwarded a ticket you get one shot for proper
218 authentication. */
219 /* If tgt was passed unlink file */
220 if (ticket)
221 {
222 if (strcmp(ticket,"none"))
223 unlink(ticket);
224 else
225 ticket = NULL;
226 }
227#endif /* KRB4 */
228
229 /* If local XAUTHORITY was created, remove it. */
230 if (xauthfile) unlink(xauthfile);
231
232 exit(1);
233}