OpenDNSSEC-signer  1.3.9
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 #include <stdarg.h> /* va_start(), va_end() */
41 #include <stdio.h> /* fflush, fprintf(), vsnprintf() */
42 #include <stdlib.h> /* exit() */
43 #include <string.h> /* strlen() */
44 
45 #ifdef HAVE_SYSLOG_H
46 #include <strings.h> /* strncasecmp() */
47 #include <syslog.h> /* openlog(), closelog(), syslog() */
48 static int logging_to_syslog = 0;
49 #else /* !HAVE_SYSLOG_H */
50 #define LOG_EMERG 0 /* ods_fatal_exit */
51 #define LOG_ALERT 1 /* ods_log_alert */
52 #define LOG_CRIT 2 /* ods_log_crit */
53 #define LOG_ERR 3 /* ods_log_error */
54 #define LOG_WARNING 4 /* ods_log_warning */
55 #define LOG_NOTICE 5 /* ods_log_info */
56 #define LOG_INFO 6 /* ods_log_verbose */
57 #define LOG_DEBUG 7 /* ods_log_debug */
58 #endif /* HAVE_SYSLOG_H */
59 
60 #define LOG_DEEEBUG 8 /* ods_log_deeebug */
61 
62 static FILE* logfile = NULL;
63 static int log_level = LOG_CRIT;
64 
65 #define CTIME_LENGTH 26
66 
67 
68 /* TODO:
69  - log_init should have program_name variable
70  - wrap special case logging onto generic one
71  - check if xml-specific logging functions are still neeeded (enforcer)
72  -
73 */
74 
75 #define MY_PACKAGE_TARNAME "ods-signerd"
76 
77 static const char* log_str = "log";
78 
83 void
84 ods_log_init(const char *filename, int use_syslog, int verbosity)
85 {
86 #ifdef HAVE_SYSLOG_H
87  int facility;
88 #endif /* HAVE_SYSLOG_H */
89  ods_log_verbose("[%s] switching log to %s verbosity %i (log level %i)",
90  log_str, use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"),
91  verbosity, verbosity+2);
92  if (logfile && logfile != stderr) {
93  ods_fclose(logfile);
94  }
95  log_level = verbosity + 2;
96 
97 #ifdef HAVE_SYSLOG_H
98  if(logging_to_syslog) {
99  closelog();
100  logging_to_syslog = 0;
101  }
102  if(use_syslog) {
103  facility = ods_log_get_facility(filename);
104  openlog(MY_PACKAGE_TARNAME, LOG_NDELAY, facility);
105  logging_to_syslog = 1;
106  return;
107  }
108 #endif /* HAVE_SYSLOG_H */
109 
110  if(filename && filename[0]) {
111  logfile = ods_fopen(filename, NULL, "a");
112  if (logfile) {
113  ods_log_debug("[%s] new logfile %s", log_str, filename);
114  return;
115  }
116  logfile = stderr;
117  ods_log_warning("[%s] cannot open %s for appending, logging to "
118  "stderr", log_str, filename);
119  } else {
120  logfile = stderr;
121  }
122  return;
123 }
124 
125 
130 void
132 {
133  ods_log_debug("[%s] close log", log_str);
134  ods_log_init(NULL, 0, 0);
135 }
136 
137 
145 #ifdef HAVE_SYSLOG_H
146 int
147 ods_log_get_facility(const char* facility)
148 {
149  int length;
150 
151  if (!facility) {
152  return LOG_DAEMON;
153  }
154  length = strlen(facility);
155 
156  if (length == 4 && strncasecmp(facility, "KERN", 4) == 0)
157  return LOG_KERN;
158  else if (length == 4 && strncasecmp(facility, "USER", 4) == 0)
159  return LOG_USER;
160  else if (length == 4 && strncasecmp(facility, "MAIL", 4) == 0)
161  return LOG_MAIL;
162  else if (length == 6 && strncasecmp(facility, "DAEMON", 6) == 0)
163  return LOG_DAEMON;
164  else if (length == 4 && strncasecmp(facility, "AUTH", 4) == 0)
165  return LOG_AUTH;
166  else if (length == 3 && strncasecmp(facility, "LPR", 3) == 0)
167  return LOG_LPR;
168  else if (length == 4 && strncasecmp(facility, "NEWS", 4) == 0)
169  return LOG_NEWS;
170  else if (length == 4 && strncasecmp(facility, "UUCP", 4) == 0)
171  return LOG_UUCP;
172  else if (length == 4 && strncasecmp(facility, "CRON", 4) == 0)
173  return LOG_CRON;
174  else if (length == 6 && strncasecmp(facility, "LOCAL0", 6) == 0)
175  return LOG_LOCAL0;
176  else if (length == 6 && strncasecmp(facility, "LOCAL1", 6) == 0)
177  return LOG_LOCAL1;
178  else if (length == 6 && strncasecmp(facility, "LOCAL2", 6) == 0)
179  return LOG_LOCAL2;
180  else if (length == 6 && strncasecmp(facility, "LOCAL3", 6) == 0)
181  return LOG_LOCAL3;
182  else if (length == 6 && strncasecmp(facility, "LOCAL4", 6) == 0)
183  return LOG_LOCAL4;
184  else if (length == 6 && strncasecmp(facility, "LOCAL5", 6) == 0)
185  return LOG_LOCAL5;
186  else if (length == 6 && strncasecmp(facility, "LOCAL6", 6) == 0)
187  return LOG_LOCAL6;
188  else if (length == 6 && strncasecmp(facility, "LOCAL7", 6) == 0)
189  return LOG_LOCAL7;
190  ods_log_warning("[%s] syslog facility %s not supported, logging to "
191  "log_daemon", log_str, facility);
192  return LOG_DAEMON;
193 
194 }
195 #endif /* HAVE_SYSLOG_H */
196 
201 int
203 {
204  return log_level;
205 }
206 
211 static void
212 ods_log_vmsg(int priority, const char* t, const char* s, va_list args)
213 {
214  char message[ODS_SE_MAXLINE];
215  static char nowstr[CTIME_LENGTH];
216  time_t now = time_now();
217 
218  vsnprintf(message, sizeof(message), s, args);
219 
220 #ifdef HAVE_SYSLOG_H
221  if (logging_to_syslog) {
222  syslog(priority, "%s", message);
223  return;
224  }
225 #endif /* HAVE_SYSLOG_H */
226 
227  if (!logfile) {
228  return;
229  }
230 
231  (void) ctime_r(&now, nowstr);
232  nowstr[CTIME_LENGTH-2] = '\0'; /* remove trailing linefeed */
233 
234  fprintf(logfile, "[%s] %s[%i] %s: %s\n", nowstr,
235  MY_PACKAGE_TARNAME, priority, t, message);
236  fflush(logfile);
237 }
238 
239 
244 void
245 ods_log_deeebug(const char *format, ...)
246 {
247  va_list args;
248  va_start(args, format);
249  if (log_level >= LOG_DEEEBUG) {
250  ods_log_vmsg(LOG_DEBUG, "debug ", format, args);
251  }
252  va_end(args);
253 }
254 
255 
260 void
261 ods_log_debug(const char *format, ...)
262 {
263  va_list args;
264  va_start(args, format);
265  if (log_level >= LOG_DEBUG) {
266  ods_log_vmsg(LOG_DEBUG, "debug ", format, args);
267  }
268  va_end(args);
269 }
270 
271 
276 void
277 ods_log_verbose(const char *format, ...)
278 {
279  va_list args;
280  va_start(args, format);
281  if (log_level >= LOG_INFO) {
282  ods_log_vmsg(LOG_INFO, "verbose", format, args);
283  }
284  va_end(args);
285 }
286 
287 
292 void
293 ods_log_info(const char *format, ...)
294 {
295  va_list args;
296  va_start(args, format);
297  if (log_level >= LOG_NOTICE) {
298  ods_log_vmsg(LOG_NOTICE, "msg ", format, args);
299  }
300  va_end(args);
301 }
302 
303 
308 void
309 ods_log_warning(const char *format, ...)
310 {
311  va_list args;
312  va_start(args, format);
313  if (log_level >= LOG_WARNING) {
314  ods_log_vmsg(LOG_WARNING, "warning", format, args);
315  }
316  va_end(args);
317 }
318 
319 
324 void
325 ods_log_error(const char *format, ...)
326 {
327  va_list args;
328  va_start(args, format);
329  if (log_level >= LOG_ERR) {
330  ods_log_vmsg(LOG_ERR, "error ", format, args);
331  }
332  va_end(args);
333 }
334 
335 
340 void
341 ods_log_crit(const char *format, ...)
342 {
343  va_list args;
344  va_start(args, format);
345  if (log_level >= LOG_CRIT) {
346  ods_log_vmsg(LOG_CRIT, "crit ", format, args);
347  }
348  va_end(args);
349 }
350 
351 
356 void
357 ods_log_alert(const char *format, ...)
358 {
359  va_list args;
360  va_start(args, format);
361  if (log_level >= LOG_ALERT) {
362  ods_log_vmsg(LOG_ALERT, "alert ", format, args);
363  }
364  va_end(args);
365 }
366 
367 
372 void
373 ods_fatal_exit(const char *format, ...)
374 {
375  va_list args;
376  va_start(args, format);
377  if (log_level >= LOG_CRIT) {
378  ods_log_vmsg(LOG_CRIT, "fatal ", format, args);
379  }
380  va_end(args);
381  abort();
382 }