X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/59a56cef04cee5be8e3b0f89f45d11c1b2114482..107077d7fd6736711bf5cd980221723401d37c51:/src/src/log.c diff --git a/src/src/log.c b/src/src/log.c index 0a41cd35a..af6e8b01b 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -2,9 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2023 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ -/* Copyright (c) The Exim Maintainers 2020 - 2021 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for writing log files. The code for maintaining datestamped log files was originally contributed by Tony Sheen. */ @@ -12,7 +13,6 @@ log files was originally contributed by Tony Sheen. */ #include "exim.h" -#define LOG_NAME_SIZE 256 #define MAX_SYSLOG_LEN 870 #define LOG_MODE_FILE 1 @@ -30,7 +30,6 @@ static uschar *log_names[] = { US"main", US"reject", US"panic", US"debug" }; static uschar mainlog_name[LOG_NAME_SIZE]; static uschar rejectlog_name[LOG_NAME_SIZE]; -static uschar debuglog_name[LOG_NAME_SIZE]; static uschar *mainlog_datestamp = NULL; static uschar *rejectlog_datestamp = NULL; @@ -268,7 +267,7 @@ Returns: a file descriptor, or < 0 on failure (errno set) */ static int -log_open_already_exim(uschar * const name) +log_open_already_exim(const uschar * const name) { int fd = -1; const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NONBLOCK; @@ -392,7 +391,7 @@ Returns: a file descriptor, or < 0 on failure (errno set) */ int -log_open_as_exim(uschar * const name) +log_open_as_exim(const uschar * const name) { int fd = -1; const uid_t euid = geteuid(); @@ -475,7 +474,7 @@ Returns: nothing */ static void -open_log(int *fd, int type, uschar *tag) +open_log(int * fd, int type, const uschar * tag) { uid_t euid; BOOL ok, ok2; @@ -531,8 +530,8 @@ switch (type) 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. */ + 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; @@ -685,11 +684,11 @@ Returns: length actually written, persisting an errno from write() */ ssize_t -write_to_fd_buf(int fd, const uschar *buf, size_t length) +write_to_fd_buf(int fd, const uschar * buf, size_t length) { ssize_t wrote; size_t total_written = 0; -const uschar *p = buf; +const uschar * p = buf; size_t left = length; while (1) @@ -712,6 +711,12 @@ while (1) return total_written; } +static inline ssize_t +write_gstring_to_fd_buf(int fd, const gstring * g) +{ +return write_to_fd_buf(fd, g->s, g->ptr); +} + static void @@ -807,7 +812,7 @@ log_write(unsigned int selector, int flags, const char *format, ...) { int paniclogfd; ssize_t written_len; -gstring gs = { .size = LOG_BUFFER_SIZE-1, .ptr = 0, .s = log_buffer }; +gstring gs = { .size = LOG_BUFFER_SIZE-2, .ptr = 0, .s = log_buffer }; gstring * g; va_list ap; @@ -953,11 +958,9 @@ DEBUG(D_any|D_v) } va_end(ap); - g->size = LOG_BUFFER_SIZE; - g = string_catn(g, US"\n", 1); - debug_printf("%s", string_from_gstring(g)); + debug_printf("%Y\n", g); - gs.size = LOG_BUFFER_SIZE-1; /* Having used the buffer for debug output, */ + gs.size = LOG_BUFFER_SIZE-2; /* Having used the buffer for debug output, */ gs.ptr = 0; /* reset it for the real use. */ gs.s = log_buffer; } @@ -992,7 +995,7 @@ if (LOGGING(pid)) if (!syslog_pid) pid_position[1] = g->ptr; /* … and end+1 of the PID */ } -if (f.really_exim && message_id[0] != 0) +if (f.really_exim && message_id[0]) g = string_fmt_append(g, "%s ", message_id); if (flags & LOG_CONFIG) @@ -1039,6 +1042,8 @@ if ( flags & LOG_RECIPIENTS } } +/* actual size, now we are placing the newline (and space for NUL) */ +gs.size = LOG_BUFFER_SIZE; g = string_catn(g, US"\n", 1); string_from_gstring(g); @@ -1113,7 +1118,7 @@ if ( flags & LOG_MAIN /* Failing to write to the log is disastrous */ - written_len = write_to_fd_buf(mainlogfd, g->s, g->ptr); + written_len = write_gstring_to_fd_buf(mainlogfd, g); if (written_len != g->ptr) { log_write_failed(US"main log", g->ptr, written_len); @@ -1172,8 +1177,8 @@ if (flags & LOG_REJECT) g = g2; else /* Buffer is full; truncate */ { - g->ptr -= 100; /* For message and separator */ - if (g->s[g->ptr-1] == '\n') g->ptr--; + gstring_trim(g, 100); /* For message and separator */ + gstring_trim_trailing(g, '\n'); g = string_cat(g, US"\n*** truncated ***\n"); break; } @@ -1228,7 +1233,7 @@ if (flags & LOG_REJECT) if (fstat(rejectlogfd, &statbuf) >= 0) rejectlog_inode = statbuf.st_ino; } - written_len = write_to_fd_buf(rejectlogfd, g->s, g->ptr); + written_len = write_gstring_to_fd_buf(rejectlogfd, g); if (written_len != g->ptr) { log_write_failed(US"reject log", g->ptr, written_len); @@ -1263,7 +1268,7 @@ if (flags & LOG_PANIC) if (panic_save_buffer) (void) write(paniclogfd, panic_save_buffer, Ustrlen(panic_save_buffer)); - written_len = write_to_fd_buf(paniclogfd, g->s, g->ptr); + written_len = write_gstring_to_fd_buf(paniclogfd, g); if (written_len != g->ptr) { int save_errno = errno; @@ -1280,7 +1285,10 @@ if (flags & LOG_PANIC) /* Give up if the DIE flag is set */ if ((flags & LOG_PANIC_DIE) != LOG_PANIC) - die(NULL, US"Unexpected failure, please try later"); + if (panic_coredump) + kill(getpid(), SIGSEGV); /* deliberate trap */ + else + die(NULL, US"Unexpected failure, please try later"); } } @@ -1365,8 +1373,9 @@ Returns: nothing on success - bomb out on failure */ void -decode_bits(unsigned int *selector, size_t selsize, int *notall, - uschar *string, bit_table *options, int count, uschar *which, int flags) +decode_bits(unsigned int * selector, size_t selsize, int * notall, + const uschar * string, bit_table * options, int count, uschar * which, + int flags) { uschar *errmsg; if (!string) return; @@ -1375,7 +1384,7 @@ if (*string == '=') { char *end; /* Not uschar */ memset(selector, 0, sizeof(*selector)*selsize); - *selector = strtoul(CS string+1, &end, 0); + *selector = strtoul(CCS string+1, &end, 0); if (!*end) return; errmsg = string_sprintf("malformed numeric %s_selector setting: %s", which, string); @@ -1387,9 +1396,9 @@ if (*string == '=') else for(;;) { BOOL adding; - uschar *s; + const uschar * s; int len; - bit_table *start, *end; + bit_table * start, * end; Uskip_whitespace(&string); if (!*string) return; @@ -1485,7 +1494,7 @@ 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) +debug_logging_activate(const uschar * tag_name, const uschar * opts) { if (debug_file) { @@ -1521,9 +1530,27 @@ else } +void +debug_logging_from_spool(const uschar * filename) +{ +if (debug_fd < 0) + { + Ustrncpy(debuglog_name, filename, sizeof(debuglog_name)); + if ((debug_fd = log_open_as_exim(filename)) >= 0) + debug_file = fdopen(debug_fd, "w"); + DEBUG(D_deliver) debug_printf("debug enabled by spoolfile\n"); + } +/* +else DEBUG(D_deliver) + debug_printf("debug already active; ignoring spoolfile '%s'\n", filename); +*/ +} + + void debug_logging_stop(BOOL kill) { +debug_printf("debug terminated by %s\n", kill ? "kill" : "stop"); debug_pretrigger_discard(); if (!debug_file || !debuglog_name[0]) return;