1/*
2 *	$Id: log.c,v 1.11 2008/01/24 17:08:46 psavola Exp $
3 *
4 *	Authors:
5 *	 Lars Fenneberg		<lf@elemental.net>
6 *
7 *	This software is Copyright 1996,1997 by the above mentioned author(s),
8 *	All Rights Reserved.
9 *
10 *	The license which is distributed with this software in the file
11 *	COPYRIGHT applies to this software. If your distribution is missing
12 *	this file, you may request it from <pekkas@netcore.fi>.
13 *
14 */
15
16#include <config.h>
17#include <includes.h>
18#include <radvd.h>
19
20static int	log_method = L_NONE;
21static char *log_ident;
22static char *log_file;
23static FILE *log_file_fd;
24static int log_facility;
25static int debug_level = 0;
26
27int
28log_open(int method, char *ident, char *log, int facility)
29{
30	log_method = method;
31	log_ident = ident;
32
33	switch (log_method) {
34		case L_NONE:
35		case L_STDERR:
36			break;
37		case L_STDERR_SYSLOG:
38			/* fallthrough */
39		case L_SYSLOG:
40			if (facility == -1)
41				log_facility = LOG_DAEMON;
42			else
43				log_facility = facility;
44
45			openlog(log_ident, LOG_PID, log_facility);
46			break;
47		case L_LOGFILE:
48			if (!log)
49			{
50				fprintf(stderr, "%s: no logfile specified\n", log_ident);
51				return (-1);
52			}
53			log_file = log;
54			if ((log_file_fd = fopen(log_file, "a")) == NULL)
55			{
56				fprintf(stderr, "%s: can't open %s: %s\n", log_ident, log_file, strerror(errno));
57				return (-1);
58			}
59			break;
60		default:
61			fprintf(stderr, "%s: unknown logging method: %d\n", log_ident, log_method);
62			log_method = L_NONE;
63			return (-1);
64	}
65	return 0;
66}
67
68/* note: [dfv]log() is also called from root context */
69static int
70vlog(int prio, char *format, va_list ap)
71{
72	char tstamp[64], buff[1024];
73	struct tm *tm;
74	time_t current;
75
76	vsnprintf(buff, sizeof(buff), format, ap);
77
78	switch (log_method) {
79		case L_NONE:
80			break;
81		case L_SYSLOG:
82			syslog(prio, "%s", buff);
83			break;
84		case L_STDERR_SYSLOG:
85			syslog(prio, "%s", buff);
86			if (prio > LOG_ERR) /* fall through for messages with high priority */
87				break;
88		case L_STDERR:
89			current = time(NULL);
90			tm = localtime(&current);
91			(void) strftime(tstamp, sizeof(tstamp), LOG_TIME_FORMAT, tm);
92
93			fprintf(stderr, "[%s] %s: %s\n", tstamp, log_ident, buff);
94    			fflush(stderr);
95			break;
96		case L_LOGFILE:
97			current = time(NULL);
98			tm = localtime(&current);
99			(void) strftime(tstamp, sizeof(tstamp), LOG_TIME_FORMAT, tm);
100
101			fprintf(log_file_fd, "[%s] %s: %s\n", tstamp, log_ident, buff);
102    			fflush(log_file_fd);
103			break;
104		default:
105			fprintf(stderr, "%s: unknown logging method: %d\n", log_ident, log_method);
106			log_method = L_NONE;
107			return (-1);
108	}
109	return 0;
110}
111
112void
113dlog(int prio, int level, char *format, ...)
114{
115	va_list ap;
116	int res;
117
118	if (debug_level < level)
119		return;
120
121	va_start(ap, format);
122	res = vlog(prio, format, ap);
123	va_end(ap);
124
125	/* XXX: should we do something if res < 0.. */
126}
127
128void
129flog(int prio, char *format, ...)
130{
131	va_list ap;
132	int res;
133
134	va_start(ap, format);
135	res = vlog(prio, format, ap);
136	va_end(ap);
137
138	/* XXX: should we do something if res < 0.. */
139}
140
141int
142log_close(void)
143{
144	switch (log_method) {
145		case L_NONE:
146		case L_STDERR:
147			break;
148		case L_STDERR_SYSLOG:
149		case L_SYSLOG:
150			closelog();
151			break;
152		case L_LOGFILE:
153			fclose(log_file_fd);
154			break;
155		default:
156			fprintf(stderr, "%s: unknown logging method: %d\n", log_ident, log_method);
157			log_method = L_NONE;
158			return (-1);
159	}
160	return 0;
161}
162
163int
164log_reopen(void)
165{
166	log_close();
167	return log_open(log_method, log_ident, log_file, log_facility);
168}
169
170void
171set_debuglevel(int level)
172{
173	debug_level = level;
174}
175
176int
177get_debuglevel(void)
178{
179	return debug_level;
180}
181