* va_list, and the applicable errno value (if any).
*
* The canonical version of this file is maintained in the rra-c-util package,
- * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
*
* Written by Russ Allbery <eagle@eyrie.org>
- * Copyright 2008, 2009, 2010, 2013
+ * Copyright 2015-2016, 2020 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008-2010, 2013-2014
* The Board of Trustees of the Leland Stanford Junior University
- * Copyright (c) 2004, 2005, 2006
- * by Internet Systems Consortium, Inc. ("ISC")
- * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- * 2002, 2003 by The Internet Software Consortium and Rich Salz
+ * Copyright 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright 1991, 1994-2003 The Internet Software Consortium and Rich Salz
*
* This code is derived from software contributed to the Internet Software
* Consortium by Rich Salz.
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
+ *
+ * SPDX-License-Identifier: ISC
*/
#include <config.h>
#include <errno.h>
#ifdef HAVE_SYSLOG_H
-# include <syslog.h>
+# include <syslog.h>
#endif
#ifdef _WIN32
-# include <windows.h>
-# define LOG_DEBUG EVENTLOG_SUCCESS
-# define LOG_INFO EVENTLOG_INFORMATION_TYPE
-# define LOG_NOTICE EVENTLOG_INFORMATION_TYPE
-# define LOG_WARNING EVENTLOG_WARNING_TYPE
-# define LOG_ERR EVENTLOG_ERROR_TYPE
-# define LOG_CRIT EVENTLOG_ERROR_TYPE
+# include <windows.h>
+# define LOG_DEBUG EVENTLOG_SUCCESS
+# define LOG_INFO EVENTLOG_INFORMATION_TYPE
+# define LOG_NOTICE EVENTLOG_INFORMATION_TYPE
+# define LOG_WARNING EVENTLOG_WARNING_TYPE
+# define LOG_ERR EVENTLOG_ERROR_TYPE
+# define LOG_CRIT EVENTLOG_ERROR_TYPE
#endif
#include <util/macros.h>
#include <util/xmalloc.h>
/* 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
-};
+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 *debug_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;
+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 (*list != stdout_handlers && *list != stderr_handlers)
free(*list);
- *list = xmalloc(sizeof(message_handler_func) * (count + 1));
+ *list = xcalloc(count + 1, sizeof(message_handler_func));
for (i = 0; i < count; i++)
(*list)[i] = (message_handler_func) va_arg(args, message_handler_func);
(*list)[count] = NULL;
* 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(unsigned int count, ...) \
- { \
- va_list args; \
- \
- va_start(args, count); \
- message_handlers(& type ## _handlers, count, args); \
- va_end(args); \
+/* clang-format off */
+#define HANDLER_FUNCTION(type) \
+ void \
+ message_handlers_ ## type(unsigned int count, ...) \
+ { \
+ va_list args; \
+ \
+ va_start(args, count); \
+ message_handlers(& type ## _handlers, count, args); \
+ va_end(args); \
}
+/* clang-format on */
HANDLER_FUNCTION(debug)
HANDLER_FUNCTION(notice)
HANDLER_FUNCTION(warn)
HANDLER_FUNCTION(die)
+/*
+ * Reset all handlers back to the defaults and free all allocated memory.
+ * This is primarily useful for programs that undergo comprehensive memory
+ * allocation analysis.
+ */
+void
+message_handlers_reset(void)
+{
+ free(debug_handlers);
+ debug_handlers = NULL;
+ if (notice_handlers != stdout_handlers) {
+ free(notice_handlers);
+ notice_handlers = stdout_handlers;
+ }
+ if (warn_handlers != stderr_handlers) {
+ free(warn_handlers);
+ warn_handlers = stderr_handlers;
+ }
+ if (die_handlers != stderr_handlers) {
+ free(die_handlers);
+ die_handlers = stderr_handlers;
+ }
+}
+
+
/*
* Print a message to stdout, supporting message_program_name.
*/
* This needs further attention on Windows. For example, it currently doesn't
* log the errno information.
*/
-static void
+static void __attribute__((__format__(printf, 3, 0)))
message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
{
char *buffer;
exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
}
status = vsnprintf(buffer, len + 1, fmt, args);
- if (status < 0) {
+ if (status < 0 || (size_t) status >= len + 1) {
warn("failed to format output with vsnprintf in syslog handler");
free(buffer);
return;
CloseEventLog(eventlog);
}
}
-#else /* !_WIN32 */
+#else /* !_WIN32 */
if (err == 0)
syslog(pri, "%s", buffer);
else
* Do the same sort of wrapper to generate all of the separate syslog logging
* functions.
*/
+/* clang-format off */
#define SYSLOG_FUNCTION(name, type) \
void \
message_log_syslog_ ## name(size_t l, const char *f, va_list a, int e) \
SYSLOG_FUNCTION(warning, WARNING)
SYSLOG_FUNCTION(err, ERR)
SYSLOG_FUNCTION(crit, CRIT)
+/* clang-format on */
/*