OpenDNSSEC-signer 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-ia64-j6OroR/opendnssec-1.2.1.dfsg/signer/src/util/log.c

Go to the documentation of this file.
00001 /*
00002  * $Id: log.c 4512 2011-02-23 09:48:58Z matthijs $
00003  *
00004  * Copyright (c) 2009 NLnet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "config.h"
00035 #include "util/duration.h"
00036 #include "util/file.h"
00037 #include "util/log.h"
00038 
00039 #include <stdarg.h> /* va_start(), va_end()  */
00040 #include <stdio.h> /* fflush, fprintf(), vsnprintf() */
00041 #include <stdlib.h> /* exit() */
00042 #include <string.h> /* strlen() */
00043 
00044 #ifdef HAVE_SYSLOG_H
00045 #include <strings.h> /* strncasecmp() */
00046 #include <syslog.h> /* openlog(), closelog(), syslog() */
00047 static int logging_to_syslog = 0;
00048 #else /* !HAVE_SYSLOG_H */
00049 #define LOG_EMERG   0 /* se_fatal_exit */
00050 #define LOG_ALERT   1 /* se_log_alert */
00051 #define LOG_CRIT    2 /* se_log_crit */
00052 #define LOG_ERR     3 /* se_log_error */
00053 #define LOG_WARNING 4 /* se_log_warning */
00054 #define LOG_NOTICE  5 /* se_log_info */
00055 #define LOG_INFO    6 /* se_log_verbose */
00056 #define LOG_DEBUG   7 /* se_log_debug */
00057 #endif /* HAVE_SYSLOG_H */
00058 
00059 #define LOG_DEEEBUG 8 /* se_log_deeebug */
00060 
00061 static FILE* logfile = NULL;
00062 static int log_level = LOG_CRIT;
00063 
00064 #define CTIME_LENGTH 26
00065 
00066 
00067 /* TODO:
00068    - prepend ods_ in common library
00069    - log_init should have program_name variable)
00070    - wrap special case logging onto generic one
00071    - check if xml-specific logging functions are still neeeded (enforcer)
00072    -
00073 */
00074 
00075 #define MY_PACKAGE_TARNAME "ods-signerd"
00076 
00077 
00082 void
00083 se_log_init(const char *filename, int use_syslog, int verbosity)
00084 {
00085 #ifdef HAVE_SYSLOG_H
00086     int facility;
00087 #endif /* HAVE_SYSLOG_H */
00088     se_log_verbose("switching log to %s verbosity %i (log level %i)",
00089         use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"),
00090         verbosity, verbosity+2);
00091     if (logfile && logfile != stderr) {
00092             se_fclose(logfile);
00093         }
00094     log_level = verbosity + 2;
00095 
00096 #ifdef HAVE_SYSLOG_H
00097     if(logging_to_syslog) {
00098         closelog();
00099         logging_to_syslog = 0;
00100     }
00101     if(use_syslog) {
00102        facility = se_log_get_facility(filename);
00103        openlog(MY_PACKAGE_TARNAME, LOG_NDELAY, facility);
00104        logging_to_syslog = 1;
00105        return;
00106     }
00107 #endif /* HAVE_SYSLOG_H */
00108 
00109     if(filename && filename[0]) {
00110         logfile = se_fopen(filename, NULL, "a");
00111         if (logfile) {
00112             se_log_debug("new logfile %s", filename);
00113             return;
00114         }
00115         logfile = stderr;
00116         se_log_warning("cannot open %s for appending, logging to "
00117                        "stderr", filename);
00118     } else {
00119         logfile = stderr;
00120     }
00121     return;
00122 }
00123 
00124 
00129 void
00130 se_log_close(void)
00131 {
00132     se_log_debug("close log");
00133     se_log_init(NULL, 0, 0);
00134 }
00135 
00136 
00144 #ifdef HAVE_SYSLOG_H
00145 int
00146 se_log_get_facility(const char* facility)
00147 {
00148     int length;
00149 
00150     if (!facility) {
00151         return LOG_DAEMON;
00152     }
00153     length = strlen(facility);
00154 
00155     if (length == 4 && strncasecmp(facility, "KERN", 4) == 0)
00156         return LOG_KERN;
00157     else if (length == 4 && strncasecmp(facility, "USER", 4) == 0)
00158         return LOG_USER;
00159     else if (length == 4 && strncasecmp(facility, "MAIL", 4) == 0)
00160         return LOG_MAIL;
00161     else if (length == 6 && strncasecmp(facility, "DAEMON", 6) == 0)
00162         return LOG_DAEMON;
00163     else if (length == 4 && strncasecmp(facility, "AUTH", 4) == 0)
00164         return LOG_AUTH;
00165     else if (length == 3 && strncasecmp(facility, "LPR", 3) == 0)
00166         return LOG_LPR;
00167     else if (length == 4 && strncasecmp(facility, "NEWS", 4) == 0)
00168         return LOG_NEWS;
00169     else if (length == 4 && strncasecmp(facility, "UUCP", 4) == 0)
00170         return LOG_UUCP;
00171     else if (length == 4 && strncasecmp(facility, "CRON", 4) == 0)
00172         return LOG_CRON;
00173     else if (length == 6 && strncasecmp(facility, "LOCAL0", 6) == 0)
00174         return LOG_LOCAL0;
00175     else if (length == 6 && strncasecmp(facility, "LOCAL1", 6) == 0)
00176         return LOG_LOCAL1;
00177     else if (length == 6 && strncasecmp(facility, "LOCAL2", 6) == 0)
00178         return LOG_LOCAL2;
00179     else if (length == 6 && strncasecmp(facility, "LOCAL3", 6) == 0)
00180         return LOG_LOCAL3;
00181     else if (length == 6 && strncasecmp(facility, "LOCAL4", 6) == 0)
00182         return LOG_LOCAL4;
00183     else if (length == 6 && strncasecmp(facility, "LOCAL5", 6) == 0)
00184         return LOG_LOCAL5;
00185     else if (length == 6 && strncasecmp(facility, "LOCAL6", 6) == 0)
00186         return LOG_LOCAL6;
00187     else if (length == 6 && strncasecmp(facility, "LOCAL7", 6) == 0)
00188         return LOG_LOCAL7;
00189     se_log_warning("syslog facility %s not supported, logging to "
00190                    "log_daemon", facility);
00191     return LOG_DAEMON;
00192 
00193 }
00194 #endif /* HAVE_SYSLOG_H */
00195 
00196 
00201 static void
00202 se_log_vmsg(int priority, const char* t, const char* s, va_list args)
00203 {
00204     char message[ODS_SE_MAXLINE];
00205     static char nowstr[CTIME_LENGTH];
00206     size_t len = 0;
00207     time_t now = time_now();
00208 
00209     vsnprintf(message, sizeof(message), s, args);
00210     message[ODS_SE_MAXLINE-1] = '\0';
00211     len = strlen(message);
00212     message[len] = '\0';
00213 
00214 #ifdef HAVE_SYSLOG_H
00215     if (logging_to_syslog) {
00216         syslog(priority, "%s", message);
00217         return;
00218     }
00219 #endif /* HAVE_SYSLOG_H */
00220 
00221     if (!logfile) {
00222         return;
00223     }
00224 
00225     (void) ctime_r(&now, nowstr);
00226     nowstr[CTIME_LENGTH-2] = '\0'; /* remove trailing linefeed */
00227 
00228     fprintf(logfile, "[%s] %s[%i] %s: %s\n", nowstr,
00229         MY_PACKAGE_TARNAME, priority, t, message);
00230     fflush(logfile);
00231 }
00232 
00233 
00238 void
00239 se_log_deeebug(const char *format, ...)
00240 {
00241     va_list args;
00242     va_start(args, format);
00243     if (log_level >= LOG_DEEEBUG) {
00244         se_log_vmsg(LOG_DEBUG, "debug", format, args);
00245     }
00246     va_end(args);
00247 }
00248 
00249 
00254 void
00255 se_log_debug(const char *format, ...)
00256 {
00257     va_list args;
00258     va_start(args, format);
00259     if (log_level >= LOG_DEBUG) {
00260         se_log_vmsg(LOG_DEBUG, "debug", format, args);
00261     }
00262     va_end(args);
00263 }
00264 
00265 
00270 void
00271 se_log_verbose(const char *format, ...)
00272 {
00273     va_list args;
00274     va_start(args, format);
00275     if (log_level >= LOG_INFO) {
00276         se_log_vmsg(LOG_INFO, "verbose", format, args);
00277     }
00278     va_end(args);
00279 }
00280 
00281 
00286 void
00287 se_log_info(const char *format, ...)
00288 {
00289     va_list args;
00290     va_start(args, format);
00291     if (log_level >= LOG_NOTICE) {
00292         se_log_vmsg(LOG_NOTICE, "msg", format, args);
00293     }
00294     va_end(args);
00295 }
00296 
00297 
00302 void
00303 se_log_warning(const char *format, ...)
00304 {
00305     va_list args;
00306     va_start(args, format);
00307     if (log_level >= LOG_WARNING) {
00308         se_log_vmsg(LOG_WARNING, "warning", format, args);
00309     }
00310     va_end(args);
00311 }
00312 
00313 
00318 void
00319 se_log_error(const char *format, ...)
00320 {
00321     va_list args;
00322     va_start(args, format);
00323     if (log_level >= LOG_ERR) {
00324         se_log_vmsg(LOG_ERR, "error", format, args);
00325     }
00326     va_end(args);
00327 }
00328 
00329 
00334 void
00335 se_log_crit(const char *format, ...)
00336 {
00337     va_list args;
00338     va_start(args, format);
00339     if (log_level >= LOG_CRIT) {
00340         se_log_vmsg(LOG_CRIT, "critical", format, args);
00341     }
00342     va_end(args);
00343 }
00344 
00345 
00350 void
00351 se_log_alert(const char *format, ...)
00352 {
00353     va_list args;
00354     va_start(args, format);
00355     if (log_level >= LOG_ALERT) {
00356         se_log_vmsg(LOG_ALERT, "critical", format, args);
00357     }
00358     va_end(args);
00359 }
00360 
00361 
00366 void
00367 se_fatal_exit(const char *format, ...)
00368 {
00369     va_list args;
00370     va_start(args, format);
00371     if (log_level >= LOG_CRIT) {
00372         se_log_vmsg(LOG_CRIT, "fatal error", format, args);
00373     }
00374     va_end(args);
00375     abort();
00376 }