HomeCodeschnipselupdate_server.pl 

update_server.pl

Weitersagen:

Dieses Perl-Skript lädt nur alle veränderten Dateien über FTP auf den Server hoch.

Perl-Code:
#!/usr/bin/perl -w

use strict;

use Digest::MD5;
use File::Find;
use Data::Dumper;
use Net::FTP;
use File::Temp;
use File::Basename;
use Term::ReadKey;

my $dir = "www"; # the directory
my $dir_replace = "felektro"; # how to replace $dir in remote path
my @exclude_regexp_list = (qr{/\.svn\b}, qr{~$}, qr{^#.*#$}, qr{\.sql$}, qr{\.pl$}, qr{\.pm$}, qr{\.log$}, qr{\.out$}, qr{\.txt$}, qr{\.svg$}, qr{\.dat$}, qr{\.xcf}); # a list of regexp that get excluded

my $host = "myhost.de"
my $username = "user123"
my $password = undef; # String or undef to ask everytime

my $filelistref; # to store the data

# File::Find provides a convenient way to process a directory recursively
find(sub {
  my $match = 0;
  my $regexp;
  # search thru exclude list
  foreach $regexp (@exclude_regexp_list) {
    if ($File::Find::name =~ $regexp) {
      $match = 1;
      last;
    }
  }
  if($match) {
    # exclude
    print "E: $File::Find::name\n";
  }
  else {
    $filelistref->{$File::Find::name} = {};
  }
}, $dir);

if(!defined $password) {
  print "password: ";
  ReadMode 2; # password
  $password = ReadLine(0);
  ReadMode 1; # normal
  chomp($password);
  print "\n";
}

# ftp connection
my $ftp = Net::FTP->new($host) or die "ftp connection failed, stopped at $!";
$ftp->login($username, $password) or die $!; # Hier Benutzername und Password eingeben
$ftp->binary;


my $attempt = 1;
my $attempt_file = "";
foreach my $file (sort keys %{$filelistref}) {
  # read and write cache file for every processed file
  my $cachefile = 'update_server_cache.dat';
  my $cache; # like $cache->{$file}->{'md5'}, $cache->{$file}->{'type'}
  if(-e $cachefile) {
    $cache = do ($cachefile) or die $!;
  }
  
  # create data structure
  if(-d $file) {
    print "D: " . $file . "\n";
    $filelistref->{$file}->{'type'} = 'directory';
    $filelistref->{$file}->{'md5'} = 'na';
  }
  else {
    my $md5 = Digest::MD5->new;
    open(FH, $file) or die $!;
    binmode(FH);
    $md5->addfile(*FH) or die $1;
    close(FH);
    $filelistref->{$file}->{'type'} = 'file';
    $filelistref->{$file}->{'md5'} = $md5->hexdigest;
    if ((defined $cache->{$file}->{'md5'}) and ($cache->{$file}->{'md5'} eq $filelistref->{$file}->{'md5'})) {
      print "S: " . $file . "\n";
    }
    else {
      if($attempt_file ne $file) {
        $attempt_file = $file;
        $attempt = 1;
      }
      else {
        $attempt++;
      }

      my ($fname, $fpath) = fileparse($file);
      $fpath =~ s|$dir/|$dir_replace/|;
      
      my $seconds = 20 + (-s $file)/40000;
      
      print "copy " . $file . " -> " . $fpath . $fname . " (" . $seconds . "s)\n";
      
      $ftp->mkdir($fpath, 1) or die "unable to create directory '$fpath', stopped at $!"; # 1 = recursive
      
      eval {
        local $SIG{ALRM} = sub { die "timeout" };
        alarm $seconds;
        $ftp->put($file, "$fpath/$fname");
        alarm 0;
      };
      if($@) {
        if($@ !~ /timeout/) {
          die $@;
        }
        undef $@;
        
        if($attempt < 3) {
          print "timed out (" . $seconds . "s)... retry (attempt " . ($attempt+1) . ")\n";
          
          undef $ftp;
          $ftp = Net::FTP->new($host) or die "ftp connection failed, stopped at $!";
          $ftp->login($username, $password) or die $!;
          $ftp->binary;
          
          redo;
        }
        else {
          die "timed out (" . $seconds . "s)... failed after " . $attempt . " attempts";
        }
      }

      $cache->{$file} = {
        'type' => 'file',
        'md5' => $filelistref->{$file}->{'md5'}
      };
    }
    # write cache file
    open(FH, ">" . $cachefile) or die $!;
    print FH "# generated by $0\n";
    print FH "# " . localtime() . "\n";
    print FH Dumper $cache;
    close FH;
  }
}

$ftp->quit;
Teile diese Seite!    RSS-Feed abonnieren:
RSS