X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=debug.c;h=68f0f05ac03ff125dbb65ed49470a85e9f19c5a3;hb=refs%2Fheads%2FRADSECPROXY-51;hp=f507f50cd54c9fb6e75f71708b9f6fba8a164d89;hpb=ba96d1cc28b9f1a54720bc997b38a9fabf896cdd;p=radsecproxy.git diff --git a/debug.c b/debug.c index f507f50..68f0f05 100644 --- a/debug.c +++ b/debug.c @@ -1,35 +1,250 @@ -/* - * Copyright (C) 2007 Stig Venaas - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ +/* Copyright (c) 2007-2009, UNINETT AS + * Copyright (c) 2010-2011, NORDUnet A/S */ +/* See LICENSE for licensing information. */ +#ifndef SYS_SOLARIS9 #include +#endif #include #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include "debug.h" +#include "util.h" -static uint8_t debug_level = 0; +static char *debug_ident = NULL; +static uint8_t debug_level = DBG_INFO; +static char *debug_filepath = NULL; +static FILE *debug_file = NULL; +static int debug_syslogfacility = 0; +#if defined(WANT_FTICKS) +static int fticks_syslogfacility = 0; +#endif +static uint8_t debug_timestamp = 0; -void debug(uint8_t level, char *format, ...) { +void debug_init(char *ident) { + debug_file = stderr; + setvbuf(debug_file, NULL, _IONBF, 0); + debug_ident = ident; +} + +void debug_set_level(uint8_t level) { + switch (level) { + case 1: + debug_level = DBG_ERR; + return; + case 2: + debug_level = DBG_WARN; + return; + case 3: + debug_level = DBG_NOTICE; + return; + case 4: + debug_level = DBG_INFO; + return; + case 5: + debug_level = DBG_DBG; + return; + } +} + +void debug_timestamp_on() { + debug_timestamp = 1; +} + +uint8_t debug_get_level() { + return debug_level; +} + +int debug_set_destination(char *dest, int log_type) { + static const char *facstrings[] = { + "LOG_DAEMON", "LOG_MAIL", "LOG_USER", "LOG_LOCAL0", + "LOG_LOCAL1", "LOG_LOCAL2", "LOG_LOCAL3", "LOG_LOCAL4", + "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7", NULL }; + static const int facvals[] = { + LOG_DAEMON, LOG_MAIL, LOG_USER, LOG_LOCAL0, + LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, + LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 }; extern int errno; - + int i; + + if (!strncasecmp(dest, "file:///", 8)) { + if (log_type != LOG_TYPE_FTICKS) { + debug_filepath = stringcopy(dest + 7, 0); + debug_file = fopen(debug_filepath, "a"); + if (!debug_file) { + debug_file = stderr; + debugx(1, DBG_ERR, "Failed to open logfile %s\n%s", + debug_filepath, strerror(errno)); + } + setvbuf(debug_file, NULL, _IONBF, 0); + } else { + debug(DBG_WARN, "FTicksSyslogFacility starting with file:/// not " + "permitted, assuming default F-Ticks destination"); + } + return 1; + } + if (!strncasecmp(dest, "x-syslog://", 11) || log_type == LOG_TYPE_FTICKS) { + if (!strncasecmp(dest, "x-syslog://", 11)) { + dest += 11; + if (*dest == '/') + dest++; + } + if (*dest) { + for (i = 0; facstrings[i]; i++) + if (!strcasecmp(dest, facstrings[i])) + break; + if (!facstrings[i]) + debugx(1, DBG_ERR, "Unknown syslog facility %s", dest); + if (log_type != LOG_TYPE_FTICKS) + debug_syslogfacility = facvals[i]; +#if defined(WANT_FTICKS) + else if (log_type == LOG_TYPE_FTICKS) + fticks_syslogfacility = facvals[i]; +#endif + } else { + if (log_type != LOG_TYPE_FTICKS) + debug_syslogfacility = LOG_DAEMON; +#if defined(WANT_FTICKS) + else if (log_type == LOG_TYPE_FTICKS) + fticks_syslogfacility = 0; +#endif + } + openlog(debug_ident, LOG_PID, debug_syslogfacility); + return 1; + } + debug(DBG_ERR, "Unknown log destination, exiting %s", dest); + exit(1); +} + +void debug_reopen_log() { + extern int errno; + + /* not a file, noop, return success */ + if (!debug_filepath) { + debug(DBG_ERR, "skipping reopen"); + return; + } + + if (debug_file != stderr) + fclose(debug_file); + + debug_file = fopen(debug_filepath, "a"); + if (debug_file) + debug(DBG_ERR, "Reopened logfile %s", debug_filepath); + else { + debug_file = stderr; + debug(DBG_ERR, "Failed to open logfile %s, using stderr\n%s", + debug_filepath, strerror(errno)); + } + setvbuf(debug_file, NULL, _IONBF, 0); +} + +void debug_logit(uint8_t level, const char *format, va_list ap) { + struct timeval now; + char *timebuf; + int priority; + + if (debug_syslogfacility) { + switch (level) { + case DBG_DBG: + priority = LOG_DEBUG; + break; + case DBG_INFO: + priority = LOG_INFO; + break; + case DBG_NOTICE: + priority = LOG_NOTICE; + break; + case DBG_WARN: + priority = LOG_WARNING; + break; + case DBG_ERR: + priority = LOG_ERR; + break; + default: + priority = LOG_DEBUG; + } + vsyslog(priority, format, ap); + } else { + if (debug_timestamp && (timebuf = malloc(256))) { + gettimeofday(&now, NULL); + ctime_r(&now.tv_sec, timebuf); + timebuf[strlen(timebuf) - 1] = '\0'; + fprintf(debug_file, "%s: ", timebuf + 4); + free(timebuf); + } + vfprintf(debug_file, format, ap); + fprintf(debug_file, "\n"); + } +} + +void debug(uint8_t level, char *format, ...) { + va_list ap; + if (level < debug_level) + return; + va_start(ap, format); + debug_logit(level, format, ap); + va_end(ap); +} + +void debugx(int status, uint8_t level, char *format, ...) { + if (level >= debug_level) { + va_list ap; + va_start(ap, format); + debug_logit(level, format, ap); + va_end(ap); + } + exit(status); +} + +void debugerrno(int err, uint8_t level, char *format, ...) { + if (level >= debug_level) { + va_list ap; + size_t len = strlen(format); + char *tmp = malloc(len + 1024 + 2); + assert(tmp); + strcpy(tmp, format); + tmp[len++] = ':'; + tmp[len++] = ' '; + if (strerror_r(err, tmp + len, 1024)) + tmp = format; + va_start(ap, format); + debug_logit(level, tmp, ap); + va_end(ap); + } +} + +void debugerrnox(int err, uint8_t level, char *format, ...) { if (level >= debug_level) { va_list ap; va_start(ap, format); - vfprintf(stderr, format, ap); + debugerrno(err, level, format, ap); va_end(ap); - if (errno) { - fprintf(stderr, ": "); - perror(NULL); - fprintf(stderr, "errno=%d\n", errno); - } else - fprintf(stderr, "\n"); } - if (level >= DBG_ERR) - exit(1); + exit(err); +} + +#if defined(WANT_FTICKS) +void fticks_debug(const char *format, ...) { + int priority; + va_list ap; + va_start(ap, format); + if (!debug_syslogfacility && !fticks_syslogfacility) + debug_logit(0xff, format, ap); + else { + priority = LOG_DEBUG | fticks_syslogfacility; + vsyslog(priority, format, ap); + va_end(ap); + } } +#endif +/* Local Variables: */ +/* c-file-style: "stroustrup" */ +/* End: */