--- lib/Qpsmtpd/TcpServer.pm.xinetd Wed Oct 4 15:49:49 2006 +++ lib/Qpsmtpd/TcpServer.pm Sun Nov 5 16:20:44 2006 @@ -1,6 +1,7 @@ package Qpsmtpd::TcpServer; use Qpsmtpd::SMTP; use Qpsmtpd::Constants; +use Socket; @ISA = qw(Qpsmtpd::SMTP); use strict; @@ -12,12 +13,25 @@ sub start_connection { my $self = shift; - die "Qpsmtpd::TcpServer must be started by tcpserver\n" - unless $ENV{TCPREMOTEIP}; + my ($remote_host, $remote_info, $remote_ip); - my $remote_host = $ENV{TCPREMOTEHOST} || ( $ENV{TCPREMOTEIP} ? "[$ENV{TCPREMOTEIP}]" : "[noip!]"); - my $remote_info = $ENV{TCPREMOTEINFO} ? "$ENV{TCPREMOTEINFO}\@$remote_host" : $remote_host; - my $remote_ip = $ENV{TCPREMOTEIP}; + if ($ENV{TCPREMOTEIP}) { + # started from tcpserver (or some other superserver which + # exports the TCPREMOTE* variables. + $remote_ip = $ENV{TCPREMOTEIP}; + $remote_host = $ENV{TCPREMOTEHOST} || "[$remote_ip]"; + $remote_info = $ENV{TCPREMOTEINFO} ? "$ENV{TCPREMOTEINFO}\@$remote_host" : $remote_host; + } else { + # Started from inetd or similar. + # get info on the remote host from the socket. + # ignore ident/tap/... + my $hersockaddr = getpeername(STDIN) + or die "getpeername failed: $0 must be called from tcpserver, (x)inetd or a similar program which passes a socket to stdin"; + my ($port, $iaddr) = sockaddr_in($hersockaddr); + $remote_ip = inet_ntoa($iaddr); + $remote_host = gethostbyaddr($iaddr, AF_INET) || "[$remote_ip]"; + $remote_info = $remote_host; + } $self->log(LOGNOTICE, "Connection from $remote_info [$remote_ip]"); # if the local dns resolver doesn't filter it out we might get