OpenDNSSEC-signer  1.4.3
log.c
Go to the documentation of this file.
1 /*
2  * $Id: log.c 3845 2010-08-31 14:19:24Z matthijs $
3  *
4  * Copyright (c) 2009 NLnet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
34 #include "config.h"
35 #include "shared/duration.h"
36 #include "shared/file.h"
37 #include "shared/log.h"
38 #include "shared/util.h"
39 
40 #ifdef HAVE_SYSLOG_H
41 static int logging_to_syslog = 0;
42 #endif /* !HAVE_SYSLOG_H */
43 
44 #include <stdarg.h> /* va_start(), va_end() */
45 #include <stdio.h> /* fflush, fprintf(), vsnprintf() */
46 #include <stdlib.h> /* exit() */
47 #include <string.h> /* strlen() */
48 
49 static FILE* logfile = NULL;
50 static int log_level = LOG_CRIT;
51 
52 #define CTIME_LENGTH 26
53 
59 #if defined(HAVE_SYSLOG_R) && defined(HAVE_OPENLOG_R) && defined(HAVE_CLOSELOG_R)
60 struct syslog_data sdata = SYSLOG_DATA_INIT;
61 #else
62 #undef HAVE_SYSLOG_R
63 #undef HAVE_OPENLOG_R
64 #undef HAVE_CLOSELOG_R
65 #endif
66 
67 /* TODO:
68  - log_init should have program_name variable
69  - wrap special case logging onto generic one
70  - check if xml-specific logging functions are still neeeded (enforcer)
71  -
72 */
73 
74 #define MY_PACKAGE_TARNAME "ods-signerd"
75 
76 static const char* log_str = "log";
77 
82 void
83 ods_log_init(const char *filename, int use_syslog, int verbosity)
84 {
85 #ifdef HAVE_SYSLOG_H
86  int facility;
87 #endif /* HAVE_SYSLOG_H */
88  ods_log_verbose("[%s] switching log to %s verbosity %i (log level %i)",
89  log_str, use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"),
90  verbosity, verbosity+2);
91  if (logfile && logfile != stderr) {
92  ods_fclose(logfile);
93  }
94  log_level = verbosity + 2;
95 
96 #ifdef HAVE_SYSLOG_H
97  if(logging_to_syslog) {
98 #ifdef HAVE_CLOSELOG_R
99  closelog_r(&sdata);
100 #else
101  closelog();
102 #endif
103  logging_to_syslog = 0;
104  }
105  if(use_syslog) {
106  facility = ods_log_get_facility(filename);
107 #ifdef HAVE_OPENLOG_R
108  openlog_r(MY_PACKAGE_TARNAME, LOG_NDELAY, facility, &sdata);
109 #else
110  openlog(MY_PACKAGE_TARNAME, LOG_NDELAY, facility);
111 #endif
112  logging_to_syslog = 1;
113  return;
114  }
115 #endif /* HAVE_SYSLOG_H */
116 
117  if(filename && filename[0]) {
118  logfile = ods_fopen(filename, NULL, "a");
119  if (logfile) {
120  ods_log_debug("[%s] new logfile %s", log_str, filename);
121  return;
122  }
123  logfile = stderr;
124  ods_log_warning("[%s] cannot open %s for appending, logging to "
125  "stderr", log_str, filename);
126  } else {
127  logfile = stderr;
128  }
129  return;
130 }
131 
132 
137 void
139 {
140  ods_log_debug("[%s] close log", log_str);
141  ods_log_init(NULL, 0, 0);
142 }
143 
144 
152 #ifdef HAVE_SYSLOG_H
153 int
154 ods_log_get_facility(const char* facility)
155 {
156  int length;
157 
158  if (!facility) {
159  return LOG_DAEMON;
160  }
161  length = strlen(facility);
162 
163  if (length == 4 && strncasecmp(facility, "KERN", 4) == 0)
164  return LOG_KERN;
165  else if (length == 4 && strncasecmp(facility, "USER", 4) == 0)
166  return LOG_USER;
167  else if (length == 4 && strncasecmp(facility, "MAIL", 4) == 0)
168  return LOG_MAIL;
169  else if (length == 6 && strncasecmp(facility, "DAEMON", 6) == 0)
170  return LOG_DAEMON;
171  else if (length == 4 && strncasecmp(facility, "AUTH", 4) == 0)
172  return LOG_AUTH;
173  else if (length == 3 && strncasecmp(facility, "LPR", 3) == 0)
174  return LOG_LPR;
175  else if (length == 4 && strncasecmp(facility, "NEWS", 4) == 0)
176  return LOG_NEWS;
177  else if (length == 4 && strncasecmp(facility, "UUCP", 4) == 0)
178  return LOG_UUCP;
179  else if (length == 4 && strncasecmp(facility, "CRON", 4) == 0)
180  return LOG_CRON;
181  else if (length == 6 && strncasecmp(facility, "LOCAL0", 6) == 0)
182  return LOG_LOCAL0;
183  else if (length == 6 && strncasecmp(facility, "LOCAL1", 6) == 0)
184  return LOG_LOCAL1;
185  else if (length == 6 && strncasecmp(facility, "LOCAL2", 6) == 0)
186  return LOG_LOCAL2;
187  else if (length == 6 && strncasecmp(facility, "LOCAL3", 6) == 0)
188  return LOG_LOCAL3;
189  else if (length == 6 && strncasecmp(facility, "LOCAL4", 6) == 0)
190  return LOG_LOCAL4;
191  else if (length == 6 && strncasecmp(facility, "LOCAL5", 6) == 0)
192  return LOG_LOCAL5;
193  else if (length == 6 && strncasecmp(facility, "LOCAL6", 6) == 0)
194  return LOG_LOCAL6;
195  else if (length == 6 && strncasecmp(facility, "LOCAL7", 6) == 0)
196  return LOG_LOCAL7;
197  ods_log_warning("[%s] syslog facility %s not supported, logging to "
198  "log_daemon", log_str, facility);
199  return LOG_DAEMON;
200 
201 }
202 #endif /* HAVE_SYSLOG_H */
203 
208 int
210 {
211  return log_level;
212 }
213 
218 static void
219 ods_log_vmsg(int priority, const char* t, const char* s, va_list args)
220 {
221  char message[ODS_SE_MAXLINE];
222  static char nowstr[CTIME_LENGTH];
223  time_t now = time_now();
224 
225  vsnprintf(message, sizeof(message), s, args);
226 
227 #ifdef HAVE_SYSLOG_H
228  if (logging_to_syslog) {
229 #ifdef HAVE_SYSLOG_R
230  syslog_r(priority, &sdata, "%s", message);
231 #else
232  syslog(priority, "%s", message);
233 #endif
234  return;
235  }
236 #endif /* HAVE_SYSLOG_H */
237 
238  if (!logfile) {
239  return;
240  }
241 
242  (void) ctime_r(&now, nowstr);
243  nowstr[CTIME_LENGTH-2] = '\0'; /* remove trailing linefeed */
244 
245  fprintf(logfile, "[%s] %s[%i] %s: %s\n", nowstr,
246  MY_PACKAGE_TARNAME, priority, t, message);
247  fflush(logfile);
248 }
249 
250 
255 void
256 ods_log_deeebug(const char *format, ...)
257 {
258  va_list args;
259  va_start(args, format);
260  if (log_level >= LOG_DEEEBUG) {
261  ods_log_vmsg(LOG_DEBUG, "debug ", format, args);
262  }
263  va_end(args);
264 }
265 
266 
271 void
272 ods_log_debug(const char *format, ...)
273 {
274  va_list args;
275  va_start(args, format);
276  if (log_level >= LOG_DEBUG) {
277  ods_log_vmsg(LOG_DEBUG, "debug ", format, args);
278  }
279  va_end(args);
280 }
281 
282 
287 void
288 ods_log_verbose(const char *format, ...)
289 {
290  va_list args;
291  va_start(args, format);
292  if (log_level >= LOG_INFO) {
293  ods_log_vmsg(LOG_INFO, "verbose", format, args);
294  }
295  va_end(args);
296 }
297 
298 
303 void
304 ods_log_info(const char *format, ...)
305 {
306  va_list args;
307  va_start(args, format);
308  if (log_level >= LOG_NOTICE) {
309  ods_log_vmsg(LOG_NOTICE, "msg ", format, args);
310  }
311  va_end(args);
312 }
313 
314 
319 void
320 ods_log_warning(const char *format, ...)
321 {
322  va_list args;
323  va_start(args, format);
324  if (log_level >= LOG_WARNING) {
325  ods_log_vmsg(LOG_WARNING, "warning", format, args);
326  }
327  va_end(args);
328 }
329 
330 
335 void
336 ods_log_error(const char *format, ...)
337 {
338  va_list args;
339  va_start(args, format);
340  if (log_level >= LOG_ERR) {
341  ods_log_vmsg(LOG_ERR, "error ", format, args);
342  }
343  va_end(args);
344 }
345 
346 
351 void
352 ods_log_crit(const char *format, ...)
353 {
354  va_list args;
355  va_start(args, format);
356  if (log_level >= LOG_CRIT) {
357  ods_log_vmsg(LOG_CRIT, "crit ", format, args);
358  }
359  va_end(args);
360 }
361 
362 
367 void
368 ods_log_alert(const char *format, ...)
369 {
370  va_list args;
371  va_start(args, format);
372  if (log_level >= LOG_ALERT) {
373  ods_log_vmsg(LOG_ALERT, "alert ", format, args);
374  }
375  va_end(args);
376 }
377 
378 
383 void
384 ods_fatal_exit(const char *format, ...)
385 {
386  va_list args;
387  va_start(args, format);
388  if (log_level >= LOG_CRIT) {
389  ods_log_vmsg(LOG_CRIT, "fatal ", format, args);
390  }
391  va_end(args);
392  abort();
393 }
void ods_log_alert(const char *format,...)
Definition: log.c:368
void ods_log_debug(const char *format,...)
Definition: log.c:272
#define CTIME_LENGTH
Definition: log.c:52
#define MY_PACKAGE_TARNAME
Definition: log.c:74
#define LOG_INFO
Definition: log.h:52
void ods_fatal_exit(const char *format,...)
Definition: log.c:384
void ods_log_info(const char *format,...)
Definition: log.c:304
void ods_log_error(const char *format,...)
Definition: log.c:336
#define LOG_NOTICE
Definition: log.h:51
int ods_log_get_facility(const char *facility)
FILE * ods_fopen(const char *file, const char *dir, const char *mode)
Definition: file.c:187
void ods_log_crit(const char *format,...)
Definition: log.c:352
#define LOG_ALERT
Definition: log.h:47
#define LOG_CRIT
Definition: log.h:48
void ods_log_close(void)
Definition: log.c:138
#define LOG_ERR
Definition: log.h:49
int ods_log_get_level()
Definition: log.c:209
void ods_log_verbose(const char *format,...)
Definition: log.c:288
#define LOG_DEEEBUG
Definition: log.h:55
void ods_fclose(FILE *fd)
Definition: file.c:247
void ods_log_deeebug(const char *format,...)
Definition: log.c:256
#define LOG_DEBUG
Definition: log.h:53
void ods_log_init(const char *filename, int use_syslog, int verbosity)
Definition: log.c:83
#define LOG_WARNING
Definition: log.h:50
void ods_log_warning(const char *format,...)
Definition: log.c:320
time_t time_now(void)
Definition: duration.c:515