#!/usr/bin/perl # 引数1に実行したいホストのIPアドレス # 引数2に実行したいユーザ名(例: postmaster) # 引数3に実行したいユーザのパスワード # 引数4に実行したいCLIコマンド use strict; use Socket; use FileHandle; my ($con_host, $con_port); my ($ip, $sockaddr); my ($arg, $buf, $ret, $len); my ($user, $password,$cli_cmd); my ($errCode,$idCounter,@responses,$debug); my ($snd_cmd,$rin,$rcv,$ret_code); my ($chr01,$chr02); my ($timeout); ################# postmaster の設定 ############### # $user = 'postmaster'; # $password = 'abcdefg'; ################# 接続先の設定 #################### # $con_host = '172.20.100.100'; $con_port = 106; $timeout = 30; my ($debug); #$debug = "YES"; $debug = "NO"; ($arg) = @ARGV; $con_host=$ARGV[0]; $user=$ARGV[1]; $password=$ARGV[2]; $cli_cmd=$ARGV[3]; # ソケットの生成 $ip = inet_aton($con_host) || die "host($con_host) not found.\n"; $sockaddr = pack_sockaddr_in($con_port, $ip); socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die "socket error.\n"; # ソケットの接続 connect(SOCKET, $sockaddr) || die "connect $con_host $con_port error.\n"; autoflush SOCKET (1); #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; # 接続時の受信 recv(SOCKET,$rcv,1000,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 3); if ($ret_code eq "200") { }else{ close(SOCKET); die "PWD READY ERROR.\n"; } # ユーザ名送信 $snd_cmd="USER $user\0"; if ( $debug eq "YES" ){ printf "Send:%s\n",$snd_cmd; } send(SOCKET,$snd_cmd,0); #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; #受信 recv(SOCKET,$rcv,1000,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 3); if ($ret_code eq "300") { }else{ close(SOCKET); die "USER send ERROR.\n"; } # パスワード送信 $snd_cmd="PASS $password\0"; if ( $debug eq "YES" ){ printf "Send:%s\n",$snd_cmd; } send(SOCKET,$snd_cmd,0); #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; #受信 recv(SOCKET,$rcv,1000,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 3); if ($ret_code eq "200") { }else{ close(SOCKET); die "USER or PASS ERROR.\n"; } # コマンド送信 $snd_cmd="$cli_cmd\0"; if ( $debug eq "YES" ){ printf "Send:%s\n",$snd_cmd; } send(SOCKET,$snd_cmd,0); #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; # 出足の5文字受信 recv(SOCKET,$rcv,5,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 5); if ($ret_code eq "200 O") { # 200 OKで完結する場合 #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; #受信 recv(SOCKET,$rcv,1000,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 1); if ($ret_code eq "K") { printf "200 OK\n"; }else{ close(SOCKET); die "USER or PASS ERROR.\n"; } }elsif ($ret_code eq "200 d") { # data followがある場合 for (;;) { #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; # この行の改行までスキップ recv(SOCKET,$rcv,1,0); if ( $rcv eq "\n" ){ last; } } $chr01=""; $chr02=""; for(;;) { #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; recv(SOCKET,$rcv,1,0); printf "%s",$rcv; $chr01=$chr02; $chr02=substr($rcv, 0, 1); if ( $chr01 eq "\r" ){ if ( $chr02 eq "\n" ){ last; } } } }else{ close(SOCKET); die "COMMAND ERROR.\n"; } # QUIT送信 $snd_cmd="QUIT\0"; if ( $debug eq "YES" ){ printf "Send:%s\n",$snd_cmd; } send(SOCKET,$snd_cmd,0); #タイムアウト処理 $rin = ''; vec($rin,fileno(SOCKET),1) = 1; select($rin, undef, undef, $timeout) or die "Request timeout.\n"; #受信 recv(SOCKET,$rcv,1000,0); if ( $debug eq "YES" ){ printf "Recv:%s\n",$rcv; } $ret_code=substr($rcv, 0, 3); if ($ret_code eq "200") { }else{ close(SOCKET); die "QUIT ERROR.\n"; } close(SOCKET); exit;