]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
debug: Add debug_syslog_format setting
authorMartin Schwenke <martin@meltin.net>
Thu, 28 Oct 2021 08:05:19 +0000 (19:05 +1100)
committerRalph Boehme <slow@samba.org>
Mon, 1 Nov 2021 06:37:32 +0000 (06:37 +0000)
Without debug_hires_timestamp this produces a syslog style header
containing:

  "MON DD HH:MM:SS HOSTNAME PROGNAME[PID] "

With debug_hires_timestamp this produces a syslog style header
containing:

  "RFC5424-TIMESTAMP HOSTNAME PROGNAME[PID] "

All other settings are ignored.

This will be made visible via smb.conf in a subsequent commit.

This commit adds some simple hostname handling.  It avoids using
get_myname() from util.c because using that potentially pulls in all
manner of dependencies.  No real error handling is done.  In the worst
case debug_set_hostname() sets the hostname to a truncated version of
the given string.  Similarly, in an even weirder world,
ensure_hostname() sets the hostname to a truncation of "unknown".
Both of these are unlikely in all reasonable cases.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/util/debug.c
lib/util/debug.h

index b0ac6ce40ea684f95769fd57f466cb0f22cc739e..2f4a86734ce12a47c6c9cf603ab069e18b6cd190 100644 (file)
@@ -24,6 +24,8 @@
 #include "system/filesys.h"
 #include "system/syslog.h"
 #include "system/locale.h"
+#include "system/network.h"
+#include "system/time.h"
 #include "time_basic.h"
 #include "close_low_fd.h"
 #include "memory.h"
@@ -89,6 +91,7 @@ static struct {
        bool initialized;
        enum debug_logtype logtype; /* The type of logging we are doing: eg stdout, file, stderr */
        char prog_name[255];
+       char hostname[HOST_NAME_MAX+1];
        bool reopening_logs;
        bool schedule_reopen_logs;
 
@@ -1071,6 +1074,35 @@ void debug_set_settings(struct debug_settings *settings,
        debug_set_backends(logging_param);
 }
 
+static void ensure_hostname(void)
+{
+       int ret;
+
+       if (state.hostname[0] != '\0') {
+               return;
+       }
+
+       ret = gethostname(state.hostname, sizeof(state.hostname));
+       if (ret != 0) {
+               strlcpy(state.hostname, "unknown", sizeof(state.hostname));
+               return;
+       }
+
+       /*
+        * Ensure NUL termination, since POSIX isn't clear about that.
+        *
+        * Don't worry about truncating at the first '.' or similar,
+        * since this is usually not fully qualified.  Trying to
+        * truncate opens up the multibyte character gates of hell.
+        */
+       state.hostname[sizeof(state.hostname) - 1] = '\0';
+}
+
+void debug_set_hostname(const char *name)
+{
+       strlcpy(state.hostname, name, sizeof(state.hostname));
+}
+
 /**
   control the name of the logfile and whether logging will be to stdout, stderr
   or a file, and set up syslog
@@ -1671,11 +1703,52 @@ bool dbghdrclass(int level, int cls, const char *location, const char *func)
         * not yet loaded, then default to timestamps on.
         */
        if (!(state.settings.timestamp_logs ||
-             state.settings.debug_prefix_timestamp)) {
+             state.settings.debug_prefix_timestamp ||
+             state.settings.debug_syslog_format)) {
                return true;
        }
 
        GetTimeOfDay(&tv);
+
+       if (state.settings.debug_syslog_format) {
+               if (state.settings.debug_hires_timestamp) {
+                       timeval_str_buf(&tv, true, true, &tvbuf);
+               } else {
+                       time_t t;
+                       struct tm *tm;
+
+                       t = (time_t)tv.tv_sec;
+                       tm = localtime(&t);
+                       if (tm != NULL) {
+                               size_t len;
+                               len = strftime(tvbuf.buf,
+                                              sizeof(tvbuf.buf),
+                                              "%b %e %T",
+                                              tm);
+                               if (len == 0) {
+                                       /* Trigger default time format below */
+                                       tm = NULL;
+                               }
+                       }
+                       if (tm == NULL) {
+                               snprintf(tvbuf.buf,
+                                        sizeof(tvbuf.buf),
+                                        "%ld seconds since the Epoch", (long)t);
+                       }
+               }
+
+               ensure_hostname();
+               state.hs_len = snprintf(state.header_str,
+                                       sizeof(state.header_str),
+                                       "%s %s %s[%u]: ",
+                                       tvbuf.buf,
+                                       state.hostname,
+                                       state.prog_name,
+                                       (unsigned int) getpid());
+
+               goto full;
+       }
+
        timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
                        &tvbuf);
 
index 9ab699a41485b7a868242564fc5d6c3689b4bc05..7317c2f43c506149471882d29f96a0b28f7415fb 100644 (file)
@@ -300,6 +300,7 @@ struct debug_settings {
        bool timestamp_logs;
        bool debug_prefix_timestamp;
        bool debug_hires_timestamp;
+       bool debug_syslog_format;
        bool debug_pid;
        bool debug_uid;
        bool debug_class;
@@ -315,6 +316,7 @@ void debug_set_logfile(const char *name);
 void debug_set_settings(struct debug_settings *settings,
                        const char *logging_param,
                        int syslog_level, bool syslog_only);
+void debug_set_hostname(const char *name);
 bool reopen_logs_internal( void );
 void force_check_log_size( void );
 bool need_to_check_log_size( void );