#!/usr/bin/perl -w

# 2001-03-05 Dobrica Pavlinusic <dpavlin@rot13.org>
#
# reads e-mail addresses from stdin and dump format for .htusers on stdout
# which will use auth_pop3 for user authentification
#
# This tool is good for batch import and it will do it's best to resolve
# all sendmail related output from expn. However, it's not tested on
# other mailers.
#
# usage:
#
# cat emails.txt | email2htusers.pl [remote.smtp.server] [smtp_port] >> .htusers
#

use strict;
use Socket;

my $debug=0;

my $reuse_conn=0;	# if you set this to 1, it will try to do all expn
			# over single tcp connection. It nice to smtp server,
			# but sendmail slows down after 10 expns or so...

my ($remote,$port, $iaddr, $paddr, $proto, $line);

$remote = shift || 'localhost';
$port = shift || 25;

print "# using remote $remote port $port\n" if ($debug);

sub open_conn {
	if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
	die "No port" unless $port;
	$iaddr = inet_aton($remote) || die "no host: $remote";
	$paddr = sockaddr_in($port, $iaddr);

	$proto = getprotobyname('tcp');
	socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
	connect(SOCK, $paddr) || die "connect: $!";
	select(SOCK); $|=1;
	select(STDOUT); $|=1;

	my $hello=<SOCK>;	# hello

}

sub close_conn {
	close (SOCK) || die "close: $!";
}

my %tested;

sub try_expn {
	my $login=$_[0];
	if (! defined($tested{$login})) {
		$tested{$login}++;
		print SOCK "expn $login\n";
		my $response=<SOCK>;
		while ($response =~ /^2\d\d-(.+)/) {
			my $rest=$1;
			print "# $response\n" if ($debug);
			if ($rest=~/[\d\. ]+([^<]+) <\\*(\w+)\@($remote[^>]*)>/) {
				print "# $2:$1:auth_pop3:$2\@$3\n";
			}
			$response=<SOCK>;
		};
		print "# $response\n" if ($debug);
		if ($response =~ /^2\d\d (.+)/) {
			my $rest=$1;
			if ($rest=~/[\d\. ]+([^<]+) <\\*(\w+)\@($remote[^>]*)>/) {
				print "$2:$1:auth_pop3:$2\@$3\n";
			}
		} else {
			print "# can't add e-mail address $login\n";
		}
		return 0;
	}
}

open_conn if ($reuse_conn);

while(<STDIN>) {
	chomp;
	next if (/^#/ || /^$/);
	open_conn if (! $reuse_conn);
	try_expn($_);
	close_conn if (! $reuse_conn);
}

close_conn if ($reuse_conn);
exit;
