[exim-cvs] Utility: exim_msgdate

Etusivu
Poista viesti
Vastaa
Lähettäjä: Exim Git Commits Mailing List
Päiväys:  
Vastaanottaja: exim-cvs
Aihe: [exim-cvs] Utility: exim_msgdate
Gitweb: https://git.exim.org/exim.git/commitdiff/7b5fe03f9c6c2a322dc385ab78b60ccfe1fe33fe
Commit:     7b5fe03f9c6c2a322dc385ab78b60ccfe1fe33fe
Parent:     73d6e13f9b0cc4f708210372c59893950b3f7097
Author:     Andrew Aitchison <exim@???>
AuthorDate: Sun Feb 12 11:28:49 2023 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Thu Feb 16 18:49:36 2023 +0000


    Utility: exim_msgdate
---
 doc/doc-docbook/spec.xfpt    |  16 +-
 src/ACKNOWLEDGMENTS          |   1 +
 src/OS/Makefile-Base         |  20 +-
 src/scripts/exim_install     |   2 +-
 src/src/exim_msgdate.src     | 579 +++++++++++++++++++++++++++++++++++++++++++
 test/README                  |   8 +
 test/confs/0700              |  11 +
 test/confs/0701              |  12 +
 test/confs/0702              |  12 +
 test/confs/0703              |  12 +
 test/runtest                 |  14 +-
 test/scripts/0000-Basic/0700 | 165 ++++++++++++
 test/scripts/0000-Basic/0701 |  69 ++++++
 test/scripts/0000-Basic/0702 |  71 ++++++
 test/scripts/0000-Basic/0703 |  79 ++++++
 test/stderr/0700             |  67 +++++
 test/stderr/0701             |  20 ++
 test/stderr/0702             |  22 ++
 test/stderr/0703             |  30 +++
 test/stdout/0700             | 229 +++++++++++++++++
 test/stdout/0701             | 155 ++++++++++++
 test/stdout/0702             | 134 ++++++++++
 test/stdout/0703             |  74 ++++++
 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