#!/usr/local/bin/perl -w # patchinfo - get info about a Sun patch (or many) from its file # # by Rob Funk , 21 Feb 2000 # # By default, prints most applicable combination of # Solaris Release, Unbundled Product, and Unbundled Release. # Options: # -s Show Synopsis instead of default # -v Show all key/value pairs # -c Send entire README file to standard output # -w Write README to file, filename in form 109999-01.README my $tar="/usr/local/bin/tar";# must be GNU tar, since we use O switch my $gzip="/usr/local/bin/gzip"; my $compress="/usr/local/bin/gzip";# can be compress or gzip my $unzip="/usr/local/bin/unzip";# /usr/bin/unzip on Solaris 7 and up my $awk="/usr/bin/nawk";# shouldn't be needed since we're in Perl sub get_type { my $type; my ($f)=@_; # find out type of file # $type=`/bin/file $f`; # slow but accurate # if ($type =~ /gzip/) { # $type="gzip"; # } elsif ($type =~ /zip/) { # $type="zip"; # } elsif ($type =~ /compress/) { # $type="compress"; # } else { # get it from filename (fast) if ($f =~ /\.zip$/i) { $type="zip"; } elsif ($f =~ /\.Z$/) { $type="compress"; } elsif ($f =~ /\.g?z$/) { $type="gzip"; } else { print STDERR "Unknown file type for $f\n"; $type=""; } # } return $type; } sub get_readme { my ($f,$type)=@_; my ($rlist,$readme); my ($min,$n); $min=99999; if ($type eq "compress") { $rlist="$compress -dc $f | $tar tf -"; } elsif ($type eq "gzip") { $rlist="$gzip -dc $f | $tar tf -"; } elsif ($type eq "zip") { $rlist="$unzip -l $f"; # | $awk '{print $4}' } if (! open(RLIST,"$rlist |")) { print(STDERR "Cannot list patch contents\n"); $readme=""; return $readme; } while () { next unless (/(^|\/)README/); chomp; if ($type eq "zip") { $_=(split(/\s+/,$_))[4]; } $n=s,/,/,g; # count slashes # take the README that's shallowest in the tree (fewest slashes) if ($n < $min) { $min=$n; $readme=$_; } } close(RLIST); return $readme; } sub get_subject { my($f,$r,$type)=@_; my ($rcat,$outfile); my ($k,$v,@v); my (%h); if ($type eq "compress") { $rcat="$compress -dc $f | $tar xOf - $r"; } elsif ($type eq "gzip") { $rcat="$gzip -dc $f | $tar xOf - $r"; } elsif ($type eq "zip") { $rcat="$unzip -p $f $r"; } if (! open(RCAT,"$rcat |")) { print(STDERR "Cannot open readme file\n"); $out=""; return $out; } if ($write) { $outfile=$f; $outfile =~ s,^.*/,,; # strip off initial path $outfile =~ s,\..*$,,;# strip off trailing extensions #$outfile =~ s,(\d{6})-\d{2},$1,; # strip off version $outfile = "$outfile.README"; if (! open(F,">$outfile")) { print STDERR "Cannot open $outfile for write\n"; $out=""; return $out; } print STDERR "Writing to $outfile\n"; select F; } while () { print if ($cat or $write); chomp; s/^Patch-ID#/Patch-ID:/; if (/: / and /^[A-Z]/) { ($k,@v) = split(/: /,$_); $v=join(": ",@v); next if ($k =~ /^ /); next if ($v =~ /^ /); $k =~ s/ +/ /g; $k =~ s/^ | $//g; $v =~ s/ +/ /g; $v =~ s/^ | $//g; if ($k and $v) { $v =~ s/Enterptise/Enterprise/g; # common(?) misspelling $k=lc($k); print "{$k} $v\n" if ($verbose); $h{$k} = $v; } } } close(RCAT); if ($write) { select STDOUT; close F; } if ($h{"unbundled product"}) { if ($h{"unbundled release"}) { $out=sprintf("%s %s",$h{"unbundled product"},$h{"unbundled release"}); } else { $out=$h{"unbundled product"}; } if ($h{"solaris release"} and $h{"solaris release"} !~ /[, ]/) { $out=sprintf("Solaris %s ; $out",$h{"solaris release"}); } } elsif ($h{"solaris release"}) { $out=sprintf("Solaris %s",$h{"solaris release"}); } elsif ($h{"sunos release"}) { if ($h{"sunos release"} =~ /^SunOS/) { $out=$h{"sunos release"}; } else { $out=sprintf("SunOS %s",$h{"sunos release"}); } } else { $out="" } if ($synopsis) { $out=$h{"synopsis"}; } return $out; } ######### my ($type,$readme,$subject); my (@flags,@args); local ($verbose,$cat,$synopsis); # globals for flags @flags=grep(/^-/,@ARGV); @args=grep(!/^-/,@ARGV); foreach $flag (@flags) { if ($flag eq "-h") { print < Usage: patchinfo [options] file ... By default, prints most applicable combination of Solaris Release, Unbundled Product, and Unbundled Release. Options: -s Show Synopsis instead of default -v Show all key/value pairs -c Send entire README file to standard output -w Write README to file, filename in form 109999-01.README -h This help listing EOH exit 0; } if ($flag eq "-v") { $verbose=1; } if ($flag eq "-c") { $cat=1; } if ($flag eq "-s") { $synopsis=1; } if ($flag eq "-w") { $write=1; } } foreach $file (@args) { $type=get_type($file); next unless ($type); $readme=get_readme($file,$type); next unless ($readme); $subject=get_subject($file,$readme,$type); next unless ($subject); next if ($cat or $verbose or $write); if ($#args > 0) { print "$file: $subject\n"; } else { print "$subject\n"; } } exit 0;