#!/usr/bin/perl # Author: Brad Fitzpatrick # Copyright 2006. # License: terms of Perl itself. # Warranty: none. use at your own risk. use strict; use Digest::SHA1; use Getopt::Long; my $in_file; my $out_file; usage() unless GetOptions( 'to=s' => \$out_file, 'from=s' => \$in_file, ); sub usage { die "Always 'cd' into the directory you want to save the layout or mimic the layout of, then either: To save the layout of a tree: treearrange --to=arrangement-file.dat To restore elsewhere, after you move the arrangement-file.dat: treearrange --from=arrangement-file.dat "; } die "Must have --to or --from file" unless $out_file xor $in_file; my $outfh; if ($out_file) { open ($outfh, ">$out_file") or die "Failed to open $out_file: $!\n"; } my $infh; my %wanted; if ($in_file) { open ($infh, $in_file) or die "Failed to open $in_file: $!\n"; while (<$infh>) { die "bad format" unless /^(\w+)\t(.+)/; my ($dig, $file) = ($1, $2); $wanted{$dig} = $file; } } my @files = `find -type f`; chomp @files; my $tot = @files; my $n = 0; foreach my $f (@files) { $n++; print "file $n / $tot...\n"; $f =~ s!./!!; my $dig = file_sha($f); if ($wanted{$dig} && $wanted{$dig} ne $f) { print " $f -> $wanted{$dig}\n"; system("install", "-D", "-p", $f, $wanted{$dig}) and die "Failed to install.\n"; unlink $f; } if ($outfh) { print $outfh "$dig\t$f\n"; } } exit 0 if $out_file; sub file_sha { my $file = shift; open (my $fh, $file) or die "error opening $file: $!"; my $sha1 = Digest::SHA1->new; $sha1->addfile($fh); return $sha1->hexdigest; }