Due to needs in code synchronization between test machine and product machine,an ftp uploading program using Net::FTP module was developed.The Program Reads in a config file,parses host and file configuration to process ftp file uploading.
- #! /usr/bin/perl -w
- ##############################################################################################
- ##########FileName:ftp_put.pl
- ##########Usage:perl ftp_put.pl configFileName logFileName
- ##########Copyright (c) 2011.8-2011.9 Zhu Song.
- ##########All rights reserved.
- ##########This program is free software.
- ##########you can redistribute it and/or modify it under the same terms as Perl itself.
- ##############################################################################################
- use strict;
- use IO::File;
- use Net::FTP;
- use Data::Dumper;
- my $LOGFILE;
- my $CONFIGFILE;
- my $log_fh;
- my $config_fh;
- my %profile;
- my $ftp_ref;
- sub usage()
- {
- print STDOUT "Usage:perl ftp_put.pl configFileName logFileName\n";
- exit 1;
- }
- sub parseInput()
- {
- $CONFIGFILE = $ARGV[0];
- $LOGFILE = $ARGV[1];
- }
- sub initializeLogFile()
- {
- $LOGFILE or die "not initialized LOGFILE yet\n";
- my ($sec,$min,$hour,$day,$mon,$year,$isdist) = localtime;
- $LOGFILE = $LOGFILE."\.".($year + 1900).($mon + 1).($day + 1);
- }
- sub openLogFile()
- {
- $log_fh = IO::File->new($LOGFILE,"w") or die "can't open $LOGFILE to write\n";
- $log_fh->autoflush(1);
- }
- sub _log()
- {
- my $text = shift;
- $log_fh->write($text) or die "error happenned when writing logfile\n";
- }
- sub writeLog()
- {
- my $logText = shift;
- my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdist) = localtime;
- my $time = sprintf("[%04d-%02d-%02d %02d:%02d:%2d]",$year + 1900,$mon + 1,$day + 1,$hour,$min,$sec);
- &_log($time.$logText);
- }
- sub log_warn
- {
- &writeLog ( "[". __LINE__ ."] " ." @_");
- }
- sub log_die
- {
- &writeLog ( "[". __LINE__ ."] " ." @_");
- }
- sub checkHost
- {
- my $host_ref = shift;
- if( defined($host_ref->{'IP'}) && defined($host_ref->{'ACCOUNT'}) && defined($host_ref->{'PASSWORD'}) )
- {
- 1;
- }
- else
- {
- 0;
- }
- }
- sub loadConfig()
- {
- $config_fh = IO::File->new($CONFIGFILE,"r") or die "can't open configFile $CONFIGFILE to read:$!\n";
- my $host_flag = 0;
- my $file_flag = 0;
- my $task_count = 0;
- while(my $cfLine = <$config_fh>)
- {
- chomp($cfLine);
- #######如果输入行是空行或者输入行不以[或者 开头,读入下一行
- next if ($cfLine =~ m/^ *$/) || ( $cfLine !~ m/^\s+.*\S+/ && $cfLine !~ m/^[ \[]/);
- if( $cfLine =~ m/^\[HOST\]/ )
- {
- if ($host_flag == 1)
- {
- checkHost $profile{HOST} or die "host config initialization failed.\n";
- $host_flag = 0;
- }
- else
- {
- $host_flag = 1;
- }
- }
- elsif($cfLine =~ m/^ / && $host_flag == 1)
- {
- my ($host_key,$host_value) = split(/=/,$cfLine);
- $host_key =~ s/ *\[(\S+)\].*/$1/;
- $host_value =~ s/ *(\S+) */$1/;
- $profile{HOST}{$host_key} = $host_value;
- &writeLog("$host_key:$host_value\n");
- }
- elsif($cfLine =~ m/^ / && $file_flag == 1)
- {
- my ($file_key,$file_value) = split(/=/,$cfLine);
- $file_key =~ s/ *\[(\S+)\].*/$1/;
- $file_value =~ s/\s+//g;
- die "error while reading file config:\n" unless($file_key eq "PATH" or $file_key eq "FILELIST");
- if( $file_key eq "PATH" )
- {
- $task_count++;
- my ($source_dir,$remote_dir,$remote_bak) = split(/,/,$file_value);
- $profile{TASK}[$task_count - 1]{'SOURCEDIR'} = $source_dir;
- $profile{TASK}[$task_count - 1]{'REMOTEDIR'} = $remote_dir;
- $profile{TASK}[$task_count - 1]{'REMOTEBAK'} = $remote_bak;
- }
- elsif ($file_key eq "FILELIST" and defined(@{$profile{TASK}}[$task_count - 1]))
- {
- @{${${profile{TASK}}[$task_count - 1 ]}{'FILELIST'}} = split(/,/,$file_value);
- }
- else
- {
- print STDERR "file profile config error\n";
- }
- &writeLog("$file_key:$file_value\n");
- }
- elsif($cfLine =~ m/^\[FILE\]/)
- {
- if ($file_flag == 1)
- {
- $file_flag = 0;
- }
- else
- {
- $file_flag = 1;
- }
- }
- }
- }
- sub connectToFTP
- {
- $ftp_ref = Net::FTP->new($profile{HOST}->{'IP'}, Debug => 0) or die("Cannot connect to $profile{HOST}->{IP}: $@");
- $ftp_ref->login($profile{HOST}->{'ACCOUNT'},$profile{HOST}->{'PASSWORD'}) or die("Cannot login ".$ftp_ref->message);
- if(!$ftp_ref->binary)
- {
- &writeLog ( "[". __LINE__ ."] " .$ftp_ref->message);
- }
- &writeLog("successfully login to host $profile{HOST}->{'IP'}\taccount:$profile{HOST}->{'ACCOUNT'}\n");
- }
- sub remote_backup()
- {
- my($remote_directory,$remote_backup,$file_ref) = @_;
- $ftp_ref->cwd($remote_directory) or die("can't change remote working directory to $remote_directory\n");
- foreach my $file(@{$file_ref})
- {
- if(!$ftp_ref->rename($file,$remote_backup."/".$file))
- {
- &writeLog("[". __LINE__ ."] ",$ftp_ref->message);
- next;
- }
- else
- {
- &writeLog("successfully rename $file to $remote_backup/$file remotely\n");
- }
- }
- &writeLog("remote backup done\n");
- }
- sub put_files()
- {
- my($source_dir,$remote_directory,$remote_backup,$file_ref) = @_;
- chdir($source_dir) or die("can't change local working directory to $source_dir\n");
- $ftp_ref->cwd($remote_directory) or die("can't change remote working directory to $remote_directory\n");
- foreach my $file(@{$file_ref})
- {
- if(!$ftp_ref->put($file,$remote_directory."/".$file))
- {
- &writeLog("[". __LINE__ ."] ",$ftp_ref->message);
- next;
- }
- else
- {
- &writeLog("successfully put localfile $file to remote host $remote_directory/$file\n");
- }
- }
-
- }
- sub disconnectFromFTP()
- {
- $ftp_ref->quit;
- &writeLog("ftp_put has done,disconnected from remote host:$profile{HOST}->{'IP'}\n");
- }
- sub proc_ftp
- {
- foreach my $task_ref(@{$profile{TASK}})
- {
- my $source_dir = $task_ref->{'SOURCEDIR'};
- my $remote_dir = $task_ref->{'REMOTEDIR'};
- my $remote_bak = $task_ref->{'REMOTEBAK'};
- my $fileList_ref = $task_ref->{'FILELIST'};
- &remote_backup($remote_dir,$remote_bak,$fileList_ref);
- &put_files($source_dir,$remote_dir,$remote_bak,$fileList_ref);
- }
- }
- sub sendfile()
- {
- &connectToFTP;
- &proc_ftp;
- &disconnectFromFTP;
- }
- usage if @ARGV != 2;
- parseInput;
- initializeLogFile;
- openLogFile;
- loadConfig;
- $SIG{__WARN__} = \&log_warn;
- $SIG{__DIE__} = \&log_die;
- print Dumper(\%profile);
- &sendfile;
config文件配置如下:
- [HOST]
- [IP] = 135.100.101.88
- [ACCOUNT]= billapp1
- [PASSWORD] = billapp1
- [HOST]
- [FILE]
- [PATH] = /billapp1/appcj/songwolf/test,/billapp1/appcj/aioss/datafile/datafile/bak,/billapp1/appcj/aioss/datafile/datafile/baktest
- [FILELIST] = test.c,test1.c,test2.c
- [PATH] = /billapp1/appcj/songwolf/test/awk,/billapp1/appcj/aioss/datafile/datafile/bak,/billapp1/appcj/aioss/datafile/datafile/baktest
- [FILELIST] = jieduan.sh,student.sh
- [FILE]
总结:
1.autovivification is very useful when dealing with programs that need to parse config file
2.this uploading program need to be improved to have system independence and more convinient usage
of config file.so,to be continued.....
阅读(1619) | 评论(1) | 转发(0) |