]> The Tcpdump Group git mirrors - libpcap/blob - rpcapd/log.c
Support logging rpcapd messages to the "system log".
[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 static HANDLE log_handle = INVALID_HANDLE;
65
66 #define MESSAGE_SUBKEY \
67 "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\rpcapd"
68
69 static void rpcapd_log_init(void)
70 {
71 if (log_to_systemlog)
72 {
73 HKEY hey_handle;
74
75 /*
76 * Register our message stuff in the Registry.
77 *
78 * First, create the registry key for us. If the key
79 * already exists, this succeeds and returns a handle
80 * for it.
81 */
82 if (RegCreateKey(HKEY_LOCAL_MACHINE, MESSAGE_SUBKEY,
83 &key_handle) != ERROR_SUCCESS) {
84 /*
85 * Failed - give up and just log to the
86 * standard error.
87 */
88 log_to_systemlog = 0;
89 return;
90 }
91 log_handle = RegisterEventSource(NULL, "rpcapd");
92 }
93 }
94
95 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
96 va_list ap)
97 {
98 WORD eventlog_type;
99 DWORD event_id;
100 char msgbuf[1024];
101 char *strings[1];
102
103 if (log_handle == INVALID_HANDLE) {
104 /* Failed to initialize, or haven't tried */
105 return;
106 }
107
108 switch (priority) {
109
110 case LOGPRIO_DEBUG:
111 //
112 // XXX - what *should* we do about debug messages?
113 //
114 eventlog_type = EVENTLOG_INFORMATION_TYPE;
115 event_id = RPCAPD_INFO_ID;
116 break;
117
118 case LOGPRIO_INFO:
119 eventlog_type = EVENTLOG_INFORMATION_TYPE;
120 event_id = RPCAPD_INFO_ID;
121 break;
122
123 case LOGPRIO_WARNING:
124 eventlog_type = EVENTLOG_WARNING_TYPE;
125 event_id = RPCAPD_WARNING_ID;
126 break;
127
128 case LOGPRIO_ERROR:
129 eventlog_type = EVENTLOG_ERROR_TYPE;
130 event_id = RPCAPD_ERROR_ID;
131 break;
132
133 default:
134 /* Don't do this. */
135 return;
136 }
137
138 vsprintf(msgbuf, message, ap);
139
140 strings[0] = msgbuf;
141 /*
142 * If this fails, how are we going to report it?
143 */
144 (void) ReportEvent(log_handle, eventlog_type, 0, event_id, NULL, 1, 0,
145 strings, NULL);
146 }
147 #else
148 static void rpcapd_log_init(void)
149 {
150 if (log_to_systemlog)
151 {
152 openlog("rpcapd", LOG_PID, LOG_DAEMON);
153 }
154 }
155
156 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
157 va_list ap)
158 {
159 int syslog_priority;
160
161 switch (priority) {
162
163 case LOGPRIO_DEBUG:
164 syslog_priority = LOG_DEBUG;
165 break;
166
167 case LOGPRIO_INFO:
168 syslog_priority = LOG_INFO;
169 break;
170
171 case LOGPRIO_WARNING:
172 syslog_priority = LOG_WARNING;
173 break;
174
175 case LOGPRIO_ERROR:
176 syslog_priority = LOG_ERR;
177 break;
178
179 default:
180 /* Don't do this. */
181 return;
182 }
183
184 vsyslog(syslog_priority, message, ap);
185 }
186 #endif
187
188 void rpcapd_log_set(int log_to_systemlog_arg, int log_debug_messages_arg)
189 {
190 log_debug_messages = log_debug_messages_arg;
191 log_to_systemlog = log_to_systemlog_arg;
192 }
193
194 void rpcapd_log(log_priority priority, const char *message, ...)
195 {
196 static int initialized = 0;
197 va_list ap;
198
199 if (!initialized) {
200 //
201 // Initialize the logging system.
202 //
203 rpcapd_log_init();
204 initialized = 1;
205 }
206
207 if (priority != LOGPRIO_DEBUG || log_debug_messages) {
208 va_start(ap, message);
209 if (log_to_systemlog)
210 {
211 rpcapd_vlog_systemlog(priority, message, ap);
212 }
213 else
214 {
215 rpcapd_vlog_stderr(priority, message, ap);
216 }
217 va_end(ap);
218 }
219 }