1*7c478bd9Sstevel@tonic-gate#!/usr/bin/perl 2*7c478bd9Sstevel@tonic-gate# 3*7c478bd9Sstevel@tonic-gate# CDDL HEADER START 4*7c478bd9Sstevel@tonic-gate# 5*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 7*7c478bd9Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 8*7c478bd9Sstevel@tonic-gate# with the License. 9*7c478bd9Sstevel@tonic-gate# 10*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 12*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions 13*7c478bd9Sstevel@tonic-gate# and limitations under the License. 14*7c478bd9Sstevel@tonic-gate# 15*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 16*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 18*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 19*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 20*7c478bd9Sstevel@tonic-gate# 21*7c478bd9Sstevel@tonic-gate# CDDL HEADER END 22*7c478bd9Sstevel@tonic-gate# 23*7c478bd9Sstevel@tonic-gate# 24*7c478bd9Sstevel@tonic-gate# Copyright (c) 2000 by Sun Microsystems, Inc. 25*7c478bd9Sstevel@tonic-gate# All rights reserved. 26*7c478bd9Sstevel@tonic-gate# 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate# 31*7c478bd9Sstevel@tonic-gate# check for perl5 -- we use things unavailable in perl4 32*7c478bd9Sstevel@tonic-gate# 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gatedie "Sorry, this program requires perl version 5.000 or up. You have $]. Stopping" if $] < 5.000; 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate$DBM_DIR_CHARACTERIZATION = "directory for the dbm databases"; 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate$Usage = 39*7c478bd9Sstevel@tonic-gate"Usage: get_depend_info 40*7c478bd9Sstevel@tonic-gate -dbdir <$DBM_DIR_CHARACTERIZATION> [ -s ] [ -cons ] [ -root directory ] 41*7c478bd9Sstevel@tonic-gate [ -f ] [ -p ] [ -pkg SUNWxxx ] [ filename ] 42*7c478bd9Sstevel@tonic-gate [-h for help]\n"; 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate$Help = 45*7c478bd9Sstevel@tonic-gate"This program statically analyzes executable files and their 46*7c478bd9Sstevel@tonic-gatesymbolic links using /usr/bin/ldd and /usr/bin/strings. It 47*7c478bd9Sstevel@tonic-gatecan accept filename(s) or packages as the list of files to be 48*7c478bd9Sstevel@tonic-gateanalyzed. By default, the program will report the file 49*7c478bd9Sstevel@tonic-gatedependencies and which packages those dependencies came from. 50*7c478bd9Sstevel@tonic-gateThere is one required argument: 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate -dbdir <dir> the $DBM_DIR_CHARACTERIZATION 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gateThe optional argument -h produces this message instead of any processing. 55*7c478bd9Sstevel@tonic-gateThe optional argument -cons tells the tool to be conservative and not to 56*7c478bd9Sstevel@tonic-gaterun /usr/bin/strings. 57*7c478bd9Sstevel@tonic-gateThe optional argument -root allows you to specify a new root (useful for 58*7c478bd9Sstevel@tonic-gatedoing analysis on build trees). 59*7c478bd9Sstevel@tonic-gateThe optional argument -pkg allows you to specify a package name. 60*7c478bd9Sstevel@tonic-gateThe optional argument -f only outputs the filename of the dependencies 61*7c478bd9Sstevel@tonic-gateThe optional argument -p only outputs the packanames of the dependencies 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gateThe optional argument -s ONLY outputs symbolic links for files or packages. 64*7c478bd9Sstevel@tonic-gateNo ldd or strings analysis is done. 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gateSome Examples: 67*7c478bd9Sstevel@tonic-gateget_depend_info -dbdir ./DBM /usr/bin/ls 68*7c478bd9Sstevel@tonic-gateget_depend_info -dbdir ./DBM /usr/bin/* 69*7c478bd9Sstevel@tonic-gateget_depend_info -dbdir ./DBM -pkg SUNWnisu 70*7c478bd9Sstevel@tonic-gateget_depend_info -f -dbdir ./DBM -pkg SUNWnisu 71*7c478bd9Sstevel@tonic-gateget_depend_info -s -dbdir ./DBM /usr/bin/* 72*7c478bd9Sstevel@tonic-gateget_depend_info -s -dbdir ./DBM -pkg SUNWnisu 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gateNOTE: Run make_pkg_db to create the database directory for get_depend_info 76*7c478bd9Sstevel@tonic-gate"; 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate# 79*7c478bd9Sstevel@tonic-gate# process arguments 80*7c478bd9Sstevel@tonic-gate# 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate@PkgList = ""; 83*7c478bd9Sstevel@tonic-gate$PackageOnly = false; 84*7c478bd9Sstevel@tonic-gate$FileOnly = false; 85*7c478bd9Sstevel@tonic-gate$Verbose = true; 86*7c478bd9Sstevel@tonic-gate$Silent = false; 87*7c478bd9Sstevel@tonic-gate$SymLink = false; 88*7c478bd9Sstevel@tonic-gate$NoStrings = false; 89*7c478bd9Sstevel@tonic-gate$Root = ""; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gatewhile (@ARGV) { 92*7c478bd9Sstevel@tonic-gate $arg = shift (@ARGV); 93*7c478bd9Sstevel@tonic-gate if ($arg eq "-h") { 94*7c478bd9Sstevel@tonic-gate print "$Help\n$Usage"; 95*7c478bd9Sstevel@tonic-gate exit 0; 96*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-dbdir") { 97*7c478bd9Sstevel@tonic-gate $DBDir = shift(@ARGV) unless ($ARGV[0] =~ /^-/); 98*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-s") { 99*7c478bd9Sstevel@tonic-gate $SymLink = true; 100*7c478bd9Sstevel@tonic-gate $Silent = true; 101*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-p") { 102*7c478bd9Sstevel@tonic-gate $PackageOnly = true; 103*7c478bd9Sstevel@tonic-gate $Verbose = false; 104*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-f") { 105*7c478bd9Sstevel@tonic-gate $FileOnly = true; 106*7c478bd9Sstevel@tonic-gate $Verbose = false; 107*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-cons") { 108*7c478bd9Sstevel@tonic-gate $NoStrings = true; 109*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-pkg") { 110*7c478bd9Sstevel@tonic-gate $PKGName = shift(@ARGV) unless ($ARGV[0] =~ /^-/); 111*7c478bd9Sstevel@tonic-gate } elsif ($arg eq "-root") { 112*7c478bd9Sstevel@tonic-gate $Root = shift(@ARGV) unless ($ARGV[0] =~ /^-/); 113*7c478bd9Sstevel@tonic-gate }else { 114*7c478bd9Sstevel@tonic-gate push(@filelist, $arg); 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate} 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gateif (!$DBDir) { 119*7c478bd9Sstevel@tonic-gate print STDERR "Required argument -dbdir missing. \n$Usage"; 120*7c478bd9Sstevel@tonic-gate exit 1; 121*7c478bd9Sstevel@tonic-gate} 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gateif ($PKGName) { 124*7c478bd9Sstevel@tonic-gate # For a given pkg definition directory, this subroutine will 125*7c478bd9Sstevel@tonic-gate # go through the proto files and look for executable files. 126*7c478bd9Sstevel@tonic-gate # It will then put all the executable files into @filelist 127*7c478bd9Sstevel@tonic-gate &HandlePackageName($PKGName); 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate if ($PackageOnly eq true) { 130*7c478bd9Sstevel@tonic-gate $Silent = true; 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate} 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate&OpenDBs; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate$Silent = true if (($Verbose eq false) && ($PackageOnly eq false) 137*7c478bd9Sstevel@tonic-gate && ($FileOnly eq false)); 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gateforeach $entry (@filelist) { 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate print("\n\nAnalyzing $Root$entry:\n") unless ($Silent eq true); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate # make sure file exists 144*7c478bd9Sstevel@tonic-gate if (!(-r $entry)) { 145*7c478bd9Sstevel@tonic-gate print STDERR "Could not open file $entry\n"; 146*7c478bd9Sstevel@tonic-gate next; 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate $file = $FTYPE{$entry}; 151*7c478bd9Sstevel@tonic-gate $pkgs = $PKGS{$entry}; 152*7c478bd9Sstevel@tonic-gate $abslink = $ABSLINK{$entry}; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate if ($file eq "d") { 155*7c478bd9Sstevel@tonic-gate print("Input file is a directory\n") unless ($Silent eq true); 156*7c478bd9Sstevel@tonic-gate next; 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate # destfile represents the actual file we are interested in! 160*7c478bd9Sstevel@tonic-gate if ($abslink =~ /\w/) { 161*7c478bd9Sstevel@tonic-gate $destfile = $abslink; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate if (($FTYPE{$entry} eq "s") && ($SymLink eq true)) { 164*7c478bd9Sstevel@tonic-gate print("$entry is linked to $destfile:$PKGS{$destfile}\n"); 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate else { 168*7c478bd9Sstevel@tonic-gate $destfile = $entry; 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate # if the -s flag is set, tell 'em about sym links and go to the next file 172*7c478bd9Sstevel@tonic-gate next if ($SymLink eq true); 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate $mode = $MODE{$destfile}; 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate # Handle the case where the user resets $ROOT 177*7c478bd9Sstevel@tonic-gate $destfile = "$Root$destfile" if ($Root =~ /\w/); 178*7c478bd9Sstevel@tonic-gate $filecmd = `/usr/bin/file $destfile 2>&1`; 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate # make sure we are dealing with an executable 181*7c478bd9Sstevel@tonic-gate if (($mode !~ /(.)(.*)7/) && ($mode !~ /(.)(.*)5/) && ($mode !~ /(.)(.*)3/) && ($mode !~ /(.)(.*)1/)){ 182*7c478bd9Sstevel@tonic-gate print("Input file is not an executable\n"); 183*7c478bd9Sstevel@tonic-gate next; 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate # Kernel modules are handled separately 187*7c478bd9Sstevel@tonic-gate if ($destfile =~ /\/kernel\//) { 188*7c478bd9Sstevel@tonic-gate &HandleKernelMod($destfile, $FTYPE{$entry}); 189*7c478bd9Sstevel@tonic-gate &OutputPackageList if (($PackageOnly eq true) && !($PKGName)); 190*7c478bd9Sstevel@tonic-gate next; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate # take care of scripts 194*7c478bd9Sstevel@tonic-gate if (($filecmd =~ /script/) || ($filecmd =~ /text/)) { 195*7c478bd9Sstevel@tonic-gate &HandleScripts($destfile); 196*7c478bd9Sstevel@tonic-gate &OutputPackageList if (($PackageOnly eq true) && !($PKGName)); 197*7c478bd9Sstevel@tonic-gate next; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate # Its not a script, not a kernel module, so its get to be a binary 201*7c478bd9Sstevel@tonic-gate &HandleBinaries($destfile); 202*7c478bd9Sstevel@tonic-gate &OutputPackageList if (($PackageOnly eq true) && !($PKGName)); 203*7c478bd9Sstevel@tonic-gate} 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gateif (($PKGName) && ($SymLink eq false)) { 206*7c478bd9Sstevel@tonic-gate print ("\n\nPackage dependencies for $PKGName:\n"); 207*7c478bd9Sstevel@tonic-gate &OutputPackageList; 208*7c478bd9Sstevel@tonic-gate} 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate&CloseDBs; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate#===========================END OF MAIN==================================== 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gatesub GetLddInfo { # return multi-line string of ldd info for File 215*7c478bd9Sstevel@tonic-gatelocal ($FileID, $FileType) = @_; 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate $outstring = "* Not a File\n"; 218*7c478bd9Sstevel@tonic-gate return ($outstring) if $FileType =~ /[Mlsdc]/; # ldd results not useful here 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate # 221*7c478bd9Sstevel@tonic-gate # use map file to see if this is a file that gives a known bad ldd return 222*7c478bd9Sstevel@tonic-gate # 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate# if ($Unsup{$FileID} == 1) { 225*7c478bd9Sstevel@tonic-gate# $outstring = "* unsupported or unknown file type, per map file"; 226*7c478bd9Sstevel@tonic-gate# return ($outstring); 227*7c478bd9Sstevel@tonic-gate# } 228*7c478bd9Sstevel@tonic-gate# $err = ""; 229*7c478bd9Sstevel@tonic-gate# $string = `/usr/bin/ldd $FileID 2>&1`; 230*7c478bd9Sstevel@tonic-gate# if ($?) { # if some error (don't just get wait status here) 231*7c478bd9Sstevel@tonic-gate# $errnum = 0 + $!; 232*7c478bd9Sstevel@tonic-gate# $err = "==$?==$errnum=="; 233*7c478bd9Sstevel@tonic-gate# if (($err eq "==256==29==") || ($err eq "==256==0==")) { 234*7c478bd9Sstevel@tonic-gate# $err = "*"; # these are normal ldd returns 235*7c478bd9Sstevel@tonic-gate# } else { 236*7c478bd9Sstevel@tonic-gate# die "Unexpected ldd return $? $!"; 237*7c478bd9Sstevel@tonic-gate# } 238*7c478bd9Sstevel@tonic-gate# $string =~ s/\/usr\/bin\/ldd:[^\0]*://g; # trim up error line 239*7c478bd9Sstevel@tonic-gate# } elsif ($string =~ s/warning:.*://) { # other normal ldd returns 240*7c478bd9Sstevel@tonic-gate# $err = "*"; 241*7c478bd9Sstevel@tonic-gate# } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate $outstring = ""; 244*7c478bd9Sstevel@tonic-gate $string = `/usr/bin/ldd $FileID 2>&1`; 245*7c478bd9Sstevel@tonic-gate # on a non-zero ldd, return nothing 246*7c478bd9Sstevel@tonic-gate return ($outstring) if ($?); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate $outstring = ""; 250*7c478bd9Sstevel@tonic-gate @infolines = split(/\s*\n\s*/, $string); 251*7c478bd9Sstevel@tonic-gate foreach $line (@infolines) { 252*7c478bd9Sstevel@tonic-gate $line =~ s/^\s+//; # trim leading ws 253*7c478bd9Sstevel@tonic-gate next unless $line; # skip if blank 254*7c478bd9Sstevel@tonic-gate @words = split(/\s/, $line); 255*7c478bd9Sstevel@tonic-gate $filename = $words[0]; 256*7c478bd9Sstevel@tonic-gate $outstring .= "$filename\n"; 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate return ($outstring); 259*7c478bd9Sstevel@tonic-gate} 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gatesub CloseDBs { 262*7c478bd9Sstevel@tonic-gate # close the dbs 263*7c478bd9Sstevel@tonic-gate dbmclose(FTYPE); 264*7c478bd9Sstevel@tonic-gate dbmclose(MODE); 265*7c478bd9Sstevel@tonic-gate dbmclose(PKGS); 266*7c478bd9Sstevel@tonic-gate dbmclose(ABSLINK); 267*7c478bd9Sstevel@tonic-gate dbmclose(PKGNAMES); 268*7c478bd9Sstevel@tonic-gate} 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gatesub OpenDBs { 271*7c478bd9Sstevel@tonic-gate # open the databases for read-only 272*7c478bd9Sstevel@tonic-gate dbmopen(%FTYPE, "$DBDir/FTYPE", 0664) || 273*7c478bd9Sstevel@tonic-gate die"Cannot open dbm db $DBDir/FTYPE\n"; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate dbmopen(%MODE, "$DBDir/MODE", 0664) || 276*7c478bd9Sstevel@tonic-gate die"Cannot open dbm db $DBDir/MODE\n"; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate dbmopen(%PKGS, "$DBDir/PKGS", 0664) || 279*7c478bd9Sstevel@tonic-gate die"Cannot open dbm db $DBDir/PKGS\n"; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate dbmopen(%ABSLINK, "$DBDir/ABSLINK", 0664) || 282*7c478bd9Sstevel@tonic-gate die"Cannot open dbm db $DBDir/ABSLINK \n"; 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate dbmopen(%PKGNAMES, "$DBDir/PKGNAMES", 0644) || 285*7c478bd9Sstevel@tonic-gate die"Cannot open dbm db $DBDir/PKGNAMES\n"; 286*7c478bd9Sstevel@tonic-gate} 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gatesub HandleKernelMod { 289*7c478bd9Sstevel@tonic-gatelocal ($entry, $ftype) = @_; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate # search for the magic right, starting from the right (ie. end of path) 292*7c478bd9Sstevel@tonic-gate $index = rindex($entry, "kernel"); 293*7c478bd9Sstevel@tonic-gate # rindex() returns where the "kernel" began, add 6 to get 294*7c478bd9Sstevel@tonic-gate # "{some path}/kernel" 295*7c478bd9Sstevel@tonic-gate $index += 6; 296*7c478bd9Sstevel@tonic-gate # OK, now pull out the absolute path 297*7c478bd9Sstevel@tonic-gate $KernelPath = substr($entry, 0, $index); 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate # There are two ways to figure out the dependencies. 300*7c478bd9Sstevel@tonic-gate # First, we check to see if /usr/bin/ldd will tell us. 301*7c478bd9Sstevel@tonic-gate # If ldd fails, then we need to look at the output of /usr/bin/strings 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate $LddInfo = ""; 304*7c478bd9Sstevel@tonic-gate $LddInfo = &GetLddInfo($entry, $ftype); 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if ($LddInfo =~ /\w/) { 307*7c478bd9Sstevel@tonic-gate @list = ""; 308*7c478bd9Sstevel@tonic-gate @list = split(/\n/, $LddInfo); 309*7c478bd9Sstevel@tonic-gate foreach $file (@list) { 310*7c478bd9Sstevel@tonic-gate $found = 0; 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate # first, check to see if there is a module relative to 313*7c478bd9Sstevel@tonic-gate # this file 314*7c478bd9Sstevel@tonic-gate if ($FTYPE{"$KernelPath/$file"} =~ /\w/){ 315*7c478bd9Sstevel@tonic-gate &Output("$KernelPath/$file"); 316*7c478bd9Sstevel@tonic-gate $found++; 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate # Haven't found it yet, check /kernel 320*7c478bd9Sstevel@tonic-gate if (($FTYPE{"/kernel/$file"} =~ /\w/) && ($found == 0)){ 321*7c478bd9Sstevel@tonic-gate &Output("/kernel/$file"); 322*7c478bd9Sstevel@tonic-gate $found++; 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate # Haven't found it yet, check /usr/kernel 326*7c478bd9Sstevel@tonic-gate if (($FTYPE{"/usr/kernel/$file"} =~ /\w/) && ($found == 0)){ 327*7c478bd9Sstevel@tonic-gate &Output("/usr/kernel/$file"); 328*7c478bd9Sstevel@tonic-gate $found++; 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate if ($found == 0) { 332*7c478bd9Sstevel@tonic-gate print("Could not resolve $file\n"); 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate return; 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate # the ldd failed, so now let's look at the string output 339*7c478bd9Sstevel@tonic-gate $string = ""; 340*7c478bd9Sstevel@tonic-gate @infolines = ""; 341*7c478bd9Sstevel@tonic-gate @outlines = ""; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate $string = `/usr/bin/strings $entry 2>&1`; 344*7c478bd9Sstevel@tonic-gate @infolines = split(/\s*\n\s*/, $string); 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate foreach $line (@infolines) { 347*7c478bd9Sstevel@tonic-gate if ($line =~ /\//){ 348*7c478bd9Sstevel@tonic-gate push (@outlines,$line); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate foreach $line (@outlines) { 353*7c478bd9Sstevel@tonic-gate @words = split(/\s/, $line); 354*7c478bd9Sstevel@tonic-gate foreach $word (@words) { 355*7c478bd9Sstevel@tonic-gate $found = 0; 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate # first, check to see if there is a module relative to 358*7c478bd9Sstevel@tonic-gate # this file 359*7c478bd9Sstevel@tonic-gate if ($FTYPE{"$KernelPath/$word"} =~ /\w/){ 360*7c478bd9Sstevel@tonic-gate &Output("$KernelPath/$word"); 361*7c478bd9Sstevel@tonic-gate $found++; 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate 364*7c478bd9Sstevel@tonic-gate # Haven't found it yet, check /kernel 365*7c478bd9Sstevel@tonic-gate if (($FTYPE{"/kernel/$word"} =~ /\w/) && ($found == 0)){ 366*7c478bd9Sstevel@tonic-gate &Output("/kernel/$word"); 367*7c478bd9Sstevel@tonic-gate $found++; 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate # Haven't found it yet, check /usr/kernel 371*7c478bd9Sstevel@tonic-gate if (($FTYPE{"/usr/kernel/$word"} =~ /\w/) && ($found == 0)){ 372*7c478bd9Sstevel@tonic-gate &Output("/usr/kernel/$word"); 373*7c478bd9Sstevel@tonic-gate $found++; 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate} 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gatesub GetStringsInfo { # return multi-line string of ldd info for File 380*7c478bd9Sstevel@tonic-gatelocal ($FileID, $FileType) = @_; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate $outstring = "* Not a File\n"; 383*7c478bd9Sstevel@tonic-gate return ($outstring) if $FileType =~ /[Mlsdc]/; # ldd results not useful here 384*7c478bd9Sstevel@tonic-gate return ($outstring) if ($NoStrings eq true); # we are running in conservative mode 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate # use map file to see if this is a file that gives a known bad ldd return 387*7c478bd9Sstevel@tonic-gate if ($Unsup{$FileID} == 1) { 388*7c478bd9Sstevel@tonic-gate $outstring = "* unsupported or unknown file type, per map file"; 389*7c478bd9Sstevel@tonic-gate return ($outstring); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate $err = ""; 392*7c478bd9Sstevel@tonic-gate $string = ""; 393*7c478bd9Sstevel@tonic-gate $string = `/usr/bin/strings $FileID 2>&1`; 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate $outstring = ""; 396*7c478bd9Sstevel@tonic-gate @infolines = ""; 397*7c478bd9Sstevel@tonic-gate @outlines = ""; 398*7c478bd9Sstevel@tonic-gate @infolines = split(/\s*\n\s*/, $string); 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate foreach $line (@infolines) { 401*7c478bd9Sstevel@tonic-gate if (($line =~ /\//) && !($line =~ /%/) && !($line =~ m%/$%)){ 402*7c478bd9Sstevel@tonic-gate push (@outlines,$line); 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate @outlines = sort(@outlines); 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate foreach $word (@outlines) { 408*7c478bd9Sstevel@tonic-gate if ($lastword ne $word) { 409*7c478bd9Sstevel@tonic-gate $outstring .= $word; $outstring .= "\n"; 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate $lastword = $word; 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate return ($outstring); 414*7c478bd9Sstevel@tonic-gate} 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gatesub HandleScripts { 417*7c478bd9Sstevel@tonic-gatelocal ($filename) = @_; 418*7c478bd9Sstevel@tonic-gate open(SCRIPT, $filename); 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate undef @output; 421*7c478bd9Sstevel@tonic-gate while (<SCRIPT>) { 422*7c478bd9Sstevel@tonic-gate s/^\s+//; # trim leading ws 423*7c478bd9Sstevel@tonic-gate s/=/ /g; # get rid of all = 424*7c478bd9Sstevel@tonic-gate s/\`/ /g; # get rid of all ` 425*7c478bd9Sstevel@tonic-gate next if ($_ =~ /^#/); # strip out obvious comments 426*7c478bd9Sstevel@tonic-gate next unless $_; # skip if blank 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate $line = $_; 429*7c478bd9Sstevel@tonic-gate @words = split(/\s/, $line); 430*7c478bd9Sstevel@tonic-gate foreach $word (@words) { 431*7c478bd9Sstevel@tonic-gate if (($PKGS{$word} =~ /\w/) && ($FTYPE{$word} ne "d")) { 432*7c478bd9Sstevel@tonic-gate push(@output, $word); 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate @output = sort(@output); 438*7c478bd9Sstevel@tonic-gate $count = 0; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate # make sure we don't output dupes 441*7c478bd9Sstevel@tonic-gate foreach $file (@output) { 442*7c478bd9Sstevel@tonic-gate if ($count == 0) { 443*7c478bd9Sstevel@tonic-gate &Output($file); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate if (($count > 0) && ($output[$count] ne $output[$count-1])) { 447*7c478bd9Sstevel@tonic-gate &Output($file); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate $count++; 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate # remember to play nice 453*7c478bd9Sstevel@tonic-gate close(SCRIPT); 454*7c478bd9Sstevel@tonic-gate} 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gatesub HandleBinaries { 457*7c478bd9Sstevel@tonic-gatelocal ($filename) = @_; 458*7c478bd9Sstevel@tonic-gate $LddInfo = &GetLddInfo($destfile, $FTYPE{$filename}); 459*7c478bd9Sstevel@tonic-gate $StringInfo = &GetStringsInfo($destfile, $FTYPE{$filename}); 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate # Parse the ldd output. 462*7c478bd9Sstevel@tonic-gate # Libs can be found in /kernel or /usr/lib 463*7c478bd9Sstevel@tonic-gate @list = split(/\n/, $LddInfo); 464*7c478bd9Sstevel@tonic-gate foreach $file (@list) { 465*7c478bd9Sstevel@tonic-gate $found = 0; 466*7c478bd9Sstevel@tonic-gate if ($FTYPE{"/kernel/$file"} =~ /\w/){ 467*7c478bd9Sstevel@tonic-gate &Output("/kernel/$file"); 468*7c478bd9Sstevel@tonic-gate $found++; 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate if ($FTYPE{"/usr/lib/$file"} =~ /\w/){ 472*7c478bd9Sstevel@tonic-gate &Output("/usr/lib/$file"); 473*7c478bd9Sstevel@tonic-gate $found++; 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate if ($found == 0) { 477*7c478bd9Sstevel@tonic-gate print("Could not resolve $file\n"); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate # For the strings output, we parse it to see if we can match it to 482*7c478bd9Sstevel@tonic-gate # any files distributed in a package. 483*7c478bd9Sstevel@tonic-gate @list = split(/\n/, $StringInfo); 484*7c478bd9Sstevel@tonic-gate foreach $file (@list) { 485*7c478bd9Sstevel@tonic-gate if (($FTYPE{$file} =~ /\w/) && ($FTYPE{$file} ne "d")) { 486*7c478bd9Sstevel@tonic-gate &Output($file); 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate} 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gatesub Output { 492*7c478bd9Sstevel@tonic-gatelocal($filename) = @_; 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate # If they want a package listing, a unique sorted list 495*7c478bd9Sstevel@tonic-gate # will be outputted later. Here we simply push elements onto 496*7c478bd9Sstevel@tonic-gate # this list. 497*7c478bd9Sstevel@tonic-gate if ($PKGName) { 498*7c478bd9Sstevel@tonic-gate push(@PkgList, "$PKGS{$filename}\n"); 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate if ($Verbose eq true) { 502*7c478bd9Sstevel@tonic-gate print("$filename:$PKGS{$filename}\n"); 503*7c478bd9Sstevel@tonic-gate return; 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate # If they want a package listing, a unique sorted list 507*7c478bd9Sstevel@tonic-gate # will be outputted later. Here we simply push elements onto 508*7c478bd9Sstevel@tonic-gate # this list. 509*7c478bd9Sstevel@tonic-gate if ($PackageOnly eq true) { 510*7c478bd9Sstevel@tonic-gate push(@PkgList, "$PKGS{$filename}\n"); 511*7c478bd9Sstevel@tonic-gate return; 512*7c478bd9Sstevel@tonic-gate } 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate if ($FileOnly eq true) { 515*7c478bd9Sstevel@tonic-gate print("$filename\n"); 516*7c478bd9Sstevel@tonic-gate return; 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate} 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gatesub HandlePackageName { 521*7c478bd9Sstevel@tonic-gatelocal($pkg) = @_; 522*7c478bd9Sstevel@tonic-gate $pkgchk = `/usr/sbin/pkgchk -l $pkg | grep Pathname | sed 's/Pathname: //'`; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate @files = split(/\n/, $pkgchk); 525*7c478bd9Sstevel@tonic-gate foreach $file (@files) { 526*7c478bd9Sstevel@tonic-gate push(@filelist, $file); 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate} 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gatesub OutputPackageList { 531*7c478bd9Sstevel@tonic-gatelocal($filename) = @_; 532*7c478bd9Sstevel@tonic-gate # If the user specified a package list, here we sort 533*7c478bd9Sstevel@tonic-gate # the list and make sure we don't output dupes. 534*7c478bd9Sstevel@tonic-gate $lastpkg = ""; 535*7c478bd9Sstevel@tonic-gate @outPkgs = sort(@PkgList); 536*7c478bd9Sstevel@tonic-gate 537*7c478bd9Sstevel@tonic-gate foreach $pkg (@outPkgs) { 538*7c478bd9Sstevel@tonic-gate $pkg =~ s/\s*$//; # trim extra space off the end 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate # make sure this entry isn't a dupe before 541*7c478bd9Sstevel@tonic-gate # printing it 542*7c478bd9Sstevel@tonic-gate if ($lastpkg ne $pkg) { 543*7c478bd9Sstevel@tonic-gate print("P $pkg\t$PKGNAMES{$pkg}\n"); 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate $lastpkg = $pkg; 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate # reset the list for the next entry 550*7c478bd9Sstevel@tonic-gate @PkgList = ""; 551*7c478bd9Sstevel@tonic-gate} 552*7c478bd9Sstevel@tonic-gate 553