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