xref: /freebsd/contrib/libpcap/rpcapd/log.c (revision afdbf109c6a661a729938f68211054a0a50d38ac)
157e22627SCy Schubert /*
257e22627SCy Schubert  * Copyright (c) 1993, 1994, 1995, 1996, 1998
357e22627SCy Schubert  *	The Regents of the University of California.  All rights reserved.
457e22627SCy Schubert  *
557e22627SCy Schubert  * Redistribution and use in source and binary forms, with or without
657e22627SCy Schubert  * modification, are permitted provided that: (1) source code distributions
757e22627SCy Schubert  * retain the above copyright notice and this paragraph in its entirety, (2)
857e22627SCy Schubert  * distributions including binary code include the above copyright notice and
957e22627SCy Schubert  * this paragraph in its entirety in the documentation or other materials
1057e22627SCy Schubert  * provided with the distribution, and (3) all advertising materials mentioning
1157e22627SCy Schubert  * features or use of this software display the following acknowledgement:
1257e22627SCy Schubert  * ``This product includes software developed by the University of California,
1357e22627SCy Schubert  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1457e22627SCy Schubert  * the University nor the names of its contributors may be used to endorse
1557e22627SCy Schubert  * or promote products derived from this software without specific prior
1657e22627SCy Schubert  * written permission.
1757e22627SCy Schubert  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1857e22627SCy Schubert  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1957e22627SCy Schubert  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2057e22627SCy Schubert  */
2157e22627SCy Schubert 
2257e22627SCy Schubert #include <config.h>
2357e22627SCy Schubert 
2457e22627SCy Schubert #include <stdio.h>
2557e22627SCy Schubert #include <stdarg.h>
2657e22627SCy Schubert #include <stdlib.h>
2757e22627SCy Schubert 
2857e22627SCy Schubert #ifdef _WIN32
2957e22627SCy Schubert #include <windows.h>
3057e22627SCy Schubert #else
3157e22627SCy Schubert #include <syslog.h>
3257e22627SCy Schubert #endif
3357e22627SCy Schubert 
3457e22627SCy Schubert #include "portability.h"
3557e22627SCy Schubert 
3657e22627SCy Schubert #include "log.h"
3757e22627SCy Schubert 
3857e22627SCy Schubert static int log_to_systemlog;
3957e22627SCy Schubert static int log_debug_messages;
4057e22627SCy Schubert 
4157e22627SCy Schubert static void rpcapd_vlog_stderr(log_priority,
4257e22627SCy Schubert     PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
4357e22627SCy Schubert 
rpcapd_vlog_stderr(log_priority priority,const char * message,va_list ap)4457e22627SCy Schubert static void rpcapd_vlog_stderr(log_priority priority, const char *message, va_list ap)
4557e22627SCy Schubert {
4657e22627SCy Schubert 	const char *tag;
4757e22627SCy Schubert 
4857e22627SCy Schubert 	/*
4957e22627SCy Schubert 	 * Squelch warnings from compilers that *don't* assume that
5057e22627SCy Schubert 	 * priority always has a valid enum value and therefore don't
5157e22627SCy Schubert 	 * assume that we'll always go through one of the case arms.
5257e22627SCy Schubert 	 *
5357e22627SCy Schubert 	 * If we have a default case, compilers that *do* assume that
5457e22627SCy Schubert 	 * will then complain about the default case code being
5557e22627SCy Schubert 	 * unreachable.
5657e22627SCy Schubert 	 *
5757e22627SCy Schubert 	 * Damned if you do, damned if you don't.
5857e22627SCy Schubert 	 */
5957e22627SCy Schubert 	tag = "";
6057e22627SCy Schubert 
6157e22627SCy Schubert 	switch (priority) {
6257e22627SCy Schubert 
6357e22627SCy Schubert 	case LOGPRIO_DEBUG:
6457e22627SCy Schubert 		tag = "DEBUG: ";
6557e22627SCy Schubert 		break;
6657e22627SCy Schubert 
6757e22627SCy Schubert 	case LOGPRIO_INFO:
6857e22627SCy Schubert 		tag = "";
6957e22627SCy Schubert 		break;
7057e22627SCy Schubert 
7157e22627SCy Schubert 	case LOGPRIO_WARNING:
7257e22627SCy Schubert 		tag = "warning: ";
7357e22627SCy Schubert 		break;
7457e22627SCy Schubert 
7557e22627SCy Schubert 	case LOGPRIO_ERROR:
7657e22627SCy Schubert 		tag = "error: ";
7757e22627SCy Schubert 		break;
7857e22627SCy Schubert 	}
7957e22627SCy Schubert 
8057e22627SCy Schubert 	fprintf(stderr, "rpcapd: %s", tag);
8157e22627SCy Schubert 	vfprintf(stderr, message, ap);
8257e22627SCy Schubert 	putc('\n', stderr);
8357e22627SCy Schubert }
8457e22627SCy Schubert 
8557e22627SCy Schubert static void rpcapd_vlog_systemlog(log_priority,
8657e22627SCy Schubert     PCAP_FORMAT_STRING(const char *), va_list) PCAP_PRINTFLIKE(2, 0);
8757e22627SCy Schubert 
8857e22627SCy Schubert #ifdef _WIN32
8957e22627SCy Schubert #define MESSAGE_SUBKEY \
9057e22627SCy Schubert     "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\rpcapd"
9157e22627SCy Schubert 
rpcapd_vlog_systemlog(log_priority priority,const char * message,va_list ap)9257e22627SCy Schubert static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
9357e22627SCy Schubert     va_list ap)
9457e22627SCy Schubert {
9557e22627SCy Schubert #if 0
9657e22627SCy Schubert 	static int initialized = 0;
9757e22627SCy Schubert 	HKEY hey_handle;
9857e22627SCy Schubert 	static HANDLE log_handle;
9957e22627SCy Schubert 	WORD eventlog_type;
10057e22627SCy Schubert 	DWORD event_id;
10157e22627SCy Schubert 	char msgbuf[1024];
10257e22627SCy Schubert 	char *strings[1];
10357e22627SCy Schubert 
10457e22627SCy Schubert 	if (!initialized) {
10557e22627SCy Schubert 		/*
10657e22627SCy Schubert 		 * Register our message stuff in the Registry.
10757e22627SCy Schubert 		 *
10857e22627SCy Schubert 		 * First, create the registry key for us.  If the key
10957e22627SCy Schubert 		 * already exists, this succeeds and returns a handle
11057e22627SCy Schubert 		 * for it.
11157e22627SCy Schubert 		 */
11257e22627SCy Schubert 		if (RegCreateKey(HKEY_LOCAL_MACHINE, MESSAGE_SUBKEY,
11357e22627SCy Schubert 		    &key_handle) != ERROR_SUCCESS) {
11457e22627SCy Schubert 			/*
11557e22627SCy Schubert 			 * Failed - give up and just log this message,
11657e22627SCy Schubert 			 * and all subsequent messages, to the
11757e22627SCy Schubert 			 * standard error.
11857e22627SCy Schubert 			 */
11957e22627SCy Schubert 			log_to_systemlog = 0;
12057e22627SCy Schubert 			initialized = 1;
12157e22627SCy Schubert 			rpcapd_vlog_stderr(priority, message, ap);
12257e22627SCy Schubert 			return;
12357e22627SCy Schubert 		}
12457e22627SCy Schubert 		log_handle = RegisterEventSource(NULL, "rpcapd");
12557e22627SCy Schubert 		initialized = 1;
12657e22627SCy Schubert 	}
12757e22627SCy Schubert 
12857e22627SCy Schubert 	switch (priority) {
12957e22627SCy Schubert 
13057e22627SCy Schubert 	case LOGPRIO_DEBUG:
13157e22627SCy Schubert 		//
13257e22627SCy Schubert 		// XXX - what *should* we do about debug messages?
13357e22627SCy Schubert 		//
13457e22627SCy Schubert 		eventlog_type = EVENTLOG_INFORMATION_TYPE;
13557e22627SCy Schubert 		event_id = RPCAPD_INFO_ID;
13657e22627SCy Schubert 		break;
13757e22627SCy Schubert 
13857e22627SCy Schubert 	case LOGPRIO_INFO:
13957e22627SCy Schubert 		eventlog_type = EVENTLOG_INFORMATION_TYPE;
14057e22627SCy Schubert 		event_id = RPCAPD_INFO_ID;
14157e22627SCy Schubert 		break;
14257e22627SCy Schubert 
14357e22627SCy Schubert 	case LOGPRIO_WARNING:
14457e22627SCy Schubert 		eventlog_type = EVENTLOG_WARNING_TYPE;
14557e22627SCy Schubert 		event_id = RPCAPD_WARNING_ID;
14657e22627SCy Schubert 		break;
14757e22627SCy Schubert 
14857e22627SCy Schubert 	case LOGPRIO_ERROR:
14957e22627SCy Schubert 		eventlog_type = EVENTLOG_ERROR_TYPE;
15057e22627SCy Schubert 		event_id = RPCAPD_ERROR_ID;
15157e22627SCy Schubert 		break;
15257e22627SCy Schubert 
15357e22627SCy Schubert 	default:
15457e22627SCy Schubert 		/* Don't do this. */
15557e22627SCy Schubert 		return;
15657e22627SCy Schubert 	}
15757e22627SCy Schubert 
15857e22627SCy Schubert 	vsprintf(msgbuf, message, ap);
15957e22627SCy Schubert 
16057e22627SCy Schubert 	strings[0] = msgbuf;
16157e22627SCy Schubert 	/*
16257e22627SCy Schubert 	 * If this fails, how are we going to report it?
16357e22627SCy Schubert 	 */
16457e22627SCy Schubert 	(void) ReportEvent(log_handle, eventlog_type, 0, event_id, NULL, 1, 0,
16557e22627SCy Schubert 	    strings, NULL);
16657e22627SCy Schubert #else
16757e22627SCy Schubert 	rpcapd_vlog_stderr(priority, message, ap);
16857e22627SCy Schubert #endif
16957e22627SCy Schubert }
17057e22627SCy Schubert #else
rpcapd_vlog_systemlog(log_priority priority,const char * message,va_list ap)17157e22627SCy Schubert static void rpcapd_vlog_systemlog(log_priority priority, const char *message,
17257e22627SCy Schubert     va_list ap)
17357e22627SCy Schubert {
17457e22627SCy Schubert 	static int initialized = 0;
17557e22627SCy Schubert 	int syslog_priority;
17657e22627SCy Schubert 
17757e22627SCy Schubert 	if (!initialized) {
17857e22627SCy Schubert 		//
17957e22627SCy Schubert 		// Open the log.
18057e22627SCy Schubert 		//
18157e22627SCy Schubert 		openlog("rpcapd", LOG_PID, LOG_DAEMON);
18257e22627SCy Schubert 		initialized = 1;
18357e22627SCy Schubert 	}
18457e22627SCy Schubert 
18557e22627SCy Schubert 	switch (priority) {
18657e22627SCy Schubert 
18757e22627SCy Schubert 	case LOGPRIO_DEBUG:
18857e22627SCy Schubert 		syslog_priority = LOG_DEBUG;
18957e22627SCy Schubert 		break;
19057e22627SCy Schubert 
19157e22627SCy Schubert 	case LOGPRIO_INFO:
19257e22627SCy Schubert 		syslog_priority = LOG_INFO;
19357e22627SCy Schubert 		break;
19457e22627SCy Schubert 
19557e22627SCy Schubert 	case LOGPRIO_WARNING:
19657e22627SCy Schubert 		syslog_priority = LOG_WARNING;
19757e22627SCy Schubert 		break;
19857e22627SCy Schubert 
19957e22627SCy Schubert 	case LOGPRIO_ERROR:
20057e22627SCy Schubert 		syslog_priority = LOG_ERR;
20157e22627SCy Schubert 		break;
20257e22627SCy Schubert 
20357e22627SCy Schubert 	default:
20457e22627SCy Schubert 		/* Don't do this. */
20557e22627SCy Schubert 		return;
20657e22627SCy Schubert 	}
20757e22627SCy Schubert 
20857e22627SCy Schubert #ifdef HAVE_VSYSLOG
20957e22627SCy Schubert 	vsyslog(syslog_priority, message, ap);
21057e22627SCy Schubert #else
21157e22627SCy Schubert 	/*
21257e22627SCy Schubert 	 * Thanks, IBM, for not providing vsyslog() in AIX!
21357e22627SCy Schubert 	 *
21457e22627SCy Schubert 	 * They also warn that the syslog functions shouldn't
21557e22627SCy Schubert 	 * be used in multithreaded programs, but the only thing
21657e22627SCy Schubert 	 * obvious that seems to make the syslog_r functions
21757e22627SCy Schubert 	 * better is that they have an additional argument
21857e22627SCy Schubert 	 * that points to the information that's static to
21957e22627SCy Schubert 	 * the syslog code in non-thread-safe versions.  Most
22057e22627SCy Schubert 	 * of that data is set by openlog(); since we already
22157e22627SCy Schubert 	 * do an openlog before doing logging, and don't
22257e22627SCy Schubert 	 * change that data afterwards, I suspect that, in
22357e22627SCy Schubert 	 * practice, the regular syslog routines are OK for
22457e22627SCy Schubert 	 * us (especially given that we'd end up having one
22557e22627SCy Schubert 	 * static struct syslog_data anyway, which means we'd
22657e22627SCy Schubert 	 * just be like the non-thread-safe version).
22757e22627SCy Schubert 	 */
22857e22627SCy Schubert 	char logbuf[1024+1];
22957e22627SCy Schubert 
230*6f9cba8fSJoseph Mingrone 	vsnprintf(logbuf, sizeof logbuf, message, ap);
23157e22627SCy Schubert 	syslog(syslog_priority, "%s", logbuf);
23257e22627SCy Schubert #endif
23357e22627SCy Schubert }
23457e22627SCy Schubert #endif
23557e22627SCy Schubert 
rpcapd_log_set(int log_to_systemlog_arg,int log_debug_messages_arg)23657e22627SCy Schubert void rpcapd_log_set(int log_to_systemlog_arg, int log_debug_messages_arg)
23757e22627SCy Schubert {
23857e22627SCy Schubert 	log_debug_messages = log_debug_messages_arg;
23957e22627SCy Schubert 	log_to_systemlog = log_to_systemlog_arg;
24057e22627SCy Schubert }
24157e22627SCy Schubert 
rpcapd_log(log_priority priority,const char * message,...)24257e22627SCy Schubert void rpcapd_log(log_priority priority, const char *message, ...)
24357e22627SCy Schubert {
24457e22627SCy Schubert 	va_list ap;
24557e22627SCy Schubert 
24657e22627SCy Schubert 	if (priority != LOGPRIO_DEBUG || log_debug_messages) {
24757e22627SCy Schubert 		va_start(ap, message);
24857e22627SCy Schubert 		if (log_to_systemlog)
24957e22627SCy Schubert 		{
25057e22627SCy Schubert 			rpcapd_vlog_systemlog(priority, message, ap);
25157e22627SCy Schubert 		}
25257e22627SCy Schubert 		else
25357e22627SCy Schubert 		{
25457e22627SCy Schubert 			rpcapd_vlog_stderr(priority, message, ap);
25557e22627SCy Schubert 		}
25657e22627SCy Schubert 		va_end(ap);
25757e22627SCy Schubert 	}
25857e22627SCy Schubert }
259