#!/usr/bin/perl -W # TP synchronisation de fichiers en perl # # Question 3 # basé sur la question 2, version sans références # BUG: ne créé pas les répertoires! # # Antoine Miné # 26/01/2007 use File::Copy; # pour avoir copy # par défaut, on n'exécute pas les actions $doit = 0; # lecture des arguments foreach (@ARGV) { if ($_ eq "--doit") { $doit = 1; } elsif (!defined($dirB)) { $dirB = $_; } elsif (!defined($dirA)) { $dirA = $_; } else { die "argument $_ en trop"; } } # vérification des arguments die "utilisation: $0 [--doit] repertoire-courant repertoire-archive" unless defined($dirA) && defined($dirB); # ceci n'a pas changé depuis mirroir2bis.pl sub parcours { my $dir = shift; opendir(DIR,"$root/$dir") or return; my @files = readdir(DIR) or return; closedir(DIR); foreach (@files) { next if /^\.\.?$/; $filename = "$dir/$_"; $fullfilename = "$root/$filename"; if (-d $fullfilename) { parcours($filename); } elsif (-f $fullfilename) { $result = `sha1sum "$fullfilename"`; chomp $result; $result =~ s/ .*$//; $table{$filename} = $result; } } } $root = $dirA; %table = (); parcours("."); %tableA = %table; $root = $dirB; %table = (); parcours("."); %tableB = %table; # copie les fichiers de B vers A for (keys %tableB) { next if defined($tableA{$_}) && $tableA{$_} eq $tableB{$_}; $fileA = "$dirA/$_"; $fileB = "$dirB/$_"; print "copie $fileB => $fileA\n"; if ($doit) { # copie, avec message d'erreur en cas d'échec # BUG: pour que cela fonctionne bien, il faudrait s'assurer que # le répertoire où placer $fileA existe bien # (en le créant au besoin en appelant par exemple `mkdir -p`) copy($fileB,$fileA) or warn "échec de la copie de $fileB vers $fileA ($!)"; } } # efface les fichiers de A for (keys %tableA) { next if defined($tableB{$_}); $file = "$dirA/$_"; print "détruit $file\n"; if ($doit) { # effacement, avec message d'erreur en cas d'échec unlink "$file" or warn "échec de la destruction de $file ($!)"; } }