/*
Copyright (C) 1999-2004 IC & S dbmail@ic-s.nl
Copyright (c) 2004-2006 NFG Net Facilities Group BV support@nfg.nl
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
*
* Debugging and memory checking functions */
#include "dbmail.h"
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(BSD4_4)
extern char *__progname; /* Program name, from crt0. */
#else
char *__progname = NULL;
#endif
char hostname[16];
/* the debug variables */
static trace_t TRACE_SYSLOG = TRACE_ERROR; /* default: errors, warnings, fatals */
static trace_t TRACE_STDERR = TRACE_FATAL; /* default: fatal errors only */
/*
* configure the debug settings
*/
void configure_debug(trace_t trace_syslog, trace_t trace_stderr)
{
TRACE_SYSLOG = trace_syslog;
TRACE_STDERR = trace_stderr;
}
/* Make sure that these match trace_t. */
static const char * const trace_text[] = {
"FATAL",
"Error",
"Warning",
"Message",
"Info",
"Debug"
};
static const char * trace_to_text(trace_t level)
{
return trace_text[level];
}
/* Call me like this:
*
* TRACE(TRACE_ERROR, "Something happened with error code [%d]", resultvar);
*
* Please #define THIS_MODULE "mymodule" at the top of each file.
* Arguments for __FILE__ and __func__ are added by the TRACE macro.
*
* trace() and TRACE() are macros in debug.h
*
*/
void trace(trace_t level, const char * module,
const char * file, const char * function,
int line, char *formatstring, ...)
{
va_list argp;
gchar *message;
const char *syslog_format = "%s:[%s] %s,%s(+%d): %s";
const char *stderr_format = "%s %s %s[%d]: %s:[%s] %s,%s(+%d): %s";
static int configured=0;
size_t l;
/* Return now if we're not logging anything. */
if (level > TRACE_STDERR && level > TRACE_SYSLOG)
return;
va_start(argp, formatstring);
message = g_strdup_vprintf(formatstring, argp);
va_end(argp);
l = strlen(message);
if (level <= TRACE_STDERR) {
time_t now = time(NULL);
struct tm *tmp = localtime(&now);
char date[32];
if (! configured) {
memset(&hostname,'\0',16);
gethostname(&hostname,16);
configured=1;
}
memset(date,0,sizeof(date));
strftime(date,32,"%b %d %H:%M:%S", tmp);
fprintf(stderr, stderr_format, date, hostname, __progname?__progname:"", getpid(), trace_to_text(level), module, file, function, line, message);
if (message[l] != '\n')
fprintf(stderr, "\n");
fflush(stderr);
}
if (level <= TRACE_SYSLOG) {
if (message[l] == '\n')
message[l] = '\0';
/* set LOG_ALERT at warnings */
if (level <= TRACE_WARNING)
syslog(LOG_ALERT, syslog_format, trace_to_text(level), module, file, function, line, message);
else
syslog(LOG_NOTICE, syslog_format, trace_to_text(level), module, file, function, line, message);
}
g_free(message);
/* Bail out on fatal errors. */
if (level == TRACE_FATAL)
exit(EX_TEMPFAIL);
}
syntax highlighted by Code2HTML, v. 0.9.1