X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/45bf0bfc3321e55518caab66385171883e717896..8f2cf8f5adaa08ef84b47bf9bc2f71e39236c22d:/src/src/log.c diff --git a/src/src/log.c b/src/src/log.c index e22fc4fdf..7a73b154a 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -3,7 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 */ +/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for writing log files. The code for maintaining datestamped @@ -487,62 +487,60 @@ people want, I hope. */ ok = string_format(buffer, sizeof(buffer), CS file_path, log_names[type]); -/* Save the name of the mainlog for rollover processing. Without a datestamp, -it gets statted to see if it has been cycled. With a datestamp, the datestamp -will be compared. The static slot for saving it is the same size as buffer, -and the text has been checked above to fit, so this use of strcpy() is OK. */ - -if (type == lt_main) - { - Ustrcpy(mainlog_name, buffer); - if (string_datestamp_offset > 0) - mainlog_datestamp = mainlog_name + string_datestamp_offset; - } - -/* Ditto for the reject log */ - -else if (type == lt_reject) +switch (type) { - Ustrcpy(rejectlog_name, buffer); - if (string_datestamp_offset > 0) - rejectlog_datestamp = rejectlog_name + string_datestamp_offset; - } - -/* and deal with the debug log (which keeps the datestamp, but does not -update it) */ + case lt_main: + /* Save the name of the mainlog for rollover processing. Without a datestamp, + it gets statted to see if it has been cycled. With a datestamp, the datestamp + will be compared. The static slot for saving it is the same size as buffer, + and the text has been checked above to fit, so this use of strcpy() is OK. */ + Ustrcpy(mainlog_name, buffer); + if (string_datestamp_offset > 0) + mainlog_datestamp = mainlog_name + string_datestamp_offset; + break; -else if (type == lt_debug) - { - Ustrcpy(debuglog_name, buffer); - if (tag) - { - /* this won't change the offset of the datestamp */ - ok2 = string_format(buffer, sizeof(buffer), "%s%s", - debuglog_name, tag); - if (ok2) - Ustrcpy(debuglog_name, buffer); - } - } + case lt_reject: + /* Ditto for the reject log */ + Ustrcpy(rejectlog_name, buffer); + if (string_datestamp_offset > 0) + rejectlog_datestamp = rejectlog_name + string_datestamp_offset; + break; -/* Remove any datestamp if this is the panic log. This is rare, so there's no -need to optimize getting the datestamp length. We remove one non-alphanumeric -char afterwards if at the start, otherwise one before. */ + case lt_debug: + /* and deal with the debug log (which keeps the datestamp, but does not + update it) */ + Ustrcpy(debuglog_name, buffer); + if (tag) + { + /* this won't change the offset of the datestamp */ + ok2 = string_format(buffer, sizeof(buffer), "%s%s", + debuglog_name, tag); + if (ok2) + Ustrcpy(debuglog_name, buffer); + } + break; -else if (string_datestamp_offset >= 0) - { - uschar * from = buffer + string_datestamp_offset; - uschar * to = from + string_datestamp_length; + default: + /* Remove any datestamp if this is the panic log. This is rare, so there's no + need to optimize getting the datestamp length. We remove one non-alphanumeric + char afterwards if at the start, otherwise one before. */ + if (string_datestamp_offset >= 0) + { + uschar * from = buffer + string_datestamp_offset; + uschar * to = from + string_datestamp_length; - if (from == buffer || from[-1] == '/') - { - if (!isalnum(*to)) to++; - } - else - if (!isalnum(from[-1])) from--; + if (from == buffer || from[-1] == '/') + { + if (!isalnum(*to)) to++; + } + else + if (!isalnum(from[-1])) from--; - /* This copy is ok, because we know that to is a substring of from. But - due to overlap we must use memmove() not Ustrcpy(). */ - memmove(from, to, Ustrlen(to)+1); + /* This copy is ok, because we know that to is a substring of from. But + due to overlap we must use memmove() not Ustrcpy(). */ + memmove(from, to, Ustrlen(to)+1); + } + break; } /* If the file name is too long, it is an unrecoverable disaster */ @@ -553,12 +551,8 @@ if (!ok) /* We now have the file name. After a successful open, return. */ -*fd = log_open_as_exim(buffer); - -if (*fd >= 0) - { +if ((*fd = log_open_as_exim(buffer)) >= 0) return; - } euid = geteuid(); @@ -899,6 +893,11 @@ if (!path_inspected) "More than one path given in log_file_path: using %s", file_path); } +/* Optionally trigger debug */ + +if (flags & LOG_PANIC && dtrigger_selector & BIT(DTi_panictrigger)) + debug_trigger_fire(); + /* If debugging, show all log entries, but don't show headers. Do it all in one go so that it doesn't get split when multi-processing. */ @@ -1463,13 +1462,15 @@ misconfiguration. The first use of this is in ACL logic, "control = debug/tag=foo/opts=+expand" which can be combined with conditions, etc, to activate extra logging only -for certain sources. The second use is inetd wait mode debug preservation. */ +for certain sources. The second use is inetd wait mode debug preservation. + +It might be nice, in ACL-initiated pretrigger mode, to not create the file +immediately but only upon a trigger - but we'd need another cmdline option +to pass the name through child_exxec_exim(). */ void debug_logging_activate(uschar *tag_name, uschar *opts) { -int fd = -1; - if (debug_file) { debug_printf("DEBUGGING ACTIVATED FROM WITHIN CONFIG.\n" @@ -1477,7 +1478,7 @@ if (debug_file) return; } -if (tag_name != NULL && (Ustrchr(tag_name, '/') != NULL)) +if (tag_name && (Ustrchr(tag_name, '/') != NULL)) { log_write(0, LOG_MAIN|LOG_PANIC, "debug tag may not contain a '/' in: %s", tag_name); @@ -1495,24 +1496,26 @@ do not segfault; note that nondefault log locations will not work */ if (!*file_path) set_file_path(); -open_log(&fd, lt_debug, tag_name); +open_log(&debug_fd, lt_debug, tag_name); -if (fd != -1) - debug_file = fdopen(fd, "w"); +if (debug_fd != -1) + debug_file = fdopen(debug_fd, "w"); else log_write(0, LOG_MAIN|LOG_PANIC, "unable to open debug log"); } void -debug_logging_stop(void) +debug_logging_stop(BOOL kill) { +debug_pretrigger_discard(); if (!debug_file || !debuglog_name[0]) return; debug_selector = 0; fclose(debug_file); debug_file = NULL; -unlink_log(lt_debug); +debug_fd = -1; +if (kill) unlink_log(lt_debug); }