#!/usr/bin/perl # -*perl*- use Net::FTP; # # Copyright Andrew M. Bishop 1998-2007 # # Edit this line to set the name of the directory to mirror. $dir="/home/demon/www"; # Edit this line to set the name of the homepages server. $www="homepages.demon.co.uk"; # Edit this line to set wildcards for files not to mirror. @except=("PRIVATE","STATS","LOGS","~\$","#\$"); # The directory to mirror, the homepages server, the username, the password. $user=""; $pass=""; $demon=1; # Enables the Demon specific features # Parse the command line arguments. while ( $#ARGV >= 0 ) { $_=$ARGV[0]; switch: { $_ eq '-v' && do { $verbose=1; last switch;}; $_ eq '-vv' && do { $verbose=2; last switch;}; $_ eq '-s' && do { shift; $www=$ARGV[0]; last switch;}; $_ eq '-d' && do { shift; $dir=$ARGV[0]; last switch;}; $_ eq '-u' && do { shift; $user=$ARGV[0]; last switch;}; $_ eq '-p' && do { shift; $pass=$ARGV[0]; last switch;}; } shift; } $dir || die "No directory specified, use '-d directory'\n"; $www || die "No web server host specified, use '-s server'\n"; $user || die "No username specified, use '-u username'\n"; $pass || die "No password specified, use '-p password'\n"; # # Set up things # chdir $dir || die "Cannot change to $dir\n"; select STDOUT; $|=1; # # Find all of the files here # @here=(); @new=(); `touch -t 010100001970 ls-lR` if(!-f "ls-lR"); $lasttime=(stat("ls-lR"))[9]; open(FIND,"find . -print|") || die "Cannot execute find\n"; while() { chop; next if($_ eq "."); next if($_ eq "./count.txt"); next if($_ eq "./count.new"); next if($_ eq "./count.log"); next if($_ eq "./ls-lR"); $skip=0; foreach $except (@except) { $skip=1 if(/$except/); } next if($skip); push(@here,substr($_,2)); if(-f $_) { $thistime=(stat($_))[9]; push(@new,substr($_,2)) if($thistime>$lasttime); } } close(FIND); @here=sort(@here); @new=sort(@new); # # Find all of the files there # @there=(); open(LS,"ls-lR"); $dir="."; while() { chop; @fields=split(/ +/); chop($dir=$_) if($#fields==0); next if($#fields<7); $file=$fields[$#fields]; next if($file eq "." || $file eq ".."); next if($file eq "count.txt"); next if($file eq "ls-lR"); if(substr("$dir/",0,2) eq "./") { push(@there,substr("$dir/$file",2)); } else { push(@there,"$dir/$file"); } } close(LS); @there=sort(@there); # # Connect to the FTP server and send the commands # $ftp=Net::FTP->new($www,Debug=>($verbose>1),Passive=>1) || die "Cannot connect to $www ; $@\n"; $ftp->login($user,$pass) || die "Cannot login ; ".$ftp->message; $ftp->binary() || die "Cannot set binary mode ; ".$ftp->message; if($demon) { $ftp->cwd("docroot") || die "Cannot change to 'docroot' ; ".$ftp->message; } ($heren,$theren,$newn)=(0,0,0); while($heren<=$#here || $theren<=$#there) { if($theren<=$#there && ($heren>$#here || $there[$theren] lt $here[$heren])) { print "Deleting $there[$theren]\n" if($verbose>=1); $ftp->delete($there[$theren]) || $ftp->rmdir($there[$theren]); $theren++; } elsif($heren<=$#here && ($theren>$#there || $there[$theren] gt $here[$heren])) { if(-f $here[$heren]) { print "Putting $here[$heren]\n" if($verbose>=1); $ftp->put($here[$heren],$here[$heren]) || die "Cannot put file '$here[$heren]' ; ".$ftp->message; } elsif(-d $here[$heren]) { print "Creating $here[$heren]\n" if($verbose>=1); $ftp->mkdir($here[$heren]) || die "Cannot put create directory '$here[$heren]' ; ".$ftp->message; } $newn++ if($here[$heren] eq $new[$newn]); $heren++; } elsif($here[$heren] eq $new[$newn]) { print "Updating $here[$heren]\n" if($verbose>=1); $ftp->put($here[$heren],$here[$heren]) || die "Cannot put file '$here[$heren]' ; ".$ftp->message; $newn++; $theren++ if($here[$heren] eq $there[$theren]); $heren++; } else { $heren++; $theren++; } } # # Get the recursive directory listing # print "Generating ls-lR\n" if($verbose>=1); @ls_lR=($ftp->dir("-lR")); open(LS_LR,">ls-lR"); foreach $line (@ls_lR) { print LS_LR "$line\n"; } close(LS_LR); # # Get the counter # if($demon) { print "Getting counter\n" if($verbose>=1); $ftp->get("count.txt") || die "Cannot get file 'count.txt' ; ".$ftp->message; if (-f "count.new") { print "Putting counter\n" if($verbose>=1); $ftp->put("count.new","count.txt") || die "Cannot put file 'count.new' ; ".$ftp->message; } } # # Get the logs # if($demon) { (undef,undef,undef,undef,$uid,$gid,undef)=stat("."); if(! -d "LOGS") { mkdir "LOGS" ; chown $uid,$gid,"LOGS"; } print "Getting log files\n" if($verbose>=1); chdir "LOGS"; $ftp->cwd("../logs") || die "Cannot change to '../logs' ; ".$ftp->message; @logs=($ftp->ls()); foreach $log (@logs) { if(! -f $log && $log ne "today") { print "Getting log file '$log'\n" if($verbose>=1); $ftp->get($log); chown $uid,$gid,$log; } } chdir ".."; } # # Get the stats # if($demon) { (undef,undef,undef,undef,$uid,$gid,undef)=stat("."); if(! -d "STATS") { mkdir "STATS" ; chown $uid,$gid,"STATS"; } print "Getting statistics\n" if($verbose>=1); chdir "STATS"; $ftp->cwd("../stats") || die "Cannot change to '../stats' ; ".$ftp->message; @stats=($ftp->ls()); foreach $stat (@stats) { if($stat =~ m/\.png/) { $remotemtime=$ftp->mdtm($stat); $localmtime=(stat($stat))[9]; if(!$localmtime || $remotemtime>$localmtime) { print "Getting stat file '$stat'\n" if($verbose>=1); $ftp->get($stat); chown $uid,$gid,$stat; } } } chdir ".."; } $ftp->quit(); # # Log the results. # # Used space open(LS,"ls-lR"); $bytes=0; while() { chop; @fields=split(/ +/); next if($#fields<7); next if($fields[$#fields] eq "." || $fields[$#fields] eq ".."); $bytes+=$fields[4]; } close(LS); printf "\nUsed %d kB of allowance.\n",int(0.5+$bytes/1024) if($verbose); # Counter if($demon) { if(open(COUNT,") { ($then,$numthen)=split(/ +/); } close(LOG); } $now=time; $numnow=; $numnew=$numnow-$numthen; $numnew=$numnow if($numnew<0); $elapsed=$now-$then; $rate=$numnew*86400/$elapsed; open(LOG,">>count.log"); printf(LOG "%8d %5d %4d %s",$now,$numnow,$numnew,&ctime($now)); close(LOG); printf "\nThere have been %d extra hits on the homepage (total %d), %4.1f per day.\n",$numnew,$numnow,$rate if($verbose); close(COUNT); unlink "count.txt"; } unlink "count.new" if( -f "count.new"); } ##################### #### Subroutines #### ##################### # # ctime : A subroutine to convert time to ctime format. # # Argument: # time : The time # # Return Value: # date : A string containing the date in ctime format. # sub ctime { local($time) = @_; local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($time); local(@day) = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); local(@month)= ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); local(@d2) = ('00' .. '60'); $day[$wday].' '.$month[$mon].' '.$d2[$mday].' '.$d2[$hour].':'.$d2[$min].':'.$d2[$sec].' '.($year+1900)."\n"; }