home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 February / PCWorld_2000-02_cd.bin / live / usr / bin / chkdupexe < prev    next >
Text File  |  1999-01-26  |  4KB  |  120 lines

  1. #!/usr/bin/perl -w
  2. #
  3. # chkdupexe version 2.1.1
  4. #
  5. # Simple script to look for and list duplicate executables and dangling
  6. # symlinks in the system executable directories.
  7. #
  8. # Copyright 1993 Nicolai Langfeldt. janl@math.uio.no
  9. #  Distribute under gnu copyleft (included in perl package) 
  10. #
  11. # Modified 1995-07-04 Michael Shields <shields@tembel.org>
  12. #     Don't depend on GNU ls.
  13. #     Cleanups.
  14. #     Merge together $ENV{'PATH'} and $execdirs.
  15. #     Don't break if there are duplicates in $PATH.
  16. #
  17. # Modified 1996-02-16 Nicolai Langfeldt (janl@math.uio.no).
  18. #     I was thinking admins would edit the $execdirs list to suit their
  19. #     machine(s) when I wrote this.  This is ofcourse not the case, thus
  20. #     Michaels fixes.  And my fixes to his :-)
  21. #     - Working duplicate dirs detection.
  22. #     - Added more checks
  23. #     - Took out $PATH from the list of checked directories and added a
  24. #    check for $execdirs and $PATH consistency instead
  25. #     - Made it possible to run with perl -w
  26.  
  27. $execdirs='/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin '.
  28.   '/usr/X11R6/bin /usr/TeX/bin /usr/tex/bin /usr/games '.
  29.   '/usr/local/games';
  30.  
  31. # Turn off buffering for the output channel.
  32. $|=1;
  33.  
  34. # Values from /usr/include/linux/errno.h.  Existence of linux/errno.ph is not
  35. # something to count on... :-(
  36. $ENOENT=2;
  37.  
  38. %didthis=();
  39.  
  40. foreach $dir (split(/\s+/, "$execdirs"), "\0", split(/:/, $ENV{PATH})) {
  41.  
  42.   if ($dir eq "\0") { $checkingpath = 1; next; }
  43.  
  44.   # It's like this: One directory corresponds to one $device,$inode tuple
  45.   # If a symlink points to a directory we already checked that directory
  46.   # will have the same $device,$inode tuple.
  47.  
  48.   # Does this directory have any real exstence outside the ravings of
  49.   # symlinks pointing hither and dither?
  50.   ($device,$inode)=stat($dir); 
  51.   if (!defined($device)) {
  52.     # Nonexistant directory, or dangling symlink?
  53.     ($dum)=lstat($dir);
  54.     next if $! == $ENOENT;
  55.     if (!$dum) {
  56.       print "Dangling symlink: $dir\n";
  57.       next;
  58.     }
  59.     warn "Nonexistent directory: $dir\n" if ($checkingpath);
  60.     next;
  61.   }
  62.  
  63.   if (!-d _) {
  64.     print "Not a directory: $dir\n";
  65.     next;
  66.   }
  67.  
  68.   next if defined($didthis{$device,$inode});
  69.  
  70.   $didthis{$device,$inode}=1;
  71.  
  72.   chdir($dir) || die "Could not chdir $dir: $!\n";
  73. # This would give us the true directory name, do we want that?
  74. #  chop($dir=`pwd`);
  75.   opendir(DIR,".") || 
  76.     die "NUTS! Personaly I think your perl or filesystem is broken.\n".
  77.       "I've done all sorts of checks on $dir, and now I can't open it!\n";
  78.   foreach $_ (readdir(DIR)) {
  79.     lstat($_);
  80.     if (-l _) {
  81.       ($dum)=stat($_);
  82.       print "Dangling symlink: $dir/$_\n" unless defined($dum);
  83.       next;
  84.     }
  85.     next unless -f _ && -x _;    # Only handle regular executable files
  86.     if (defined($count{$_})) {
  87.       $progs{$_}.=" $dir/$_";
  88.       $count{$_}++;
  89.     } else {
  90.       $progs{$_}="$dir/$_";
  91.       $count{$_}=1;
  92.     }
  93.   }
  94.   closedir(DIR);
  95. }
  96.  
  97. open(LS,"| xargs -r ls -ldU");
  98. while (($prog,$paths)=each %progs) {
  99.   print LS "$paths\n" if ($count{$prog}>1);
  100. }
  101. close(LS);
  102.  
  103. exit 0;
  104.  
  105. @unchecked=();
  106. # Check if the users PATH contains something I've not checked. The site admin
  107. # might want to know about inconsistencies in user PATHs and chkdupexec 
  108. # configuration
  109. foreach $dir (split(/:/,$ENV{'PATH'})) {
  110.   ($device,$inode)=stat($dir);
  111.   next unless defined($device);
  112.   next if defined($didthis{$device,$inode});
  113.   push(@unchecked,$dir);
  114.   $didthis{$device,$inode}=1;
  115. }
  116.  
  117. print "Warning: Your path contains these directories which chkdupexe has not checked:\n",join(',',@unchecked),
  118.   ".\nPlease review the execdirs list in chkdupexe.\n"
  119.     if ($#unchecked>=$[);
  120.