From 50439777c119771ec208a42a0522f962463867bb Mon Sep 17 00:00:00 2001 From: Joey Schulze Date: Sat, 28 May 2016 16:24:05 +0200 Subject: [PATCH 1/2] First version --- src/mirrordir | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100755 src/mirrordir diff --git a/src/mirrordir b/src/mirrordir new file mode 100755 index 0000000..802a3df --- /dev/null +++ b/src/mirrordir @@ -0,0 +1,156 @@ +#! /usr/bin/perl + +# Copyright (c) 2016 Joey Schulze +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA + +use strict; +use warnings; + +use File::Copy; +use File::Path; +use File::DirCompare; +use Getopt::Long; + +my $opt_dry_run; +my $opt_verbose; +my $opt_source; +my $opt_destination; + +my @mirrordirs; + +sub help +{ + print < 1; + + if (!copy $src, $dst) { + printf STDERR "copy %s %s failed\n", $src, $dst; + return; + } + + my @stat_src = stat $src; + my @stat_dst = stat $dst; + + if ($stat_src[7] != $stat_dst[7]) { + printf STDERR "copy %s %s failed (size mismatch)\n", $src, $dst; + return; + } + + utime $stat_src[9], $stat_src[9], $dst; +} + +sub compare_process_item +{ + my $a = shift; + my $b = shift; + + if (! $b) { + my $dst = $opt_destination . substr($a, length $opt_source); + + if (-d $a) { + printf "mirror %s %s\n", $a, $dst if $opt_verbose; + push @mirrordirs, [$a, $dst] unless $opt_dry_run; + } else { + printf "copy %s %s\n", $a, $dst if $opt_verbose; + copy_file $a, $dst unless $opt_dry_run; + } + } elsif (! $a) { + if (-d $b) { + printf "rmdir %s\n", $b if $opt_verbose; + rmtree $b unless $opt_dry_run; + } else { + printf "delete %s\n", $b if $opt_verbose; + unlink $b unless $opt_dry_run; + } + } else { + if (-f $a && -f $b) { + printf "copy %s %s\n", $a, $b if $opt_verbose; + copy_file $a, $b unless $opt_dry_run; + } elsif (-d $b) { + printf "rmdir %s\n", $b if $opt_verbose; + rmtree $b unless $opt_dry_run; + + printf "copy %s %s\n", $a, $b if $opt_verbose; + copy_file $a, $b unless $opt_dry_run; + } elsif (-d $a) { + printf "delete %s\n", $b if $opt_verbose; + unlink $b unless $opt_dry_run; + + my $pos = rindex $b, '/'; + my $relpath = substr($b, $pos); + printf "mirror %s %s\n", $opt_source.$relpath, $opt_destination.$relpath if $opt_verbose; + push @mirrordirs, [$opt_source.$relpath, $opt_destination.$relpath] unless $opt_dry_run; + } + } +} + +sub mirror_directory +{ + File::DirCompare->compare($opt_source, $opt_destination, \&compare_process_item); +} + +sub mirror_directories +{ + mirror_directory; + + while (my $item = shift @mirrordirs) { + $opt_source = $item->[0]; + $opt_destination = $item->[1]; + mirror_directory; + } +} + +GetOptions ( + 'help|h' => \&help, + 'verbose|v' => \$opt_verbose, + 'dry-run|dryrun' => \$opt_dry_run, +); + +die "Not enough parameters\n" unless scalar @ARGV == 2; + +$| = 1; + +$opt_source = $ARGV[0]; +$opt_destination = $ARGV[1]; + +mirror_directories; -- 2.20.1 From 4feabf8d30cf233a7abeae88fd96b158e1dea938 Mon Sep 17 00:00:00 2001 From: Joey Schulze Date: Sat, 25 Sep 2021 19:03:54 +0200 Subject: [PATCH 2/2] Assert existence of destination --- src/mirrordir | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mirrordir b/src/mirrordir index 802a3df..836bf67 100755 --- a/src/mirrordir +++ b/src/mirrordir @@ -126,6 +126,7 @@ sub compare_process_item sub mirror_directory { + assert_directory $opt_destination; File::DirCompare->compare($opt_source, $opt_destination, \&compare_process_item); } -- 2.20.1