Retries: rework DB keys, and fix exinext IPv6. Bug 3086
[exim.git] / src / src / exinext.src
index c942120b0d8b740be2800959cc9daf98e78a1b4c..5724812c4c0870147e3ef0b04504f90baaf362b3 100644 (file)
@@ -1,7 +1,7 @@
 #! /bin/sh
-# $Cambridge: exim/src/src/exinext.src,v 1.1 2004/10/07 10:39:01 ph10 Exp $
 
-# Copyright (c) 1996-2004 University of Cambridge.
+# Copyright (c) The Exim Maintainers 2023
+# Copyright (c) University of Cambridge, 1995 - 2007
 # See the file NOTICE for conditions of use and distribution.
 
 # Except when they appear in comments, the following placeholders in this
@@ -26,16 +26,23 @@ config=
 eximmacdef=
 exim_path=
 
-if expr $1 : '\-' >/dev/null ; then
-  while expr $1 : '\-' >/dev/null ; do
+if [ "x$1" = x--version -o "x$1" = x-v ]
+then
+    echo "`basename $0`: $0"
+    echo "build: EXIM_RELEASE_VERSIONEXIM_VARIANT_VERSION"
+    exit 0
+fi
+
+if expr -- $1 : '\-' >/dev/null ; then
+  while expr -- $1 : '\-' >/dev/null ; do
     if [ "$1" = "-C" ]; then
       config=$2
       shift
       shift
-    elif expr $1 : '\-D' >/dev/null ; then
+    elif expr -- $1 : '\-D' >/dev/null ; then
       eximmacdef="$eximmacdef $1"
-      if expr $1 : '\-DEXIM_PATH=' >/dev/null ; then
-        exim_path=`expr $1 : '\-DEXIM_PATH=\(.*\)'`
+      if expr -- $1 : '\-DEXIM_PATH=' >/dev/null ; then
+        exim_path=`expr -- $1 : '\-DEXIM_PATH=\(.*\)'`
       fi
       shift
     else
@@ -65,9 +72,9 @@ if [ "$config" = "" ]; then
   # suffixed file in each case.
 
   set `awk -F: '{ for (i = 1; i <= NF; i++) print $i }' <<End
-  CONFIGURE_FILE
-  End
-  `
+CONFIGURE_FILE
+End
+`
   while [ "$config" = "" -a $# -gt 0 ] ; do
     if [ -f "$1$hostsuffix" ] ; then
       config="$1$hostsuffix"
@@ -107,13 +114,17 @@ qualify_domain=`$exim_path $eximmacdef -C $config -bP qualify_domain | sed 's/.*
 #              pick up routing delays after temporary recipient errors.
 #              Also add unqualified subject if it looks like a message id.
 # 01-Apr-2004  Add the -C feature for testing
+# 22-Dec-2005  Complete the -C feature (!)
 
 if [ "$argone" = "" ]; then
   echo "Usage: exinext <address>|<domain>|<local-part>"
   exit 1
 fi
 
-perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain <<'End'
+perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain $config <<'End'
+
+  # We don't import anything, but guard against future changes which do
+  BEGIN { pop @INC if $INC[-1] eq '.' };
 
   # Name the arguments
 
@@ -122,6 +133,7 @@ perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain <<'End'
   $subject = $ARGV[2];
   $spool = $ARGV[3];
   $qualify = $ARGV[4];
+  $config = $ARGV[5];
 
   # If the subject doesn't contain an @ then construct an address
   # for the domain, and ensure that in both cases the domain is
@@ -133,7 +145,7 @@ perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain <<'End'
   # Run Exim to get a list of hosts for the given domain; for
   # each one construct the appropriate retry key.
 
-  open(LIST, "$exim -v -bt $address |") ||
+  open(LIST, "$exim -C $config -v -bt $address |") ||
     die "can't run exim to route $address";
 
   while (<LIST>)
@@ -151,6 +163,7 @@ perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain <<'End'
 
   if (scalar(@list) == 0)
     {
+    push(@list, $subject) if $subject =~ /^\w{6}-\w{11}-\w{4}$/;
     push(@list, $subject) if $subject =~ /^\w{6}-\w{6}-\w{2}$/;
 
     if ($subject !~ /\@/ && $subject !~ /\./)
@@ -182,45 +195,18 @@ perl - $exim_path "$eximmacdef" $argone $spool_directory $qualify_domain <<'End'
         $printed = 1;
         if (/^\s*T:[^:\s]*:/)
           {
+         # We rely on non-space-containing strings, for parsing
+
           ($key,$error,$error2,$text) = /^\s*T:(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/;
 
-          # Parsing the keys is a nightmare because of IPv6. The design of the
-          # format for the keys is a complete shambles. All my fault (PH). But
-          # I don't want to change it just for this purpose. If they key
-          # contains more than 3 colons, we have an IPv6 address, because
-          # an IPv6 address must contain at least two colons.
-
-          # Deal with IPv4 addresses (3 colons or fewer)
-
-          if ($key !~ /:([^:]*?:){3}/)
-            {
-            ($host,$ip,$port,$msgid) = $key =~
-              /^([^:]*):([^:]*)(?::([^:]*)(?::(\S*)|)|)/;
-            }
-
-          # Deal with IPv6 addresses; sorting out the colons is a complete
-          # mess. We should be able to find the host name and IP address from
-          # further in the message. That seems the easiest escape plan here. We
-          # can use those to match the rest of the key.
-
-          else
-            {
-            ($host,$ip) = $text =~ /host\s(\S+)\s\[([^]]+)\]/;
-            if (defined $host)
-              {
-              ($port,$msgid) = $key =~
-                /^$host:$ip(?::([^:]*)(?::(\S*)|)|)/;
-              }
-
-           # This will probably be wrong...
-
-           else
-             {
-             ($host,$ip) = $key =~ /([^:]*):(.*)/;
-             }
-            }
-
-          printf("Transport: %s [%s]", $host, $ip);
+         ($host,$ip,$port,$msgid) = $key =~
+           /^([^:[]*|\[[^]]*\])        # host (could be an ip)
+             :([^:[]*|\[[^]]*\])       # ip
+             (?::(\d{1,5}))?           # maybe port
+             (?::(\S{23}))?            # maybe msgid
+             $/x;
+
+          printf("Transport: %s %s", $host, $ip);
           print ":$port" if defined $port;
           print " $msgid" if defined $msgid;
           print " error $error: $text\n";