1*0Sstevel@tonic-gate#!/usr/bin/perl 2*0Sstevel@tonic-gate# 3*0Sstevel@tonic-gate# CDDL HEADER START 4*0Sstevel@tonic-gate# 5*0Sstevel@tonic-gate# The contents of this file are subject to the terms of the 6*0Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only 7*0Sstevel@tonic-gate# (the "License"). You may not use this file except in compliance 8*0Sstevel@tonic-gate# with the License. 9*0Sstevel@tonic-gate# 10*0Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*0Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing. 12*0Sstevel@tonic-gate# See the License for the specific language governing permissions 13*0Sstevel@tonic-gate# and limitations under the License. 14*0Sstevel@tonic-gate# 15*0Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each 16*0Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*0Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the 18*0Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying 19*0Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner] 20*0Sstevel@tonic-gate# 21*0Sstevel@tonic-gate# CDDL HEADER END 22*0Sstevel@tonic-gate# 23*0Sstevel@tonic-gate# 24*0Sstevel@tonic-gate# Copyright (c) 2000 by Sun Microsystems, Inc. 25*0Sstevel@tonic-gate# All rights reserved. 26*0Sstevel@tonic-gate# 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate# ident "%Z%%M% %I% %E% SMI" 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate$PkgDir = "/var/sadm/pkg"; # where to find the pkg directories 31*0Sstevel@tonic-gate$PROGRAM_NAME = "make_pkg_db"; 32*0Sstevel@tonic-gate$DBM_DIR_CHARACTERIZATION = "directory for the dbm databases"; 33*0Sstevel@tonic-gate$INPUT_FILES_CHARACTERIZATION = "one or more files in /var/sadm/install/contents format"; 34*0Sstevel@tonic-gate$PKGDEFS_DIRECTORY = "package pool directory"; 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate$Usage = 37*0Sstevel@tonic-gate"Usage: $PROGRAM_NAME 38*0Sstevel@tonic-gate [-ifiles <$INPUT_FILES_CHARACTERIZATION>] 39*0Sstevel@tonic-gate [-pkgdef <$PKGDEFS_DIRECTORY>] 40*0Sstevel@tonic-gate -dbdir <$DBM_DIR_CHARACTERIZATION> 41*0Sstevel@tonic-gate [-h for help]\n"; 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate$Help = 44*0Sstevel@tonic-gate"This program initializes a set of dbm databases with information 45*0Sstevel@tonic-gatefrom /var/sadm/install/contents or a user-defined package pool directory. 46*0Sstevel@tonic-gateThere is one required argument: 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate -dbdir <dir> the $DBM_DIR_CHARACTERIZATION 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate\nThe optional argument -h produces this message instead of any processing. 51*0Sstevel@tonic-gate\nThe optional argument -ifiles is used for symbolic link resolution. 52*0Sstevel@tonic-gate\nThe optional argument -pkgdef creates the databases based upon a package \npool directory instead of /var/sadm/install/contents on the local machine. 53*0Sstevel@tonic-gate"; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate# 57*0Sstevel@tonic-gate# check for perl5 -- we use things unavailable in perl4 58*0Sstevel@tonic-gate# 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gatedie "Sorry, this program requires perl version 5.000 or up. You have $]. Stopping" if $] < 5.000; 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate# 63*0Sstevel@tonic-gate# process arguments 64*0Sstevel@tonic-gate# 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate$PKGDefs = ""; 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gatewhile (@ARGV) { 69*0Sstevel@tonic-gate $arg = shift (@ARGV); 70*0Sstevel@tonic-gate if ($arg eq "-h") { 71*0Sstevel@tonic-gate print "$Help\n$Usage"; 72*0Sstevel@tonic-gate exit 0; 73*0Sstevel@tonic-gate } elsif ($arg eq "-ifiles") { 74*0Sstevel@tonic-gate while (($ARGV[0] !~ /^-/) && (@ARGV)){ 75*0Sstevel@tonic-gate push (@IFiles, shift(@ARGV)); 76*0Sstevel@tonic-gate } 77*0Sstevel@tonic-gate } elsif ($arg eq "-dbdir") { 78*0Sstevel@tonic-gate $DBDir = shift(@ARGV) unless ($ARGV[0] =~ /^-/); 79*0Sstevel@tonic-gate } elsif ($arg eq "-pkgdef") { 80*0Sstevel@tonic-gate $PKGDefs = shift(@ARGV) unless ($ARGV[0] =~ /^-/); 81*0Sstevel@tonic-gate } else { 82*0Sstevel@tonic-gate print STDERR "Unrecognized argument $arg. \n$Usage"; 83*0Sstevel@tonic-gate exit 1; 84*0Sstevel@tonic-gate } 85*0Sstevel@tonic-gate} 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate# make sure the package pool directory exists 88*0Sstevel@tonic-gateif (($PKGDefs) && !(-d $PKGDefs)) { 89*0Sstevel@tonic-gate print STDERR "Cannot open the directory $PKGDefs\n"; 90*0Sstevel@tonic-gate exit 1; 91*0Sstevel@tonic-gate} 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate# Here we define the input files which will be parsed 94*0Sstevel@tonic-gateif ($PKGDefs) { 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate $dirs = `ls $PKGDefs`; 97*0Sstevel@tonic-gate @dirlist = split(/\s*\n\s*/, $dirs); 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate foreach $dir (@dirlist) { 100*0Sstevel@tonic-gate push(@IFiles, "$PKGDefs/$dir/pkgmap"); 101*0Sstevel@tonic-gate } 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate reverse(@IFiles); 104*0Sstevel@tonic-gate} 105*0Sstevel@tonic-gateelse { 106*0Sstevel@tonic-gate push(@IFiles, "/var/sadm/install/contents"); 107*0Sstevel@tonic-gate} 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gateif (!@IFiles) { 110*0Sstevel@tonic-gate print STDERR "Required argument -ifiles missing. \n$Usage"; 111*0Sstevel@tonic-gate exit 1; 112*0Sstevel@tonic-gate} 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gateif (!$DBDir) { 115*0Sstevel@tonic-gate print STDERR "Required argument -dbdir missing. \n$Usage"; 116*0Sstevel@tonic-gate exit 1; 117*0Sstevel@tonic-gate} 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate$Struct = \%struct; # here is the structure we'll store everything in 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate# 124*0Sstevel@tonic-gate# now open the dbm databases we will initialize 125*0Sstevel@tonic-gate# 126*0Sstevel@tonic-gate&yelp ("...initializing the databases\n"); 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gateunless (-d "$DBDir") { 129*0Sstevel@tonic-gate &yelp("Creating directory $DBDir\n"); 130*0Sstevel@tonic-gate mkdir($DBDir, 0777); 131*0Sstevel@tonic-gate} 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate# db for package names from the /var/sadm/pkg/foo/pkginfo files 134*0Sstevel@tonic-gatedbmopen(%PKGNAMES, "$DBDir/PKGNAMES", 0644) || die"Cannot open dbm db $DBDir/PKGNAMES\n"; 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate# db for entity file types 137*0Sstevel@tonic-gatedbmopen(%FTYPE, "$DBDir/FTYPE", 0664) || die"Cannot open dbm db $DBDir/FTYPE\n"; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate# db for entity modes types 140*0Sstevel@tonic-gatedbmopen(%MODE, "$DBDir/MODE", 0664) || die"Cannot open dbm db $DBDir/MODE\n"; 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate# db for entity packages 143*0Sstevel@tonic-gatedbmopen(%PKGS, "$DBDir/PKGS", 0664) || die"Cannot open dbm db $DBDir/PKGS\n"; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate# db for absolute link targets 146*0Sstevel@tonic-gatedbmopen(%ABSLINK, "$DBDir/ABSLINK", 0664) || die"Cannot open dbm db $DBDir/ABSLINK\n"; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gateundef %FTYPE; # remove existing records, if any 150*0Sstevel@tonic-gateundef %MODE; 151*0Sstevel@tonic-gateundef %PKGS; 152*0Sstevel@tonic-gateundef %ABSLINK; 153*0Sstevel@tonic-gateundef %PKGNAMES; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate$Debug = 1; # print extra gibberish 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate# 158*0Sstevel@tonic-gate# go make the package names db 159*0Sstevel@tonic-gate# 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate&MakePackageNamesDB($PkgDir); 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate# 164*0Sstevel@tonic-gate# read and parse each input file in contents file format 165*0Sstevel@tonic-gate# 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate&yelp ("...making the FTYPE MODE and PKGS databases\n"); 168*0Sstevel@tonic-gateforeach $IFile (@IFiles) { 169*0Sstevel@tonic-gate if ($PKGDefs) { 170*0Sstevel@tonic-gate unless (-r $IFile) { 171*0Sstevel@tonic-gate print STDERR "Could not open file: $IFile\n"; 172*0Sstevel@tonic-gate next; 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate @pkgname = split("/", $IFile); 176*0Sstevel@tonic-gate $thisPkg = @pkgname[($#pkgname-1)]; 177*0Sstevel@tonic-gate $pkgInfo="$PKGDefs/$thisPkg/pkginfo"; 178*0Sstevel@tonic-gate $thisBaseDir=""; 179*0Sstevel@tonic-gate if (-r $pkgInfo) { 180*0Sstevel@tonic-gate $BASEDIR = `grep '^BASEDIR' $pkgInfo`; 181*0Sstevel@tonic-gate $BASEDIR =~ s/^BASEDIR=//; 182*0Sstevel@tonic-gate chomp($BASEDIR); 183*0Sstevel@tonic-gate $thisBaseDir = $BASEDIR; 184*0Sstevel@tonic-gate } 185*0Sstevel@tonic-gate } 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate open (IFILE, "$IFile") || die "cannot open input file $IFile\n"; 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate # Tell the user what we are looking at UNLESS they are looking at a package 190*0Sstevel@tonic-gate # pool. A package pool could have hundreds of entries which just creates 191*0Sstevel@tonic-gate # a lot of useless (and confusing) output. 192*0Sstevel@tonic-gate &yelp("...opening $IFile\n") unless ($PKGDefs); 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate while (<IFILE>) { # loop over file line-at-a-time 195*0Sstevel@tonic-gate if ($PKGDefs) { 196*0Sstevel@tonic-gate next if /^:/; # ignore these lines from a pkgmap 197*0Sstevel@tonic-gate next if (/(\S+)\s+[i]\s+/); 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate else { 200*0Sstevel@tonic-gate next if /^#/; # ignore comments 201*0Sstevel@tonic-gate next if /^\s*$/; # ignore blanks 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate chop; 206*0Sstevel@tonic-gate undef $FType; 207*0Sstevel@tonic-gate undef $Mode; 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate $line=$_; 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate if ($PKGDefs) { 212*0Sstevel@tonic-gate &ParsePkgmapEntry($line); 213*0Sstevel@tonic-gate @Pkgs = $thisPkg; 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate else { 216*0Sstevel@tonic-gate &ParseContentsEntry($_); 217*0Sstevel@tonic-gate } 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate # if this entry was supplied by a earlier file, skip it 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate if ($FTYPE{$Entity} =~ /\w/) { 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate # don't bother complaining about directories, we know the same 224*0Sstevel@tonic-gate # directory could exist in multiple packages 225*0Sstevel@tonic-gate next if ($FTYPE{$Entity} eq "d"); 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate if ($PKGDefs) { 228*0Sstevel@tonic-gate # In the case where we are going through a package pool, we 229*0Sstevel@tonic-gate # expect that a file may reside in multiple packages. If 230*0Sstevel@tonic-gate # that is detected, we simply add this package to the list of 231*0Sstevel@tonic-gate # packages for that file 232*0Sstevel@tonic-gate 233*0Sstevel@tonic-gate $currPkgs = $PKGS{$Entity}; 234*0Sstevel@tonic-gatenext if ($FTYPE{$Entity} eq "s"); 235*0Sstevel@tonic-gate $PKGS{$Entity} = "$currPkgs $thisPkg"; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate else { 238*0Sstevel@tonic-gate # In the case where we are reading in from 239*0Sstevel@tonic-gate # /var/sadm/install.contents, we do not expect to see any 240*0Sstevel@tonic-gate # over-ridden files EXCEPT when the "-ifiles" option is used. 241*0Sstevel@tonic-gate &yelp("...OVERRIDDEN: $line\n"); 242*0Sstevel@tonic-gate } 243*0Sstevel@tonic-gate next; 244*0Sstevel@tonic-gate } else { 245*0Sstevel@tonic-gate $Package = join(" ",@Pkgs);# store supplying packages sep by " " 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate # This is a hack. In the case of directories like /bin which 248*0Sstevel@tonic-gate # would belong in many packages, the $PKGS hash would not 249*0Sstevel@tonic-gate # be able to handle such a long entry. So for directories, I 250*0Sstevel@tonic-gate # just place the first package I find. For this tool, it doesn't 251*0Sstevel@tonic-gate # matter since this tool does not report which directories come 252*0Sstevel@tonic-gate # from which package. 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate if ($FType eq "d") { 255*0Sstevel@tonic-gate @FirstPackage = split(" ", $Package); 256*0Sstevel@tonic-gate $PKGS{$Entity} = $FirstPackage[0]; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate else { 259*0Sstevel@tonic-gate $PKGS{$Entity} = $Package; # update PKGS database 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate # 264*0Sstevel@tonic-gate # put what we need from this entry line into the dbs 265*0Sstevel@tonic-gate # 266*0Sstevel@tonic-gate 267*0Sstevel@tonic-gate &yelp ("***NO FILETYPE! IGNORING ENTRY: $_\n") unless $FType; 268*0Sstevel@tonic-gate $FTYPE{$Entity} = $FType; # update the FTYPE database 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate # 271*0Sstevel@tonic-gate # now collect the possible paths for each basename 272*0Sstevel@tonic-gate # 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gate ($path, $base) = $Entity =~ /(.*\/)(.*)/; 275*0Sstevel@tonic-gate push(@{$Struct->{"PATHS"}->{$base}}, $Entity); 276*0Sstevel@tonic-gate if ($FType =~ /[ls]/) { # link 277*0Sstevel@tonic-gate $rellinkent = "$Entity;$RelEntity"; 278*0Sstevel@tonic-gate push (@RelLinkEnts,$rellinkent); # make list of ents to resolve 279*0Sstevel@tonic-gate } else { 280*0Sstevel@tonic-gate $MODE{$Entity} = $Mode if $Mode ne ""; # update MODE database 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate } 283*0Sstevel@tonic-gate close IFILE; 284*0Sstevel@tonic-gate} # end foreach $IFile 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate# 287*0Sstevel@tonic-gate# now convert the relative links into absolute ones 288*0Sstevel@tonic-gate# 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate&yelp ("...making the ABSLINK database\n"); 291*0Sstevel@tonic-gateforeach $rellinkent (@RelLinkEnts) { 292*0Sstevel@tonic-gate ($Entity, $RelEntity) = split(/;/, $rellinkent); 293*0Sstevel@tonic-gate $AbsLink = &GetAbsLink($Entity, $RelEntity); 294*0Sstevel@tonic-gate $ABSLINK{$Entity} = $AbsLink; 295*0Sstevel@tonic-gate} 296*0Sstevel@tonic-gate 297*0Sstevel@tonic-gate# 298*0Sstevel@tonic-gate# close the dbs -- we're done 299*0Sstevel@tonic-gate# 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gatedbmclose (FTYPE); 302*0Sstevel@tonic-gatedbmclose (MODE); 303*0Sstevel@tonic-gatedbmclose (PKGS); 304*0Sstevel@tonic-gatedbmclose (ABSLINK); 305*0Sstevel@tonic-gatedbmclose (PKGNAMES); 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate&yelp ("...DONE\n"); 308*0Sstevel@tonic-gate#===========================END OF MAIN==================================== 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gatesub GetAbsLink { # convert relative link to actual one 311*0Sstevel@tonic-gatelocal ($entry, $rellink) = @_; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate return $rellink if $rellink =~ /^\//; # just return if abs already 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate @RelPath = split(/\//,$rellink); 316*0Sstevel@tonic-gate @EntryPath = split(/\//,$entry); 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate # 319*0Sstevel@tonic-gate # get the filename part 320*0Sstevel@tonic-gate # 321*0Sstevel@tonic-gate 322*0Sstevel@tonic-gate undef @AbsPath; 323*0Sstevel@tonic-gate @AbsPath = (pop(@RelPath)) if $RelPath[$#RelPath] =~ /w/; 324*0Sstevel@tonic-gate pop @EntryPath; 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate # 327*0Sstevel@tonic-gate # pop the relative path until a relative dir shows up 328*0Sstevel@tonic-gate # 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate while (@RelPath) { 331*0Sstevel@tonic-gate $relhere = pop(@RelPath); 332*0Sstevel@tonic-gate if ($relhere =~ /\w/) { # there's a letter or number 333*0Sstevel@tonic-gate unshift (@AbsPath, $relhere); # its a dirname; keep it 334*0Sstevel@tonic-gate } elsif ($relhere =~ /^\.\.$/) { # its a .. pop up one dir 335*0Sstevel@tonic-gate pop(@EntryPath); 336*0Sstevel@tonic-gate } elsif ($relhere =~ /^\.$/) { # it's a . -- stop 337*0Sstevel@tonic-gate last; 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate while (@EntryPath) { # complete the path 342*0Sstevel@tonic-gate unshift(@AbsPath, pop(@EntryPath)); # ...from the remaining entry 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate $abspath = join("/", @AbsPath); 345*0Sstevel@tonic-gate if (!$FTYPE{$abspath}) { # no installed entity ! 346*0Sstevel@tonic-gate# NICKI - for now 347*0Sstevel@tonic-gate &yelp("***CANNOT FIND ABSOLUTE PATH $abspath FOR ENTRY: $entry=$rellink\n"); 348*0Sstevel@tonic-gate# &yelp("***CANNOT RESOLVE ABSOLUTE PATH $abspath\n"); 349*0Sstevel@tonic-gate 350*0Sstevel@tonic-gate# COMMENTED OUT BY NICKI 351*0Sstevel@tonic-gate# $base = $rellink; 352*0Sstevel@tonic-gate# $base =~ s/.*\///; # get basename we're looking for 353*0Sstevel@tonic-gate# @cans = @{$Struct->{"PATHS"}->{$base}}; # get all entities ... 354*0Sstevel@tonic-gate# $numcans = $#cans + 1; # ... with this base 355*0Sstevel@tonic-gate 356*0Sstevel@tonic-gate# &yelp(" There are $numcans entries with this basename:\n"); 357*0Sstevel@tonic-gate# foreach $can (@cans) { 358*0Sstevel@tonic-gate# &yelp(" $can\n"); 359*0Sstevel@tonic-gate# } 360*0Sstevel@tonic-gate# $abspath = ""; 361*0Sstevel@tonic-gate } 362*0Sstevel@tonic-gate return $abspath; 363*0Sstevel@tonic-gate} 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gatesub ParseContentsEntry { 366*0Sstevel@tonic-gate#invocation: &ParseContentsEntry($l); # $l is a line in the file 367*0Sstevel@tonic-gatelocal ($l) = @_; 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate # 370*0Sstevel@tonic-gate # look for b or c entries, like: 371*0Sstevel@tonic-gate # /devices/pseudo/openeepr@0:openprom c none 38 0 0640 root sys SUNWcsd 372*0Sstevel@tonic-gate # 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate if (($Entity,$FType,$Class,$Maj,$Min,$Mode,$Owner,$Group,@Pkgs) = 375*0Sstevel@tonic-gate ($l =~ /^(\S+)\s+([bc])\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-7]+)\s+([a-z]+)\s+([a-z]+)\s+([A-Z].*)/)) { 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate # 378*0Sstevel@tonic-gate # look for d entries, like 379*0Sstevel@tonic-gate # /devices/pseudo d none 0755 root sys SUNWcsd 380*0Sstevel@tonic-gate # 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate } elsif (($Entity,$FType,$Class,$Mode,$Owner,$Group,@Pkgs) = 383*0Sstevel@tonic-gate ($l =~ /^(\S+)\s+([d])\s+(\w+)\s+([0-7]+)\s+([a-z]+)\s+([a-z]+)\s+([A-Z].*)/)) { 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gate # 386*0Sstevel@tonic-gate # look for f or e or v entries, like 387*0Sstevel@tonic-gate # /etc/asppp.cf f none 0744 root sys 360 27915 801314234 SUNWapppr 388*0Sstevel@tonic-gate # 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate } elsif (($Entity,$FType,$Class,$Mode,$Owner,$Group, 391*0Sstevel@tonic-gate $Size,$Checksum,$Modtime,@Pkgs) = 392*0Sstevel@tonic-gate ($l =~ /^(\S+)\s+([fev])\s+(\w+)\s+([0-7]+)\s+([a-z]+)\s+([a-z]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([A-Z].*)/)) { 393*0Sstevel@tonic-gate 394*0Sstevel@tonic-gate # 395*0Sstevel@tonic-gate # look for l or s entries, like 396*0Sstevel@tonic-gate # /bin=./usr/bin s none SUNWcsr 397*0Sstevel@tonic-gate # 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate } elsif (($Entity,$RelEntity,$FType,$Class,@Pkgs) = 400*0Sstevel@tonic-gate ($l =~ /^([^=]+)=(\S+)\s+([ls])\s+(\w+)\s+([A-Z].*)/)) { 401*0Sstevel@tonic-gate } else { 402*0Sstevel@tonic-gate print STDERR "Unrecognized entry in $IFile: $l\n"; 403*0Sstevel@tonic-gate } 404*0Sstevel@tonic-gate} 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gatesub ParsePkgmapEntry { 407*0Sstevel@tonic-gatelocal ($line) = @_; 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate # for validation of input 410*0Sstevel@tonic-gate $Unresolved = true; 411*0Sstevel@tonic-gate 412*0Sstevel@tonic-gate # look for d entries, like 413*0Sstevel@tonic-gate # 1 d root etc 775 root sys 414*0Sstevel@tonic-gate 415*0Sstevel@tonic-gate if (($Part,$FType,$Class,$Entity,$Mode,$Owner,$Group) = 416*0Sstevel@tonic-gate ($line =~ /^(\S+)\s+([d])\s+(\w+)\s+(\S+)\s+(\d+)\s+(\w+)\s+(\w+)/)) { 417*0Sstevel@tonic-gate # prepend a install root 418*0Sstevel@tonic-gate if ($thisBaseDir eq "/") { 419*0Sstevel@tonic-gate $Entity = "/$Entity"; 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate else { 422*0Sstevel@tonic-gate $Entity = "$thisBaseDir/$Entity"; 423*0Sstevel@tonic-gate } 424*0Sstevel@tonic-gate $Unresolved = false; 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate 427*0Sstevel@tonic-gate # look for e,f or v entries, like 428*0Sstevel@tonic-gate # 1 e master boot/solaris/devicedb/master 0644 root sys 75 5775 940882596 429*0Sstevel@tonic-gate 430*0Sstevel@tonic-gate elsif (($Part,$FType,$Class,$Entity,$Mode,$Owner,$Group,$Size,$Checksum,$Modtime) = 431*0Sstevel@tonic-gate ($line =~ /^(\S+)\s+([efv])\s+(\w+)\s+(\S+)\s+(\d+)\s+(\w+)\s+(\w+)/)) { 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate # prepend a install root 434*0Sstevel@tonic-gate if ($thisBaseDir eq "/") { 435*0Sstevel@tonic-gate $Entity = "/$Entity"; 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate else { 438*0Sstevel@tonic-gate $Entity = "$thisBaseDir/$Entity"; 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate $Unresolved = false; 441*0Sstevel@tonic-gate } 442*0Sstevel@tonic-gate elsif (($Part, $FType, $Class, $Entity, $RelEntity) = 443*0Sstevel@tonic-gate ($line =~ /^(\S+)\s+([ls])\s+(\w+)\s+(\S+)[=](\S+)/)) { 444*0Sstevel@tonic-gate 445*0Sstevel@tonic-gate # prepend a install root 446*0Sstevel@tonic-gate if ($thisBaseDir eq "/") { 447*0Sstevel@tonic-gate $Entity = "/$Entity"; 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate else { 450*0Sstevel@tonic-gate $Entity = "$thisBaseDir/$Entity"; 451*0Sstevel@tonic-gate } 452*0Sstevel@tonic-gate $Unresolved = false; 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate print ("UNRESOLVED: $line\n") if ($Unresolved eq true); 456*0Sstevel@tonic-gate} 457*0Sstevel@tonic-gate 458*0Sstevel@tonic-gatesub ParsePrototypeEntry { 459*0Sstevel@tonic-gate#invocation: &ParsePrototypeEntry($l); # $l is a line in the file 460*0Sstevel@tonic-gatelocal ($l) = @_; 461*0Sstevel@tonic-gate 462*0Sstevel@tonic-gate # 463*0Sstevel@tonic-gate # look for b or c entries, like: 464*0Sstevel@tonic-gate # /devices/pseudo/openeepr@0:openprom c none 38 0 0640 root sys SUNWcsd 465*0Sstevel@tonic-gate # 466*0Sstevel@tonic-gate 467*0Sstevel@tonic-gate if (($Entity,$FType,$Class,$Maj,$Min,$Mode,$Owner,$Group,@Pkgs) = 468*0Sstevel@tonic-gate ($l =~ /^(\S+)\s+([bc])\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-7]+)\s+([a-z]+)\s+([a-z]+)\s+([A-Z].*)/)) { 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate # 471*0Sstevel@tonic-gate # look for d entries, like 472*0Sstevel@tonic-gate # d root etc 775 root sys 473*0Sstevel@tonic-gate # 474*0Sstevel@tonic-gate 475*0Sstevel@tonic-gate } elsif (($FType,$Class,$Entity,$Mode,$Owner,$Group) = 476*0Sstevel@tonic-gate ($l =~ /^([d])\s+(\w+)\s+(\S+)\s+([0-7]+)\s+(\w+)\s+(\w+)/)) { 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate # 479*0Sstevel@tonic-gate # look for f or e or v entries, like 480*0Sstevel@tonic-gate # e preserve etc/acct/holidays 664 bin bin 481*0Sstevel@tonic-gate # 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate } elsif (($FType,$Class,$Entity,$Mode,$Owner,$Group) = 484*0Sstevel@tonic-gate ($l =~ /^([fev])\s+(\w+)\s+(\S+)\s+([0-7]+)\s+(\w+)\s+(\w+)/)) { 485*0Sstevel@tonic-gate 486*0Sstevel@tonic-gate # 487*0Sstevel@tonic-gate # look for l or s entries, like 488*0Sstevel@tonic-gate # l root etc/rc2.d/S21perf=../../etc/init.d/perf 489*0Sstevel@tonic-gate # 490*0Sstevel@tonic-gate 491*0Sstevel@tonic-gate } elsif (($FType,$Class,$Entity,$RelEntity) = 492*0Sstevel@tonic-gate ($l =~ /^([ls])\s+(\w+)\s+([^=]+)=(\S+)/)) { 493*0Sstevel@tonic-gate } else { 494*0Sstevel@tonic-gate print STDERR "Unrecognized Prototype File entry: $l\n"; 495*0Sstevel@tonic-gate } 496*0Sstevel@tonic-gate} 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gatesub yelp { 499*0Sstevel@tonic-gatelocal($String) = @_; 500*0Sstevel@tonic-gate print "$String"; 501*0Sstevel@tonic-gate} 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gatesub MakePackageNamesDB { 506*0Sstevel@tonic-gate#invocation: &MakePackageNamesDB($PkgDir); 507*0Sstevel@tonic-gatelocal ($PkgDir) = @_; # argument is parent directory of pkg dirs 508*0Sstevel@tonic-gate 509*0Sstevel@tonic-gate #$PkgDir = "/var/sadm/pkg"; 510*0Sstevel@tonic-gate opendir(PKGDIR, "$PkgDir") || die "Cannot open package directory $PkgDir\n"; 511*0Sstevel@tonic-gate @Pkgs = grep(/^[A-Z]/,readdir(PKGDIR)); # list of all package directories 512*0Sstevel@tonic-gate foreach $Pkg (@Pkgs) { # loop over 'em 513*0Sstevel@tonic-gate $InfoFile = "$PkgDir/$Pkg/pkginfo"; # full name of the pkginfo file 514*0Sstevel@tonic-gate if (-r $InfoFile) { # if we can read it 515*0Sstevel@tonic-gate $str = `grep '^NAME=' $InfoFile`; # just grep the entry 516*0Sstevel@tonic-gate $str =~ s/\s*\n$//; # trim trailing ws 517*0Sstevel@tonic-gate $str =~ s/.*=\s*//; # trim leading NAME= 518*0Sstevel@tonic-gate if ($str =~ /\w/) { # if the name has a letter or number in it 519*0Sstevel@tonic-gate $PKGNAMES{$Pkg} = $str; 520*0Sstevel@tonic-gate } else { 521*0Sstevel@tonic-gate &yelp("***Cannot find usable NAME entry in $InfoFile\n"); 522*0Sstevel@tonic-gate } 523*0Sstevel@tonic-gate } else { 524*0Sstevel@tonic-gate &yelp("***Cannot find readable file $InfoFile\n"); 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate } # end of loop over package directories 527*0Sstevel@tonic-gate} 528