This is a simple FTP srver, which supports the basic FTP needs. Program is multi-threaded, so it supports multiple clients at the same time. Tested with the command line ftp client came with Windows XP, and was fine.

use IO::Socket::INET; use threads; use strict; use Data::Dumper; $| ++; my $s = IO::Socket::INET->new(Proto => "tcp", LocalPort => 21, Listen +=> 10, Reuse => 1); while (my $cc = $s->accept()) { threads->create(\&session, $cc); #session($cc); } sub session { my $cc = shift; print $cc "220 Service ready\r\n"; my $daddr; my $dport; my $type = 'A'; while (my $res = <$cc>) { $res =~ /(.*)\r\n/; $res = $1; print "<$res>\n"; if ($res =~ /USER (.+)/) { print $cc "331 user name okay, need password\r\n"; } elsif ($res =~ /PASS (.+)/) { print $cc "230 User logged in\r\n"; } elsif ($res =~ /TYPE (\w)/) { $type = $1; print $cc "200 Command okay.\r\n"; } elsif ($res =~ /PORT (\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) { $dport = ($5 << 8) + $6; $daddr = "$1.$2.$3.$4"; print $cc "200 Command okay.\r\n"; } elsif ($res =~ /STOR (.+)/) { my $filename = $1; open FILE, ">", $filename; print $cc "150 File status okay; about to open data connec +tion.\r\n"; my $dc = IO::Socket::INET->new(Proto => "tcp", PeerAddr => + $daddr, PeerPort => $dport, Reuse => 1); if ($type eq 'I') { binmode($dc); binmode(FILE); } my $data; while (read($dc, $data, 1024)) { syswrite(FILE, $data); } close(FILE); print $cc "226 Closing data connection, file transfer succ +essful\r\n"; close($dc); } elsif ($res =~ /RETR (.+)/) { my $filename = $1; if (open FILE, "<", $filename) { print $cc "150 File status okay; about to open data co +nnection.\r\n"; my $dc = IO::Socket::INET->new(Proto => "tcp", PeerAdd +r => $daddr, PeerPort => $dport, Reuse => 1); if ($type eq 'I') { binmode($dc); binmode(FILE); } my $data; while (read(FILE, $data, 1024)) { send($dc, $data, 0); } close(FILE); print $cc "226 Closing data connection, file transfer +successful\r\n"; close($dc); } else { print $cc "450 Requested file action not taken. File u +navailable.\r\n"; } } elsif ($res =~ /QUIT/) { close($cc); last; } else { } } }

Replies are listed 'Best First'.
Re: A simple FTP server
by Jaap (Curate) on Oct 18, 2004 at 09:56 UTC
    elsif ($res =~ /PASS (.+)/) { print $cc "230 User logged in\r\n"; }
    Not the best password protection i've ever seen ;-)
Re: A simple FTP server
by dubu (Initiate) on Oct 26, 2004 at 21:13 UTC
    It gives me more of an headache that this script allows to retrieve and (over)write any file on the server (as far as the FTP server process has the right to). ;-)
Re: A simple FTP server
by Anonymous Monk on Oct 06, 2014 at 17:38 UTC

    How to handle the <PASV> command in this code?