]> The Tcpdump Group git mirrors - libpcap/blob - rpcapd/log.c
Defer initialization of a log system to the first attempt to log to it.
[libpcap] / rpcapd / log.c
1 #include <stdio.h>
2 #include <stdarg.h>
3 #include <stdlib.h>
4
5 #ifdef _WIN32
6 #include <windows.h>
7 #else
8 #include <syslog.h>
9 #endif
10
11 #include "log.h"
12
13 static int log_to_systemlog;
14 static int log_debug_messages;
15
16 static void rpcapd_vlog_stderr(log_priority,
17 PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
18
19 static void rpcapd_vlog_stderr(log_priority priority, const char *message, va_list ap)
20 {
21 const char *tag;
22
23 /*
24 * Squelch warnings from compilers that *don't* assume that
25 * priority always has a valid enum value and therefore don't
26 * assume that we'll always go through one of the case arms.
27 *
28 * If we have a default case, compilers that *do* assume that
29 * will then complain about the default case code being
30 * unreachable.
31 *
32 * Damned if you do, damned if you don't.
33 */
34 tag = "";
35
36 switch (priority) {
37
38 case LOGPRIO_DEBUG:
39 tag = "DEBUG: ";
40 break;
41
42 case LOGPRIO_INFO:
43 tag = "";
44 break;
45
46 case LOGPRIO_WARNING:
47 tag = "warning: ";
48 break;
49
50 case LOGPRIO_ERROR:
51 tag = "error: ";
52 break;
53 }
54
55 fprintf(stderr, "rpcapd: %s", tag);
56 vfprintf(stderr, message, ap);
57 putc('\n', stderr);
58 }
59
60 static void rpcapd_vlog_systemlog(log_priority,
61 PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
62
63 #ifdef _WIN32
64 #define MESSAGE_SUBKEY \
65 "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\rpcapd"
66
67 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
68 va_list ap)
69 {
70 static int initialized = 0;
71 HKEY hey_handle;
72 static HANDLE log_handle;
73 WORD eventlog_type;
74 DWORD event_id;
75 char msgbuf[1024];
76 char *strings[1];
77
78 if (!initialized) {
79 /*
80 * Register our message stuff in the Registry.
81 *
82 * First, create the registry key for us. If the key
83 * already exists, this succeeds and returns a handle
84 * for it.
85 */
86 if (RegCreateKey(HKEY_LOCAL_MACHINE, MESSAGE_SUBKEY,
87 &key_handle) != ERROR_SUCCESS) {
88 /*
89 * Failed - give up and just log this message,
90 * and all subsequent messages, to the
91 * standard error.
92 */
93 log_to_systemlog = 0;
94 initialized = 1;
95 rpcapd_vlog_stderr(priority, message, ap);
96 return;
97 }
98 log_handle = RegisterEventSource(NULL, "rpcapd");
99 initialized = 1;
100 }
101
102 switch (priority) {
103
104 case LOGPRIO_DEBUG:
105 //
106 // XXX - what *should* we do about debug messages?
107 //
108 eventlog_type = EVENTLOG_INFORMATION_TYPE;
109 event_id = RPCAPD_INFO_ID;
110 break;
111
112 case LOGPRIO_INFO:
113 eventlog_type = EVENTLOG_INFORMATION_TYPE;
114 event_id = RPCAPD_INFO_ID;
115 break;
116
117 case LOGPRIO_WARNING:
118 eventlog_type = EVENTLOG_WARNING_TYPE;
119 event_id = RPCAPD_WARNING_ID;
120 break;
121
122 case LOGPRIO_ERROR:
123 eventlog_type = EVENTLOG_ERROR_TYPE;
124 event_id = RPCAPD_ERROR_ID;
125 break;
126
127 default:
128 /* Don't do this. */
129 return;
130 }
131
132 vsprintf(msgbuf, message, ap);
133
134 strings[0] = msgbuf;
135 /*
136 * If this fails, how are we going to report it?
137 */
138 (void) ReportEvent(log_handle, eventlog_type, 0, event_id, NULL, 1, 0,
139 strings, NULL);
140 }
141 #else
142 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
143 va_list ap)
144 {
145 static int initialized = 0;
146 int syslog_priority;
147
148 if (!initialized) {
149 //
150 // Open the log.
151 //
152 openlog("rpcapd", LOG_PID, LOG_DAEMON);
153 initialized = 1;
154 }
155
156 switch (priority) {
157
158 case LOGPRIO_DEBUG:
159 syslog_priority = LOG_DEBUG;
160 break;
161
162 case LOGPRIO_INFO:
163 syslog_priority = LOG_INFO;
164 break;
165
166 case LOGPRIO_WARNING:
167 syslog_priority = LOG_WARNING;
168 break;
169
170 case LOGPRIO_ERROR:
171 syslog_priority = LOG_ERR;
172 break;
173
174 default:
175 /* Don't do this. */
176 return;
177 }
178
179 vsyslog(syslog_priority, message, ap);
180 }
181 #endif
182
183 void rpcapd_log_set(int log_to_systemlog_arg, int log_debug_messages_arg)
184 {
185 log_debug_messages = log_debug_messages_arg;
186 log_to_systemlog = log_to_systemlog_arg;
187 }
188
189 void rpcapd_log(log_priority priority, const char *message, ...)
190 {
191 va_list ap;
192
193 if (priority != LOGPRIO_DEBUG || log_debug_messages) {
194 va_start(ap, message);
195 if (log_to_systemlog)
196 {
197 rpcapd_vlog_systemlog(priority, message, ap);
198 }
199 else
200 {
201 rpcapd_vlog_stderr(priority, message, ap);
202 }
203 va_end(ap);
204 }
205 }