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