#! /bin/sh

# Copyright (c) 1996 University of Cambridge.
# See the file NOTICE for conditions of use and distribution.


# A shell+perl script to fish out the next retry time for a given domain;
# it first calls exim to find out which hosts are set up for that domain and
# then fishes out the retry data for each one.

# 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.
# Set $hostsuffix if a suffixed file is found.

configure_file_use_node=
if [ "$configure_file_use_node" = "yes" ]; then
  host=`uname -n`
  if [ ! "$host" != "" ]; then
      if [ -f /usr/pkg/etc/exim/configure.$host ]; then
          hostsuffix=.$host
      fi
  fi
fi

# Set the configuration file name

config=/usr/pkg/etc/exim/configure$hostsuffix

# Determine where the spool directory is. Search for an exim_path setting
# in the configure file; otherwise use the bin directory. Call that version
# of Exim to find the spool directory and the qualify domain.

exim_path=`grep '^[      ]*exim_path' $config | sed 's/.*=[       ]*//'`
if test "$exim_path" = ""; then exim_path=/usr/pkg/sbin/exim; fi
spool_directory=`$exim_path -C $config -bP spool_directory | sed 's/.*=[  ]*//'`
qualify_domain=`$exim_path -C $config -bP qualify_domain | sed 's/.*=[  ]*//'`

# Now do the job. Perl uses $ so frequently that we don't want to have to
# escape them all from the shell, so pass in shell variable values as
# arguments.

# 16-May-1996  Fixed it to do better if routing fails to complete.
#              Improved the format of the output.
# 10-Jun-1996  Complain if no argument given.
# 02-Aug-1996  Lower case the domain.
# 14-Jan-1999  Add subject to want list even if remote host found, so as to
#              pick up routing delays after temporary recipient errors.
#              Also add unqualified subject if it looks like a message id.

if [ "$1" = "" ]; then
  echo "Usage: exinext <address>|<domain>|<local-part>"
  exit 1
fi

perl - $exim_path $1 $spool_directory $qualify_domain <<'End'

  # Name the arguments

  $exim = $ARGV[0];
  $subject = $ARGV[1];
  $spool = $ARGV[2];
  $qualify = $ARGV[3];

  # If the subject doesn't contain an @ then construct an address
  # for the domain, and ensure that in both cases the domain is
  # lower cased.

  $address = ($subject =~ /^([^\@]*)\@([^\@]*)$/)?
    "$1\@\L$2\E" : "User\@\L$subject\E";

  # 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 |") ||
    die "can't run exim to route $address";

  while (<LIST>)
    {
    chop;
    push(@list, $_) if s/\s*host (\S+)\s+\[(.+)\].*/$1:$2/;
    print "$_\n" if /cannot be resolved/;
    }
  close(LIST);

  # If there were no hosts, assume that what was given was a local
  # username, unless it contains an @, and construct a suitable retry
  # key for that. Also, if it looks like a message id, search for that
  # as well, so as to pick up message-specific retry data.

  if (scalar(@list) == 0)
    {
    push(@list, $subject) if $subject =~ /^\w{6}-\w{6}-\w{2}$/;

    if ($subject !~ /\@/ && $subject !~ /\./)
      {
      push(@list, "$subject\@$qualify");
      }
    else
      {
      print "No remote hosts found for $subject\n";
      }
    }

  # Always search for the full address, even if hosts are found, in case
  # there is a routing delay caused by a temporary recipient error.

  push(@list, $subject);

  # Run exim_dumpdb to get out the retry data and pick off what we want

  open(DATA, "${exim}_dumpdb $spool retry |") ||
    die "can't run exim_dumpdb";

  while (<DATA>)
    {
    for ($i = 0; $i <= $#list; $i++)
      {
      if (/$list[$i]/)
        {
        $printed = 1;
        if (/:[^:\s]+:/)
          {
          ($host,$ip,$error,$error2,$text) =
            /^\s*\S:([^:]+):(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/;
          print "Deliver: $host [$ip] error $error: $text\n";
          }
        else
          {
          ($type,$domain,$error,$error2,$text) =
            /^\s*(\S):(\S+)\s+(\S+)\s+(\S+)\s*(.*)$/;
          $type = ($type eq 'R')? "Route: " :
                  ($type eq 'T')? "Deliver: " :
                  ($type eq 'D')? "Direct: " : "";
          print "$type$domain error $error: $text\n";
          }
        $_ = <DATA>;
        ($first,$last,$next,$expired) =
          /^(\S+\s+\S+)\s+(\S+\s+\S+)\s+(\S+\s+\S+)\s*(\*?)/;
        print "  first failed: $first\n";
        print "  last tried:   $last\n";
        print "  next try at:  $next\n";
        print "  past final cutoff time\n" if $expired eq "*";
        }
      }
    }

  close(DATA);
  print "No retry data found for $subject\n" if !$printed;
End

