#!/usr/local/bin/perl -w # $Id: ftp-client-2.pl,v 1.2 2002/02/05 17:53:09 68user Exp $ use Socket; # Socketモジュールを使う $hostname = 'localhost'; $username = 'zxr400'; $password = ''; #---------- コマンドコネクションを作成 ----------------- # FTP プロトコルを使う $port = getservbyname('ftp', 'tcp'); # ホスト名を、IPアドレスの構造体に変換 $iaddr = inet_aton($hostname) || die "$hostname は存在しないホストです。$!"; # ポート番号と IP アドレスをまとめて構造体に変換 $sock_addr = pack_sockaddr_in($port, $iaddr); # ソケット生成 socket(COMMAND, PF_INET, SOCK_STREAM, 0) || die "ソケットを生成できません。$!"; # 指定のホストの指定のポートに接続 connect(COMMAND, $sock_addr) || die "$hostname のポート $port に接続できません。$!"; # ファイルハンドル COMMAND をバッファリングしない select(COMMAND); $|=1; select(STDOUT); #---------- ユーザ認証 --------------------------------- print COMMAND "USER $username\n"; print COMMAND "PASS $password\n"; #---------- データ用コネクションを作成 ----------------- # ソケット生成 socket(DATA_WAITING, PF_INET, SOCK_STREAM, 0) || die "ソケットを生成できません。$!"; # ソケットオプション設定 setsockopt(DATA_WAITING, SOL_SOCKET, SO_REUSEADDR, 1) || die "setsockoptでエラーが発生しました。$!"; # ソケットにアドレス(=名前)を割り付ける bind(DATA_WAITING, pack_sockaddr_in(0, INADDR_ANY)); || die "bind に失敗しました。$!"; # OSに、クライアントからの接続を受け入れるよう指示 listen(DATA_WAITING, SOMAXCONN) || die "listen できません。$!"; #---------- ローカルホストの IP アドレスを取得 --------------- $local_sock_addr = getsockname(COMMAND); ($tmp, $local_addr) = unpack_sockaddr_in($local_sock_addr); $local_ip = inet_ntoa($local_addr); # IPアドレス aaa.bbb.ccc.ddd を aaa,bbb,ccc,dddという形式に $local_ip =~ s/\./,/g; #---------- データコネクションのポート番号を取得 ------------- $local_sock_addr = getsockname(DATA_WAITING); ($data_port, $tmp) = unpack_sockaddr_in($local_sock_addr); #---------- PORT・LIST コマンドを送信 ------------------------- # FTP サーバに、データコネクションの IP アドレスとポートの情報を渡す printf COMMAND "PORT $local_ip,%d,%d\n" ,$data_port/256,$data_port%256; # ファイル一覧を送るよう要求 print COMMAND "LIST\n"; #---------- データコネクションを使って、データ受信 ----------- # FTP サーバ側からの接続を待つ accept(DATA, DATA_WAITING); # 送られてくるデータの内容を表示 while (){ print $_; } #---------- 終了処理 ---------------------------------------- # データ用コネクションclose close(DATA); close(DATA_WAITING); # QUITを送ってセッション終了 print COMMAND "QUIT\n"; close(COMMAND);