home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- #
- # Usage: lndir old-dir new-dir
- #
- # Compare two directories, and link all identical files.
-
- # Check args && fetch names.
-
- ((($olddir,$newdir) = @ARGV) == 2 && -d $olddir && -d $newdir)
- || die "Usage: $0 old-dir new-dir\n";
-
- # Get all files in the new dir.
-
- open(FIND,"find $newdir -type f -print|");
-
- $|=1;
-
- FILE: while ($new = <FIND>) {
- chop $new;
- ($file = $new) =~ s#^$newdir/##o
- || die "find said $new?\n";
- $old = "$olddir/$file";
-
- # Get stat info for both files.
-
- ($ndev,$nino,$nmode,$nnlink,$nuid,$ngid,$nrdev,$nsize,
- $natime,$nmtime,$nctime,$nblksize,$nblocks)
- = stat($new);
-
- unless ($nino) {
- print "$new: $!\n";
- next FILE;
- }
-
- unless (-f _) {
- warn "$new is not a plain file\n";
- next FILE;
- }
-
- ($odev,$oino,$omode,$onlink,$ouid,$ogid,$ordev,$osize,
- $oatime,$omtime,$octime,$oblksize,$oblocks)
- = stat($old);
-
- unless ($oino) {
- next FILE;
- }
-
- unless (-f _) {
- warn "$old is not a plain file\n";
- next FILE;
- }
-
- # Quick check on size and mode.
-
- if ($nsize != $osize) {
- print "$file differs\n";
- next FILE;
- }
-
- if ($nmode != $omode) {
- print "$file mode differs\n";
- next FILE;
- }
-
- # Already linked? (Perhaps symbolically?)
- # Compare dev/inode numbers.
-
- if ($ndev == $odev && $nino == $oino) {
- print "$file already linked\n";
- next FILE;
- }
-
- # Now compare the two files.
-
- unless (open(NEW,"$new")) {
- print "$new: $!\n";
- next FILE;
- }
- unless (open(OLD,"$old")) {
- print "$old: $!\n";
- next FILE;
- }
- $blksize = $nblksize || 8192;
- while (read(OLD,$obuf,$blksize)) {
- read(NEW,$nbuf,$blksize);
- if ($obuf ne $nbuf) {
- print "$file differs\n";
- next FILE;
- }
- }
-
- # Okay, let's link.
-
- if (unlink($new) && link($old, $new)) {
- print "$file linked to $old\n";
- next FILE;
- }
-
- print "$file: $!\n";
- }
-