#!/usr/bin/perl -w use strict; use IPC::Open2; use FileHandle; $| = 1; use vars qw($r $w); open2($r, $w, join(" ",@ARGV)) or die "Error running ".join(" ",@ARGV).": $!\n"; $w->autoflush(1); if ($ENV{SENTGREETING}) { while (<$r>) { if (!/^(\d+)([\- ])(.*)$/) { # Invalid line?... # Let's just call it the end. last; } if ($1 != 220) { &failedproxy; } if ($2 ne '-') { last; } } } if ($ENV{EHLO}) { print $w $ENV{EHLO}; while (<$r>) { if (!/^(\d+)([\- ])(.*)$/) { # Invalid line?... # Let's just call it the end. last; } if ($1 != 250) { &failedproxy; } if ($2 ne '-') { last; } } } if ($ENV{AUTHENTICATED}) { print "235 2.0.0 OK Authenticated. Hello, $ENV{AUTHENTICATED}\r\n"; } if ($ENV{CMD}) { print $w $ENV{CMD}; } &proxy($r,$w); exit(0); sub proxy { warn "Starting proxy!\n"; my($r,$w)=@_; my($rin,$win,$ein); my($rout,$wout,$eout); my $nfound; my($rbufend,$wbufend); my($rembuf,$locbuf); my($remdone,$locdone); my $ret; $rembuf = $locbuf = ''; while (!( ($remdone || $locdone) && (!length($rembuf) && !length($locbuf) ) )) { $rin=$win=$ein=''; if (length($locbuf) > 0) { vec($win,fileno($w),1) = 1; } else { vec($rin,fileno(STDIN),1) = 1; } if (length($rembuf) > 0) { vec($win,fileno(STDOUT),1) = 1; } else { vec($rin,fileno($r),1) = 1; } $ein = $rin | $win; $nfound = select($rout=$rin,$wout=$win,$eout=$ein,86400); if ($nfound == 0) { die "Select error\n"; } if (length($locbuf)) { if (vec($wout,fileno($w),1)) { my $sofar = 0; my $howmuch; while ($sofar < length($locbuf)) { $howmuch = syswrite($w,$locbuf,length($locbuf)-$sofar,$sofar); if ($howmuch <= 0) { die "syswrite error\n"; } $sofar += $howmuch; } $locbuf = ''; } } else { if (vec($rout,fileno(STDIN),1)) { if (($ret=sysread(STDIN,$locbuf,8192)) <= 0) { if (!defined($ret)) { die "sysread error\n"; } elsif ($ret == 0) { $locdone = 1; } } } } if (length($rembuf)) { if (vec($wout,fileno(STDOUT),1)) { my $sofar = 0; my $howmuch; while ($sofar < length($rembuf)) { $howmuch = syswrite(STDOUT,$rembuf,length($rembuf)-$sofar,$sofar); if ($howmuch <= 0) { die "syswrite error\n"; } $sofar += $howmuch; } $rembuf = ''; } } else { if (vec($rout,fileno($r),1)) { if (($ret=sysread($r,$rembuf,8192)) <= 0) { if (!defined($ret)) { die "sysread error\n"; } elsif ($ret == 0) { $remdone = 1; } } } } } }