-/* $Cambridge: exim/src/exim_monitor/em_log.c,v 1.4 2007/01/08 10:50:17 ph10 Exp $ */
-
/*************************************************
* Exim Monitor *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
+/* Copyright (c) The Exim Maintainters 2021 - 2022 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* This module contains code for scanning the smaill log,
+/* This module contains code for scanning the main log,
extracting information from it, and displaying a "tail". */
#include "em_hdr.h"
static int size = 0;
static int top = 0;
+static void show_log(char *s, ...) PRINTF_FUNCTION(1,2);
+
static void show_log(char *s, ...)
{
int length, newtop;
#ifdef ANONYMIZE
{
uschar *p = buffer + 9;
- if (p[6] == '-' && p[13] == '-') p += 17;
+ if ( p[MESSAGE_ID_TIME_LEN] == '-'
+ && p[MESSAGE_ID_TIME_LEN + MESSAGE_ID_PID_LEN + 1] == '-')
+ p += MESSAGE_ID_LENGTH + 1;
while (p < buffer + length)
{
if (LOG != NULL)
{
- fseek(LOG, log_position, SEEK_SET);
+ if (fseek(LOG, log_position, SEEK_SET))
+ {
+ perror("logfile fseek");
+ exit(1);
+ }
while (Ufgets(buffer, log_buffer_len, LOG) != NULL)
{
uschar *id;
uschar *p = buffer;
- void *reset_point;
+ rmark reset_point;
int length = Ustrlen(buffer);
- int i;
+ pcre2_match_data * md = pcre2_match_data_create(1, NULL);
/* Skip totally blank lines (paranoia: there shouldn't be any) */
it for various regular expression matches and take appropriate
action. Get the current store point so we can reset to it. */
- reset_point = store_get(0);
+ reset_point = store_mark();
/* First, update any stripchart data values, noting that the zeroth
stripchart is the queue length, which is handled elsewhere, and the
1st may the a size monitor. */
- for (i = stripchart_varstart; i < stripchart_number; i++)
- {
- if (pcre_exec(stripchart_regex[i], NULL, CS buffer, length, 0, PCRE_EOPT,
- NULL, 0) >= 0)
+ for (int i = stripchart_varstart; i < stripchart_number; i++)
+ if (pcre2_match(stripchart_regex[i], (PCRE2_SPTR)buffer, length,
+ 0, PCRE_EOPT, md, NULL) >= 0)
stripchart_total[i]++;
- }
/* Munge the log entry and display shortened form on one line.
- We omit the date and show only the time. Remove any time zone offset. */
+ We omit the date and show only the time. Remove any time zone offset.
+ Take note of the presence of [pid]. */
- if (pcre_exec(yyyymmdd_regex,NULL,CS buffer,length,0,PCRE_EOPT,NULL,0) >= 0)
+ if (pcre2_match(yyyymmdd_regex, (PCRE2_SPTR) buffer, length, 0, PCRE_EOPT,
+ md, NULL) >= 0)
{
- if ((buffer[20] == '+' || buffer[20] == '-') &&
- isdigit(buffer[21]) && buffer[25] == ' ')
+ int pidlength = 0;
+ if ( (buffer[20] == '+' || buffer[20] == '-')
+ && isdigit(buffer[21]) && buffer[25] == ' ')
memmove(buffer + 20, buffer + 26, Ustrlen(buffer + 26) + 1);
- id = string_copyn(buffer + 20, MESSAGE_ID_LENGTH);
+ if (buffer[20] == '[')
+ while (Ustrchr("[]0123456789", buffer[20+pidlength++]) != NULL)
+ ;
+ id = string_copyn(buffer + 20 + pidlength, MESSAGE_ID_LENGTH);
show_log("%s", buffer+11);
}
else
id = US"";
show_log("%s", buffer);
}
+ pcre2_match_data_free(md);
/* Deal with frozen and unfrozen messages */
if (strstric(buffer, US"frozen", FALSE) != NULL)
{
queue_item *qq = find_queue(id, queue_noop, 0);
- if (qq != NULL)
- {
- if (strstric(buffer, US"unfrozen", FALSE) != NULL)
- qq->frozen = FALSE;
- else qq->frozen = TRUE;
- }
+ if (qq)
+ qq->frozen = strstric(buffer, US"unfrozen", FALSE) == NULL;
}
/* Notice defer messages, and add the destination if it
if ((p = Ustrstr(buffer, "==")) != NULL)
{
queue_item *qq = find_queue(id, queue_noop, 0);
- if (qq != NULL)
+ if (qq)
{
dest_item *d;
uschar *q, *r;
if (log_datestamping)
{
uschar log_file_wanted[256];
- string_format(log_file_wanted, sizeof(log_file_wanted), CS log_file);
+ /* Do *not* use "%s" here, we need the %D datestamp in the log_file string to
+ be expanded. The trailing NULL arg is to quieten preprocessors that need at
+ least one arg for a variadic set in a macro. */
+ string_format(log_file_wanted, sizeof(log_file_wanted), CS log_file, NULL);
if (Ustrcmp(log_file_wanted, log_file_open) != 0)
{
if (LOG != NULL)
{
if (LOG != NULL) fclose(LOG);
LOG = TEST;
- fstat(fileno(LOG), &statdata);
+ if (fstat(fileno(LOG), &statdata))
+ {
+ fprintf(stderr, "fstat %s: %s\n", log_file_open, strerror(errno));
+ exit(1);
+ }
log_inode = statdata.st_ino;
}
}