/Anton.Dobrov/Perl/perlTask/ftp-client/Manage_ftp.pm
http://usu-wtf.googlecode.com/ · Perl · 267 lines · 262 code · 4 blank · 1 comment · 19 complexity · 8d9147f4f47fc9a88af39770edcf17b3 MD5 · raw file
- #!/usr/bin/perl
-
- sub open_connection
- {
- return "exist" if ($REMOTE_SOCK);
- my $paddr = inet_aton($_[0]);
- socket REMOTE_SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp') or die "Cannot create socket\n";
- connect REMOTE_SOCK, sockaddr_in(21, $paddr) or die "Cannot connect to server '$_[0]'\n";
- $REMOTE_SOCK = 1;
- $server_name = $_[0];
- my $str = listen_sock(*REMOTE_SOCK, $mode{'-T'});
- if ($str =~ /^404/)
- {
- print $str if $mode{'-v'};
- print " Server is hidden or simply offended at all.\n If you want to know what really happened,\n run the program without a parameter '-v'\n" unless $mode{'-v'};
- exit;
- }
- print $str if $mode{'-v'};
- if ($mode{'-a'})
- {
- send REMOTE_SOCK, "USER anonymous".$EOL, 0;
- send REMOTE_SOCK, "PASS Password".$EOL, 0;
- }
- else
- {
- print "User: " unless $mode{'-X'};
- $str = <STDIN>;
- chomp $str;
- send REMOTE_SOCK, "USER $str".$EOL, 0;
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- print "Password: " unless $mode{'-X'};
- if ($mode{'-X'})
- {
- $str = <STDIN>;
- }
- else
- {
- ReadMode 2, STDIN;
- $str = ReadLine(0);
- ReadMode 0;
- print "\n";
- }
- chomp $str;
- send REMOTE_SOCK, "PASS $str".$EOL, 0;
- }
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- feat();
- send REMOTE_SOCK, "OPTS UTF8 ON".$EOL, 0 if $feat{'UTF8'};
- send REMOTE_SOCK, "TYPE I".$EOL, 0;
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- listen_sock(*REMOTE_SOCK, $mode{'-T'}) unless $mode{'-v'};
- return 1;
- }
-
- sub user
- {
- return "no_connect" unless $REMOTE_SOCK;
- chomp $_[0];
- send REMOTE_SOCK, "USER $_[0]".$EOL, 0;
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- print "Password: " unless $mode{'-X'};
- if ($mode{'-X'})
- {
- $str = <STDIN>;
- }
- else
- {
- ReadMode 2, STDIN;
- $str = ReadLine(0);
- ReadMode 0;
- print "\n";
- }
- chomp $str;
- send REMOTE_SOCK, "PASS $str".$EOL, 0;
- send REMOTE_SOCK, "OPTS UTF8 ON".$EOL, 0 if $feat{'UTF8'};
- send REMOTE_SOCK, "TYPE I".$EOL, 0;
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- listen_sock(*REMOTE_SOCK, $mode{'-T'}) unless $mode{'-v'};
- return 1;
- }
-
- sub ls
- {
- return "no_connect" unless $REMOTE_SOCK;
- my ($ip, $port) = get_pasv();
- return 1 if ($ip == 530);
- my $paddr = inet_aton($ip);
- socket LIST_SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp') or die "Cannot create socket\n";
- connect LIST_SOCK, sockaddr_in($port, $paddr) or die "Cannot connect to server '$ip'\n";
- send REMOTE_SOCK, "$_[0]".$EOL, 0;
- if ($mode{'-v'})
- {
- print listen_sock(*LIST_SOCK, $mode{'-T'});
- }
- else
- {
- my $ls = listen_sock(*LIST_SOCK, $mode{'-T'});
- print "$_\n", grep {$_ !~ /^[0-9]{3} /} (split /(\n)|(\r\n)/, $ls);
- }
- shutdown LIST_SOCK, 2;
- return 1;
- }
-
- sub mv
- {
- $_[0] =~ /('|"|)?(.*?)\1 ('|"|)?(.*?)\3/g;
- my ($param1, $param2) = ($2, $4);
- return "no_connect" unless REMOTE_SOCK;
- send REMOTE_SOCK, "RNFR $param1".$EOL, 0;
- send REMOTE_SOCK, "RNTO $param2".$EOL, 0;
- return 1;
- }
-
- sub size
- {
- return "no_connect" unless REMOTE_SOCK;
- return "This command is not supported by server\n" unless $feat{'SIZE'};
- my $flag = 0;
- /()/;
- $flag = shift if ($_[0] =~ /^-h (.*)/);
- send REMOTE_SOCK, "SIZE @{_}${1}".$EOL, 0;
- my $str = listen_sock(*REMOTE_SOCK, $mode{'-T'});
- $str =~ /([0-9]{3}) ([0-9]*)/;
- if ($1 != 213)
- {
- print $str if $mode{'-v'};
- return 1;
- }
- unless ($flag)
- {
- print $2, " B\n";
- return 1;
- }
- my $size = $2;
- my @units = ('B', 'KB', 'MB', 'GB', 'TB', 'PB');
- my $units = 0;
- while ($size >= 1024 && $units < 5)
- {
- $size /= 1024;
- $units++;
- }
- print '', (sprintf "%.2f", $size), " $units[$units]\n";
- return 1;
- }
-
- sub simple_manipulation
- {
- return "no_connect" unless $REMOTE_SOCK;
- my $todo = shift;
- send REMOTE_SOCK, "$todo @_".$EOL, 0;
- return 1;
- }
-
- sub disconnect
- {
- return "no_connect" unless $REMOTE_SOCK;
- send REMOTE_SOCK, "QUIT".$EOL, 0;
- print listen_sock(*REMOTE_SOCK, $mode{'-T'}) if $mode{'-v'};
- shutdown REMOTE_SOCK, 2;
- $REMOTE_SOCK = 0;
- return 1;
- }
-
- sub get_pasv
- {
- return "no_connect" unless $REMOTE_SOCK;
- send REMOTE_SOCK, "PASV".$EOL, 0;
- while (1)
- {
- my $str = listen_sock(*REMOTE_SOCK, $mode{'-T'});
- return 1 if $str =~ /530/;
- print $str if $mode{'-v'};
- return ("$1.$2.$3.$4", ($5*256+$6)) if $str =~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/;
- }
- }
-
- sub feat
- {
- return "no_connect" unless $REMOTE_SOCK;
- send REMOTE_SOCK, "FEAT".$EOL, 0;
- my $str = listen_sock(*REMOTE_SOCK, $mode{'-T'});
- $feat{$_} = 1 foreach (grep {/(SIZE)|(UTF8)/} (split " ", $str));
-
- return 1;
- }
-
- sub listen_sock
- {
- local *SOURCE = $_[0];
- my $timeout = $_[1];
- my ($buf, $res, $write_command, $rin, $rout) = ('defined :)', '');
- vec ($rin, fileno(SOURCE), 1) = 1;
- while ($buf ne '')
- {
- my $nfound = select($rout = $rin, '', '', $timeout);
- die 'Select() error' if ($nfound == -1);
- last if ($nfound == 0);
- die 'Recv() error' if (!defined(recv SOURCE, $buf, 512, 0)); #kakyato error
- $res .= $buf;
- }
- return $res;
- }
-
- sub listen_sock_for_file
- {
- local (*SOURCE, *DEST) = ($_[0], $_[1]);
- my $timeout = $_[2];
- my ($buf, $write_command, $rin, $rout) = ('defined :)');
- vec ($rin, fileno(SOURCE), 1) = 1;
- while ($buf ne '')
- {
- my $nfound = select($rout = $rin, '', '', $timeout);
- die 'Select() error' if ($nfound == -1);
- last if ($nfound == 0);
- die 'Recv() error' if (!defined(recv SOURCE, $buf, 512, 0));
- print DEST $buf;
- }
- }
-
- sub help
- {
- my $param = lc shift;
- my %help =
- (
- 'open' => "Connect to remote tftp",
- 'ls' => "List contents of remote directory",
- 'dir' => "List contents of remote directory (extended)",
- 'send' => "Send one file",
- 'recv' => "Receive file",
- 'cd' => "Change remote working directory",
- 'pwd' => "Print working directory on remote machine",
- 'user' => "Send new user information",
- 'mv' => "Rename file; file name with spaces must be quoted",
- 'rm' => "Delete remote file",
- 'mkdir' => "Make directory on the remote machine",
- 'rmdir' => "Remove directory on the remote machine",
- 'disconnect' => "Terminate ftp session",
- 'size' => "Returns size of file; type 'size -h' for human-readable format",
- 'quit' => "Terminate ftp session and exit"
- );
- if ($param)
- {
- print "$param\t\t$help{$param}\n" if $help{$param};
- print "Unknown command\n" unless $help{$param};
- }
- else
- {
- print "$_\t" foreach (sort keys %help);
- print "\n";
- }
- return 1;
- }
-
- sub usage_ftp
- {
- print "Transfers files to and from a computer running an FTP server service.\n\n";
- print "FTP [-h] [-v] [-a] [-T time] [-X filename] [host]\n\n";
- print " -h\t\tPrint this help and exit.\n";
- print " -a\t\tlogin as anonymous.\n";
- print " -v\t\tSuppresses display of remote server responses.\n";
- print " -T time\tSet how long to wait for a response from the server;\n\t\ttime in seconds.\n";
- print " -X filename\tSpecifies a text file containing FTP commands; the commands\n\t\twill automatically run after FTP starts.\n";
- print " host\t\tSpecifies the host name or IP address of the remote host\n\t\tto connect to.\n";
- return 1;
- }
-
- 1;