sub decode { my $class = shift; my($data) = @_; my $self = {};
my $cmdhead = 0; my $cmdtail = 0; my @parts = (); my $cmdcount = 0; my $returnindex = 0; my $data_len = length($data);
# 如果数据长度过短则不处理 if ($data_len >= 4) { # 一个包里的FTP命令个数 $self->{cmdcount} = 0; # 搜索回车,之前认为是一个命令行,需要注意的是一个包里可能包含多个FTP命令 while ( (($returnindex = index ($data,"\x0a",$cmdhead)) >=0) || (($returnindex < 0) && (($data_len - $cmdhead) >= 4))) { # 调整一个命令行串尾指针 if ($returnindex < 0) { $cmdtail = $data_len -1; } else { $cmdtail = $returnindex; }
if ((my $cmdlen = ($cmdtail - $cmdhead + 1)) >= 4) { # 取出命令行串 my $cmdline = substr($data,$cmdhead,$cmdlen); # 从命令行里拆分出命令名和它的参数串 if (splitcmd($cmdline,\@parts)) { $self->{cmdcount}++; my $cmdindex = "cmd"."$self->{cmdcount}"; my $paraindex = "para"."$self->{cmdcount}"; # 记录到要返回到主程序的对象 $self->{$cmdindex} = $parts[0]; $self->{$paraindex} = $parts[1]; } } # 调整命令行串头指针 $cmdhead = $cmdtail + 1; }
# 如果命令个数大于0,则说明解码是有效的 if ($self->{cmdcount} == 0) { $self->{valid} = 0; } else { $self->{valid} = 1; }
} else { $self->{valid} = 0; }
# 返回对象
bless($self, $class); return $self; }
sub splitcmd { my ($cmdline,$parts) = @_;
# 去除行尾的回车 chomp($cmdline); # 用正则表达式抽取出命令名字和参数,既然效率不是考虑的主要问题就“毫无顾忌”地使用正则表达式,因为方便 if ($cmdline =~ m/^\s*([a-zA-Z]{3,4})\s+(.*)/) { my $valid_cmd = 0; # 检查抽出来的命令名字是否是一个已知的合法FTP命令 for (my $i=0;$i<@ftp_cmds;$i++) { if ($ftp_cmds[$i] eq uc($1)) { $valid_cmd = 1; last; } } # 如果是合法的命令则返回给调用函数 if ($valid_cmd) { ${$parts}[0] = $1; ${$parts}[1] = $2; return 1; } else { return 0; }
} else { return 0; } }
# # Module initialisation #
1;
# autoloaded methods go after the END token (&& pod) below
__END__
|