]> eyrie.org Git - kerberos/krb5-strength.git/blobdiff - util/messages.c
Add dependabot configuration
[kerberos/krb5-strength.git] / util / messages.c
index 52fcfb744ded90644d3ca56f0e11507548293be8..0e79a4397db346ce4ece104e375459d44dc5c1e1 100644 (file)
  * 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 <rra@stanford.edu>
- * Copyright 2008, 2009, 2010
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * 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.
@@ -75,6 +74,8 @@
  * 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;
@@ -131,7 +128,7 @@ message_handlers(message_handler_func **list, unsigned int count, va_list args)
 
     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;
@@ -143,22 +140,49 @@ message_handlers(message_handler_func **list, unsigned int count, va_list args)
  * 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.
  */
@@ -200,10 +224,11 @@ message_log_stderr(size_t len UNUSED, const char *fmt, va_list args, int err)
  * 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;
+    int status;
 
     buffer = malloc(len + 1);
     if (buffer == NULL) {
@@ -211,7 +236,12 @@ message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
                 (unsigned long) len + 1, __FILE__, __LINE__, strerror(errno));
         exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
     }
-    vsnprintf(buffer, len + 1, fmt, args);
+    status = vsnprintf(buffer, len + 1, fmt, args);
+    if (status < 0 || (size_t) status >= len + 1) {
+        warn("failed to format output with vsnprintf in syslog handler");
+        free(buffer);
+        return;
+    }
 #ifdef _WIN32
     {
         HANDLE eventlog;
@@ -222,7 +252,7 @@ message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
             CloseEventLog(eventlog);
         }
     }
-#else /* !_WIN32 */
+#else  /* !_WIN32 */
     if (err == 0)
         syslog(pri, "%s", buffer);
     else
@@ -236,6 +266,7 @@ message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
  * 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) \
@@ -248,6 +279,7 @@ SYSLOG_FUNCTION(notice,  NOTICE)
 SYSLOG_FUNCTION(warning, WARNING)
 SYSLOG_FUNCTION(err,     ERR)
 SYSLOG_FUNCTION(crit,    CRIT)
+/* clang-format on */
 
 
 /*