#!/usr/bin/perl -w

use strict;

my %dups;
my %colors = (   
  'black'         => "\033[0;30m",
  'blue'          => "\033[0;34m",
  'green'         => "\033[0;32m",
  'cyan'          => "\033[0;36m",
  'red'           => "\033[0;31m",
  'purple'        => "\033[0;35m",
  'brown'         => "\033[0;33m",
  'light_gray'    => "\033[0;37m",
  'dark_gray'     => "\033[1;30m",
  'light_blue'    => "\033[1;34m",
  'light_green'   => "\033[1;32m",
  'light_cyan'    => "\033[1;36m",
  'light_red'     => "\033[1;31m",
  'light_purple'  => "\033[1;35m",
  'yellow'        => "\033[1;33m",
  'white'         => "\033[1;37m",
  'nothing'       => "\033[0m",
);

# edit this stuff to change the color hiliting on files
my %c = (
  'hilite'  => $colors{'cyan'},
  'default' => $colors{'nothing'},
);

# you need at least one path
die "Please specify at least one directory (eg \"$0 /etc\".\n" unless @ARGV;

# step through the specified paths and process them
foreach my $path (@ARGV) {
  search_dir($path);
}

# print out a list of files with two or more paths
foreach my $file (sort keys %dups) {
  next unless $dups{$file};
  my @a = @{$dups{$file}};
  next unless @a > 1;

  print "$c{'hilite'}$file$c{'default'}: " . join(', ', @a) . "\n";
}

exit 0;

sub search_dir {
  my ($path, $dh, @dirs) = shift;

  # print out a warning if we couldn't read from this directory
  unless (opendir $dh, $path) {
    warn "Couldn't open directory \"$path\": $!.\n";
    return;
  }

  foreach my $file (readdir $dh) {
    # skip . and .., but not regular dot-files
    next if $file =~ /^\.$/ or $file =~ /^\.\.$/;

    if ($dups{$file}) {
      push @{$dups{$file}}, $path;
    } else {
      my @a = ($path);
      $dups{$file} = \@a;
    }

    # if it's a direcotry and not a symbolic link, then add it to the
    # list of directories to scan
    push @dirs, "$path/$file" if -d "$path/$file" and ! -l "$path/$file";
  }

  closedir $dh;

  # cycle through the subdirectories in this directory and process each
  # of them (we deliberately do this _after_ closing the parent
  # directory in order to avoid running out of file descriptors during
  # deep recursion)
  foreach my $dir (@dirs) {
    search_dir($dir);
  }
}


