summaryrefslogtreecommitdiff
path: root/rsync/rsync.driver
blob: 14dd3e5fbae57f746e80a62bc463718ac994fd84 (plain)
    1 #!/usr/bin/perl
    2 #
    3 # /etc/ports/drivers/rsync: rsync(1) driver script for ports(8)
    4 #
    5 
    6 use warnings;
    7 use strict;
    8 use File::Basename;
    9 
   10 my $host = '';
   11 my $collection = '';
   12 my $destination = '';
   13 my %new_checkouts;
   14 my %old_checkouts;
   15 
   16 sub error
   17 {
   18 	my $message = shift;
   19 	print "Error: $message ($!)\nUpdating failed\n";
   20 	exit 1;
   21 }
   22 
   23 sub warning
   24 {
   25 	my $message = shift;
   26 	print "Warning: $message ($!)\n";
   27 }
   28 
   29 if ($#ARGV < 0)
   30 {
   31 	print "Usage: $0 <file>\n";
   32 	exit 1;
   33 }
   34 
   35 open(FILE, $ARGV[0]) or error("Couldn't open $ARGV[0]");
   36 while (<FILE>)
   37 {
   38 	chomp;
   39 	if    (/^host=(.*)/)        { $host = $1; }
   40 	elsif (/^collection=(.*)/)  { $collection = $1; }
   41 	elsif (/^destination=(.*)/) { $destination = $1; }
   42 }
   43 close(FILE);
   44 
   45 if ($host eq '')        { error("Host field not set in $ARGV[0]");        }
   46 if ($collection eq '')  { error("Collection field not set in $ARGV[0]");  }
   47 if ($destination eq '') { error("Destination field not set in $ARGV[0]"); }
   48 
   49 if (-e "$destination/.checkouts")
   50 {
   51 	# read the old .checkouts file into memory
   52 	open(FILE, "$destination/.checkouts") or error("Couldn't read checkouts from $destination/.checkouts");
   53 	while (<FILE>)
   54 	{
   55 		chomp;
   56 		$old_checkouts{$_} = 1;
   57 	}
   58 	close(FILE);
   59 }
   60 
   61 print "Updating file list from " . $host . "::$collection\n";
   62 
   63 # get the remote file list (new .checkouts)
   64 open(PIPE, 'rsync -crz --no-human-readable ' . $host . '::' . $collection . '|') or error("Couldn't open pipe to rsync");
   65 while (<PIPE>)
   66 {
   67 	chomp;
   68 
   69 	next if /^MOTD:/;	# ignore MOTD lines
   70 	s/^(.{43})//;		# ignore the first 43 characters (mode, date etc...)
   71 	next if /^.$/;		# ignore the . directory
   72 
   73 	$new_checkouts{$_} = 1;
   74 }
   75 close(PIPE);
   76 error("Running rsync failed") unless $? == 0;
   77 
   78 print "Updating collection " . basename($destination) . "\n";
   79 
   80 # now really run rsync
   81 open(PIPE, 'rsync -crz --no-human-readable --log-format "%o %n" ' . $host . "::$collection $destination|") or error("Couldn't open pipe to rsync");
   82 while (<PIPE>)
   83 {
   84 	chomp;
   85 
   86 	if (/^recv (.*)/)
   87 	{
   88 		if ($old_checkouts{$1})
   89 		{
   90 			s/^recv/ Edit/;
   91 		}
   92 		else
   93 		{
   94 			s/^recv/ Checkout/;
   95 		}
   96 	}
   97 
   98 	print $_ . "\n";
   99 }
  100 close(PIPE);
  101 error("Running rsync failed") unless $? == 0;
  102 
  103 # save new checkouts into .checkouts
  104 open(FILE, ">$destination/.checkouts") or error("Couldn't save checkouts to $destination/.checkouts");
  105 foreach my $checkout (sort keys %new_checkouts)
  106 {
  107 	print FILE "$checkout\n";
  108 }
  109 close(FILE);
  110 
  111 # use chroot as an additional safety measure when removing files
  112 chroot($destination) or error("Couldn't chroot into $destination");
  113 chdir('/');
  114 
  115 # iterate through old checkouts, remove obsolete files
  116 foreach my $checkout (sort keys %old_checkouts)
  117 {
  118 	if (!$new_checkouts{$checkout})
  119 	{
  120 		if (-f $checkout)
  121 		{
  122 			print " Delete $checkout\n";
  123 			unlink($checkout) or warning("Couldn't delete $checkout");
  124 		}
  125 	}
  126 }
  127 
  128 # iterate through old checkouts, remove obsolete directories
  129 foreach my $checkout (sort keys %old_checkouts)
  130 {
  131 	if (!$new_checkouts{$checkout})
  132 	{
  133 		if (-d $checkout)
  134 		{
  135 			print " Delete $checkout\n";
  136 			rmdir($checkout) or warning("Couldn't delete $checkout");
  137 		}
  138 	}
  139 }
  140 
  141 print "Finished successfully\n";
  142 
  143 # End of file

Generated by cgit