diff options
Diffstat (limited to 'rpcapd/log.c')
-rw-r--r-- | rpcapd/log.c | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/rpcapd/log.c b/rpcapd/log.c new file mode 100644 index 0000000..7b5fee5 --- /dev/null +++ b/rpcapd/log.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996, 1998 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by the University of California, + * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of + * the University nor the names of its contributors may be used to endorse + * or promote products derived from this software without specific prior + * written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> + +#ifdef _WIN32 +#include <windows.h> +#else +#include <syslog.h> +#endif + +#include "portability.h" + +#include "log.h" + +static int log_to_systemlog; +static int log_debug_messages; + +static void rpcapd_vlog_stderr(log_priority, + PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0); + +static void rpcapd_vlog_stderr(log_priority priority, const char *message, va_list ap) +{ + const char *tag; + + /* + * Squelch warnings from compilers that *don't* assume that + * priority always has a valid enum value and therefore don't + * assume that we'll always go through one of the case arms. + * + * If we have a default case, compilers that *do* assume that + * will then complain about the default case code being + * unreachable. + * + * Damned if you do, damned if you don't. + */ + tag = ""; + + switch (priority) { + + case LOGPRIO_DEBUG: + tag = "DEBUG: "; + break; + + case LOGPRIO_INFO: + tag = ""; + break; + + case LOGPRIO_WARNING: + tag = "warning: "; + break; + + case LOGPRIO_ERROR: + tag = "error: "; + break; + } + + fprintf(stderr, "rpcapd: %s", tag); + vfprintf(stderr, message, ap); + putc('\n', stderr); +} + +static void rpcapd_vlog_systemlog(log_priority, + PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0); + +#ifdef _WIN32 +#define MESSAGE_SUBKEY \ + "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\rpcapd" + +static void rpcapd_vlog_systemlog(log_priority priority, const char *message, + va_list ap) +{ +#if 0 + static int initialized = 0; + HKEY hey_handle; + static HANDLE log_handle; + WORD eventlog_type; + DWORD event_id; + char msgbuf[1024]; + char *strings[1]; + + if (!initialized) { + /* + * Register our message stuff in the Registry. + * + * First, create the registry key for us. If the key + * already exists, this succeeds and returns a handle + * for it. + */ + if (RegCreateKey(HKEY_LOCAL_MACHINE, MESSAGE_SUBKEY, + &key_handle) != ERROR_SUCCESS) { + /* + * Failed - give up and just log this message, + * and all subsequent messages, to the + * standard error. + */ + log_to_systemlog = 0; + initialized = 1; + rpcapd_vlog_stderr(priority, message, ap); + return; + } + log_handle = RegisterEventSource(NULL, "rpcapd"); + initialized = 1; + } + + switch (priority) { + + case LOGPRIO_DEBUG: + // + // XXX - what *should* we do about debug messages? + // + eventlog_type = EVENTLOG_INFORMATION_TYPE; + event_id = RPCAPD_INFO_ID; + break; + + case LOGPRIO_INFO: + eventlog_type = EVENTLOG_INFORMATION_TYPE; + event_id = RPCAPD_INFO_ID; + break; + + case LOGPRIO_WARNING: + eventlog_type = EVENTLOG_WARNING_TYPE; + event_id = RPCAPD_WARNING_ID; + break; + + case LOGPRIO_ERROR: + eventlog_type = EVENTLOG_ERROR_TYPE; + event_id = RPCAPD_ERROR_ID; + break; + + default: + /* Don't do this. */ + return; + } + + vsprintf(msgbuf, message, ap); + + strings[0] = msgbuf; + /* + * If this fails, how are we going to report it? + */ + (void) ReportEvent(log_handle, eventlog_type, 0, event_id, NULL, 1, 0, + strings, NULL); +#else + rpcapd_vlog_stderr(priority, message, ap); +#endif +} +#else +static void rpcapd_vlog_systemlog(log_priority priority, const char *message, + va_list ap) +{ + static int initialized = 0; + int syslog_priority; + + if (!initialized) { + // + // Open the log. + // + openlog("rpcapd", LOG_PID, LOG_DAEMON); + initialized = 1; + } + + switch (priority) { + + case LOGPRIO_DEBUG: + syslog_priority = LOG_DEBUG; + break; + + case LOGPRIO_INFO: + syslog_priority = LOG_INFO; + break; + + case LOGPRIO_WARNING: + syslog_priority = LOG_WARNING; + break; + + case LOGPRIO_ERROR: + syslog_priority = LOG_ERR; + break; + + default: + /* Don't do this. */ + return; + } + +#ifdef HAVE_VSYSLOG + vsyslog(syslog_priority, message, ap); +#else + /* + * Thanks, IBM, for not providing vsyslog() in AIX! + * + * They also warn that the syslog functions shouldn't + * be used in multithreaded programs, but the only thing + * obvious that seems to make the syslog_r functions + * better is that they have an additional argument + * that points to the information that's static to + * the syslog code in non-thread-safe versions. Most + * of that data is set by openlog(); since we already + * do an openlog before doing logging, and don't + * change that data afterwards, I suspect that, in + * practice, the regular syslog routines are OK for + * us (especially given that we'd end up having one + * static struct syslog_data anyway, which means we'd + * just be like the non-thread-safe version). + */ + char logbuf[1024+1]; + + pcap_vsnprintf(logbuf, sizeof logbuf, message, ap); + syslog(syslog_priority, "%s", logbuf); +#endif +} +#endif + +void rpcapd_log_set(int log_to_systemlog_arg, int log_debug_messages_arg) +{ + log_debug_messages = log_debug_messages_arg; + log_to_systemlog = log_to_systemlog_arg; +} + +void rpcapd_log(log_priority priority, const char *message, ...) +{ + va_list ap; + + if (priority != LOGPRIO_DEBUG || log_debug_messages) { + va_start(ap, message); + if (log_to_systemlog) + { + rpcapd_vlog_systemlog(priority, message, ap); + } + else + { + rpcapd_vlog_stderr(priority, message, ap); + } + va_end(ap); + } +} |