diff options
Diffstat (limited to 'src/messages.c')
-rw-r--r-- | src/messages.c | 493 |
1 files changed, 0 insertions, 493 deletions
diff --git a/src/messages.c b/src/messages.c deleted file mode 100644 index 7a54e0a..0000000 --- a/src/messages.c +++ /dev/null @@ -1,493 +0,0 @@ -/* $Id: messages.c 5496 2002-06-07 13:59:06Z alexk $ -** -** Message and error reporting (possibly fatal). -** -** Usage: -** -** extern int cleanup(void); -** extern void log(int, const char *, va_list, int); -** -** message_fatal_cleanup = cleanup; -** message_program_name = argv[0]; -** -** warn("Something horrible happened at %lu", time); -** syswarn("Couldn't unlink temporary file %s", tmpfile); -** -** die("Something fatal happened at %lu", time); -** sysdie("open of %s failed", filename); -** -** debug("Some debugging message about %s", string); -** trace(TRACE_PROGRAM, "Program trace output"); -** notice("Informational notices"); -** -** message_handlers_warn(1, log); -** warn("This now goes through our log function"); -** -** These functions implement message reporting through user-configurable -** handler functions. debug() only does something if DEBUG is defined, -** trace() supports sending trace messages in one of a number of configurable -** classes of traces so that they can be turned on or off independently, and -** notice() and warn() just output messages as configured. die() similarly -** outputs a message but then exits, normally with a status of 1. -** -** The sys* versions do the same, but append a colon, a space, and the -** results of strerror(errno) to the end of the message. All functions -** accept printf-style formatting strings and arguments. -** -** If message_fatal_cleanup is non-NULL, it is called before exit by die and -** sysdie and its return value is used as the argument to exit. It is a -** pointer to a function taking no arguments and returning an int, and can be -** used to call cleanup functions or to exit in some alternate fashion (such -** as by calling _exit). -** -** If message_program_name is non-NULL, the string it points to, followed by -** a colon and a space, is prepended to all error messages logged through the -** message_log_stdout and message_log_stderr message handlers (the former is -** the default for notice, and the latter is the default for warn and die). -** -** Honoring error_program_name and printing to stderr is just the default -** handler; with message_handlers_* the handlers for any message function can -** be changed. By default, notice prints to stdout, warn and die print to -** stderr, and the others don't do anything at all. These functions take a -** count of handlers and then that many function pointers, each one to a -** function that takes a message length (the number of characters snprintf -** generates given the format and arguments), a format, an argument list as a -** va_list, and the applicable errno value (if any). -*/ - -/* Used for unused parameters to silence gcc warnings. */ -#define UNUSED __attribute__((__unused__)) - -/* Make available the bool type. */ -#if INN_HAVE_STDBOOL_H -# include <stdbool.h> -#else -# undef true -# undef false -# define true (1) -# define false (0) -# ifndef __cplusplus -# define bool int -# endif -#endif /* INN_HAVE_STDBOOL_H */ - -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <stdio.h> -#include <errno.h> -#include <syslog.h> -#include <crypt.h> -#include <fcntl.h> -#include <pwd.h> -#include <grp.h> - -/* The functions are actually macros so that we can pick up the file and line - number information for debugging error messages without the user having to - pass those in every time. */ -#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) -#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) -#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__) -#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) -#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) - -/* These are the currently-supported types of traces. */ -enum message_trace { - TRACE_NETWORK, /* Network traffic. */ - TRACE_PROGRAM, /* Stages of program execution. */ - TRACE_ALL /* All traces; this must be last. */ -}; - -/* The reporting functions. The ones prefaced by "sys" add a colon, a space, - and the results of strerror(errno) to the output and are intended for - reporting failures of system calls. */ -extern void trace(enum message_trace, const char *, ...) - __attribute__((__format__(printf, 2, 3))); -extern void notice(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void sysnotice(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void warn(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void syswarn(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -extern void die(const char *, ...) - __attribute__((__noreturn__, __format__(printf, 1, 2))); -extern void sysdie(const char *, ...) - __attribute__((__noreturn__, __format__(printf, 1, 2))); - -/* Debug is handled specially, since we want to make the code disappear - completely unless we're built with -DDEBUG. We can only do that with - support for variadic macros, though; otherwise, the function just won't do - anything. */ -#if !defined(DEBUG) && (INN_HAVE_C99_VAMACROS || INN_HAVE_GNU_VAMACROS) -# if INN_HAVE_C99_VAMACROS -# define debug(format, ...) /* empty */ -# elif INN_HAVE_GNU_VAMACROS -# define debug(format, args...) /* empty */ -# endif -#else -extern void debug(const char *, ...) - __attribute__((__format__(printf, 1, 2))); -#endif - -/* Set the handlers for various message functions. All of these functions - take a count of the number of handlers and then function pointers for each - of those handlers. These functions are not thread-safe; they set global - variables. */ -extern void message_handlers_debug(int count, ...); -extern void message_handlers_trace(int count, ...); -extern void message_handlers_notice(int count, ...); -extern void message_handlers_warn(int count, ...); -extern void message_handlers_die(int count, ...); - -/* Enable or disable tracing for particular classes of messages. */ -extern void message_trace_enable(enum message_trace, bool); - -/* Some useful handlers, intended to be passed to message_handlers_*. All - handlers take the length of the formatted message, the format, a variadic - argument list, and the errno setting if any. */ -extern void message_log_stdout(int, const char *, va_list, int); -extern void message_log_stderr(int, const char *, va_list, int); -extern void message_log_syslog_debug(int, const char *, va_list, int); -extern void message_log_syslog_info(int, const char *, va_list, int); -extern void message_log_syslog_notice(int, const char *, va_list, int); -extern void message_log_syslog_warning(int, const char *, va_list, int); -extern void message_log_syslog_err(int, const char *, va_list, int); -extern void message_log_syslog_crit(int, const char *, va_list, int); - -/* The type of a message handler. */ -typedef void (*message_handler_func)(int, const char *, va_list, int); - -/* If non-NULL, called before exit and its return value passed to exit. */ -extern int (*message_fatal_cleanup)(void); - -/* If non-NULL, prepended (followed by ": ") to all messages printed by either - message_log_stdout or message_log_stderr. */ -extern const char *message_program_name; - -/* The default handler lists. */ -static message_handler_func stdout_handlers[2] = { - message_log_stdout, NULL -}; -static message_handler_func stderr_handlers[2] = { - message_log_stderr, NULL -}; - -/* The list of logging functions currently in effect. */ -static message_handler_func *debug_handlers = NULL; -static message_handler_func *trace_handlers = NULL; -static message_handler_func *notice_handlers = stdout_handlers; -static message_handler_func *warn_handlers = stderr_handlers; -static message_handler_func *die_handlers = stderr_handlers; - -/* If non-NULL, called before exit and its return value passed to exit. */ -int (*message_fatal_cleanup)(void) = NULL; - -/* If non-NULL, prepended (followed by ": ") to messages. */ -const char *message_program_name = NULL; - -/* Whether or not we're currently outputting a particular type of trace. */ -static bool tracing[TRACE_ALL] = { false /* false, ... */ }; - - -/* -** Set the handlers for a particular message function. Takes a pointer to -** the handler list, the count of handlers, and the argument list. -*/ -static void -message_handlers(message_handler_func **list, int count, va_list args) -{ - int i; - - if (*list != stdout_handlers && *list != stderr_handlers) - free(*list); - *list = xmalloc(sizeof(message_handler_func) * (count + 1)); - for (i = 0; i < count; i++) - (*list)[i] = (message_handler_func) va_arg(args, message_handler_func); - (*list)[count] = NULL; -} - - -/* -** There's no good way of writing these handlers without a bunch of code -** duplication since we can't assume variadic macros, but I can at least make -** it easier to write and keep them consistent. -*/ -#define HANDLER_FUNCTION(type) \ - void \ - message_handlers_ ## type(int count, ...) \ - { \ - va_list args; \ - \ - va_start(args, count); \ - message_handlers(& type ## _handlers, count, args); \ - va_end(args); \ - } -HANDLER_FUNCTION(debug) -HANDLER_FUNCTION(trace) -HANDLER_FUNCTION(notice) -HANDLER_FUNCTION(warn) -HANDLER_FUNCTION(die) - - -/* -** Print a message to stdout, supporting message_program_name. -*/ -void -message_log_stdout(int len UNUSED, const char *fmt, va_list args, int err) -{ - if (message_program_name != NULL) - fprintf(stdout, "%s: ", message_program_name); - vfprintf(stdout, fmt, args); - if (err) - fprintf(stdout, ": %s", strerror(err)); - fprintf(stdout, "\n"); -} - - -/* -** Print a message to stderr, supporting message_program_name. Also flush -** stdout so that errors and regular output occur in the right order. -*/ -void -message_log_stderr(int len UNUSED, const char *fmt, va_list args, int err) -{ - fflush(stdout); - if (message_program_name != NULL) - fprintf(stderr, "%s: ", message_program_name); - vfprintf(stderr, fmt, args); - if (err) - fprintf(stderr, ": %s", strerror(err)); - fprintf(stderr, "\n"); -} - - -/* -** Log a message to syslog. This is a helper function used to implement all -** of the syslog message log handlers. It takes the same arguments as a -** regular message handler function but with an additional priority -** argument. -*/ -static void -message_log_syslog(int pri, int len, const char *fmt, va_list args, int err) -{ - char *buffer; - - buffer = malloc(len + 1); - if (buffer == NULL) { - fprintf(stderr, "failed to malloc %u bytes at %s line %d: %s", - len + 1, __FILE__, __LINE__, strerror(errno)); - exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); - } - vsnprintf(buffer, len + 1, fmt, args); - syslog(pri, err ? "%s: %m" : "%s", buffer); - free(buffer); -} - - -/* -** Do the same sort of wrapper to generate all of the separate syslog logging -** functions. -*/ -#define SYSLOG_FUNCTION(name, type) \ - void \ - message_log_syslog_ ## name(int l, const char *f, va_list a, int e) \ - { \ - message_log_syslog(LOG_ ## type, l, f, a, e); \ - } -SYSLOG_FUNCTION(debug, DEBUG) -SYSLOG_FUNCTION(info, INFO) -SYSLOG_FUNCTION(notice, NOTICE) -SYSLOG_FUNCTION(warning, WARNING) -SYSLOG_FUNCTION(err, ERR) -SYSLOG_FUNCTION(crit, CRIT) - - -/* -** Enable or disable tracing for particular classes of messages. -*/ -void -message_trace_enable(enum message_trace type, bool enable) -{ - if (type > TRACE_ALL) - return; - if (type == TRACE_ALL) { - int i; - - for (i = 0; i < TRACE_ALL; i++) - tracing[i] = enable; - } else { - tracing[type] = enable; - } -} - - -/* -** All of the message handlers. There's a lot of code duplication here too, -** but each one is still *slightly* different and va_start has to be called -** multiple times, so it's hard to get rid of the duplication. -*/ - -#ifdef DEBUG -void -debug(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - - if (debug_handlers == NULL) - return; - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = debug_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, 0); - va_end(args); - } -} -#elif !INN_HAVE_C99_VAMACROS && !INN_HAVE_GNU_VAMACROS -void debug(const char *format UNUSED, ...) { } -#endif - -void -trace(enum message_trace type, const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - - if (trace_handlers == NULL || !tracing[type]) - return; - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = trace_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, 0); - va_end(args); - } -} - -void -notice(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = notice_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, 0); - va_end(args); - } -} - -void -sysnotice(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - int error = errno; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = notice_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, error); - va_end(args); - } -} - -void -warn(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = warn_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, 0); - va_end(args); - } -} - -void -syswarn(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - int error = errno; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length < 0) - return; - for (log = warn_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, error); - va_end(args); - } -} - -void -die(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length >= 0) - for (log = die_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, 0); - va_end(args); - } - exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); -} - -void -sysdie(const char *format, ...) -{ - va_list args; - message_handler_func *log; - int length; - int error = errno; - - va_start(args, format); - length = vsnprintf(NULL, 0, format, args); - va_end(args); - if (length >= 0) - for (log = die_handlers; *log != NULL; log++) { - va_start(args, format); - (**log)(length, format, args, error); - va_end(args); - } - exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1); -} |