X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b6b4b129892a99747a586e5d4acb68fe7176ab4b..8f2cf8f5adaa08ef84b47bf9bc2f71e39236c22d:/src/src/log.c diff --git a/src/src/log.c b/src/src/log.c index dff7d3211..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 @@ -497,11 +497,15 @@ switch (type) Ustrcpy(mainlog_name, buffer); if (string_datestamp_offset > 0) mainlog_datestamp = mainlog_name + string_datestamp_offset; + break; + 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; + case lt_debug: /* and deal with the debug log (which keeps the datestamp, but does not update it) */ @@ -514,6 +518,8 @@ switch (type) if (ok2) Ustrcpy(debuglog_name, buffer); } + break; + 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 @@ -534,6 +540,7 @@ switch (type) 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 */ @@ -544,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(); @@ -701,36 +704,18 @@ return total_written; } -void -set_file_path(BOOL *multiple) + +static void +set_file_path(void) { -uschar *s; int sep = ':'; /* Fixed separator - outside use */ -const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH; - -logging_mode = 0; -while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) +uschar *t; +const uschar *tt = US LOG_FILE_PATH; +while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE))) { - if (Ustrcmp(s, "syslog") == 0) - logging_mode |= LOG_MODE_SYSLOG; - else if (logging_mode & LOG_MODE_FILE) /* we know a file already */ - { - if (multiple) *multiple = TRUE; - } - else - { - logging_mode |= LOG_MODE_FILE; - - /* If a non-empty path is given, use it */ - - if (*s) - file_path = string_copy(s); - - /* If the path is empty, we want to use the first non-empty, non- - syslog item in LOG_FILE_PATH, if there is one, since the value of - log_file_path may have been set at runtime. If there is no such item, - use the ultimate default in the spool directory. */ - } + if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue; + file_path = string_copy(t); + break; } } @@ -738,11 +723,7 @@ while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) void mainlog_close(void) { -/* avoid closing it if it is closed already or if we do not see a chance -to open the file mainlog later again */ -if (mainlogfd < 0 /* already closed */ - || !(geteuid() == 0 || geteuid() == exim_uid)) - return; +if (mainlogfd < 0) return; (void)close(mainlogfd); mainlogfd = -1; mainlog_inode = 0; @@ -857,7 +838,38 @@ if (!path_inspected) /* If nothing has been set, don't waste effort... the default values for the statics are file_path="" and logging_mode = LOG_MODE_FILE. */ - if (*log_file_path) set_file_path(&multiple); + if (*log_file_path) + { + int sep = ':'; /* Fixed separator - outside use */ + uschar *s; + const uschar *ss = log_file_path; + + logging_mode = 0; + while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) + { + if (Ustrcmp(s, "syslog") == 0) + logging_mode |= LOG_MODE_SYSLOG; + else if (logging_mode & LOG_MODE_FILE) + multiple = TRUE; + else + { + logging_mode |= LOG_MODE_FILE; + + /* If a non-empty path is given, use it */ + + if (*s) + file_path = string_copy(s); + + /* If the path is empty, we want to use the first non-empty, non- + syslog item in LOG_FILE_PATH, if there is one, since the value of + log_file_path may have been set at runtime. If there is no such item, + use the ultimate default in the spool directory. */ + + else + set_file_path(); /* Empty item in log_file_path */ + } /* First non-syslog item in log_file_path */ + } /* Scan of log_file_path */ + } /* If no modes have been selected, it is a major disaster */ @@ -881,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. */ @@ -1445,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" @@ -1459,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); @@ -1475,34 +1494,29 @@ if (opts) resulting in certain setup not having been done. Hack this for now so we do not segfault; note that nondefault log locations will not work */ -if (!*file_path) set_file_path(NULL); +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); } -void -open_logs(void) -{ -set_file_path(NULL); -open_log(&mainlogfd, lt_main, 0); -open_log(&rejectlogfd, lt_reject, 0); -} /* End of log.c */