#!/usr/bin/perl use strict; use Cwd 'abs_path'; my $RSYNC = '/usr/bin/rsync'; my $dest_dir = $ARGV[-1]; usage(1) if $dest_dir eq '' || $dest_dir =~ /^--/; if (!-d $dest_dir) { print STDERR "$dest_dir is not a directory.\n\n"; usage(1); } if (@_ = grep(/^--(link|compare)-dest/, @ARGV)) { $_ = join(' or ', @_); print STDERR "You may not use $_ as an rsync option.\n\n"; usage(1); } $dest_dir = abs_path($dest_dir); if ($dest_dir eq '/') { print STDERR 'You must not use "/" as the destination directory.', "\n\n"; usage(1); } my $old_dir = "$dest_dir~old~"; my $new_dir = $ARGV[-1] = "$dest_dir~new~"; if (-d $old_dir) { rename($old_dir, $new_dir) or die "Unable to rename $old_dir to $new_dir: $!"; } if (system($RSYNC, "--link-dest=$dest_dir", @ARGV)) { if ($? == -1) { print "failed to execute $RSYNC: $!\n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %d\n", $? >> 8; } exit $?; } rename($dest_dir, $old_dir) or die "Unable to rename $new_dir to $old_dir: $!"; rename($new_dir, $dest_dir) or die "Unable to rename $new_dir to $dest_dir: $!"; exit; sub usage { my($ret) = @_; my $fh = $ret ? *STDERR : *STDOUT; print $fh <