Hi all, thanks for all expert. I try to coded the program, not a bug-free program. I have tested in few days and it is workable in my case. However, it seems take long time when "MD5" big file.
config file
# ver_check.cfg
path=/var/www
master=master
current=current
log=version_check.log
code file
# version_check.pl
#! perl -w
# Not a bug-free program
use Digest::MD5;
# _______________________________
# / /
# / Generate List Variablea /
# /______________________________/
my $flag1=1;
my $flag2=0;
my %filelist = ();
my %md5 = ();
my $current_path = $_;
my $path = $_;
my $filename = $_;
# _______________________________
# / /
# / Compare Lists Variablea /
# /_____________________________ /
my $masterfile=$currentfile=$_;
my %a=();
my %b=();
#==================================
if($#ARGV > -1){
foreach (@ARGV){
if (/\-file\:(\w.*)/){
$filename = $1;
chomp($filename);
GENLIST();
}elsif(/\-comp$/){
COMPARE();
#}elsif(/\-log\:(\w.*)/){
# my $logfile = $1;
# LOG($logfile);
}elsif(/\-v$/){
VERBOSE();
}else{
print "option: $ARGV[0]\n";
OPTION();
}
}
}else{
OPTION();
}
# Generate a list
sub GENLIST{
open(CONF, "ver_check.cfg");
while(<CONF>){
if (/path\=(.*)$/){
$path = $1;
}
}
close(CONF);
open (LIST, "ls -lAR $path|");
while(<LIST>){
if(($flag1==0) && (/^$/)){
$flag1++;
$flag2=0;
}elsif(($flag1==1) && (/(.*)\:$/)){
$flag1=0;
$flag2=1;
$current_path = $1;
}elsif(($flag2==1) && (/^(([dsrwx\-]{10})\s*(\d{1,})\s
+*([\w\-]*)\s*([\w\-]*)\s*(\d*)\s*([\w\s\:]{1,12}))\s*(\w
.*)$/)){
#$1=whole line b4 filename $2=permission $4,$5=user\gr
+oup name $8=filename
#drwxr-xr-x 2 root root 4096 Oct 23 20
+03 cgi-bin
my $desc = $1;
my $filename = $8;
my $key = "$current_path/$filename"; ## base
+ on which system
if($desc!~/^d/){
my $x = MD5("$key");
$desc = "$desc\&$x";
}
$filelist{$key} = $desc;
}
}
close(LIST);
open(OUTPUT, "> $filename");
foreach (keys %filelist){
print OUTPUT "$_|$filelist{$_}\n";
}
close(OUTPUT);
} # end of GENLIST
sub OPTION{
print "Wrong\/missing operation!\n\n";
print "You should write in this way\:\n";
print "\t\-file\:\[file\]\tCreate file list follow by the file
+ name\n";
print "\n";
exit;
} # end of OPTION
sub MD5{
my $file = $_[0];
my $md5code;
open(FILE, $file) or die "Can't open '$file': $!";
binmode(FILE);
$md5 = Digest::MD5->new;
while (<FILE>) {
$md5->add($_);
}
close(FILE);
$md5code = $md5->b64digest;
$md5{$file} = $md5code;
return $md5code;
} # end of MD5
######## Comparison part
sub COMPARE{
my @error = @_;
open(CONF, "ver_check.cfg");
while(<CONF>){
if(/^master\=(.*)$/){ $masterfile = $1};
if(/^current\=(.*)$/){ $currentfile = $1};
}
close(CONF);
%a=READIN("$masterfile");
%b=READIN("$currentfile");
foreach (keys %a){
if(!exists $b{$_}){
push(@error, "File/Dir deleted: $_\n")
}elsif($a{$_} eq $b{$_}){
delete $a{$_};
delete $b{$_};
}elsif($a{$_} ne $b{$_}){
$a{$_} =~ s/\&/ /;
$b{$_} =~ s/\&/ /;
push(@error, "File/Dir modified: $_\n$masterfi
+le : $a{$_}\n$currentfile : $b{$_}\n\n");
delete $a{$_};
delete $b{$_};
}
}
HASHSIZE_DECI(\%b, "current");
LOG(\@error);
} # end of COMPARE
sub READIN{
my $filename = $_[0];
my @temp=@_;
my %temphash=();
open(FILE, $filename);
while(<FILE>){
if(/\|/){
chomp($_);
@temp = split(/\|/,$_);
$temphash{$temp[0]}=$temp[1];
}
}
close(FILE);
return %temphash;
} # end of READIN
sub HASHSIZE_DECI{
my $temp = shift;
my $file = shift;
if((scalar (keys %$temp)) > 0){
foreach (keys %$temp){
if ($file eq "master"){
push(@error, "File/Dir deleted: $_\n")
}elsif($file eq "current"){
push(@error, "File/Dir added: $_\n")
}
}
}
} # end of HASHSIZE_DECI
sub LOG{
my $error = shift;
my $logfile = "";
open(CONF, "ver_check.cfg");
while(<CONF>){
if(/log\=(\w.*)/){ $logfile = $1}
}
close(CONF);
chomp($logfile);
if($logfile eq ""){
foreach (@$error){
print $_;
}
}else{
open(LOG, "> $logfile");
foreach (@$error){
print LOG $_
}
close(LOG);
}
}
sub VERBOSE{
}
I generate original list first
perl version_check.pl -file:master
then create a cron job
perl version_check.pl -file:current -comp
all log will save as version_check.log