OpenDNSSEC-signer 1.3.0rc3
|
00001 /* 00002 * $Id: log.c 3845 2010-08-31 14:19:24Z 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 "shared/duration.h" 00036 #include "shared/file.h" 00037 #include "shared/log.h" 00038 #include "shared/util.h" 00039 00040 #include <stdarg.h> /* va_start(), va_end() */ 00041 #include <stdio.h> /* fflush, fprintf(), vsnprintf() */ 00042 #include <stdlib.h> /* exit() */ 00043 #include <string.h> /* strlen() */ 00044 00045 #ifdef HAVE_SYSLOG_H 00046 #include <strings.h> /* strncasecmp() */ 00047 #include <syslog.h> /* openlog(), closelog(), syslog() */ 00048 static int logging_to_syslog = 0; 00049 #else /* !HAVE_SYSLOG_H */ 00050 #define LOG_EMERG 0 /* ods_fatal_exit */ 00051 #define LOG_ALERT 1 /* ods_log_alert */ 00052 #define LOG_CRIT 2 /* ods_log_crit */ 00053 #define LOG_ERR 3 /* ods_log_error */ 00054 #define LOG_WARNING 4 /* ods_log_warning */ 00055 #define LOG_NOTICE 5 /* ods_log_info */ 00056 #define LOG_INFO 6 /* ods_log_verbose */ 00057 #define LOG_DEBUG 7 /* ods_log_debug */ 00058 #endif /* HAVE_SYSLOG_H */ 00059 00060 #define LOG_DEEEBUG 8 /* ods_log_deeebug */ 00061 00062 static FILE* logfile = NULL; 00063 static int log_level = LOG_CRIT; 00064 00065 #define CTIME_LENGTH 26 00066 00067 00068 /* TODO: 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 static const char* log_str = "log"; 00078 00083 void 00084 ods_log_init(const char *filename, int use_syslog, int verbosity) 00085 { 00086 #ifdef HAVE_SYSLOG_H 00087 int facility; 00088 #endif /* HAVE_SYSLOG_H */ 00089 ods_log_verbose("[%s] switching log to %s verbosity %i (log level %i)", 00090 log_str, use_syslog?"syslog":(filename&&filename[0]?filename:"stderr"), 00091 verbosity, verbosity+2); 00092 if (logfile && logfile != stderr) { 00093 ods_fclose(logfile); 00094 } 00095 log_level = verbosity + 2; 00096 00097 #ifdef HAVE_SYSLOG_H 00098 if(logging_to_syslog) { 00099 closelog(); 00100 logging_to_syslog = 0; 00101 } 00102 if(use_syslog) { 00103 facility = ods_log_get_facility(filename); 00104 openlog(MY_PACKAGE_TARNAME, LOG_NDELAY, facility); 00105 logging_to_syslog = 1; 00106 return; 00107 } 00108 #endif /* HAVE_SYSLOG_H */ 00109 00110 if(filename && filename[0]) { 00111 logfile = ods_fopen(filename, NULL, "a"); 00112 if (logfile) { 00113 ods_log_debug("[%s] new logfile %s", log_str, filename); 00114 return; 00115 } 00116 logfile = stderr; 00117 ods_log_warning("[%s] cannot open %s for appending, logging to " 00118 "stderr", log_str, filename); 00119 } else { 00120 logfile = stderr; 00121 } 00122 return; 00123 } 00124 00125 00130 void 00131 ods_log_close(void) 00132 { 00133 ods_log_debug("[%s] close log", log_str); 00134 ods_log_init(NULL, 0, 0); 00135 } 00136 00137 00145 #ifdef HAVE_SYSLOG_H 00146 int 00147 ods_log_get_facility(const char* facility) 00148 { 00149 int length; 00150 00151 if (!facility) { 00152 return LOG_DAEMON; 00153 } 00154 length = strlen(facility); 00155 00156 if (length == 4 && strncasecmp(facility, "KERN", 4) == 0) 00157 return LOG_KERN; 00158 else if (length == 4 && strncasecmp(facility, "USER", 4) == 0) 00159 return LOG_USER; 00160 else if (length == 4 && strncasecmp(facility, "MAIL", 4) == 0) 00161 return LOG_MAIL; 00162 else if (length == 6 && strncasecmp(facility, "DAEMON", 6) == 0) 00163 return LOG_DAEMON; 00164 else if (length == 4 && strncasecmp(facility, "AUTH", 4) == 0) 00165 return LOG_AUTH; 00166 else if (length == 3 && strncasecmp(facility, "LPR", 3) == 0) 00167 return LOG_LPR; 00168 else if (length == 4 && strncasecmp(facility, "NEWS", 4) == 0) 00169 return LOG_NEWS; 00170 else if (length == 4 && strncasecmp(facility, "UUCP", 4) == 0) 00171 return LOG_UUCP; 00172 else if (length == 4 && strncasecmp(facility, "CRON", 4) == 0) 00173 return LOG_CRON; 00174 else if (length == 6 && strncasecmp(facility, "LOCAL0", 6) == 0) 00175 return LOG_LOCAL0; 00176 else if (length == 6 && strncasecmp(facility, "LOCAL1", 6) == 0) 00177 return LOG_LOCAL1; 00178 else if (length == 6 && strncasecmp(facility, "LOCAL2", 6) == 0) 00179 return LOG_LOCAL2; 00180 else if (length == 6 && strncasecmp(facility, "LOCAL3", 6) == 0) 00181 return LOG_LOCAL3; 00182 else if (length == 6 && strncasecmp(facility, "LOCAL4", 6) == 0) 00183 return LOG_LOCAL4; 00184 else if (length == 6 && strncasecmp(facility, "LOCAL5", 6) == 0) 00185 return LOG_LOCAL5; 00186 else if (length == 6 && strncasecmp(facility, "LOCAL6", 6) == 0) 00187 return LOG_LOCAL6; 00188 else if (length == 6 && strncasecmp(facility, "LOCAL7", 6) == 0) 00189 return LOG_LOCAL7; 00190 ods_log_warning("[%s] syslog facility %s not supported, logging to " 00191 "log_daemon", log_str, facility); 00192 return LOG_DAEMON; 00193 00194 } 00195 #endif /* HAVE_SYSLOG_H */ 00196 00201 int 00202 ods_log_get_level() 00203 { 00204 return log_level; 00205 } 00206 00211 static void 00212 ods_log_vmsg(int priority, const char* t, const char* s, va_list args) 00213 { 00214 char message[ODS_SE_MAXLINE]; 00215 static char nowstr[CTIME_LENGTH]; 00216 time_t now = time_now(); 00217 00218 vsnprintf(message, sizeof(message), s, args); 00219 00220 #ifdef HAVE_SYSLOG_H 00221 if (logging_to_syslog) { 00222 syslog(priority, "%s", message); 00223 return; 00224 } 00225 #endif /* HAVE_SYSLOG_H */ 00226 00227 if (!logfile) { 00228 return; 00229 } 00230 00231 (void) ctime_r(&now, nowstr); 00232 nowstr[CTIME_LENGTH-2] = '\0'; /* remove trailing linefeed */ 00233 00234 fprintf(logfile, "[%s] %s[%i] %s: %s\n", nowstr, 00235 MY_PACKAGE_TARNAME, priority, t, message); 00236 fflush(logfile); 00237 } 00238 00239 00244 void 00245 ods_log_deeebug(const char *format, ...) 00246 { 00247 va_list args; 00248 va_start(args, format); 00249 if (log_level >= LOG_DEEEBUG) { 00250 ods_log_vmsg(LOG_DEBUG, "debug ", format, args); 00251 } 00252 va_end(args); 00253 } 00254 00255 00260 void 00261 ods_log_debug(const char *format, ...) 00262 { 00263 va_list args; 00264 va_start(args, format); 00265 if (log_level >= LOG_DEBUG) { 00266 ods_log_vmsg(LOG_DEBUG, "debug ", format, args); 00267 } 00268 va_end(args); 00269 } 00270 00271 00276 void 00277 ods_log_verbose(const char *format, ...) 00278 { 00279 va_list args; 00280 va_start(args, format); 00281 if (log_level >= LOG_INFO) { 00282 ods_log_vmsg(LOG_INFO, "verbose", format, args); 00283 } 00284 va_end(args); 00285 } 00286 00287 00292 void 00293 ods_log_info(const char *format, ...) 00294 { 00295 va_list args; 00296 va_start(args, format); 00297 if (log_level >= LOG_NOTICE) { 00298 ods_log_vmsg(LOG_NOTICE, "msg ", format, args); 00299 } 00300 va_end(args); 00301 } 00302 00303 00308 void 00309 ods_log_warning(const char *format, ...) 00310 { 00311 va_list args; 00312 va_start(args, format); 00313 if (log_level >= LOG_WARNING) { 00314 ods_log_vmsg(LOG_WARNING, "warning", format, args); 00315 } 00316 va_end(args); 00317 } 00318 00319 00324 void 00325 ods_log_error(const char *format, ...) 00326 { 00327 va_list args; 00328 va_start(args, format); 00329 if (log_level >= LOG_ERR) { 00330 ods_log_vmsg(LOG_ERR, "error ", format, args); 00331 } 00332 va_end(args); 00333 } 00334 00335 00340 void 00341 ods_log_crit(const char *format, ...) 00342 { 00343 va_list args; 00344 va_start(args, format); 00345 if (log_level >= LOG_CRIT) { 00346 ods_log_vmsg(LOG_CRIT, "crit ", format, args); 00347 } 00348 va_end(args); 00349 } 00350 00351 00356 void 00357 ods_log_alert(const char *format, ...) 00358 { 00359 va_list args; 00360 va_start(args, format); 00361 if (log_level >= LOG_ALERT) { 00362 ods_log_vmsg(LOG_ALERT, "alert ", format, args); 00363 } 00364 va_end(args); 00365 } 00366 00367 00372 void 00373 ods_fatal_exit(const char *format, ...) 00374 { 00375 va_list args; 00376 va_start(args, format); 00377 if (log_level >= LOG_CRIT) { 00378 ods_log_vmsg(LOG_CRIT, "fatal ", format, args); 00379 } 00380 va_end(args); 00381 abort(); 00382 }