QUIT works, and now I can run a unix ftp client against the server and it

runs pretty good
This commit is contained in:
Daniel Stenberg 2000-11-20 14:26:09 +00:00
parent 4b8fd86f04
commit 05ec503eac
1 changed files with 28 additions and 13 deletions

View File

@ -1,4 +1,15 @@
#!/usr/bin/perl #!/usr/bin/perl
#
# $Id$
# This is the FTP server designed for the curl test suite.
#
# It is meant to excersive curl, it is not meant to become a fully working
# or even very standard compliant server.
#
# You may optionally specify port on the command line, otherwise it'll
# default to port 8921.
#
use Socket; use Socket;
use Carp; use Carp;
use FileHandle; use FileHandle;
@ -12,6 +23,8 @@ open(FTPLOG, ">log/ftpd.log") ||
sub logmsg { print FTPLOG @_; } sub logmsg { print FTPLOG @_; }
sub ftpmsg { print INPUT @_; }
my $verbose=0; # set to 1 for debugging my $verbose=0; # set to 1 for debugging
my $port = 8921; # just a default my $port = 8921; # just a default
@ -46,7 +59,7 @@ my $paddr;
sub REAPER { sub REAPER {
$waitedpid = wait; $waitedpid = wait;
$SIG{CHLD} = \&REAPER; # loathe sysV $SIG{CHLD} = \&REAPER; # loathe sysV
# logmsg "reaped $waitedpid" . ($? ? " with exit $?" : ''); logmsg "reaped $waitedpid" . ($? ? " with exit $?\n" : "\n");
} }
# USER is ok in fresh state # USER is ok in fresh state
@ -58,6 +71,7 @@ my %commandok = ( "USER" => "fresh",
"LIST" => "twosock", "LIST" => "twosock",
"RETR" => "twosock", "RETR" => "twosock",
"CWD" => "loggedin", "CWD" => "loggedin",
"QUIT" => "loggedin|twosock",
); );
# initially, we're in 'fresh' state # initially, we're in 'fresh' state
@ -74,7 +88,7 @@ my %displaytext = ('USER' => '331 We are happy you popped in!', # output FTP lin
'TYPE' => '200 I modify TYPE as you wanted', 'TYPE' => '200 I modify TYPE as you wanted',
'LIST' => '150 here comes a directory', 'LIST' => '150 here comes a directory',
'CWD' => '250 CWD command successful.', 'CWD' => '250 CWD command successful.',
'QUIT' => '221 bye bye baby',
); );
# callback functions for certain commands # callback functions for certain commands
@ -182,6 +196,10 @@ sub PASV_command {
} }
$port++; # try next port please $port++; # try next port please
} }
if(11000 == $port) {
print "500 no free ports!\r\n";
exit;
}
listen(Server2,SOMAXCONN) || die "listen: $!"; listen(Server2,SOMAXCONN) || die "listen: $!";
printf("227 Entering Passive Mode (127,0,0,1,%d,%d)\n", printf("227 Entering Passive Mode (127,0,0,1,%d,%d)\n",
@ -194,7 +212,7 @@ sub PASV_command {
my($port,$iaddr) = sockaddr_in($paddr); my($port,$iaddr) = sockaddr_in($paddr);
my $name = gethostbyaddr($iaddr,AF_INET); my $name = gethostbyaddr($iaddr,AF_INET);
logmsg "connection from $name [", inet_ntoa($iaddr), "] at port $port\n"; logmsg "data connection from $name [", inet_ntoa($iaddr), "] at port $port\n";
open(STDOUT, ">&Client2") || die "can't dup client to stdout"; open(STDOUT, ">&Client2") || die "can't dup client to stdout";
@ -232,8 +250,8 @@ sub PORT_command {
if($arg !~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) { if($arg !~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) {
logmsg "bad PORT-line: $arg\n"; logmsg "bad PORT-line: $arg\n";
print "314 silly you, go away\r\n"; print "500 silly you, go away\r\n";
return 1; exit;
} }
my $iaddr = inet_aton("$1.$2.$3.$4"); my $iaddr = inet_aton("$1.$2.$3.$4");
my $paddr = sockaddr_in(($5<<8)+$6, $iaddr); my $paddr = sockaddr_in(($5<<8)+$6, $iaddr);
@ -307,26 +325,25 @@ for ( $waitedpid = 0;
last unless defined ($_ = <STDIN>); last unless defined ($_ = <STDIN>);
ftpmsg $_;
# Remove trailing CRLF. # Remove trailing CRLF.
s/[\n\r]+$//; s/[\n\r]+$//;
unless (m/^([A-Z]{3,4})\s?(.*)/i) { unless (m/^([A-Z]{3,4})\s?(.*)/i) {
print STDERR print "500 '$_': command not understood.\r\n";
"badly formed command received: ".$_; next;
exit 0;
} }
my $FTPCMD=$1; my $FTPCMD=$1;
my $FTPARG=$2; my $FTPARG=$2;
my $full=$_; my $full=$_;
logmsg "GOT: ($1) $_\n"; logmsg "GOT: ($1) $_\n";
print INPUT "$$: $full\n";
my $ok = $commandok{$FTPCMD}; my $ok = $commandok{$FTPCMD};
if($ok !~ /$state/) { if($ok !~ /$state/) {
print "314 $FTPCMD not OK ($ok) in state: $state!\r\n"; print "500 $FTPCMD not OK in state: $state!\r\n";
exit; next;
} }
my $newstate=$statechange{$FTPCMD}; my $newstate=$statechange{$FTPCMD};
@ -363,12 +380,10 @@ for ( $waitedpid = 0;
sub spawn { sub spawn {
my $coderef = shift; my $coderef = shift;
unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') { unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
confess "usage: spawn CODEREF"; confess "usage: spawn CODEREF";
} }
my $pid; my $pid;
if (!defined($pid = fork)) { if (!defined($pid = fork)) {
logmsg "cannot fork: $!\n"; logmsg "cannot fork: $!\n";