#/usr/local/bin/perl
 #
 #  Usage: suidfind.pl [-n] [-s secure_dir] [search_starting_directory]
 #

 require "getopts.pl";

 die $usage unless &getopts'Getopts('n');

 # Do NFS stuff?  Yes unless opt:
 if (defined($opt_n)) { $skip_nfs = $opt_n; }
 else { $skip_nfs = 0; }

 if (@ARGV > 1) { die $usage; }
 elsif (@ARGV == 1) { $start_dir = shift; }

 # these may be terribly rash assumptions....
 $start_dir="/" unless defined $start_dir;

 @rwx = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
 @moname = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);

 while (($name, $pw, $uid) = getpwent) {
     $user{$uid} = $name unless $user{$uid};
 }

 while (($name, $pw, $gid) = getgrent) {
     $group{$gid} = $name unless $group{$gid};
 }

 require "find.pl";

 # Traverse desired filesystems

 &find($start_dir);

 exit;

 sub wanted {
     (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
     -d _ &&
     (	$skip_nfs &&
 	($dev < 0 || $dev >= 16384) &&
 	($prune = 1)
     )
     ||
     -f _ &&
     (
 	($mode & 04000) == 04000
 	||
 	($mode & 02000) == 02000
     ) &&
     &ls;
 }

 sub ls {
     ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
       $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);

     $pname = $name;

     if (defined $blocks) {
 	$blocks = int(($blocks + 1) / 2);
     }
     else {
 	$blocks = int(($size + 1023) / 1024);
     }

     if    (-f _) { $perms = '-'; }
     elsif (-d _) { $perms = 'd'; }
     elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
     elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
     elsif (-p _) { $perms = 'p'; }
     elsif (-S _) { $perms = 's'; }
     else         { $perms = 'l'; $pname .= ' -> ' . readlink($_); }

     $tmpmode = $mode;
     $tmp = $rwx[$tmpmode & 7];
     $tmpmode >>= 3;
     $tmp = $rwx[$tmpmode & 7] . $tmp;
     $tmpmode >>= 3;
     $tmp = $rwx[$tmpmode & 7] . $tmp;
     substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
     substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
     substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
     $perms .= $tmp;

     $user = $user{$uid} || $uid;
     $group = $group{$gid} || $gid;

     ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
     $moname = $moname[$mon];
     if (-M _ > 365.25 / 2) {
 	$timeyear = '19' . $year;
     }
     else {
 	$timeyear = sprintf("%02d:%02d", $hour, $min);
     }

     printf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
 	    $ino,
 		 $blocks,
 		      $perms,
 			    $nlink,
 				$user,
 				     $group,
 					  $sizemm,
 					      $moname,
 						 $mday,
 						     $timeyear,
 							 $pname;
     1;
 }

 sub sizemm {
     sprintf("%3d, %3d", ($rdev >> 8) & 255, $rdev & 255);
 }