# $Header: emagent/sysman/admin/scripts/Ptdpm8.pm /stpl_db_11.2.0.2.0_aix.ppc64/2 2010/04/29 23:34:26 nparaddi Exp $ # # Package : Ptdpm8.pm # # Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. # # NAME # Ptdpm8.pm # # DESCRIPTION # Collects OS package and patch details # Also collects vendor products details # # NOTES # # MODIFIED (MM/DD/YY) # nparaddi 07/22/09 - Fix lslpp calls. see bug 8418254 # bguhatha 01/12/09 - bug-7593165 # sejain 08/21/07 - bug-6086631: fixing the logic to skip patches # skumar 01/09/04 - fix OS registered software # skumar 01/02/04 - fix instdate # skumar 12/31/03 - AIX changes # mgoodric 11/05/03 - include all packages in OS Components # mgoodric 06/16/03 - fix converting Solaris timezone to JAVA timezones # mgoodric 05/11/03 - added -debug tracing # mgoodric 04/07/03 - fix finding MAC address # goramamo 11/21/02 - Remove hardcode of /var/sadm/pkg # goramamo 07/01/02 - Bug 2441807 ( Zero byte pkginfo file ) # xxu 06/25/02 - remove /usr/local/bin/perl # vkhizder 06/20/02 - vkhizder_compare_fix_2420795_collection_script_changes # goramamo 06/20/02 - OS and other s/w collection # goramamo 05/01/02 - Creation # #************************************************************* use strict; package Ptdpm8; use Carp; require 5.005; #require 5.6.1; require Exporter; use ecmErrorMsgs; use Ptdpm0; use Ptdpm2; use Ptdpm3; use Ptdpm11; #****************************************** # Export Subroutines #****************************************** @Ptdpm8::ISA = ('Exporter'); @Ptdpm8::EXPORT = qw( &getSoftwareComponents ); #****************************************** # Global Variables #****************************************** use constant NIL => ''; #****************************************** # Exported Subroutines #****************************************** sub getSoftwareComponents($) { debugTrace('Calling... getSoftwareComponents()'); my $comp = $_[0]; my %prods = (); #my $pkgloc = getPkginfoFilesLocation(); #if ($pkgloc ne NIL) #{ # %prods = getProdDetails($comp, $pkgloc); #} %prods = getAIXProdDetails($comp); return %prods; } #****************************************** # Non Exported Subroutines #****************************************** sub getProdDetails($$) { debugTrace('Calling... getProdDetails()'); my $prodflag = $_[0]; my $pkgloc = $_[1]; my $reqdprod = 1; my $patchfound = 0; my %prods = (); my (@dlist) = (); my $index = NIL; my $vendor = NIL; my $prodname = $Ptdpm2::UNKNOWN; my $prodvers = NIL; my $location = NIL; my $prod_tag = '0'; my $pkg = NIL; my $patch = NIL; my $version = NIL; my $desc = NIL; my $instdate = NIL; my $tz = NIL; my $patdate = NIL; my $rest = NIL; my $sep = ' : '; my $size = 0; my $level = 3; my $i = 0; my $j = 0; my @patdet = (); my $pkginfofile = NIL; opendir(DIR, $pkgloc) || throwECMError('OpenFailure', $pkgloc); @dlist = readdir(DIR); closedir(DIR) || throwECMError('CloseFailure', $pkgloc); $size = scalar(@dlist); for ($i = 0 ; $i < $size ; $i++) { chomp($dlist[$i]); next if (($dlist[$i] eq '.') || ($dlist[$i] eq '..')); if (!(-d "$pkgloc/$dlist[$i]")) { # if $dlist[$i] is not a directory # pkginfo does not complain # showrev: get_env_var($dlist[$i], SUNW_PATCHID) #print STDERR "showrev: get_env_var($dlist[$i], SUNW_PATCHID)\n"; next; } $pkginfofile = "$pkgloc/$dlist[$i]/pkginfo"; if (-e $pkginfofile) { debugTrace('Opening... ' . $pkginfofile); open(IN1, "< $pkginfofile") || throwECMError('OpenFailure', $pkginfofile); $index = NIL; $vendor = NIL; $prodname = $Ptdpm2::UNKNOWN; $prodvers = NIL; $location = NIL; $pkg = NIL; $patch = NIL; $version = NIL; $desc = NIL; $instdate = NIL; $tz = NIL; $patchfound = 0; while () { chomp($_); if (index($_, "VENDOR=") > -1) { ($rest, $vendor) = split ('=', $_, 2); } elsif (index($_, "PRODNAME=") > -1) { ($rest, $prodname) = split ('=', $_, 2); } elsif (index($_, "PRODVERS=") > -1) { ($rest, $prodvers) = split ('=', $_, 2); } elsif (index($_, "PKG=") > -1) { ($rest, $pkg) = split ('=', $_, 2); } elsif (index($_, "VERSION=") > -1) { ($rest, $version) = split ('=', $_, 2); ($version, $rest) = split (',', $version, 2); } elsif (index($_, "DESC=") > -1) { ($rest, $desc) = split ('=', $_, 2); } elsif (index($_, "BASEDIR=") > -1) { ($rest, $location) = split ('=', $_, 2); } elsif (index($_, "TZ=") > -1) { ($rest, $tz) = split ('=', $_, 2); } elsif (index($_, "INSTDATE=") > -1) { ($rest, $instdate) = split ('=', $_, 2); } elsif (index($_, "PATCH_INFO_") > -1) { if ($reqdprod == 1) { if ($prodname eq $Ptdpm2::UNKNOWN) { if ($vendor eq NIL) { $vendor = $Ptdpm2::UNKNOWN; } if ($prodvers eq NIL) { $prodvers = $Ptdpm2::UNKNOWN; } } if ($prodflag eq "OS") { $index = $prodflag; } else { $index = $vendor . $sep . $prodname . $sep . $prodvers; } $patchfound = 1; @patdet = split ("From:", $_); @patdet = split ("=Installed:", $patdet[0]); ($rest, $patch) = split ("PATCH_INFO_", $patdet[0]); # Patch Details $level = 2; # Bug 2441807 # Patch INSTALLATION_DATE $patdate = convLocalTimeToYYYYMMDD_hhmmss_Zone($patdet[1]); if (!defined $prods{$index}{$level}{$patch} {$Ptdpm2::INSTALLATION_DATE_TAG} || $prods{$index}{$level}{$patch} {$Ptdpm2::INSTALLATION_DATE_TAG} eq NIL) { $prods{$index}{$level}{$patch} {$Ptdpm2::INSTALLATION_DATE_TAG} = $patdate; } else { $rest = $prods{$index}{$level}{$patch} {$Ptdpm2::INSTALLATION_DATE_TAG}; $prods{$index}{$level}{$patch} {$Ptdpm2::INSTALLATION_DATE_TAG} = join (',', $rest, $patdate); } $prods{$index}{$level}{$patch}{$Ptdpm2::NAME_TAG} = $patch; $prods{$index}{$level}{$patch}{$Ptdpm2::TYPE_TAG} = 'Patch'; $prods{$index}{$level}{$patch}{$Ptdpm2::VERSION_TAG} = NIL; $prods{$index}{$level}{$patch} {$Ptdpm2::DESCRIPTION_TAG} = NIL; $patch = NIL; $patdate = NIL; } } } close(IN1) || throwECMError('CloseFailure', $pkginfofile); if ($reqdprod == 1) { $instdate = trim($instdate); $instdate = convMon_DD_YYYY_To_YYYY_MM_DD2($instdate, $tz); if ($patchfound == 0) { if ($prodname eq $Ptdpm2::UNKNOWN) { if ($vendor eq NIL) { $vendor = $Ptdpm2::UNKNOWN; } if ($prodvers eq NIL) { $prodvers = $Ptdpm2::UNKNOWN; } } $index = $vendor . $sep . $prodname . $sep . $prodvers; } if ($prodflag eq "VENDOR") { $level = 0; # This new variable was introduced to handle # the package and patches with same names # across products and also to maintain the # hierarchy of components (Prod, Pkg, Patch) # VENDOR_SOFTWARE_LOCATION if (!defined $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG} || $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG} eq NIL) { $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG} = $location; } else { $rest = $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG}; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG} = join (',', $rest, $location); } # VENDOR_SOFTWARE_INSTALLATION_DATE if (!defined $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG} || $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG} eq NIL) { $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG} = $instdate; } else { $rest = $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG}; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG} = join (',', $rest, $instdate); } $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_NAME_TAG} = $vendor; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_NAME_TAG} = $prodname; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_VERSION_TAG} = $prodvers; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_DESCRIPTION_TAG} = NIL; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_SPECIFIC_INFORMATION_TAG} = NIL; } $level = 1; if ($pkg eq NIL) { $pkg = $dlist[$i]; # Bug 2441807, caused by 0 byte file. } $prods{$index}{$level}{$pkg}{$Ptdpm2::NAME_TAG} = $pkg; $prods{$index}{$level}{$pkg}{$Ptdpm2::TYPE_TAG} = 'Package'; $prods{$index}{$level}{$pkg}{$Ptdpm2::VERSION_TAG} = $version; $prods{$index}{$level}{$pkg}{$Ptdpm2::DESCRIPTION_TAG} = $desc; $prods{$index}{$level}{$pkg}{$Ptdpm2::INSTALLATION_DATE_TAG} = $instdate; } } else { # if $dlist[$i] is a dir and $dlist[$i]/pkginfo is not there # pkginfo does not complaint # showrev: /var/sadm/pkg/$dlist[$i]/pkginfo - No such file or directory throwECMError('FileNotFound', $pkginfofile); } } %prods = showProperValues(%prods); return %prods; } sub showProperValues { my (%prods) = @_; my $i = NIL; my $j = NIL; my $k = NIL; my $l = NIL; my @sortin = (); my @sortout = (); my $size = 0; for $i (sort keys %prods) { for $j (sort keys %{$prods{$i}}) { for $k (sort keys %{$prods{$i}{$j}}) { for $l (sort keys %{$prods{$i}{$j}{$k}}) { #print STDERR "$i $j $k $l $prods{$i}{$j}{$k}{$l}\n"; # debug if (index($l, $Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG) > -1) { @sortin = split (',', $prods{$i}{$j}{$k}{$l}); @sortout = sortuniq(@sortin); $prods{$i}{$j}{$k}{$l} = join (',', @sortout); } elsif (($l eq $Ptdpm2::INSTALLATION_DATE_TAG) && index($prods{$i}{$j}{$k}{$l}, ',') > -1) { @sortin = split (',', $prods{$i}{$j}{$k}{$l}); @sortout = sortuniq(@sortin); $size = scalar(@sortout) - 1; $prods{$i}{$j}{$k}{$l} = $sortout[$size]; } elsif ( index($l, $Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG) > -1 ) { @sortin = split (',', $prods{$i}{$j}{$k}{$l}); @sortout = sortuniq(@sortin); $prods{$i}{$j}{$k}{$l} = $sortout[0]; } } } } } return %prods; } sub getAIXProdDetails { debugTrace('Calling... getAIXProdDetails()'); my $prodflag = $_[0]; my %prods = (); my (@prodlist) = (); my (@fields) = (); my (@fields1) = (); my $index = NIL; my $vendor = 'IBM'; my $prodname = $Ptdpm2::UNKNOWN; my $prodvers = $Ptdpm2::UNKNOWN; my $location = NIL; my $state = NIL; my $tz = getTimeZone(); my $prod_tag = '0'; my $prodhist = NIL; my $pkg = NIL; my $patch = NIL; my $version = NIL; my $desc = NIL; my $instdate = NIL; my $sep = ' : '; my $size = 0; my $level = 3; my $i = 0; my @patdet = (); chomp($tz); # Build the tree of installation dates of products for later consumption my %prodInstDates = (); my $value=execCmd("$Ptdpm0::LSLPP -hc all"); my @instList=split('\n',$value); for ( my $i=0;$i <= $#instList;$i++) { chomp($instList[$i]); next unless ($instList[$i] =~ m/COMMIT/); my @fields = split(':',$instList[$i]); my $prodname=$fields[1]; my $prodVersion=$fields[2]; $fields[7] =~ s/;/:/g; my $instdate = convMMDDYY_To_YYYY_MM_DD($fields[6]); $instdate = $instdate . " " . $fields[7]. " " . "(" . $tz .")"; if ( $prodInstDates{$prodname}{'COMMIT'} eq NIL || compareDates($instdate,$prodInstDates{$prodname}{'COMMIT'} ) > 0 ) { $prodInstDates{$prodname}{'COMMIT'} = $instdate; } $prodInstDates{$prodname}{$prodVersion}=$instdate; } $value=execCmd("$Ptdpm0::LSLPP -Lc all 2>$Ptdpm0::DEVNULL | $Ptdpm0::TAIL -n +2"); @prodlist = split('\n',$value); $size = scalar(@prodlist); for ($i = 0 ; $i < $size ; $i++) { chomp($prodlist[$i]); @fields = split(":", $prodlist[$i]); $state = trim($fields[5]); next if ($state ne 'C' && $state ne 'A'); $pkg = trim($fields[0]); $prodname = trim($fields[1]); $prodvers = trim($fields[2]); $desc = trim($fields[7]); $index = $vendor . $sep . $prodname . $sep . $prodvers; if ($prodflag eq "VENDOR") { $level = 0; # This new variable was introduced to handle # the package and patches with same names # across products and also to maintain the # hierarchy of components (Prod, Pkg, Patch) $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG} = $location; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG} = $prodInstDates{$prodname}{'COMMIT'}; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_NAME_TAG} = $vendor; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_NAME_TAG} = $prodname; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_VERSION_TAG} = $prodvers; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_DESCRIPTION_TAG} = NIL; $prods{$index}{$level}{$prod_tag} {$Ptdpm2::VENDOR_SOFTWARE_SPECIFIC_INFORMATION_TAG} = NIL; } $level = 1; $prods{$index}{$level}{$prodname}{$Ptdpm2::NAME_TAG} = $prodname; $prods{$index}{$level}{$prodname}{$Ptdpm2::TYPE_TAG} = 'Package'; $prods{$index}{$level}{$prodname}{$Ptdpm2::VERSION_TAG} = $prodvers; $prods{$index}{$level}{$prodname}{$Ptdpm2::DESCRIPTION_TAG} = $desc; $prods{$index}{$level}{$prodname}{$Ptdpm2::INSTALLATION_DATE_TAG} = $prodInstDates{$prodname}{'COMMIT'}; } if ($prodflag eq "VENDOR") { %prods = showProperValues(%prods); return %prods; } $value = execCmd("$Ptdpm0::INSTFIX -i -c"); @patdet = split('\n',$value); $size = scalar(@patdet); $level = 2; for ($i = 0 ; $i < $size ; $i++) { chomp($patdet[$i]); @fields = split(":", $patdet[$i]); $patch = trim($fields[0]); $prodvers = trim($fields[3]); $state = trim($fields[4]); $desc = trim($fields[5]); if (($state eq '=') && ($patch ne NIL)) { if ($prodflag eq "OS") { $index = $prodflag; } else { $index = $vendor . $sep . $patch . $sep . $prodvers; } $prods{$index}{$level}{$patch}{$Ptdpm2::INSTALLATION_DATE_TAG} = $prodInstDates{$fields[1]}{$prodvers}; $prods{$index}{$level}{$patch}{$Ptdpm2::NAME_TAG} = $patch; $prods{$index}{$level}{$patch}{$Ptdpm2::TYPE_TAG} = 'Patch'; $prods{$index}{$level}{$patch}{$Ptdpm2::VERSION_TAG} = $prodvers; $prods{$index}{$level}{$patch} {$Ptdpm2::DESCRIPTION_TAG} = $desc; } # skip to the next patch for ($i ; $i+1 < $size; $i++) { chomp($patdet[$i+1]); @fields = split(":", $patdet[$i+1]); if ($fields[0] ne $patch) { last; }; } } %prods = showProperValues(%prods); return %prods; } 1; # End of the Program