Commit 017c14cc authored by Yang Tse's avatar Yang Tse
Browse files

Start using the centralized pidfile and logfile name generation
subroutines for ftp, pop3, imap and smtp test suite servers.
parent b90703f5
Loading
Loading
Loading
Loading
+48 −34
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#                            | (__| |_| |  _ <| |___
#                             \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@@ -24,6 +24,12 @@
use strict;
use warnings;

use serverhelp qw(
    servername_str
    mainsockf_pidfilename
    datasockf_pidfilename
    );

#######################################################################
# pidfromfile returns the pid stored in the given pidfile.  The value
# of the returned pid will never be a negative value. It will be zero
@@ -167,44 +173,52 @@ sub killpid {
    }
}

#############################################################################
# Kill a specific slave
#######################################################################
# killsockfilters kills sockfilter processes for a given server.
#
sub ftpkillslave {
    my ($id, $ext, $verbose)=@_;
sub killsockfilters {
    my ($proto, $ipvnum, $idnum, $verbose) = @_;
    my $srvrname;
    my $pidfile;
    my $pid;

    return if($proto !~ /^(ftp|imap|pop3|smtp)$/);

    $srvrname = servername_str($proto, $ipvnum, $idnum) if($verbose);

    for my $base (('filt', 'data')) {
        my $f = ".sock$base$id$ext.pid";
        my $pid = processexists($f);
    $pidfile = "./". mainsockf_pidfilename($proto, $ipvnum, $idnum);
    $pid = processexists($pidfile);
    if($pid > 0) {
            printf("* kill pid for %s => %d\n", "ftp-$base$id$ext", $pid)
        printf("* kill pid for %s => %d\n", "${srvrname}-CTRL", $pid)
          if($verbose);
            kill (9, $pid);
        kill("KILL", $pid);
        waitpid($pid, 0);
    }
        unlink($f);
    }
}
    unlink($pidfile) if(-f $pidfile);

#############################################################################
# Make sure no FTP leftovers are still running. Kill all slave processes.
# This uses pidfiles since it might be used by other processes.
#
sub ftpkillslaves {
    my ($verbose) = @_;

    for my $ext (('', 'ipv6')) {
        for my $id (('', '2')) {
            for my $base (('filt', 'data')) {
                my $f = ".sock$base$id$ext.pid";
                my $pid = processexists($f);
    return if($proto ne 'ftp');

    $pidfile = "./". datasockf_pidfilename($proto, $ipvnum, $idnum);
    $pid = processexists($pidfile);
    if($pid > 0) {
                    printf("* kill pid for %s => %d\n", "ftp-$base$id$ext",
                        $pid) if($verbose);
                    kill (9, $pid);
        printf("* kill pid for %s => %d\n", "${srvrname}-DATA", $pid)
          if($verbose);
        kill("KILL", $pid);
        waitpid($pid, 0);
    }
                unlink($f);
    unlink($pidfile) if(-f $pidfile);
}

#######################################################################
# killallsockfilters kills sockfilter processes for all servers.
#
sub killallsockfilters {
    my $verbose = $_[0];

    for my $proto (('ftp', 'imap', 'pop3', 'smtp')) {
        for my $ipvnum (('4', '6')) {
            for my $idnum (('1', '2')) {
                killsockfilters($proto, $ipvnum, $idnum, $verbose);
            }
        }
    }
+134 −78
Original line number Diff line number Diff line
@@ -39,14 +39,8 @@
# All socket/network/TCP related stuff is done by the 'sockfilt' program.
#

use strict;
use warnings;
use IPC::Open2;

require "getpart.pm";
require "ftp.pm";

BEGIN {
    @INC=(@INC, $ENV{'srcdir'}, '.');
    # sub second timestamping needs Time::HiRes
    eval {
        no warnings "all";
@@ -55,29 +49,53 @@ BEGIN {
    }
}

use strict;
use warnings;
use IPC::Open2;

require "getpart.pm";
require "ftp.pm";

use serverhelp qw(
    servername_str
    server_pidfilename
    server_logfilename
    mainsockf_pidfilename
    mainsockf_logfilename
    datasockf_pidfilename
    datasockf_logfilename
    );

#**********************************************************************
# global vars...
#
my $verbose = 0;    # set to 1 for debugging
my $ftpdnum = "";   # server instance number
my $idstr = "";     # server instance string
my $idnum = 1;      # server instance number
my $ipvnum = 4;     # server IPv number (4 or 6)
my $proto = 'ftp';  # server protocol
my $srcdir = '.';   # directory where ftpserver.pl is located
my $ipv6 = "";
my $ext = "";
my $proto = 'ftp';  # default server protocol
my $srcdir;         # directory where ftpserver.pl is located
my $srvrname;       # server name for presentation purposes
my $grok_eprt;

my $path   = '.';
my $logdir = $path .'/log';

#**********************************************************************
# global vars used for server address and primary listener port
#
my $port = 8921;               # server primary listener port
my $listenaddr = '127.0.0.1';  # server address for listener port
my $port = 8921;               # default primary listener port
my $listenaddr = '127.0.0.1';  # default address for listener port

#**********************************************************************
# global vars used for file names
#
my $logfilename = 'log/logfile.log'; # Override this for each test server
my $pidfile = '.ftpd.pid';           # a default, use --pidfile
my $pidfile;            # server pid file name
my $logfile;            # server log file name
my $mainsockf_pidfile;  # pid file for primary connection sockfilt process
my $mainsockf_logfile;  # log file for primary connection sockfilt process
my $datasockf_pidfile;  # pid file for secondary connection sockfilt process
my $datasockf_logfile;  # log file for secondary connection sockfilt process

#**********************************************************************
# global vars used for server logs advisor read lock handling
@@ -133,7 +151,7 @@ my $exit_signal; # first signal handled in exit_signal_handler
sub exit_signal_handler {
    my $signame = shift;
    # For now, simply mimic old behavior.
    ftpkillslaves($verbose);
    killsockfilters($proto, $ipvnum, $idnum, $verbose);
    unlink($pidfile);
    if($serverlogslocked) {
        $serverlogslocked = 0;
@@ -142,19 +160,6 @@ sub exit_signal_handler {
    exit;
}

#**********************************************************************
# getlogfilename returns a log file name depending on given arguments.
#
sub getlogfilename {
    my ($proto, $ipversion, $ssl, $instance, $sockfilter) = @_;
    my $filename;

    # For now, simply mimic old behavior.
    $filename = "log/ftpd$ftpdnum.log";

    return $filename;
}

#**********************************************************************
# logmsg is general message logging subroutine for our test servers.
#
@@ -173,7 +178,7 @@ sub logmsg {
            localtime($seconds);
        $now = sprintf("%02d:%02d:%02d ", $hour, $min, $sec);
    }
    if(open(LOGFILEFH, ">>$logfilename")) {
    if(open(LOGFILEFH, ">>$logfile")) {
        print LOGFILEFH $now;
        print LOGFILEFH @_;
        close(LOGFILEFH);
@@ -182,8 +187,8 @@ sub logmsg {

sub ftpmsg {
  # append to the server.input file
  open(INPUT, ">>log/server$ftpdnum.input") ||
    logmsg "failed to open log/server$ftpdnum.input\n";
  open(INPUT, ">>log/server$idstr.input") ||
    logmsg "failed to open log/server$idstr.input\n";

  print INPUT @_;
  close(INPUT);
@@ -207,11 +212,11 @@ sub sysread_or_die {
    if(not defined $result) {
        ($fcaller, $lcaller) = (caller)[1,2];
        logmsg "Failed to read input\n";
        logmsg "Error: ftp$ftpdnum$ext sysread error: $!\n";
        logmsg "Error: $srvrname server, sysread error: $!\n";
        kill(9, $sfpid);
        waitpid($sfpid, 0);
        logmsg "Exited from sysread_or_die() at $fcaller " .
               "line $lcaller. ftp$ftpdnum$ext sysread error: $!\n";
               "line $lcaller. $srvrname server, sysread error: $!\n";
        unlink($pidfile);
        if($serverlogslocked) {
            $serverlogslocked = 0;
@@ -222,11 +227,11 @@ sub sysread_or_die {
    elsif($result == 0) {
        ($fcaller, $lcaller) = (caller)[1,2];
        logmsg "Failed to read input\n";
        logmsg "Error: ftp$ftpdnum$ext read zero\n";
        logmsg "Error: $srvrname server, read zero\n";
        kill(9, $sfpid);
        waitpid($sfpid, 0);
        logmsg "Exited from sysread_or_die() at $fcaller " .
               "line $lcaller. ftp$ftpdnum$ext read zero\n";
               "line $lcaller. $srvrname server, read zero\n";
        unlink($pidfile);
        if($serverlogslocked) {
            $serverlogslocked = 0;
@@ -239,17 +244,20 @@ sub sysread_or_die {
}

sub startsf {
    my $cmd="./server/sockfilt --port $port --logfile log/sockctrl$ftpdnum$ext.log --pidfile .sockfilt$ftpdnum$ext.pid $ipv6";
    $sfpid = open2(*SFREAD, *SFWRITE, $cmd);
    my $mainsockfcmd = "./server/sockfilt " .
        "--ipv$ipvnum --port $port " .
        "--pidfile \"$mainsockf_pidfile\" " .
        "--logfile \"$mainsockf_logfile\"";
    $sfpid = open2(*SFREAD, *SFWRITE, $mainsockfcmd);

    print STDERR "$cmd\n" if($verbose);
    print STDERR "$mainsockfcmd\n" if($verbose);

    print SFWRITE "PING\n";
    my $pong;
    sysread SFREAD, $pong, 5;

    if($pong !~ /^PONG/) {
        logmsg "Failed sockfilt command: $cmd\n";
        logmsg "Failed sockfilt command: $mainsockfcmd\n";
        kill(9, $sfpid);
        waitpid($sfpid, 0);
        unlink($pidfile);
@@ -922,9 +930,8 @@ sub STOR_ftp {
sub PASV_ftp {
    my ($arg, $cmd)=@_;
    my $pasvport;
    my $pidf=".sockdata$ftpdnum$ext.pid";

    my $prev = processexists($pidf);
    my $prev = processexists($datasockf_pidfile);
    if($prev > 0) {
        print "kill existing server: $prev\n" if($verbose);
        kill(9, $prev);
@@ -932,8 +939,11 @@ sub PASV_ftp {
    }

    # We fire up a new sockfilt to do the data transfer for us.
    $slavepid = open2(\*DREAD, \*DWRITE,
                      "./server/sockfilt --port 0 --logfile log/sockdata$ftpdnum$ext.log --pidfile $pidf $ipv6");
    my $datasockfcmd = "./server/sockfilt " .
        "--ipv$ipvnum --port 0 " .
        "--pidfile \"$datasockf_pidfile\" " .
        "--logfile \"$datasockf_logfile\"";
    $slavepid = open2(\*DREAD, \*DWRITE, $datasockfcmd);

    print DWRITE "PING\n";
    my $pong;
@@ -1067,11 +1077,13 @@ sub PORT_ftp {
    }

    # We fire up a new sockfilt to do the data transfer for us.
    # FIX: make it use IPv6 if need be
    my $filtcmd="./server/sockfilt --connect $port --addr $addr --logfile log/sockdata$ftpdnum$ext.log --pidfile .sockdata$ftpdnum$ext.pid $ipv6";
    $slavepid = open2(\*DREAD, \*DWRITE, $filtcmd);
    my $datasockfcmd = "./server/sockfilt " .
        "--ipv$ipvnum --connect $port --addr \"$addr\" " .
        "--pidfile \"$datasockf_pidfile\" " .
        "--logfile \"$datasockf_logfile\"";
    $slavepid = open2(\*DREAD, \*DWRITE, $datasockfcmd);

    print STDERR "$filtcmd\n" if($verbose);
    print STDERR "$datasockfcmd\n" if($verbose);

    print DWRITE "PING\n";
    my $pong;
@@ -1163,56 +1175,72 @@ sub customize {
#
# Options:
#
# -v          # verbose
# -s          # source directory
# --verbose   # verbose
# --srcdir    # source directory
# --id        # server instance number
# --proto     # server protocol
# --pidfile   # server pid file
# --logfile   # server log file
# --ipv4      # server IP version 4
# --ipv6      # server IP version 6
# --port      # server listener port
# --addr      # server address for listener port binding
#
while(@ARGV) {
    if($ARGV[0] eq '-v') {
    if($ARGV[0] eq '--verbose') {
        $verbose = 1;
    }
    elsif($ARGV[0] eq '-s') {
    elsif($ARGV[0] eq '--srcdir') {
        if($ARGV[1]) {
            $srcdir = $ARGV[1];
            shift @ARGV;
        }
    elsif($ARGV[0] eq '--id') {
        if($ARGV[1] =~ /^(\d+)$/) {
            $ftpdnum = $1 if($1 > 0);
    }
    elsif($ARGV[0] eq '--id') {
        if($ARGV[1] && ($ARGV[1] =~ /^(\d+)$/)) {
            $idnum = $1 if($1 > 0);
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--proto') {
        if($ARGV[1] =~ /^(ftp|imap|pop3|smtp)$/) {
        if($ARGV[1] && ($ARGV[1] =~ /^(ftp|imap|pop3|smtp)$/)) {
            $proto = $1;
            shift @ARGV;
        }
        else {
            die "unsupported protocol $ARGV[1]";
        }
        shift @ARGV;
    }
    elsif($ARGV[0] eq '--pidfile') {
        if($ARGV[1]) {
            $pidfile = $ARGV[1];
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--logfile') {
        if($ARGV[1]) {
            $logfile = $ARGV[1];
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--ipv4') {
        $ipvnum = 4;
        $listenaddr = '127.0.0.1' if($listenaddr eq '::1');
        $grok_eprt = 0;
    }
    elsif($ARGV[0] eq '--ipv6') {
        $ipvnum = 6;
        $listenaddr = '::1' if($listenaddr eq '127.0.0.1');
        $ipv6 = '--ipv6';
        $ext = 'ipv6';
        $grok_eprt = 1;
    }
    elsif($ARGV[0] eq '--port') {
        if($ARGV[1] =~ /^(\d+)$/) {
        if($ARGV[1] && ($ARGV[1] =~ /^(\d+)$/)) {
            $port = $1 if($1 > 1024);
        }
            shift @ARGV;
        }
    }
    elsif($ARGV[0] eq '--addr') {
        if($ARGV[1]) {
            my $tmpstr = $ARGV[1];
            if($tmpstr =~ /^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/) {
                $listenaddr = "$1.$2.$3.$4" if($ipvnum == 4);
@@ -1223,14 +1251,42 @@ while(@ARGV) {
            }
            shift @ARGV;
        }
    }
    else {
        print STDERR "\nWarning: ftpserver.pl unknown parameter: $ARGV[0]\n";
    }
    shift @ARGV;
};
}

#***************************************************************************
# Initialize command line option dependant variables
#

$logfilename = getlogfilename();
if(!$srcdir) {
    $srcdir = $ENV{'srcdir'} || '.';
}
if(!$pidfile) {
    $pidfile = "$path/". server_pidfilename($proto, $ipvnum, $idnum);
}
if(!$logfile) {
    $logfile = server_logfilename($logdir, $proto, $ipvnum, $idnum);
}

$mainsockf_pidfile = "$path/".
    mainsockf_pidfilename($proto, $ipvnum, $idnum);
$mainsockf_logfile =
    mainsockf_logfilename($logdir, $proto, $ipvnum, $idnum);

if($proto eq 'ftp') {
    $datasockf_pidfile = "$path/".
        datasockf_pidfilename($proto, $ipvnum, $idnum);
    $datasockf_logfile =
        datasockf_logfilename($logdir, $proto, $ipvnum, $idnum);
}

$srvrname = servername_str($proto, $ipvnum, $idnum);

$idstr = "$idnum" if($idnum > 1);

protocolsetup($proto);

@@ -1239,8 +1295,8 @@ $SIG{TERM} = \&exit_signal_handler;

startsf();

logmsg sprintf("%s server listens on port IPv%d/$port\n", uc($proto),
               $ipv6?6:4);
logmsg sprintf("%s server listens on port IPv${ipvnum}/${port}\n", uc($proto));

open(PID, ">$pidfile");
print PID $$."\n";
close(PID);
+46 −39
Original line number Diff line number Diff line
@@ -122,8 +122,11 @@ my $TFTP6PORT; # TFTP
my $SSHPORT; # SCP/SFTP
my $SOCKSPORT; # SOCKS4/5 port
my $POP3PORT; # POP3
my $POP36PORT; # POP3 IPv6 server port
my $IMAPPORT; # IMAP
my $IMAP6PORT; # IMAP IPv6 server port
my $SMTPPORT; # SMTP
my $SMTP6PORT; # SMTP IPv6 server port

my $srcdir = $ENV{'srcdir'} || '.';
my $CURL="../src/curl"; # what curl executable to run on the tests
@@ -957,75 +960,67 @@ sub runhttpsserver {
#
sub runpingpongserver {
    my ($proto, $id, $verbose, $ipv6) = @_;
    my $STATUS;
    my $RUNNING;
    my $port;
    my $pidfile;
    my $ip = $HOSTIP;
    my $cmd;
    my $flag;
    my $ipvnum = 4;
    my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
    my $srvrname;
    my $pidfile;
    my $logfile;
    my $flags = "";

    if($proto eq "ftp") {
        $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
        $pidfile = ($idnum>1)?$FTP2PIDFILE:$FTPPIDFILE;

        if($ipv6) {
            # if IPv6, use a different setup
            $ipvnum = 6;
            $pidfile = $FTP6PIDFILE;
            $port = $FTP6PORT;
            $ip = $HOST6IP;
        }
    }
    elsif($proto eq "pop3") {
        $port = $POP3PORT;
        $pidfile = $POP3PIDFILE;
        $port = ($ipv6) ? $POP36PORT : $POP3PORT;
    }
    elsif($proto eq "imap") {
        $port = $IMAPPORT;
        $pidfile = $IMAPPIDFILE;
        $port = ($ipv6) ? $IMAP6PORT : $IMAPPORT;
    }
    elsif($proto eq "smtp") {
        $port = $SMTPPORT;
        $pidfile = $SMTPPIDFILE;
        $port = ($ipv6) ? $SMTP6PORT : $SMTPPORT;
    }
    else {
        print STDERR "Unsupported protocol $proto!!\n";
        return 0;
    }
    $flag .= "--proto $proto ";

    if($ipv6) {
        # if IPv6, use a different setup
        $ipvnum = 6;
        $ip = $HOST6IP;
    }

    $pidfile = server_pidfilename($proto, $ipvnum, $idnum);

    # don't retry if the server doesn't work
    if ($doesntrun{$pidfile}) {
        return (0,0);
    }

    $srvrname = servername_str($proto, $ipvnum, $idnum);

    my $pid = processexists($pidfile);
    if($pid > 0) {
        stopserver($pid);
    }
    unlink($pidfile);

    # start our server:
    $flag .= $debugprotocol?"-v ":"";
    $flag .= "-s \"$srcdir\" ";
    my $addr;
    if($idnum > 1) {
        $flag .="--id $idnum ";
    }
    if($ipv6) {
        $flag .="--ipv6 ";
        $addr = $HOST6IP;
    } else {
        $addr = $HOSTIP;
    }
    $srvrname = servername_str($proto, $ipvnum, $idnum);

    $cmd="$perl $srcdir/ftpserver.pl --pidfile $pidfile $flag --port $port --addr \"$addr\"";
    $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);

    $flags .= "--verbose " if($debugprotocol);
    $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
    $flags .= "--srcdir \"$srcdir\" --proto $proto ";
    $flags .= "--id $idnum " if($idnum > 1);
    $flags .= "--ipv$ipvnum --port $port --addr \"$ip\"";

    my $cmd = "$perl $srcdir/ftpserver.pl $flags";
    my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);

    if($ftppid <= 0 || !kill(0, $ftppid)) {
@@ -1754,6 +1749,11 @@ sub checksystem {
    logmsg sprintf("POP3/%d ", $POP3PORT);
    logmsg sprintf("IMAP/%d ", $IMAPPORT);
    logmsg sprintf("SMTP/%d\n", $SMTPPORT);
    if($tftp_ipv6) {
        logmsg sprintf("POP3-IPv6/%d ", $POP36PORT);
        logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
        logmsg sprintf("SMTP-IPv6/%d ", $SMTP6PORT);
    }


    $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
@@ -1783,8 +1783,11 @@ sub subVariables {
  $$thing =~ s/%SSHPORT/$SSHPORT/g;
  $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
  $$thing =~ s/%POP3PORT/$POP3PORT/g;
  $$thing =~ s/%POP36PORT/$POP36PORT/g;
  $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
  $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
  $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
  $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
  $$thing =~ s/%CURL/$CURL/g;
  $$thing =~ s/%USER/$USER/g;
  $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
@@ -2329,10 +2332,11 @@ sub singletest {
    my @killservers = getpart("client", "killserver");
    foreach my $serv (@killservers) {
        chomp $serv;
        if($serv =~ /^ftp(\d*)(-ipv6|)/) {
            my ($id, $ext) = ($1, $2);
            #print STDERR "SERV $serv $id $ext\n";
            ftpkillslave($id, $ext, $verbose);
        if($serv =~ /^(ftp|imap|pop3|smtp)(\d*)(-ipv6|)/) {
            my $proto  = $1;
            my $idnum  = ($2 && ($2 > 1)) ? $2 : 1;
            my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
            killsockfilters($proto, $ipvnum, $idnum, $verbose);
        }
        if($run{$serv}) {
            stopserver($run{$serv}); # the pid file is in the hash table
@@ -2677,7 +2681,7 @@ sub singletest {
#######################################################################
# Stop all running test servers
sub stopservers {
    my ($verbose)=@_;
    my $verbose = $_[0];
    my $pidlist;

    for(keys %run) {
@@ -2698,7 +2702,7 @@ sub stopservers {
        delete $run{$server};
    }
    killpid($verbose, $pidlist);
    ftpkillslaves($verbose);
    killallsockfilters($verbose);
}

#######################################################################
@@ -3285,8 +3289,11 @@ $TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
$SSHPORT =   $base++; # SSH (SCP/SFTP) port
$SOCKSPORT = $base++; # SOCKS port
$POP3PORT =  $base++;
$POP36PORT = $base++;
$IMAPPORT =  $base++;
$IMAP6PORT = $base++;
$SMTPPORT =  $base++;
$SMTP6PORT = $base++;

#######################################################################
# clear and create logging directory: