Listing 2 find_reqs.pl
#!/usr/bin/perl
#
# NEPD Consulting
# Paul Guglielmino <paulg@nepd.com>
#
# Please send improvements or comments to me!
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
use strict;
use warnings;
use Getopt::Long;
my($version) = "1";
my($xref, $debug, $usage, $v);
Getopt::Long::Configure( 'permute' );
GetOptions( 'xref=s' => \$xref, 'debug' => \$debug,
'help' => \$usage, 'version' => \$v );
if ( $usage ) { print_usage(); exit 0; }
if ( $v ) { print_version(); exit 0; }
my($patch) = $ARGV[0];
if ( ! $patch ) {
print_usage();
exit 2;
}
# Holds all information on prerequisite patches. It is a hash of arrays.
my(%prereqs, %patchrevs) = ();
# Take cmd line options or supply reasonable defaults
$debug = $debug || 0;
my($patchdiag) = $xref || "patchdiag.xref";
# Load information from out Patchdiag file
read_patchdiag($patchdiag);
# Generate a list of all requires patches and remove the duplicates
my(@required_patches) = find_allreqs($patch);
@required_patches = do { my %seen; grep !$seen{$_}++, @required_patches };
print "| ", join(" ", reverse(@required_patches)), " |\n";
exit 0;
# Use already defined structures to recurse through needed patches
sub find_allreqs {
my $i;
my $p = $_[0];
my(@patches_to_check, @patch_list);
if ( defined @{$prereqs{$p}} ) {
$debug && print "Recursing down from: $p\n";
@patches_to_check = @{$prereqs{$p}};
push(@patch_list, $p);
foreach $i (@patches_to_check) {
push(@patch_list, find_allreqs(patchid($i)));
}
} else {
$debug && print "Leaf patch: $p\n";
push(@patch_list, $p);
}
return @patch_list;
}
# Return just the major patch id
sub patchid {
return( (split(/-/, $_[0]))[0] );
}
# Return just the rev number
sub patchrev {
return( (split(/-/, $_[0]))[1] );
}
# Read the entire file, look out for comments and others things not
# directly related to the patch information
sub read_patchdiag {
my($patchdiag_file) = $_[0];
my(@line, @prs, $x, $p);
open(PD, "$patchdiag_file") || die "No $patchdiag found\n";
while( <PD> ) {
if ( /^\d/ ) {
@line = split(/\|/);
@prs = ($line[8] =~ /(\d{6}-\d{2};)+?/g);
$patchrevs{patchid($line[0])} = patchrev($line[0]);
#print "$line[0] - @prs\n";
foreach $p (@prs) {
push( @{$prereqs{$line[0]}}, patchid($p) );
}
}
}
close(PD);
}
sub print_usage {
print<<EOT;
Show all required prerequisites for a Solaris patch.
Usage: $0 [OPTIONS]... Patch Number
\t --help [This message]
\t --debug [Show debugging output]
\t --xref=<filename> [Match patches against give xref file]
\t --version [Print version number]
EOT
}
sub print_version {
print "$0: Version $version\n\n";
} |