summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Aitchison <exim@aitchison.me.uk>2023-02-12 11:28:49 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2023-02-16 18:49:36 +0000
commit7b5fe03f9c6c2a322dc385ab78b60ccfe1fe33fe (patch)
tree951512297353d91e48381a747c2383b35dc6edb0
parent73d6e13f9b0cc4f708210372c59893950b3f7097 (diff)
Utility: exim_msgdate
-rw-r--r--doc/doc-docbook/spec.xfpt16
-rw-r--r--src/ACKNOWLEDGMENTS1
-rw-r--r--src/OS/Makefile-Base20
-rwxr-xr-xsrc/scripts/exim_install2
-rwxr-xr-xsrc/src/exim_msgdate.src579
-rw-r--r--test/README8
-rw-r--r--test/confs/070011
-rw-r--r--test/confs/070112
-rw-r--r--test/confs/070212
-rw-r--r--test/confs/070312
-rwxr-xr-xtest/runtest14
-rw-r--r--test/scripts/0000-Basic/0700165
-rw-r--r--test/scripts/0000-Basic/070169
-rw-r--r--test/scripts/0000-Basic/070271
-rw-r--r--test/scripts/0000-Basic/070379
-rw-r--r--test/stderr/070067
-rw-r--r--test/stderr/070120
-rw-r--r--test/stderr/070222
-rw-r--r--test/stderr/070330
-rw-r--r--test/stdout/0700229
-rw-r--r--test/stdout/0701155
-rw-r--r--test/stdout/0702134
-rw-r--r--test/stdout/070374
23 files changed, 1798 insertions, 4 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6199b5d89..1708430ae 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -1,3 +1,4 @@
+
. /////////////////////////////////////////////////////////////////////////////
. This is the primary source of the Exim Manual. It is an xfpt document that is
. converted into DocBook XML for subsequent conversion into printable and online
@@ -948,6 +949,7 @@ User filters are run as part of the routing process, described below.
.cindex "base36"
.cindex "Darwin"
.cindex "Cygwin"
+.cindex "exim_msgdate"
Every message handled by Exim is given a &'message id'& which is sixteen
characters long. It is divided into three parts, separated by hyphens, for
example &`16VDhn-0001bo-D3`&. Each part is a sequence of letters and digits,
@@ -994,6 +996,10 @@ received by the same process, or by another process with the same (re-used)
pid, it is guaranteed that the time will be different. In most cases, the clock
will already have ticked while the message was being received.
+The exim_msgdate utility (see section &<<SECTexim_msgdate>>&) can be
+used to display the date, and optionally the process id, of an Exim
+Message ID.
+
.section "Receiving mail" "SECID13"
.cindex "receiving mail"
@@ -39475,6 +39481,7 @@ the next chapter. The utilities described here are:
.irow &<<SECTtidydb>>& &'exim_tidydb'& "clean up a hints database"
.irow &<<SECTfixdb>>& &'exim_fixdb'& "patch a hints database"
.irow &<<SECTmailboxmaint>>& &'exim_lock'& "lock a mailbox file"
+.irow &<<SECTexim_msgdate>>& &'exim_msgdate'& "Message Ids for humans (exim_msgdate)"
.endtable
Another utility that might be of use to sites with many MTAs is Tom Kistner's
@@ -40198,9 +40205,16 @@ exim_lock -q /var/spool/mail/spqr \
.endd
Note that if a command is supplied, it must be entirely contained within the
second argument &-- hence the quotes.
-.ecindex IIDutils
+.section "Message Ids for humans (exim_msgdate)" "SECTexim_msgdate"
+.cindex "exim_msgdate"
+The &'exim_msgdate'& utility is written by Andrew Aitchison and included in the Exim distribution.
+This Perl script converts an Exim Mesage ID back into a human readable form.
+For details of &'exim_msgdate'&'s options, run &'exim_msgdate'& with the &%--help%& option.
+
+Section &<<SECTmessiden>>& (Message identification) describes Exim Mesage IDs.
+.ecindex IIDutils
. ////////////////////////////////////////////////////////////////////////////
. ////////////////////////////////////////////////////////////////////////////
diff --git a/src/ACKNOWLEDGMENTS b/src/ACKNOWLEDGMENTS
index 22e9909c0..c318d3fea 100644
--- a/src/ACKNOWLEDGMENTS
+++ b/src/ACKNOWLEDGMENTS
@@ -357,6 +357,7 @@ David Woodhouse Dynamic modules. Security.
Contributors
------------
Andrew Aitchison Spotted cmdline AV scanner regression with -bmalware
+ exim_msgdate
Simon Arlott Code for outbound SSL-on-connect
Patch implementing %M datestamping in log filenames
Patch restoring SIGPIPE handler for child_open_uid
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index a290b90b0..29c037401 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -249,7 +249,8 @@ utils: $(EXIM_MONITOR) exicyclog exinext exiwhat \
exigrep eximstats exipick exiqgrep exiqsumm \
transport-filter.pl convert4r3 convert4r4 \
exim_checkaccess \
- exim_dbmbuild exim_dumpdb exim_fixdb exim_tidydb exim_lock
+ exim_dbmbuild exim_dumpdb exim_fixdb exim_tidydb exim_lock \
+ exim_msgdate
# Targets for special-purpose configuration header builders
@@ -383,6 +384,23 @@ exigrep: config ../src/exigrep.src
@chmod a+x exigrep
@echo ">>> exigrep script built"
+exim_msgdate: config ../src/exim_msgdate.src
+ @rm -f exim_msgdate
+ @. ./version.sh && sed \
+ -e "s?PROCESSED_FLAG?This file has been so processed.?"\
+ -e "/^[ \t]*# /p" \
+ -e "/^[ \t]*# /d" \
+ -e "s?BIN_DIRECTORY?$(BIN_DIRECTORY)?" \
+ -e "s?PERL_COMMAND?$(PERL_COMMAND)?" \
+ -e "s?BASE_62?$${BASE_62:-62}?" \
+ -e "s?CONFIGURE_FILE\"?$(CONFIGURE_FILE)\"?" \
+ -e "s?EXIM_RELEASE_VERSION?$${EXIM_RELEASE_VERSION}?" \
+ -e "s?EXIM_VARIANT_VERSION?$${EXIM_VARIANT_VERSION}?" \
+ ../src/exim_msgdate.src > exim_msgdate-t
+ @mv exim_msgdate-t exim_msgdate
+ @chmod a+x exim_msgdate
+ @echo ">>> exim_msgdate script built"
+
eximstats: config ../src/eximstats.src
@rm -f eximstats
@. ./version.sh && sed \
diff --git a/src/scripts/exim_install b/src/scripts/exim_install
index 827841ffc..e6857adaf 100755
--- a/src/scripts/exim_install
+++ b/src/scripts/exim_install
@@ -198,7 +198,7 @@ else
set exim${EXE} ${exim_monitor} exim_dumpdb${EXE} exim_fixdb${EXE} \
exim_tidydb${EXE} exinext exiwhat exim_dbmbuild${EXE} exicyclog \
exigrep eximstats exipick exiqgrep exiqsumm exim_lock${EXE} \
- exim_checkaccess
+ exim_checkaccess exim_msgdate
fi
echo $com ""
diff --git a/src/src/exim_msgdate.src b/src/src/exim_msgdate.src
new file mode 100755
index 000000000..e5c357bca
--- /dev/null
+++ b/src/src/exim_msgdate.src
@@ -0,0 +1,579 @@
+#!PERL_COMMAND -WT
+#
+# Utility to convert an exim message-id to a human readable form
+#
+# https://bugs.exim.org/show_bug.cgi?id=2956
+# Written by Andrew C Aitchison
+#
+# Copyright (c) 2023 The Exim Maintainers 2023
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Portions taken from exicyclog.src, which is
+# Copyright (c) University of Cambridge, 1995 - 2015
+# See the file NOTICE for conditions of use and distribution.
+
+# https://bugs.exim.org/show_bug.cgi?id=2956
+# https://exim.org/exim-html-current/doc/html/spec_html/ch-how_exim_receives_and_delivers_mail.html#SECTmessiden
+
+# Except when they appear in comments, the following placeholders in this
+# source are replaced when it is turned into a runnable script:
+#
+# BASE_62
+# BIN_DIRECTORY
+# CONFIGURE_FILE
+# PERL_COMMAND
+# EXIM_RELEASE_VERSION
+# EXIM_VARIANT_VERSION
+#
+# PROCESSED_FLAG
+
+use strict;
+use File::Basename;
+use Getopt::Long;
+use Pod::Usage;
+
+use constant { TRUE => 1, FALSE => 0 };
+
+if (defined $ENV{TZ}) {
+ my $zonefile = "/usr/share/zoneinfo/$ENV{TZ}";
+ if (defined $ENV{TZDIR}) {
+ if (-d $ENV{TZDIR}) {
+ $zonefile="$ENV{TZDIR}/$ENV{TZ}";
+ } else {
+ warn "No directory TZDIR=$ENV{TZDIR}\n"
+ }
+ }
+ warn "Cannot read timezone file $zonefile (from TZDIR/TZ)\n\t'man tzset' may help.\n"
+ unless -r $zonefile;
+}
+
+my $localhost_number; # An Exim config value
+
+my $p_name = basename $0;
+my $p_version = "20230203.0";
+my $p_cp = <<EOM;
+ Copyright (c) 2023 The Exim Maintainers 2023
+
+ Portions taken from exicyclog.src, which is
+ Copyright (c) University of Cambridge, 1995 - 2015
+ See the file NOTICE for conditions of use and distribution.
+EOM
+
+$ENV{PATH} = "/bin:/usr/bin:/usr/sbin";
+
+use POSIX qw(strftime);
+
+sub main::VERSION_MESSAGE()
+{
+ print basename($0), ": $0\n";
+ print "build: EXIM_RELEASE_VERSIONEXIM_VARIANT_VERSION\n";
+ print "perl( runtime): $]\n";
+}
+
+my ($debug, $nodebug,
+ $optbase, $optbase36, $optbase62,
+ $optunix, $optgmt, $optlocal,
+ $optpid,
+ $opteximpath,$optconfigfile);
+
+# Cannot use $debug here, since we haven't read ARGV yet.
+if (FALSE) {
+ warn join(" ", $0, @ARGV), "\n";
+}
+
+# Case is ignored, abbreviations are allowed.
+GetOptions (
+ # Allow windows style arguments /...
+ # "--|-|\+|\/" => \$prefix_pattern,
+ # "--|\/" => \$long_prefix_pattern,
+
+ "b=i" => \$optbase,
+ "base=i" => \$optbase,
+ "b36" => \$optbase36,
+ "base36" => \$optbase36,
+ "b62" => \$optbase62,
+ "base62" => \$optbase62,
+
+ "localhost_number=s" => \$localhost_number, # cf "local"
+
+ "unix" => \$optunix,
+ "u" => \$optunix,
+ "GMT" => \$optgmt,
+ "UTC" => \$optgmt,
+ "zulu" => \$optgmt,
+ "local" => \$optlocal, # cf "localhost_number"
+ "l" => \$optlocal, # cf "localhost_number"
+
+ "pid" => \$optpid,
+
+ # exim args given by the test harness
+ "C=s" => \$optconfigfile,
+ "dexim_path=s" => \$opteximpath,
+
+ "debug" => \$debug,
+ "nodebug" => \$nodebug,
+ "no-debug" => \$nodebug,
+
+ 'help' => sub { pod2usage(-exit => 0) },
+ 'man' => sub {
+ pod2usage(
+ -exit => 0,
+ -verbose => 2,
+ -noperldoc => system('perldoc -V 2>/dev/null 1>&2')
+ );
+ },
+) or pod2usage;
+# die("Error in command line arguments\n");
+
+$debug = undef if $nodebug;
+
+
+if ($debug) {
+ warn "$0 ", join(" ", @ARGV), "\n";
+ warn "C=$optconfigfile\n" if defined $optconfigfile;
+ warn "dexim_path=$opteximpath\n" if defined $opteximpath;
+}
+
+unless ($optgmt || $optunix || $optlocal) {
+ $optlocal = TRUE;
+}
+
+if (defined($optbase36) && defined($optbase62)) {
+ die "cannot be base36 and base62\n";
+}
+
+if (defined $optbase36) {
+ $optbase = 36;
+}
+if (defined $optbase62) {
+ $optbase = 62;
+}
+if (defined $optbase) {
+ if ($optbase =~ 62) {
+ $optbase = 62;
+ } elsif ($optbase =~ 36) {
+ $optbase = 36;
+ } else {
+ warn "\toptbase36=$optbase36\n" if defined $optbase36;
+ warn "\toptbase62=$optbase62\n"if defined $optbase62;
+ die "unknown base option $optbase\n";
+ }
+}
+
+# Some Operating Systems have case-insensitive file systems
+# (at least by default).
+# This limits the characters available for the message-id
+# and hence the base Exim uses to encode numbers.
+#
+# We use Perl's idea of the operating system.
+# Should we instead use the script "scripts/os-type" which comes with Exim ?
+my $defaultbase;
+if ($^O =~ /darwin|cygwin/i) { # darwin aka MacOS X
+ $defaultbase = 36;
+} else {
+ $defaultbase = 62;
+}
+
+if ("BASE_62" != $defaultbase and !defined $optbase) {
+ die "base_62 mismatch: OS implies $defaultbase but config has BASE_62\n";
+}
+
+my $base=$defaultbase;
+$base = $optbase if $optbase;
+
+my $base62_chars =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+my $base36_chars="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+my $base_chars;
+if ($base == 62) {
+ $base_chars = $base62_chars;
+} else {
+ $base_chars = $base36_chars;
+}
+
+# We use this to decode both base62 and base36
+sub decode62($) {
+ #warn "decode62(", join(",", @_), ")\n";
+ my ($text) = @_;
+ unless ($text =~ /^[$base_chars]+$/) {
+ die "$text is not base $base\n";
+ }
+ my $n=0;
+ foreach my $tt (split //, $text) {
+ $n = $n * $base + index($base_chars, $tt);
+ }
+ #warn "$text -> $n\n";
+ return $n;
+} # decode62
+
+sub get_configfilename()
+{
+ if (defined $optconfigfile) {
+ if ( -r $optconfigfile ) {
+ warn "using config $optconfigfile\n" if $debug;
+ return $optconfigfile;
+ } else {
+ die "cannot read $optconfigfile\n";
+ }
+ }
+
+ # See if this installation is using the esoteric "USE_EUID" feature of
+ # Exim, in which it uses the effective user id as a suffix for the
+ # configuration file name. In order for this to work, exim_msgdate
+ # must be run under the appropriate euid.
+ my $euid = "";
+ if ("CONFIGURE_FILE_USE_EUID" eq "yes" ) {
+ $euid=`id -u`;
+ }
+
+ # See if this installation is using the esoteric "USE_NODE"
+ # feature of Exim, in which it uses the host's name as a suffix
+ # for the configuration file name.
+ my $hostsuffix="";
+ if ("CONFIGURE_FILE_USE_NODE" eq "yes") {
+ $hostsuffix=`uname -n`;
+ }
+
+ # Now find the configuration file name.
+ # This has got complicated because the CONFIGURE_FILE value may now
+ # be a list of files. The one that is used is the first one that
+ # exists. Mimic the code in readconf.c by testing first for the
+ # suffixed file in each case.
+
+ my $config="";
+ my $baseconfig;
+ foreach $baseconfig (split /:/, "CONFIGURE_FILE") {
+ chomp $baseconfig;
+ if (-f "$baseconfig$euid$hostsuffix" ) {
+ $config="$baseconfig$euid$hostsuffix";
+ } elsif (-f "$baseconfig$euid" ) {
+ $config="$baseconfig$euid";
+ } elsif (-f "$baseconfig$hostsuffix" ) {
+ $config="$baseconfig$hostsuffix";
+ } elsif (-f "$baseconfig" ) {
+ $config="$baseconfig";
+ }
+ last if $config;
+ }
+ unless ($config) {
+ die "No config file found\n";
+ }
+
+ return $config;
+} # sub get_configfilename
+
+
+if ($debug) {
+ warn "before reading configfiles:\n";
+ if (defined $localhost_number) {
+ warn "localhost_number=$localhost_number\n";
+ } else {
+ warn "localhost_number unset\n";
+ }
+}
+
+if (defined $localhost_number) {
+ if ($localhost_number eq "none") {
+ $localhost_number = undef;
+ }
+} else {
+ my $config = get_configfilename();
+ warn "Reading config $config to find localhost_number\n" if $debug;
+
+ if (-r $config) {
+ # This does not do any expansions or lookups,
+ # so could be end up with a different value for localhost_number
+ # from the one that exim finds.
+ open(CONFIG, "<", $config) or
+ die "cannot open config $config :$!\n";
+
+ while(<CONFIG>) {
+ if (/^\s*localhost_number\s*=\s*(\d+)\s*$/) {
+ $localhost_number = $1;
+ }
+ }
+ close CONFIG or die "cannot close config $config: $!\n";
+ warn "$config gives localhost_number $localhost_number\n"
+ if $debug and defined $localhost_number;
+ } else {
+ # This way we get the expanded value for localhost_number
+ # directly from exim, but we have to guess which exim binary ...
+ # On Debian and Ubuntu, /usr/sbin/exim is a link to exim4 so is OK.
+ #
+ # Even if given on command line, we cannot use $opteximpath
+ # since it is the full path to this script,
+ # or $config since it is tainted.
+ #
+ warn "running system exim -bP localhost_number\n" if $debug;
+ my $exim_bP_localhost_number = `/usr/sbin/exim -bP localhost_number`;
+ if ($exim_bP_localhost_number =~ /^localhost_number\s*=\s*(\d*)/) {
+ $localhost_number = $1;
+ }
+ warn "exim_bP_localhost_number $exim_bP_localhost_number gives localhost_number $localhost_number\n"
+ if $debug and defined $localhost_number;
+ }
+}
+
+if (defined $localhost_number) {
+ die "localhost_number > 16\n"
+ if $localhost_number > 16;
+ die "localhost_number > 10\n"
+ if $localhost_number > 10 && ($base != 62);
+}
+
+if ($debug) {
+ if (defined $localhost_number) {
+ warn "localhost_number=$localhost_number\n";
+ } else {
+ warn "localhost_number unset\n";
+ }
+}
+
+sub unpack_time($$) {
+ my ($seconds, $fractions) = @_;
+ # warn "encoded: seconds: $seconds fractions: $fractions\n";
+ $seconds = decode62($seconds);
+ $fractions = decode62($fractions) if $fractions;
+ my $id_resolution;
+ if (defined $localhost_number && $localhost_number ne "none") {
+ print "localhost_number $localhost_number\n" if $debug;
+ if ($base != 62) {
+ # MacOS/Darwin and Cygwin
+ $id_resolution = 100;
+ } else {
+ # Standard UNIX etc.
+ $id_resolution = 200;
+ }
+ $fractions -= $localhost_number * $id_resolution;
+ } else {
+ if ($base != 62) {
+ # MacOS/Darwin and Cygwin
+ $id_resolution = 1000;
+ } else {
+ # Standard UNIX etc.
+ $id_resolution = 2000;
+ }
+ }
+ while ($fractions > $id_resolution) {
+ $seconds++;
+ $fractions -= $id_resolution;
+ }
+ while ($fractions < -1e-7) {
+ $seconds--;
+ $fractions += $id_resolution;
+ }
+ # $seconds += $fractions / $id_resolution;
+
+ # warn "decoded: seconds: $seconds, fractions: $fractions/$id_resolution\n";
+
+ return ($seconds, $fractions / $id_resolution);
+} # sub unpack_time($$)
+
+sub print_time($$$$$$)
+{
+ my ($seconds, $decimal, $unix, $zulu, $localtm, $pid) = @_;
+
+ if ($debug) {
+ my $ounix = defined($unix) ? $unix : "undef";
+ my $ozulu = defined($zulu) ? $zulu : "undef";
+ my $olocal = defined($localtm) ? $localtm : "undef";
+ my $opid = defined($pid) ? $pid : "undef";
+ warn "print_time($seconds, $decimal, $ounix, $ozulu, $olocal, $opid)\n"
+ }
+
+ my $pidstring = "";
+ $pidstring = "\tpid $pid" if defined $pid;
+
+ my $decimalstring = "";
+ # if ($decimal>0)
+ {
+ $decimalstring = sprintf(".%6.6d", 1000000*$decimal);
+ }
+ my $secondsstring;
+ unless (defined $unix or defined $zulu or defined $localtm) {
+ warn "No time type requested. Reporting UNIX time\n";
+ $unix = TRUE;
+ }
+ if (defined $unix) {
+ $secondsstring = $seconds;
+ print "$secondsstring$decimalstring$pidstring\n";
+ }
+ if (defined $zulu) {
+ $secondsstring = strftime("%F %T", gmtime($seconds));
+ print "$secondsstring$decimalstring$pidstring\n";
+ }
+ if (defined $localtm) {
+ $secondsstring = strftime("%F %T%%s %Z%%s\n", localtime($seconds));
+ # print "secondstring $secondsstring\n" if $debug;
+ printf($secondsstring, $decimalstring, $pidstring);
+ }
+
+} # sub print_time($$$$$$)
+
+foreach my $msgid (@ARGV) {
+ my ($seconds, $pid, $fractions, $decimal);
+
+ if ($msgid =~
+ /(^|[\s<])E?([a-zA-Z0-9]{6})-([a-zA-Z0-9]{6})-([a-zA-Z0-9]{2})/)
+ {
+ # Should take either the log form of timestamp,
+ # the Message-ID: header form with the leading 'E', ...
+ ($seconds, $pid, $fractions) = ($2, $3, $4);
+ ($seconds, $decimal) = unpack_time($seconds, $fractions);
+ $pid = decode62($pid);
+ #warn "$seconds, $pid, $fractions\n";
+ } elsif ($msgid =~ /(^|[^0-9A-Za-z])([a-zA-Z0-9]{6})$/) {
+ # ... or just the timecode section before the first '-'
+ ($seconds, $pid, $decimal) = (decode62($2), undef, 0);
+ } else {
+ warn "$msgid not parsed\n";
+ next;
+ }
+
+ if ($debug) {
+ print "msgid: $msgid\n";
+ my $ogmt = defined($optgmt) ? $optgmt : "undef";
+ my $ounix = defined($optunix) ? $optunix : "undef";
+ my $olocal = defined($optlocal) ? $optlocal : "undef";
+ my $opid = defined($optpid) ? $optpid : "undef";
+ print "print_time($seconds, $decimal, $ounix, $ogmt, $olocal, $opid)\n";
+ }
+ $pid = undef unless $optpid;
+ print_time($seconds, $decimal, $optunix, $optgmt, $optlocal, $pid);
+}
+
+=head1 NAME
+
+ exim_msgdate - Utility to convert an exim message-id to a human readable date+time
+
+=head1 SYNOPSIS
+
+B<exim_msgdate> [ -u|--unix | --GMT | --z|-Zulu | --UTC | -l|--local ]
+ [ --base 36 | --base 62 | --base36 | --base62 | --b36 | --b62 ]
+ [ --pid ] [ --debug ] [ --localhost_number ]
+ [ -c c<full path to exim cnfig file> ]
+ exim-message-id [ | exim-message-id ...]
+
+B<exim_msgdate> --help|--man
+
+=head1 DESCRIPTION
+
+B<exim_msgdate> is a tool which converts an exim message-id to a human
+readable form, usuall just the date+time, but with the I<--pid> option
+the process id as well.
+
+=head1 Message IDs:
+
+Three exim message ID formats are recognized.
+In each case the 'X's are taken from the base (see below) which depends upon the platform.
+
+=over 4
+
+=item XXXXXX-XXXXXX-XX
+
+found in the exim logfile,
+
+=item EXXXXXX-XXXXXX-XX
+
+found in the Message-Id header,
+
+=item XXXXXX
+
+just the first six characters of the message id.
+
+=back
+
+=head1 OPTIONS
+
+=head2 Time Zones and Unix Time
+
+=over 4
+
+=item B<-u | --unix>
+
+Display time as seconds since 1 Jan 1970, the Unix Epoch.
+
+=item B<--GMT> B<-u|--UTC> B<-z|--zulu>
+
+Display time in GMT/UTC - we assume these are the same.
+Zulu time is another name for GMT.
+
+=item B<-l | --local>
+
+Display time in the local time-zone.
+
+Do not confuse this with the L<--localhost_number|/--localhost_number-n> option.
+
+=back
+
+The default is the local timezone.
+
+=head2 User Assistance Options
+
+=over 4
+
+=item B<--help>
+
+A brief list of the options
+
+=item B<--man>
+
+A more detailed manual for B<exim_msgdate>
+
+=item B<--debug>
+
+Information about what went wrong, mostly for developers.
+
+=back
+
+=head2 Specialized Options
+
+=over 4
+
+=item B<--base> n | B<--base36> | B<--base62>
+
+The message-id is usually encoded in base-62 (0-9A-Za-z),
+but on systems with case-insensitive file systems, such as MacOS and Cygwin,
+base-36 (0-9A-Z) is used instead.
+The installation script should have set the default appropriately,
+but these options allow the default base to be overridden.
+
+The default matches C<exim>; in this installation it is base-BASE_62.
+
+=item B<--pid>
+
+Report the process id as well as the date and time in the message-id.
+
+=item B<--localhost_number> n
+
+If the Exim configuration option B<localhost_number> has been set,
+the third and final section of the message-id will include this and
+the timer resolution will change (see the Exim Spec. for details).
+C<Exim_msgdate> reads the Exim config file (see L<--C|/C-full-path-to-exim-configuration-file>) to find this value,
+but it can be overridden with this option.
+
+The value is an integer between 0 and 16, or the value "none" which
+means there is no localhost_number.
+
+Do not confuse this with the L<--local|/l---local> option, which displays times
+ in the local timezone.
+
+=item B<--C> B<full path to exim configuration file>
+
+This overrides the usual exim search path.
+We set C<localhost_number> from the exim configfile.
+
+=item B<-dexim_path>
+
+The test test harness passes the full path of the C<exim> binary,
+or here the C<exim_msgdate> being tested. Not currently used.
+
+=back
+
+=head1 SEE ALSO:
+
+L<exim(8)>
+
+L<Exim spec.txt chapter 4|https://exim.org/exim-html-current/doc/html/spec_html/ch-how_exim_receives_and_delivers_mail.html#SECTmessiden>
+
+=cut
diff --git a/test/README b/test/README
index ab9fb6496..f934c0d2d 100644
--- a/test/README
+++ b/test/README
@@ -820,6 +820,14 @@ are still in existence at the end of the run (for messages that were not
delivered) are not compared with saved versions.
+ no_munge
+
+If this command is encountered anywhere in the script, the output is not
+munged before it is compared with a saved version.
+This option allows meaningful tests of the exim_msgdate utility;
+without it all date comparison checks would succeed.
+
+
no_stderr_check
If this command is encountered anywhere in the script, the stderr output from
diff --git a/test/confs/0700 b/test/confs/0700
new file mode 100644
index 000000000..932326cae
--- /dev/null
+++ b/test/confs/0700
@@ -0,0 +1,11 @@
+# Exim test configuration 0700
+
+.include DIR/aux-var/std_conf_prefix
+
+
+# ----- Main settings -----
+
+domainlist local_domains = HOSTNAME
+
+
+# End
diff --git a/test/confs/0701 b/test/confs/0701
new file mode 100644
index 000000000..faecce87e
--- /dev/null
+++ b/test/confs/0701
@@ -0,0 +1,12 @@
+# Exim test configuration 0700
+
+.include DIR/aux-var/std_conf_prefix
+
+
+# ----- Main settings -----
+
+domainlist local_domains = HOSTNAME
+
+localhost_number = 3
+
+# End
diff --git a/test/confs/0702 b/test/confs/0702
new file mode 100644
index 000000000..ab3668b1c
--- /dev/null
+++ b/test/confs/0702
@@ -0,0 +1,12 @@
+# Exim test configuration 0700
+
+.include DIR/aux-var/std_conf_prefix
+
+
+# ----- Main settings -----
+
+domainlist local_domains = HOSTNAME
+
+localhost_number = 13
+
+# End
diff --git a/test/confs/0703 b/test/confs/0703
new file mode 100644
index 000000000..15fcc3cdd
--- /dev/null
+++ b/test/confs/0703
@@ -0,0 +1,12 @@
+# Exim test configuration 0700
+
+.include DIR/aux-var/std_conf_prefix
+
+
+# ----- Main settings -----
+
+domainlist local_domains = HOSTNAME
+
+localhost_number = 20
+
+# End
diff --git a/test/runtest b/test/runtest
index 5e4b160b9..32dfe73ab 100755
--- a/test/runtest
+++ b/test/runtest
@@ -385,6 +385,15 @@ $spid = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
LINE: while(<IN>)
{
RESET_AFTER_EXTRA_LINE_READ:
+ if ($munge_skip)
+ {
+ # Munging is a no-op.
+ # Useful when testing exim_msgdate so that
+ # we compare unmunged dates and message-ids.
+ print MUNGED;
+ next;
+ }
+
# Custom munges
if ($extra)
{
@@ -3894,7 +3903,7 @@ if (defined $parm_lookups{dbm} && not cp("$parm_exim_dir/exim_dbmbuild", "eximdi
$dbm_build_deleted = 1;
}
-foreach my $tool (qw(exim_dumpdb exim_lock exinext exigrep eximstats exiqgrep)) {
+foreach my $tool (qw(exim_dumpdb exim_lock exinext exigrep eximstats exiqgrep exim_msgdate)) {
cp("$parm_exim_dir/$tool" => "eximdir/$tool")
or tests_exit(-1, "Failed to make a copy of $tool: $!");
}
@@ -4357,6 +4366,7 @@ foreach $test (@test_list)
$next_port = 1111;
$message_skip = 0;
$msglog_skip = 0;
+ $munge_skip = 0;
$stderr_skip = 0;
$stdout_skip = 0;
$rmfiltertest = 0;
@@ -4376,6 +4386,7 @@ foreach $test (@test_list)
{
if (/^no_message_check/) { $message_skip = 1; next; }
if (/^no_msglog_check/) { $msglog_skip = 1; next; }
+ if (/^no_munge/) { $munge_skip = 1; next; }
if (/^no_stderr_check/) { $stderr_skip = 1; next; }
if (/^no_stdout_check/) { $stdout_skip = 1; next; }
if (/^rmfiltertest/) { $rmfiltertest = 1; next; }
@@ -4410,6 +4421,7 @@ foreach $test (@test_list)
# set above, but doesn't hurt to leave them here.
if (/^no_message_check/) { $message_skip = 1; next; }
if (/^no_msglog_check/) { $msglog_skip = 1; next; }
+ if (/^no_munge/) { $munge_skip = 1; next; }
if (/^no_stderr_check/) { $stderr_skip = 1; next; }
if (/^no_stdout_check/) { $stdout_skip = 1; next; }
if (/^rmfiltertest/) { $rmfiltertest = 1; next; }
diff --git a/test/scripts/0000-Basic/0700 b/test/scripts/0000-Basic/0700
new file mode 100644
index 000000000..6bb10a9b7
--- /dev/null
+++ b/test/scripts/0000-Basic/0700
@@ -0,0 +1,165 @@
+# Exercising exim_msgdate
+#
+#
+# Without this, runtest would munge all dates and message-ids,
+# destroying the things we wish to test:
+no_munge
+#
+### A Message ID as it appears in an email:
+exim_msgdate E1pAnS3-003fPj-Tw
+****
+### A Message ID as it appears in the exim log:
+exim_msgdate 1pEPHo-005xgk-2e
+****
+### Just the date part of the Message ID:
+### The Epoch ...
+exim_msgdate 000000
+****
+### ... the script was under development at this time ...
+exim_msgdate 1pEPHo
+****
+### ... the end of exim msg-id time
+exim_msgdate zzzzzz
+****
+### All three time zones with a non-GMT time
+exim_msgdate -l -u -z 1o6fde-003z7E-PS
+****
+### All three types of message-ids, at once:
+exim_msgdate E000000-005XGK-00 1pAnS3-003fPj-Tw zzzzzz
+****
+### Message IDs generated on a system, such as Mac or Cygwin,
+### which has low-resolution Message-ID timestamps
+exim_msgdate --base36 000000-005XGK-00
+****
+exim_msgdate --base36 ZZZZZZ-005XGK-ZZ
+****
+255
+exim_msgdate --base36 zzzzzz-005xgk-zz
+****
+### An invalid base option
+255
+exim_msgdate --base 32 ZZZZZZ
+****
+### Message IDs generated on a standard system
+### with high-resolution Message-ID timestamps
+exim_msgdate --base62 000000-005XGK-00
+****
+exim_msgdate --base62 ZZZZZZ-005XGK-ZZ
+****
+exim_msgdate --base62 zzzzzz-005xgk-zz
+****
+### Some strings that are similar to, but not Exim Message IDs:
+exim_msgdate zzzzzz-005xgk-z@
+****
+exim_msgdate zzzzz-z005xgk-zz
+****
+exim_msgdate zzzzzzz
+****
+### Print date with localtime
+exim_msgdate -local 000000
+****
+exim_msgdate -local E1pAnS3-003fPj-Tw
+****
+exim_msgdate -local zzzzzz-003fPj-zz
+****
+### Print date with timezone GMT/Zulu
+exim_msgdate -GMT 000000-003fPj-00
+****
+exim_msgdate -GMT E1pAnS3-003fPj-Tw
+****
+exim_msgdate -zulu E1pAnS3-003fPj-Tw
+****
+exim_msgdate -zulu EZZZZZZ-003fPj-ZZ
+****
+### Print date as seconds since the UNIX epoch.
+exim_msgdate -unix E000000-003fPj-00
+****
+exim_msgdate -unix E1pAnS3-003fPj-tw
+****
+exim_msgdate -unix Ezzzzzz-003fpj-zz
+****
+### Show the process id too
+exim_msgdate -unix --pid EZZZZZZ-003fPj-ZZ
+****
+exim_msgdate -pid EZZZZZZ-003fPj-ZZ
+****
+exim_msgdate -local --pid EZZZZZZ-003fPj-ZZ
+****
+### Override the value of localhost_number set in the exim configuation file
+exim_msgdate -local --localhost_number 11 -base 62 EZZZZZZ-003FPJ-ZZ
+****
+exim_msgdate --localhost_number 11 -base 62 EZZZZZZ-003FPJ-ZZ
+****
+exim_msgdate --localhost_number 9 -base 36 EZZZZZZ-003FPJ-ZZ
+****
+255
+exim_msgdate --localhost_number 11 -base 36 EZZZZZZ-003FPJ-ZZ
+****
+exim_msgdate -localhost_number 11 --local -base 62 EZZZZZZ-003FPJ-ZZ
+****
+exim_msgdate --localhost_number -1 -base 36 EZZZZZZ-003FPJ-ZZ
+****
+255
+exim_msgdate --localhost_number 19 -base 62 EZZZZZZ-003FPJ-ZZ
+****
+### From here as 701 - 703
+### Each msg-id type, all zone
+exim_msgdate -l -u -z -pid E000000-005XGK-00
+****
+exim_msgdate -l -u -z -pid 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 3
+exim_msgdate -l -u -z -localhost_number=3 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=3 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 13
+exim_msgdate -l -u -z -localhost_number=13 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=13 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 20
+255
+exim_msgdate -l -u -z -localhost_number=20 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=36
+exim_msgdate -l -u -z --b36 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z --b36 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z --b36 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=62
+exim_msgdate -l -u -z --b62 E000000-005XGK-00
+****
+exim_msgdate -l -u -z --b62 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 ZZZZZZ
+****
diff --git a/test/scripts/0000-Basic/0701 b/test/scripts/0000-Basic/0701
new file mode 100644
index 000000000..fd16de423
--- /dev/null
+++ b/test/scripts/0000-Basic/0701
@@ -0,0 +1,69 @@
+# Exercising exim_msgdate
+#
+# This file is intended for a config with
+# localhost_number = 3
+#
+# Without this, runtest would munge all dates and message-ids,
+# destroying the things we wish to test:
+no_munge
+#
+### Each msg-id type, all zone
+exim_msgdate -l -u -z -pid E000000-005XGK-00
+****
+exim_msgdate -l -u -z -pid 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 3
+exim_msgdate -l -u -z -localhost_number=3 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=3 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 13
+exim_msgdate -l -u -z -localhost_number=13 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=13 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 20
+255
+exim_msgdate -l -u -z -localhost_number=20 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=36
+exim_msgdate -l -u -z --b36 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z --b36 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z --b36 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=62
+exim_msgdate -l -u -z --b62 E000000-005XGK-00
+****
+exim_msgdate -l -u -z --b62 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 ZZZZZZ
+****
diff --git a/test/scripts/0000-Basic/0702 b/test/scripts/0000-Basic/0702
new file mode 100644
index 000000000..bc78f9d47
--- /dev/null
+++ b/test/scripts/0000-Basic/0702
@@ -0,0 +1,71 @@
+# Exercising exim_msgdate
+#
+# This file is intended for a config with
+# localhost_number = 13
+#
+# Without this, runtest would munge all dates and message-ids,
+# destroying the things we wish to test:
+no_munge
+#
+### Each msg-id type, all zone
+exim_msgdate -l -u -z -pid E000000-005XGK-00
+****
+exim_msgdate -l -u -z -pid 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -pid 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 3
+exim_msgdate -l -u -z -localhost_number=3 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=3 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 13
+exim_msgdate -l -u -z -localhost_number=13 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=13 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 20
+255
+exim_msgdate -l -u -z -localhost_number=20 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=36
+255
+exim_msgdate -l -u -z --b36 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z --b36 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=62
+exim_msgdate -l -u -z --b62 E000000-005XGK-00
+****
+exim_msgdate -l -u -z --b62 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z --b62 000000 1PANS3 ZZZZZZ
+****
diff --git a/test/scripts/0000-Basic/0703 b/test/scripts/0000-Basic/0703
new file mode 100644
index 000000000..b3ed864bc
--- /dev/null
+++ b/test/scripts/0000-Basic/0703
@@ -0,0 +1,79 @@
+# Exercising exim_msgdate
+#
+# This file is intended for a config with
+# localhost_number = 20
+#
+# Without this, runtest would munge all dates and message-ids,
+# destroying the things we wish to test:
+no_munge
+#
+### Each msg-id type, all zone
+255
+exim_msgdate -l -u -z -pid E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z -pid 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z -pid 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z -pid 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 3
+exim_msgdate -l -u -z -localhost_number=3 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=3 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=3 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 13
+exim_msgdate -l -u -z -localhost_number=13 E000000-005XGK-00
+****
+exim_msgdate -l -u -z -localhost_number=13 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 zzzzzz
+****
+exim_msgdate -l -u -z -localhost_number=13 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, localhost_number = 20
+255
+exim_msgdate -l -u -z -localhost_number=20 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z -localhost_number=20 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=36
+255
+exim_msgdate -l -u -z --b36 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z --b36 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z --b36 000000 1PANS3 ZZZZZZ
+****
+### All msg-id types, all zones, base=62
+255
+exim_msgdate -l -u -z --b62 E000000-005XGK-00
+****
+255
+exim_msgdate -l -u -z --b62 000000-005XGK-00 ZZZZZZ-005XGK-zz 1PANS3-003FPJ-TW
+****
+255
+exim_msgdate -l -u -z --b62 000000 1PANS3 zzzzzz
+****
+255
+exim_msgdate -l -u -z --b62 000000 1PANS3 ZZZZZZ
+****
diff --git a/test/stderr/0700 b/test/stderr/0700
new file mode 100644
index 000000000..4531d5e2c
--- /dev/null
+++ b/test/stderr/0700
@@ -0,0 +1,67 @@
+### A Message ID as it appears in an email:
+### A Message ID as it appears in the exim log:
+### Just the date part of the Message ID:
+### The Epoch ...
+### ... the script was under development at this time ...
+### ... the end of exim msg-id time
+### All three time zones with a non-GMT time
+### All three types of message-ids, at once:
+### Message IDs generated on a system, such as Mac or Cygwin,
+### which has low-resolution Message-ID timestamps
+zzzzzz is not base 36
+### An invalid base option
+unknown base option 32
+### Message IDs generated on a standard system
+### with high-resolution Message-ID timestamps
+### Some strings that are similar to, but not Exim Message IDs:
+zzzzzz-005xgk-z@ not parsed
+zzzzz-z005xgk-zz not parsed
+zzzzzzz not parsed
+### Print date with localtime
+### Print date with timezone GMT/Zulu
+### Print date as seconds since the UNIX epoch.
+### Show the process id too
+### Override the value of localhost_number set in the exim configuation file
+localhost_number > 10
+localhost_number > 16
+### From here as 701 - 703
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, base=36
+zz is not base 36
+zzzzzz is not base 36
+### All msg-id types, all zones, base=62
+
+******** SERVER ********
+### A Message ID as it appears in an email:
+### A Message ID as it appears in the exim log:
+### Just the date part of the Message ID:
+### The Epoch ...
+### ... the script was under development at this time ...
+### ... the end of exim msg-id time
+### All three time zones with a non-GMT time
+### All three types of message-ids, at once:
+### Message IDs generated on a system, such as Mac or Cygwin,
+### which has low-resolution Message-ID timestamps
+### An invalid base option
+### Message IDs generated on a standard system
+### with high-resolution Message-ID timestamps
+### Some strings that are similar to, but not Exim Message IDs:
+### Print date with localtime
+### Print date with timezone GMT/Zulu
+### Print date as seconds since the UNIX epoch.
+### Show the process id too
+### Override the value of localhost_number set in the exim configuation file
+### From here as 701 - 703
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stderr/0701 b/test/stderr/0701
new file mode 100644
index 000000000..2c54c7033
--- /dev/null
+++ b/test/stderr/0701
@@ -0,0 +1,20 @@
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, base=36
+zz is not base 36
+zzzzzz is not base 36
+### All msg-id types, all zones, base=62
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stderr/0702 b/test/stderr/0702
new file mode 100644
index 000000000..352412472
--- /dev/null
+++ b/test/stderr/0702
@@ -0,0 +1,22 @@
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, base=36
+localhost_number > 10
+localhost_number > 10
+localhost_number > 10
+localhost_number > 10
+### All msg-id types, all zones, base=62
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stderr/0703 b/test/stderr/0703
new file mode 100644
index 000000000..696b3521b
--- /dev/null
+++ b/test/stderr/0703
@@ -0,0 +1,30 @@
+### Each msg-id type, all zone
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, base=36
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+### All msg-id types, all zones, base=62
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+localhost_number > 16
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stdout/0700 b/test/stdout/0700
new file mode 100644
index 000000000..2e47baa35
--- /dev/null
+++ b/test/stdout/0700
@@ -0,0 +1,229 @@
+### A Message ID as it appears in an email:
+2022-12-29 07:35:43.928000 GMT
+### A Message ID as it appears in the exim log:
+2023-01-08 06:36:04.082000 GMT
+### Just the date part of the Message ID:
+### The Epoch ...
+1970-01-01 01:00:00.000000 BST
+### ... the script was under development at this time ...
+2023-01-08 06:36:04.000000 GMT
+### ... the end of exim msg-id time
+3769-12-05 03:13:03.000000 GMT
+### All three time zones with a non-GMT time
+1656539662.789000
+2022-06-29 21:54:22.789000
+2022-06-29 22:54:22.789000 BST
+### All three types of message-ids, at once:
+1970-01-01 01:00:00.000000 BST
+2022-12-29 07:35:43.928000 GMT
+3769-12-05 03:13:03.000000 GMT
+### Message IDs generated on a system, such as Mac or Cygwin,
+### which has low-resolution Message-ID timestamps
+1970-01-01 01:00:00.000000 BST
+2038-12-24 05:45:36.295000 GMT
+### An invalid base option
+### Message IDs generated on a standard system
+### with high-resolution Message-ID timestamps
+1970-01-01 01:00:00.000000 BST
+3002-09-30 13:51:46.102500 BST
+3769-12-05 03:13:04.921500 GMT
+### Some strings that are similar to, but not Exim Message IDs:
+### Print date with localtime
+1970-01-01 01:00:00.000000 BST
+2022-12-29 07:35:43.928000 GMT
+3769-12-05 03:13:04.921500 GMT
+### Print date with timezone GMT/Zulu
+1970-01-01 00:00:00.000000
+2022-12-29 07:35:43.928000
+2022-12-29 07:35:43.928000
+3002-09-30 12:51:46.102500
+### Print date as seconds since the UNIX epoch.
+0.000000
+1672299344.734000
+56800235584.921500
+### Show the process id too
+32590299106.102500 pid 874183
+3002-09-30 13:51:46.102500 BST pid 874183
+3002-09-30 13:51:46.102500 BST pid 874183
+### Override the value of localhost_number set in the exim configuation file
+3002-09-30 13:51:45.025000 BST
+3002-09-30 13:51:45.025000 BST
+2038-12-24 05:45:38.950000 GMT
+3002-09-30 13:51:45.025000 BST
+2038-12-24 05:45:48.950000 GMT
+### From here as 701 - 703
+### Each msg-id type, all zone
+0.000000 pid 1319504
+1970-01-01 00:00:00.000000 pid 1319504
+1970-01-01 01:00:00.000000 BST pid 1319504
+0.000000 pid 1319504
+1970-01-01 00:00:00.000000 pid 1319504
+1970-01-01 01:00:00.000000 BST pid 1319504
+32590299106.921500 pid 1319504
+3002-09-30 12:51:46.921500 pid 1319504
+3002-09-30 13:51:46.921500 BST pid 1319504
+1288014663.915000 pid 774213
+2010-10-25 13:51:03.915000 pid 774213
+2010-10-25 14:51:03.915000 BST pid 774213
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 3
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+32590299121.215000
+3002-09-30 12:52:01.215000
+3002-09-30 13:52:01.215000 BST
+1288014669.150000
+2010-10-25 13:51:09.150000
+2010-10-25 14:51:09.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 13
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+32590299111.215000
+3002-09-30 12:51:51.215000
+3002-09-30 13:51:51.215000 BST
+1288014659.150000
+2010-10-25 13:50:59.150000
+2010-10-25 14:50:59.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+102953955.000000
+1973-04-06 14:19:15.000000
+1973-04-06 15:19:15.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+102953955.000000
+1973-04-06 14:19:15.000000
+1973-04-06 15:19:15.000000 BST
+2176782335.000000
+2038-12-24 05:45:35.000000
+2038-12-24 05:45:35.000000 GMT
+### All msg-id types, all zones, base=62
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+32590299106.921500
+3002-09-30 12:51:46.921500
+3002-09-30 13:51:46.921500 BST
+1288014663.915000
+2010-10-25 13:51:03.915000
+2010-10-25 14:51:03.915000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+
+******** SERVER ********
+### A Message ID as it appears in an email:
+### A Message ID as it appears in the exim log:
+### Just the date part of the Message ID:
+### The Epoch ...
+### ... the script was under development at this time ...
+### ... the end of exim msg-id time
+### All three time zones with a non-GMT time
+### All three types of message-ids, at once:
+### Message IDs generated on a system, such as Mac or Cygwin,
+### which has low-resolution Message-ID timestamps
+### An invalid base option
+### Message IDs generated on a standard system
+### with high-resolution Message-ID timestamps
+### Some strings that are similar to, but not Exim Message IDs:
+### Print date with localtime
+### Print date with timezone GMT/Zulu
+### Print date as seconds since the UNIX epoch.
+### Show the process id too
+### Override the value of localhost_number set in the exim configuation file
+### From here as 701 - 703
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stdout/0701 b/test/stdout/0701
new file mode 100644
index 000000000..533cba4cc
--- /dev/null
+++ b/test/stdout/0701
@@ -0,0 +1,155 @@
+### Each msg-id type, all zone
+-3.000000 pid 1319504
+1969-12-31 23:59:57.000000 pid 1319504
+1970-01-01 00:59:57.000000 BST pid 1319504
+-3.000000 pid 1319504
+1969-12-31 23:59:57.000000 pid 1319504
+1970-01-01 00:59:57.000000 BST pid 1319504
+32590299121.215000 pid 1319504
+3002-09-30 12:52:01.215000 pid 1319504
+3002-09-30 13:52:01.215000 BST pid 1319504
+1288014669.150000 pid 774213
+2010-10-25 13:51:09.150000 pid 774213
+2010-10-25 14:51:09.150000 BST pid 774213
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 3
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+32590299121.215000
+3002-09-30 12:52:01.215000
+3002-09-30 13:52:01.215000 BST
+1288014669.150000
+2010-10-25 13:51:09.150000
+2010-10-25 14:51:09.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 13
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+32590299111.215000
+3002-09-30 12:51:51.215000
+3002-09-30 13:51:51.215000 BST
+1288014659.150000
+2010-10-25 13:50:59.150000
+2010-10-25 14:50:59.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+102953955.000000
+1973-04-06 14:19:15.000000
+1973-04-06 15:19:15.000000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+102953955.000000
+1973-04-06 14:19:15.000000
+1973-04-06 15:19:15.000000 BST
+2176782335.000000
+2038-12-24 05:45:35.000000
+2038-12-24 05:45:35.000000 GMT
+### All msg-id types, all zones, base=62
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+32590299121.215000
+3002-09-30 12:52:01.215000
+3002-09-30 13:52:01.215000 BST
+1288014669.150000
+2010-10-25 13:51:09.150000
+2010-10-25 14:51:09.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stdout/0702 b/test/stdout/0702
new file mode 100644
index 000000000..c918ad633
--- /dev/null
+++ b/test/stdout/0702
@@ -0,0 +1,134 @@
+### Each msg-id type, all zone
+-13.000000 pid 1319504
+1969-12-31 23:59:47.000000 pid 1319504
+1970-01-01 00:59:47.000000 BST pid 1319504
+-13.000000 pid 1319504
+1969-12-31 23:59:47.000000 pid 1319504
+1970-01-01 00:59:47.000000 BST pid 1319504
+32590299111.215000 pid 1319504
+3002-09-30 12:51:51.215000 pid 1319504
+3002-09-30 13:51:51.215000 BST pid 1319504
+1288014659.150000 pid 774213
+2010-10-25 13:50:59.150000 pid 774213
+2010-10-25 14:50:59.150000 BST pid 774213
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 3
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+32590299121.215000
+3002-09-30 12:52:01.215000
+3002-09-30 13:52:01.215000 BST
+1288014669.150000
+2010-10-25 13:51:09.150000
+2010-10-25 14:51:09.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 13
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+32590299111.215000
+3002-09-30 12:51:51.215000
+3002-09-30 13:51:51.215000 BST
+1288014659.150000
+2010-10-25 13:50:59.150000
+2010-10-25 14:50:59.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+32590299111.215000
+3002-09-30 12:51:51.215000
+3002-09-30 13:51:51.215000 BST
+1288014659.150000
+2010-10-25 13:50:59.150000
+2010-10-25 14:50:59.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
diff --git a/test/stdout/0703 b/test/stdout/0703
new file mode 100644
index 000000000..128415026
--- /dev/null
+++ b/test/stdout/0703
@@ -0,0 +1,74 @@
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+-3.000000
+1969-12-31 23:59:57.000000
+1970-01-01 00:59:57.000000 BST
+32590299121.215000
+3002-09-30 12:52:01.215000
+3002-09-30 13:52:01.215000 BST
+1288014669.150000
+2010-10-25 13:51:09.150000
+2010-10-25 14:51:09.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 13
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+-13.000000
+1969-12-31 23:59:47.000000
+1970-01-01 00:59:47.000000 BST
+32590299111.215000
+3002-09-30 12:51:51.215000
+3002-09-30 13:51:51.215000 BST
+1288014659.150000
+2010-10-25 13:50:59.150000
+2010-10-25 14:50:59.150000 BST
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+56800235583.000000
+3769-12-05 03:13:03.000000
+3769-12-05 03:13:03.000000 GMT
+0.000000
+1970-01-01 00:00:00.000000
+1970-01-01 01:00:00.000000 BST
+1288014663.000000
+2010-10-25 13:51:03.000000
+2010-10-25 14:51:03.000000 BST
+32590299105.000000
+3002-09-30 12:51:45.000000
+3002-09-30 13:51:45.000000 BST
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62
+
+******** SERVER ********
+### Each msg-id type, all zone
+### All msg-id types, all zones, localhost_number = 3
+### All msg-id types, all zones, localhost_number = 13
+### All msg-id types, all zones, localhost_number = 20
+### All msg-id types, all zones, base=36
+### All msg-id types, all zones, base=62