タイトル | : Re^2: ftpサーバからcsvファイルをダウンロードしたいのですが・・・ |
記事No | : 8344 |
投稿日 | : 2012/02/25(Sat) 10:08 |
投稿者 | : km |
すみません、ソースをコピペします。
#!/usr/bin/perl --
# ftpget.pl - FTPクライアント(GET) # 2012/02/20 作成 # perl ftpget.cgi FTPサーバー ユーザー名 パスワード パス # タイプはバイナリーに固定
# 以下の変数を使う為、Socket定義、TCP定義をしなければならない use Socket; use TCP;
# コマンドラインの引数 shiftを使って手入力するのが本来のソースだが、 # 2012/2/21 仕様変更 最初から入力済みにする $HostName = '*********************'; $Usre = '**********'; $Pass = **************; #$Path = '*******************************'; $Path = '***********************';
# パスをディレクトリとファイル名に分ける $Path =~ /[^\\\/]+$/; $File = $&; ($Dir = $') =~ s/[\\\/]$//; print "$Path\n"; print "$File\n"; print "$Dir\n";
# 保存するファイルをオープン open(FILE,">$File") or die("$Fileがオープンできません"); binmode(FILE);
# 指定されたホストのFTPポートに接続する TcpConnect(ControlSock,$HostName,'ftp') or die("$TCP::Error:$!\n"); # ソケットへの出力はバッファリングしない select(ControlSock); $| = 1; select(STDOUT); print "Connect to $HostName\n";
# ローカルアドレスを得る ($MyPort,$MyAddr) = sockaddr_in(getsockname(ControlSock)); # PORTコマンド用文字列にする $PortStr = sprintf("%d, %d, %d, %d, %d, %d", unpack("C4",$MyAddr), unpack("C2",pack("n",$MyPort))); # listenするソケットをオープン # SO_REUSEADDRオプションは同じローカルアドレスで複数接続できるようにする TcpListen(ListenSock,$Myport,$MyAddr,5,SO_REUSEADDR) or die("$TCP::Error : $!\n");
$error = 0; USESOCK: { &ReceiveCode == 220 or $error = 1,last; &SendString("USER $User\n"); &ReceiveCode == 331 or $error = 1,last; &SendString("PASS $Pass\n"); &ReceiveCode == 230 or $error = 1,last; if ( $Dir ne '' ) { &SendString("CWD $Dir\n"); &ReceiveCode == 250 or $error = 1,last; } &SendString("TYPE I\n"); &ReceiveCode == 200 or $error = 1,last; &SendString("PORT $PortStr\n"); &ReceiveCode == 200 or $error = 1,last; &SendString("RETR $File\n"); &ReceiveCode == 150 or $error = 1,last; # サーバーからデータ接続を受ける $sockaddr = accept(DataSock, ListenSock); # listenソケットはもう不要なので閉じる close(ListenSock); # リモートのアドレスからポート番号、IPアドレス、ホスト名を得る { my($port,$ipaddr) = sockaddr_in($sockaddr); my $name = gethostbyaddr($ipaddr,AF_INET); $ipaddr = inet_ntoa($ipaddr); print "$name($ipaddr)のポート番号$portから接続\n"; } $writeerror = 0; print "$Fileの転送開始\n"; while( read(DataSock, $buf, 1000) ) { print FILE $buf or $writeerror = 1,last; } close(FILE); close(DataSock); if( $writeerror ) { print "$Fileの書き込みエラーで転送中断\n"; } else { print "$Fileの転送終了\n"; } &ReceiveCode == 226 or $error = 1,last; # 終了 &SendString("QUIT\n"); &ReceiveCode == 221 or $error = 1,last; } # end USESOCK: if ( $error ) { print STDERR "$0中断:応答コード$ReceiveCodeのため\n";} close(controlSock); exit; # end
# 文字列を送信、標準出力にも sub SendString { local($_) = @_; print; # 行末はCR+CFにして送る s/([^\r])\n/$1\r\n/g; print ControlSock; } # end SendString
# 応答コードを得る sub ReceiveCode { my $line; $ReceiveCode = 0; while( $line = <ControlSock> ) { print $line; # 応答コード+スペース で始まるならそれで応答は終わり if( $line =~ /^(\d+) / ) { $ReceiveCode = $1; last; } } $ReceiveCode; } # end ReciveCode
# end ftpget.pl
|