3 # chkdupexe version 2.1.1
5 # Simple script to look for and list duplicate executables and dangling
6 # symlinks in the system executable directories.
8 # Copyright 1993 Nicolai Langfeldt. janl@math.uio.no
9 # Distribute under gnu copyleft (included in perl package)
11 # Modified 1995-07-04 Michael Shields <shields@tembel.org>
12 # Don't depend on GNU ls.
14 # Merge together $ENV{'PATH'} and $execdirs.
15 # Don't break if there are duplicates in $PATH.
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.
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
27 $execdirs='/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin '.
28 '/usr/X11/bin /usr/bin/X11 /usr/local/X11/bin '.
29 '/usr/TeX/bin /usr/tex/bin /usr/games '.
32 # Turn off buffering for the output channel.
35 # Values from /usr/include/linux/errno.h. Existence of linux/errno.ph is not
36 # something to count on... :-(
41 foreach $dir (split(/\s+/, "$execdirs"), "\0", split(/:/, $ENV{PATH})) {
43 if ($dir eq "\0") { $checkingpath = 1; next; }
45 # It's like this: One directory corresponds to one $device,$inode tuple
46 # If a symlink points to a directory we already checked that directory
47 # will have the same $device,$inode tuple.
49 # Does this directory have any real exstence outside the ravings of
50 # symlinks pointing hither and dither?
51 ($device,$inode)=stat($dir);
52 if (!defined($device)) {
53 # Nonexistant directory, or dangling symlink?
55 next if $! == $ENOENT;
57 print "Dangling symlink: $dir\n";
60 warn "Nonexistent directory: $dir\n" if ($checkingpath);
65 print "Not a directory: $dir\n";
69 next if defined($didthis{$device,$inode});
71 $didthis{$device,$inode}=1;
73 chdir($dir) || die "Could not chdir $dir: $!\n";
74 # This would give us the true directory name, do we want that?
77 die "NUTS! Personaly I think your perl or filesystem is broken.\n".
78 "I've done all sorts of checks on $dir, and now I can't open it!\n";
79 foreach $_ (readdir(DIR)) {
83 print "Dangling symlink: $dir/$_\n" unless defined($dum);
86 next unless -f _ && -x _; # Only handle regular executable files
87 if (defined($count{$_})) {
88 $progs{$_}.=" $dir/$_";
98 open(LS,"| xargs -r ls -ldU");
99 while (($prog,$paths)=each %progs) {
100 print LS "$paths\n" if ($count{$prog}>1);
107 # Check if the users PATH contains something I've not checked. The site admin
108 # might want to know about inconsistencies in user PATHs and chkdupexec
110 foreach $dir (split(/:/,$ENV{'PATH'})) {
111 ($device,$inode)=stat($dir);
112 next unless defined($device);
113 next if defined($didthis{$device,$inode});
114 push(@unchecked,$dir);
115 $didthis{$device,$inode}=1;
118 print "Warning: Your path contains these directories which chkdupexe has not checked:\n",join(',',@unchecked),
119 ".\nPlease review the execdirs list in chkdupexe.\n"
120 if ($#unchecked>=$[);