#!/usr/bin/perl
# $Id: smtpcall,v 1.9 1997/03/18 03:32:05 david Exp $
#
# Usage: host port user.
#
# $Log: smtpcall,v $
# Revision 1.9  1997/03/18 03:32:05  david
# Extended the password file format to include the Maildir being delivered
# out of.
#
# Revision 1.8  1996/12/16 18:48:27  david
# Automatically detect Linux vs. Solaris.
# Now waits until other side stops transmitting mail.
# Also prints status of each e-mail transferred when debug set.
#
# Revision 1.7  1996/12/11 03:03:52  david
# Fix timeout to wait forever after the initial handshake.
#
# Revision 1.6  1996/12/09 04:35:03  david
# Completely re-wrote in PERL.  Doesn't require EXPECT any more.
#
# Revision 1.5  1996/11/25 16:38:17  david
# Forgot to connect to port via telnet.
#
# Revision 1.4  1996/11/25 16:37:21  david
# Added port parameter.
#

use Socket;

$debug = 0;
$PASSWORDS='/var/qmail/control/passwords';

$mach = `uname -s`; chop $mach;
if ( $mach eq "Linux" )
   { # Linux
   $ECHO='/bin/echo -n';
   $MD5SUM_PATH='/usr/bin/md5sum';
   }
 else
   { # Solaris
   #$ECHO='/usr/ucb/echo -n";
   #$MD5SUM_PATH="/usr/local/bin/md5sum";
   }

$remote  = shift || 'localhost';
$port    = shift || 1234;  # random port
$user    = shift || die "No user specified.\n";

if ($port =~ /\D/)
   {
   $port = getservbyname($port, 'tcp');
   }

die "No port" unless $port;

open( PASS, "<$PASSWORDS" ) || die "Can't open $PASSWORDS.";
while ( ($_ = <PASS>) && ($lhost ne $remote) && ($luser ne $user) )
   {
   chop;
   ($lhost, $luser, $lpass, $ldir) = split ":";  
   }

close( PASS );

die "Can't find $remote in $PASSWORDS.\n"
   unless ($lhost eq $remote) && ($luser eq $user);

printf "Lhost = $lhost, Luser = $luser, Lpass = $lpass\n" if $debug;

$iaddr   = inet_aton($remote)               || die "no host: $remote\n";
$paddr   = sockaddr_in($port, $iaddr);
$proto   = getprotobyname('tcp');

socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!\n";
connect(SOCK, $paddr)    || die "connect: $!\n";

select( SOCK ); $| = 1; select( STDOUT ); # Unbuffered I/O

alarm( 180 ); # Die after 180 seconds if nothing happens.

$_ = <SOCK>; chop; chop;
printf "$_\n" if $debug;

($ok, $mid, $j1, $j2) = split( ' ' );

$md5clear = $mid . $lpass;

$md5pass = &md5sum( $md5clear );

printf "Md5clear = $md5clear\n" if $debug;
printf "Md5pass = $md5pass\n" if $debug;

printf "$user $md5pass\n" if $debug;
printf SOCK "$user $md5pass\r\n";

alarm( 0 ); # Now wait forever.

# Wait for OK or -ERR from remote side.
while ( <SOCK> )
   {
   printf $_ if $debug;
   }

close (SOCK)            || die "close: $!";
exit;

sub md5sum
{
$_ = `$ECHO "$_[0]" | $MD5SUM_PATH`;
chop;
($_, $junk) = split ' ';
return $_;
}
