/**************************************************************************************************
$Id: error.c,v 1.42 2005/04/20 16:49:11 bboy Exp $
error.c: Error reporting and message output functions.
Copyright (C) 2002-2005 Don Moore <bboy@bboy.net>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**************************************************************************************************/
#include "mydnsutil.h"
#define ERROR_MAXMSGLEN 1024
/* The name of the currently running program */
char *progname = (char *)PACKAGE;
/* Should ERR_VERBOSE cause output? */
int err_verbose = 0;
#if DEBUG_ENABLED
/* Should ERR_DEBUG cause output? */
int err_debug = 0;
#endif
/* Should error functions output to a file? */
FILE *err_file = NULL;
/* The last error message output, so we don't repeat ourselves */
static char err_last[ERROR_MAXMSGLEN + 1] = "";
/**************************************************************************************************
ERROR_INIT
Initialize error reporting and output functions.
**************************************************************************************************/
void
error_init(argv0, facility)
const char *argv0; /* argv[0] from calling program */
int facility; /* Logging facility (i.e. LOG_DAEMON, etc) */
{
int option;
/* Save program name */
if (argv0)
{
char *c;
if ((c = strrchr(argv0, '/')))
progname = strdup(c+1);
else
progname = strdup((char *)argv0);
if (!progname)
Err("strdup");
}
/* Open syslog */
if (!err_file)
{
option = LOG_CONS | LOG_NDELAY | LOG_PID;
#ifdef LOG_PERROR
if (isatty(STDERR_FILENO))
option |= LOG_PERROR;
#endif
openlog(progname, option, facility);
}
}
/*--- error_init() ------------------------------------------------------------------------------*/
/**************************************************************************************************
_ERROR_OUT
This function handles all program output after command line handling.
Always returns -1.
**************************************************************************************************/
static void
_error_out(
int priority, /* Priority (i.e. LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG) */
int errappend, /* Append strerror(errno)? */
int isfatal, /* Is this error fatal? */
const char *msg
)
{
static char out[ERROR_MAXMSGLEN + 2];
static int repeat = 0;
int len;
/* Construct 'out' - the output */
#if SHOW_PID_IN_ERRORS
if (err_file && errappend)
len = snprintf(out, sizeof(out) - 2, "%s [%d]: %s: %s", progname, getpid(), msg, strerror(errno));
else if (err_file)
len = snprintf(out, sizeof(out) - 2, "%s [%d]: %s", progname, getpid(), msg);
#else
if (err_file && errappend)
len = snprintf(out, sizeof(out) - 2, "%s: %s: %s", progname, msg, strerror(errno));
else if (err_file)
len = snprintf(out, sizeof(out) - 2, "%s: %s", progname, msg);
#endif
else if (errappend)
len = snprintf(out, sizeof(out) - 2, "%s: %s", msg, strerror(errno));
else
len = snprintf(out, sizeof(out) - 2, "%s", msg);
/* Don't output the same error message again and again */
if (strcmp(out, err_last))
{
if (repeat)
{
if (err_file)
fprintf(err_file, _("%s: last message repeated %d times\n"), progname, repeat + 1);
else
syslog(priority, _("last message repeated %d times"), repeat + 1);
}
repeat = 0;
strncpy(err_last, out, ERROR_MAXMSGLEN);
if (err_file)
{
out[len++] = '\n';
out[len] = '\0';
fwrite(out, len, 1, err_file);
fflush(err_file);
}
else
syslog(priority, "%s", out);
}
else
repeat++;
/* Abort if the error should be fatal */
if (isfatal)
exit(EXIT_FAILURE);
}
/*--- _error_out() ------------------------------------------------------------------------------*/
/**************************************************************************************************
_ERROR_ASSERT_FAIL
This is called by the macro "Assert" if an assertion fails.
**************************************************************************************************/
void
_error_assert_fail(const char *assertion)
{
char msg[BUFSIZ];
snprintf(msg, sizeof(msg), "assertion failed: %s", assertion);
_error_out(LOG_ERR, 0, 1, msg);
}
/*--- _error_assert_fail() ----------------------------------------------------------------------*/
#if DEBUG_ENABLED
/**************************************************************************************************
DEBUG
**************************************************************************************************/
void
Debug(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
if (!err_debug)
return;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_DEBUG, 0, 0, msg);
}
/*--- Debug() -----------------------------------------------------------------------------------*/
#endif
/**************************************************************************************************
VERBOSE
**************************************************************************************************/
void
Verbose(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
if (!err_verbose)
return;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_WARNING, 0, 0, msg);
}
/*--- Verbose() ---------------------------------------------------------------------------------*/
/**************************************************************************************************
NOTICE
**************************************************************************************************/
void
Notice(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_WARNING, 0, 0, msg);
}
/*--- Notice() ----------------------------------------------------------------------------------*/
/**************************************************************************************************
WARN
**************************************************************************************************/
int
Warn(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_WARNING, 1, 0, msg);
return (-1);
}
/*--- Warn() ------------------------------------------------------------------------------------*/
/**************************************************************************************************
WARNX
**************************************************************************************************/
int
Warnx(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_WARNING, 0, 0, msg);
return (-1);
}
/*--- Warnx() -----------------------------------------------------------------------------------*/
/**************************************************************************************************
ERR
**************************************************************************************************/
void
Err(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_ERR, 1, 1, msg);
}
/*--- Err() -------------------------------------------------------------------------------------*/
/**************************************************************************************************
ERRX
**************************************************************************************************/
void
Errx(const char *fmt, ...)
{
char msg[BUFSIZ];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
_error_out(LOG_ERR, 0, 1, msg);
}
/*--- Errx() ------------------------------------------------------------------------------------*/
/**************************************************************************************************
WARNSQL
Outputs a warning caused by an SQL query failure.
**************************************************************************************************/
int
WarnSQL(
#if USE_PGSQL
PGconn *pgsql,
#else
MYSQL *mysql,
#endif
const char *fmt, ...)
{
char msg[BUFSIZ], out[BUFSIZ * 2];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
#if USE_PGSQL
{
char *errmsg = PQerrorMessage(pgsql), *c;
for (c = errmsg; *c; c++)
if (*c == '\r' || *c == '\n')
*c = ' ';
strtrim(errmsg);
snprintf(out, sizeof(out), "%s: %s (errno=%d)", msg, errmsg, errno);
}
#else
snprintf(out, sizeof(out), "%s: %s (errno=%d)", msg, mysql_error(mysql), errno);
#endif
_error_out(LOG_WARNING, 0, 0, out);
return (-1);
}
/*--- WarnSQL() ---------------------------------------------------------------------------------*/
/**************************************************************************************************
SQL_ERRMSG
**************************************************************************************************/
char *
sql_errmsg(
#if USE_PGSQL
PGconn *pgsql
#else
MYSQL *mysql
#endif
)
{
static char msg[BUFSIZ];
#if USE_PGSQL
{
char *errmsg = PQerrorMessage(pgsql), *c;
for (c = errmsg; *c; c++)
if (*c == '\r' || *c == '\n')
*c = ' ';
strtrim(errmsg);
snprintf(msg, sizeof(msg), "%s (errno=%d)", errmsg, errno);
}
#else
snprintf(msg, sizeof(msg), "%s (errno=%d)", mysql_error(mysql), errno);
#endif
return (msg);
}
/*--- sql_errmsg() ------------------------------------------------------------------------------*/
/**************************************************************************************************
ERRSQL
**************************************************************************************************/
void
ErrSQL(
#if USE_PGSQL
PGconn *pgsql,
#else
MYSQL *mysql,
#endif
const char *fmt, ...)
{
char msg[BUFSIZ], out[BUFSIZ * 2];
va_list ap;
/* Construct output string */
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
#if USE_PGSQL
{
char *errmsg = PQerrorMessage(pgsql), *c;
for (c = errmsg; *c; c++)
if (*c == '\r' || *c == '\n')
*c = ' ';
strtrim(errmsg);
snprintf(out, sizeof(out), "%s: %s (errno=%d)", msg, errmsg, errno);
}
#else
snprintf(out, sizeof(out), "%s: %s (errno=%d)", msg, mysql_error(mysql), errno);
#endif
_error_out(LOG_ERR, 0, 1, out);
}
/*--- ErrSQL() ----------------------------------------------------------------------------------*/
/* vi:set ts=3: */
syntax highlighted by Code2HTML, v. 0.9.1