OpenDNSSEC-signer 1.2.1
|
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 }