タイトル | : Re^2: ftpサーバからcsvファイルをダウンロードしたいのですが・・・ |
投稿日 | : 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