3 # Copyright (c) 2016 Joey Schulze <joey@infodrom.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
37 mirrordir options sourcdir destdir
41 --verbose|-v Verbose output
42 --dry-run Don\'t actually mirror
61 return unless -f $src;
63 my $pos = rindex $dst, '/';
64 assert_directory substr $dst, 0, $pos if $pos > 1;
66 if (!copy $src, $dst) {
67 printf STDERR "copy %s %s failed\n", $src, $dst;
71 my @stat_src = stat $src;
72 my @stat_dst = stat $dst;
74 if ($stat_src[7] != $stat_dst[7]) {
75 printf STDERR "copy %s %s failed (size mismatch)\n", $src, $dst;
79 utime $stat_src[9], $stat_src[9], $dst;
82 sub compare_process_item
88 my $dst = $opt_destination . substr($a, length $opt_source);
91 printf "mirror %s %s\n", $a, $dst if $opt_verbose;
92 push @mirrordirs, [$a, $dst] unless $opt_dry_run;
94 printf "copy %s %s\n", $a, $dst if $opt_verbose;
95 copy_file $a, $dst unless $opt_dry_run;
99 printf "rmdir %s\n", $b if $opt_verbose;
100 rmtree $b unless $opt_dry_run;
102 printf "delete %s\n", $b if $opt_verbose;
103 unlink $b unless $opt_dry_run;
106 if (-f $a && -f $b) {
107 printf "copy %s %s\n", $a, $b if $opt_verbose;
108 copy_file $a, $b unless $opt_dry_run;
110 printf "rmdir %s\n", $b if $opt_verbose;
111 rmtree $b unless $opt_dry_run;
113 printf "copy %s %s\n", $a, $b if $opt_verbose;
114 copy_file $a, $b unless $opt_dry_run;
116 printf "delete %s\n", $b if $opt_verbose;
117 unlink $b unless $opt_dry_run;
119 my $pos = rindex $b, '/';
120 my $relpath = substr($b, $pos);
121 printf "mirror %s %s\n", $opt_source.$relpath, $opt_destination.$relpath if $opt_verbose;
122 push @mirrordirs, [$opt_source.$relpath, $opt_destination.$relpath] unless $opt_dry_run;
129 File::DirCompare->compare($opt_source, $opt_destination, \&compare_process_item);
132 sub mirror_directories
136 while (my $item = shift @mirrordirs) {
137 $opt_source = $item->[0];
138 $opt_destination = $item->[1];
145 'verbose|v' => \$opt_verbose,
146 'dry-run|dryrun' => \$opt_dry_run,
149 die "Not enough parameters\n" unless scalar @ARGV == 2;
153 $opt_source = $ARGV[0];
154 $opt_destination = $ARGV[1];