]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/rpcapd/log.c
bhyvectl(8): Normalize the man page date
[FreeBSD/FreeBSD.git] / contrib / libpcap / rpcapd / log.c
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996, 1998
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29
30 #ifdef _WIN32
31 #include <windows.h>
32 #else
33 #include <syslog.h>
34 #endif
35
36 #include "portability.h"
37
38 #include "log.h"
39
40 static int log_to_systemlog;
41 static int log_debug_messages;
42
43 static void rpcapd_vlog_stderr(log_priority,
44     PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
45
46 static void rpcapd_vlog_stderr(log_priority priority, const char *message, va_list ap)
47 {
48         const char *tag;
49
50         /*
51          * Squelch warnings from compilers that *don't* assume that
52          * priority always has a valid enum value and therefore don't
53          * assume that we'll always go through one of the case arms.
54          *
55          * If we have a default case, compilers that *do* assume that
56          * will then complain about the default case code being
57          * unreachable.
58          *
59          * Damned if you do, damned if you don't.
60          */
61         tag = "";
62
63         switch (priority) {
64
65         case LOGPRIO_DEBUG:
66                 tag = "DEBUG: ";
67                 break;
68
69         case LOGPRIO_INFO:
70                 tag = "";
71                 break;
72
73         case LOGPRIO_WARNING:
74                 tag = "warning: ";
75                 break;
76
77         case LOGPRIO_ERROR:
78                 tag = "error: ";
79                 break;
80         }
81
82         fprintf(stderr, "rpcapd: %s", tag);
83         vfprintf(stderr, message, ap);
84         putc('\n', stderr);
85 }
86
87 static void rpcapd_vlog_systemlog(log_priority,
88     PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
89
90 #ifdef _WIN32
91 #define MESSAGE_SUBKEY \
92     "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\rpcapd"
93
94 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
95     va_list ap)
96 {
97 #if 0
98         static int initialized = 0;
99         HKEY hey_handle;
100         static HANDLE log_handle;
101         WORD eventlog_type;
102         DWORD event_id;
103         char msgbuf[1024];
104         char *strings[1];
105
106         if (!initialized) {
107                 /*
108                  * Register our message stuff in the Registry.
109                  *
110                  * First, create the registry key for us.  If the key
111                  * already exists, this succeeds and returns a handle
112                  * for it.
113                  */
114                 if (RegCreateKey(HKEY_LOCAL_MACHINE, MESSAGE_SUBKEY,
115                     &key_handle) != ERROR_SUCCESS) {
116                         /*
117                          * Failed - give up and just log this message,
118                          * and all subsequent messages, to the
119                          * standard error.
120                          */
121                         log_to_systemlog = 0;
122                         initialized = 1;
123                         rpcapd_vlog_stderr(priority, message, ap);
124                         return;
125                 }
126                 log_handle = RegisterEventSource(NULL, "rpcapd");
127                 initialized = 1;
128         }
129
130         switch (priority) {
131
132         case LOGPRIO_DEBUG:
133                 //
134                 // XXX - what *should* we do about debug messages?
135                 //
136                 eventlog_type = EVENTLOG_INFORMATION_TYPE;
137                 event_id = RPCAPD_INFO_ID;
138                 break;
139
140         case LOGPRIO_INFO:
141                 eventlog_type = EVENTLOG_INFORMATION_TYPE;
142                 event_id = RPCAPD_INFO_ID;
143                 break;
144
145         case LOGPRIO_WARNING:
146                 eventlog_type = EVENTLOG_WARNING_TYPE;
147                 event_id = RPCAPD_WARNING_ID;
148                 break;
149
150         case LOGPRIO_ERROR:
151                 eventlog_type = EVENTLOG_ERROR_TYPE;
152                 event_id = RPCAPD_ERROR_ID;
153                 break;
154
155         default:
156                 /* Don't do this. */
157                 return;
158         }
159
160         vsprintf(msgbuf, message, ap);
161
162         strings[0] = msgbuf;
163         /*
164          * If this fails, how are we going to report it?
165          */
166         (void) ReportEvent(log_handle, eventlog_type, 0, event_id, NULL, 1, 0,
167             strings, NULL);
168 #else
169         rpcapd_vlog_stderr(priority, message, ap);
170 #endif
171 }
172 #else
173 static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
174     va_list ap)
175 {
176         static int initialized = 0;
177         int syslog_priority;
178
179         if (!initialized) {
180                 //
181                 // Open the log.
182                 //
183                 openlog("rpcapd", LOG_PID, LOG_DAEMON);
184                 initialized = 1;
185         }
186
187         switch (priority) {
188
189         case LOGPRIO_DEBUG:
190                 syslog_priority = LOG_DEBUG;
191                 break;
192
193         case LOGPRIO_INFO:
194                 syslog_priority = LOG_INFO;
195                 break;
196
197         case LOGPRIO_WARNING:
198                 syslog_priority = LOG_WARNING;
199                 break;
200
201         case LOGPRIO_ERROR:
202                 syslog_priority = LOG_ERR;
203                 break;
204
205         default:
206                 /* Don't do this. */
207                 return;
208         }
209
210 #ifdef HAVE_VSYSLOG
211         vsyslog(syslog_priority, message, ap);
212 #else
213         /*
214          * Thanks, IBM, for not providing vsyslog() in AIX!
215          *
216          * They also warn that the syslog functions shouldn't
217          * be used in multithreaded programs, but the only thing
218          * obvious that seems to make the syslog_r functions
219          * better is that they have an additional argument
220          * that points to the information that's static to
221          * the syslog code in non-thread-safe versions.  Most
222          * of that data is set by openlog(); since we already
223          * do an openlog before doing logging, and don't
224          * change that data afterwards, I suspect that, in
225          * practice, the regular syslog routines are OK for
226          * us (especially given that we'd end up having one
227          * static struct syslog_data anyway, which means we'd
228          * just be like the non-thread-safe version).
229          */
230         char logbuf[1024+1];
231
232         pcap_vsnprintf(logbuf, sizeof logbuf, message, ap);
233         syslog(syslog_priority, "%s", logbuf);
234 #endif
235 }
236 #endif
237
238 void rpcapd_log_set(int log_to_systemlog_arg, int log_debug_messages_arg)
239 {
240         log_debug_messages = log_debug_messages_arg;
241         log_to_systemlog = log_to_systemlog_arg;
242 }
243
244 void rpcapd_log(log_priority priority, const char *message, ...)
245 {
246         va_list ap;
247
248         if (priority != LOGPRIO_DEBUG || log_debug_messages) {
249                 va_start(ap, message);
250                 if (log_to_systemlog)
251                 {
252                         rpcapd_vlog_systemlog(priority, message, ap);
253                 }
254                 else
255                 {
256                         rpcapd_vlog_stderr(priority, message, ap);
257                 }
258                 va_end(ap);
259         }
260 }