Upload Tizen:Base source
[framework/base/util-linux-ng.git] / misc-utils / chkdupexe.pl
1 #!@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/X11/bin /usr/bin/X11 /usr/local/X11/bin '.
29   '/usr/TeX/bin /usr/tex/bin /usr/games '.
30   '/usr/local/games';
31
32 # Turn off buffering for the output channel.
33 $|=1;
34
35 # Values from /usr/include/linux/errno.h.  Existence of linux/errno.ph is not
36 # something to count on... :-(
37 $ENOENT=2;
38
39 %didthis=();
40
41 foreach $dir (split(/\s+/, "$execdirs"), "\0", split(/:/, $ENV{PATH})) {
42
43   if ($dir eq "\0") { $checkingpath = 1; next; }
44
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.
48
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?
54     ($dum)=lstat($dir);
55     next if $! == $ENOENT;
56     if (!$dum) {
57       print "Dangling symlink: $dir\n";
58       next;
59     }
60     warn "Nonexistent directory: $dir\n" if ($checkingpath);
61     next;
62   }
63
64   if (!-d _) {
65     print "Not a directory: $dir\n";
66     next;
67   }
68
69   next if defined($didthis{$device,$inode});
70
71   $didthis{$device,$inode}=1;
72
73   chdir($dir) || die "Could not chdir $dir: $!\n";
74 # This would give us the true directory name, do we want that?
75 #  chop($dir=`pwd`);
76   opendir(DIR,".") || 
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)) {
80     lstat($_);
81     if (-l _) {
82       ($dum)=stat($_);
83       print "Dangling symlink: $dir/$_\n" unless defined($dum);
84       next;
85     }
86     next unless -f _ && -x _;   # Only handle regular executable files
87     if (defined($count{$_})) {
88       $progs{$_}.=" $dir/$_";
89       $count{$_}++;
90     } else {
91       $progs{$_}="$dir/$_";
92       $count{$_}=1;
93     }
94   }
95   closedir(DIR);
96 }
97
98 open(LS,"| xargs -r ls -ldU");
99 while (($prog,$paths)=each %progs) {
100   print LS "$paths\n" if ($count{$prog}>1);
101 }
102 close(LS);
103
104 exit 0;
105
106 @unchecked=();
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 
109 # configuration
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;
116 }
117
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>=$[);