#!/usr/bin/perl -W # TP synchronisation de fichiers en perl # # Question 2 # version avec références (plus joli, mais conceptuellement plus complexe) # # Antoine Miné # 26/01/2007 $dirB = $ARGV[0]; $dirA = $ARGV[1] or die "utilisation: $0 repertoire-courant repertoire-archive"; # parcours($root,$dir,%table) parcours récursivement le répertoire $root/$dir. # Pour chaque fichier f normal de root/dir, son hash h est calculé, et # le couple ($dir/f,h) est ajouté à %table. # %table est passé par référence! # on utilise donc le prototype ($$\%): scalaire, scalaire, référence de table sub parcours($$\%); # déclaration de prototype (pour appel récursif) sub parcours($$\%) # définition (avec rappel de prototype) { my $root = shift; my $dir = shift; my $tableref = shift; # $tableref pointe sur une table 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($root,$filename,%$tableref); } elsif (-f $fullfilename) { $result = `sha1sum "$fullfilename"`; chomp $result; $result =~ s/ .*$//; # le $$ indique qu'on parle d'une entrée de la table # pointée par tableref $$tableref{$filename} = $result; } } } # les appels à parcours sont maintenant nettements plus jolis parcours($dirA,".",%tableA); parcours($dirB,".",%tableB); # identique à la solution précédente for (keys %tableB) { next if defined($tableA{$_}) && $tableA{$_} eq $tableB{$_}; print "copie $dirB/$_ => $dirA/$_\n"; } for (keys %tableA) { next if defined($tableB{$_}); print "détruit $dirA/$_\n"; }