00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00028 #if HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include "dnxLogging.h"
00033 #include "dnxError.h"
00034 #include "dnxTransport.h"
00035 #include "dnxDebug.h"
00036
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <stdio.h>
00040 #include <stdarg.h>
00041 #include <string.h>
00042 #include <time.h>
00043 #include <errno.h>
00044 #include <assert.h>
00045 #include <unistd.h>
00046 #include <syslog.h>
00047
00048 #ifndef LOCALSTATEDIR
00049 # define LOCALSTATEDIR "/var"
00050 #endif
00051
00052 #define LOGDIR LOCALSTATEDIR "/log"
00053
00054 #ifndef DEF_LOG_FILE
00055 # define DEF_LOG_FILE LOGDIR "/dnx.log"
00056 #endif
00057
00058 #ifndef DEF_DEBUG_FILE
00059 # define DEF_DEBUG_FILE LOGDIR "/dnx.debug.log"
00060 #endif
00061
00062 #ifndef DEF_DEBUG_LEVEL
00063 # define DEF_DEBUG_LEVEL 0
00064 #endif
00065
00067 #define MAX_LOG_LINE 4096
00068 #define SYSLOG_IDENT "DNX"
00069
00070 static char SLTAG[] = "syslog:";
00071 static int defDebugLevel = DEF_DEBUG_LEVEL;
00072
00073 static int s_syslogLog = 0;
00074 static int s_syslogDebug = 0;
00075 static int s_syslogAudit = 0;
00076 static int * s_debugLevel = &defDebugLevel;
00077 static char s_logFileName[FILENAME_MAX + 1] = DEF_LOG_FILE;
00078 static char s_dbgFileName[FILENAME_MAX + 1] = DEF_DEBUG_FILE;
00079 static char s_audFileName[FILENAME_MAX + 1] = "";
00080
00081
00082
00083
00084
00093 static int decodeSyslogFlags(const char * flagstr, int defaultSev)
00094 {
00095 static struct { const char * str; int value; } sevflags[] =
00096 {
00097
00098 { "LOG_EMERG", LOG_EMERG },
00099 { "LOG_ALERT", LOG_ALERT },
00100 { "LOG_CRIT", LOG_CRIT },
00101 { "LOG_ERR", LOG_ERR },
00102 { "LOG_WARNING", LOG_WARNING },
00103 { "LOG_NOTICE", LOG_NOTICE },
00104 { "LOG_INFO", LOG_INFO },
00105 { "LOG_DEBUG", LOG_DEBUG },
00106 };
00107 static struct { const char * str; int value; } facflags[] =
00108 {
00109
00110 { "LOG_USER", LOG_USER },
00111 { "LOG_LOCAL0", LOG_LOCAL0 },
00112 { "LOG_LOCAL1", LOG_LOCAL1 },
00113 { "LOG_LOCAL2", LOG_LOCAL2 },
00114 { "LOG_LOCAL3", LOG_LOCAL3 },
00115 { "LOG_LOCAL4", LOG_LOCAL4 },
00116 { "LOG_LOCAL5", LOG_LOCAL5 },
00117 { "LOG_LOCAL6", LOG_LOCAL6 },
00118 { "LOG_LOCAL7", LOG_LOCAL7 },
00119 };
00120 char flagcpy[128];
00121 char * cp = flagcpy;
00122 char * ep;
00123 int sevFound = 0, facFound = 0;
00124 int severity, facility;
00125
00126
00127 strncpy(flagcpy, flagstr, sizeof(flagcpy) - 1);
00128 flagcpy[sizeof(flagcpy) - 1] = 0;
00129 ep = cp + strlen(cp);
00130
00131
00132 while (cp < ep)
00133 {
00134 char * np;
00135 char * tp;
00136 int i;
00137
00138
00139 while (isspace(*cp)) cp++;
00140
00141
00142 if ((tp = np = strchr(cp, '|')) == 0)
00143 tp = np = ep;
00144 *np++ = 0;
00145
00146
00147 while (tp > --cp && isspace(*tp)) *tp = 0;
00148
00149
00150 for (i = 0; i < sizeof(sevflags) / sizeof(*sevflags); i++)
00151 if (strcmp(sevflags[i].str, cp) == 0)
00152 {
00153 severity = sevflags[i].value;
00154 sevFound = 1;
00155 }
00156
00157
00158 for (i = 0; i < sizeof(facflags) / sizeof(*facflags); i++)
00159 if (strcmp(facflags[i].str, cp) == 0)
00160 {
00161 facility = facflags[i].value;
00162 facFound = 1;
00163 }
00164
00165
00166 cp = np;
00167 }
00168 if (!sevFound) severity = defaultSev;
00169 if (!facFound) facility = LOG_USER;
00170 return severity | facility;
00171 }
00172
00173
00174
00182 static FILE * openFile(const char * filename, int * pstd)
00183 {
00184 int std = 1;
00185 FILE * fp = stdout;
00186
00187
00188 if (*filename && strcmp(filename, "STDOUT") != 0)
00189 {
00190 if (strcmp(filename, "STDERR") == 0)
00191 fp = stderr;
00192 else
00193 {
00194
00195 int i = 0;
00196 do fp = fopen(filename, "a+"); while (!fp && ++i < 1000);
00197 std = 0;
00198 }
00199 }
00200 *pstd = std;
00201 return fp;
00202 }
00203
00204
00205
00212 static void dnx_vsyslog(int pri, const char * fmt, va_list ap)
00213 {
00214 #ifdef _BSD_SOURCE
00215 vsyslog(pri, fmt, ap);
00216 #else
00217 {
00218 char buf[MAX_LOG_LINE];
00219 vsnprintf(buf, sizeof(buf), fmt, ap);
00220 syslog(pri, "%s", buf);
00221 }
00222 #endif
00223 }
00224
00225
00226
00235 static int vlogger(FILE * fp, char * fmt, va_list ap)
00236 {
00237 if (!isatty(fileno(fp)))
00238 {
00239
00240
00241 char clock_buf[26];
00242 struct timespec tspec;
00243 clock_gettime(CLOCK_REALTIME, &tspec);
00244 ctime_r(&tspec.tv_sec, clock_buf);
00245 if (fprintf(fp, "[%.*s.%-3ld%.*s] ",
00246 19, clock_buf,
00247 tspec.tv_nsec / (1000L * 1000L),
00248 5, clock_buf + 19) < 0)
00249 return errno;
00250 }
00251 if (vfprintf(fp, fmt, ap) < 0)
00252 return errno;
00253 if (fputc('\n', fp) == EOF)
00254 return errno;
00255 if (fflush(fp) == EOF)
00256 return errno;
00257 return 0;
00258 }
00259
00260
00261
00262
00263
00264 void dnxLog(char * fmt, ... )
00265 {
00266 va_list ap;
00267 assert(fmt);
00268
00269 if (*s_logFileName)
00270 {
00271 if (s_syslogLog)
00272 {
00273 va_start(ap, fmt);
00274 dnx_vsyslog(s_syslogLog, fmt, ap);
00275 va_end(ap);
00276 }
00277 else
00278 {
00279 FILE * fp;
00280 int stdhandle;
00281 if ((fp = openFile(s_logFileName, &stdhandle)) != 0)
00282 {
00283 va_start(ap, fmt);
00284 vlogger(fp, fmt, ap);
00285 va_end(ap);
00286
00287 if (!stdhandle)
00288 fclose(fp);
00289 }
00290 }
00291 }
00292 }
00293
00294
00295
00296 void dnxDebug(int level, char * fmt, ... )
00297 {
00298 va_list ap;
00299 assert(fmt);
00300
00301 if (*s_dbgFileName && level <= *s_debugLevel)
00302 {
00303 if (s_syslogDebug)
00304 {
00305 va_start(ap, fmt);
00306 dnx_vsyslog(s_syslogDebug, fmt, ap);
00307 va_end(ap);
00308 }
00309 else
00310 {
00311 FILE * fp;
00312 int stdhandle;
00313 if ((fp = openFile(s_dbgFileName, &stdhandle)) != 0)
00314 {
00315 va_start(ap, fmt);
00316 vlogger(fp, fmt, ap);
00317 va_end(ap);
00318
00319 if (!stdhandle)
00320 fclose(fp);
00321 }
00322 }
00323 }
00324 }
00325
00326
00327
00328 int dnxAudit(char * fmt, ... )
00329 {
00330 int ret = 0;
00331 va_list ap;
00332 assert(fmt);
00333
00334 if (*s_audFileName)
00335 {
00336 if (s_syslogAudit)
00337 {
00338 va_start(ap, fmt);
00339 dnx_vsyslog(s_syslogAudit, fmt, ap);
00340 va_end(ap);
00341 }
00342 else
00343 {
00344 FILE * fp;
00345 int stdhandle;
00346 if ((fp = openFile(s_audFileName, &stdhandle)) != 0)
00347 {
00348 va_start(ap, fmt);
00349 ret = vlogger(fp, fmt, ap);
00350 va_end(ap);
00351
00352 if (!stdhandle)
00353 fclose(fp);
00354 }
00355 }
00356 }
00357 return ret;
00358 }
00359
00360
00361
00362 void dnxLogInit(char * logFile, char * debugFile, char * auditFile,
00363 int * debugLevel)
00364 {
00365 if (logFile)
00366 {
00367 if (strncasecmp(logFile, SLTAG, sizeof SLTAG - 1) == 0)
00368 s_syslogLog = decodeSyslogFlags(logFile
00369 + sizeof SLTAG - 1, LOG_INFO);
00370 else
00371 {
00372 strncpy(s_logFileName, logFile, sizeof(s_logFileName) - 1);
00373 s_logFileName[sizeof(s_logFileName) - 1] = 0;
00374 }
00375 }
00376 if (debugFile)
00377 {
00378 if (strncasecmp(debugFile, SLTAG, sizeof SLTAG - 1) == 0)
00379 s_syslogDebug = decodeSyslogFlags(debugFile
00380 + sizeof SLTAG - 1, LOG_DEBUG);
00381 else
00382 {
00383 strncpy(s_dbgFileName, debugFile, sizeof(s_dbgFileName) - 1);
00384 s_dbgFileName[sizeof(s_dbgFileName) - 1] = 0;
00385 }
00386 }
00387 if (auditFile)
00388 {
00389 if (strncasecmp(auditFile, SLTAG, sizeof SLTAG - 1) == 0)
00390 s_syslogDebug = decodeSyslogFlags(auditFile
00391 + sizeof SLTAG - 1, LOG_NOTICE);
00392 else
00393 {
00394 strncpy(s_audFileName, auditFile, sizeof(s_audFileName) - 1);
00395 s_audFileName[sizeof(s_audFileName) - 1] = 0;
00396 }
00397 }
00398 s_debugLevel = debugLevel;
00399
00400
00401
00402 if (s_syslogLog || s_syslogDebug || s_syslogAudit)
00403 openlog(SYSLOG_IDENT, 0, 0);
00404 }
00405
00406
00407