xref: /onnv-gate/usr/src/cmd/sgs/crle/common/config.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*0Sstevel@tonic-gate 
28*0Sstevel@tonic-gate #include	<sys/mman.h>
29*0Sstevel@tonic-gate #include	<sys/types.h>
30*0Sstevel@tonic-gate #include	<fcntl.h>
31*0Sstevel@tonic-gate #include	<unistd.h>
32*0Sstevel@tonic-gate #include	<errno.h>
33*0Sstevel@tonic-gate #include	<stdio.h>
34*0Sstevel@tonic-gate #include	<string.h>
35*0Sstevel@tonic-gate #include	"rtc.h"
36*0Sstevel@tonic-gate #include	"_crle.h"
37*0Sstevel@tonic-gate #include	"msg.h"
38*0Sstevel@tonic-gate 
39*0Sstevel@tonic-gate #pragma	ident	"%Z%%M%	%I%	%E% SMI"
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate #define	MAXNBKTS 10007
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate static const int hashsize[] = {
44*0Sstevel@tonic-gate 	3,	7,	13,	31,	53,	67,	83,	97,
45*0Sstevel@tonic-gate 	101,	151,	211,	251,	307,	353,	401,	457,	503,
46*0Sstevel@tonic-gate 	557,	601,	653,	701,	751,	809,	859,	907,	953,
47*0Sstevel@tonic-gate 	1009,	1103,	1201,	1301,	1409,	1511,	1601,	1709,	1801,
48*0Sstevel@tonic-gate 	1901,	2003,	2111,	2203,	2309,	2411,	2503,	2609,	2707,
49*0Sstevel@tonic-gate 	2801,	2903,	3001,	3109,	3203,	3301,	3407,	3511,	3607,
50*0Sstevel@tonic-gate 	3701,	3803,	3907,	4001,	5003,   6101,   7001,   8101,   9001,
51*0Sstevel@tonic-gate 	MAXNBKTS
52*0Sstevel@tonic-gate };
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate /*
55*0Sstevel@tonic-gate  * Generate a configuration file from the internal configuration information.
56*0Sstevel@tonic-gate  * (very link-editor like).
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate genconfig(Crle_desc * crle)
59*0Sstevel@tonic-gate {
60*0Sstevel@tonic-gate 	int		ndx, bkt;
61*0Sstevel@tonic-gate 	size_t		size, hashoff = 0, stroff = 0, objoff = 0;
62*0Sstevel@tonic-gate 	size_t		diroff = 0, fileoff = 0, envoff = 0;
63*0Sstevel@tonic-gate 	size_t		fltroff = 0, flteoff = 0;
64*0Sstevel@tonic-gate 	Addr		addr;
65*0Sstevel@tonic-gate 	Rtc_head	*head;
66*0Sstevel@tonic-gate 	Word		*hashtbl, * hashbkt, * hashchn, hashbkts = 0;
67*0Sstevel@tonic-gate 	char		*strtbl, *_strtbl;
68*0Sstevel@tonic-gate 	Rtc_obj		*objtbl;
69*0Sstevel@tonic-gate 	Rtc_dir		*dirtbl;
70*0Sstevel@tonic-gate 	Rtc_file	*filetbl;
71*0Sstevel@tonic-gate 	Rtc_env		*envtbl;
72*0Sstevel@tonic-gate 	Rtc_fltr	*fltrtbl;
73*0Sstevel@tonic-gate 	Rtc_flte	*fltetbl, * _fltetbl;
74*0Sstevel@tonic-gate 	Hash_tbl	*stbl = crle->c_strtbl;
75*0Sstevel@tonic-gate 	Hash_ent	*ent;
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	/*
78*0Sstevel@tonic-gate 	 * Establish the size of the configuration file.
79*0Sstevel@tonic-gate 	 */
80*0Sstevel@tonic-gate 	size = S_ROUND(sizeof (Rtc_head), sizeof (Word));
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate 	if (crle->c_hashstrnum) {
83*0Sstevel@tonic-gate 		hashoff = size;
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate 		/*
86*0Sstevel@tonic-gate 		 * Increment the hash string number to account for an initial
87*0Sstevel@tonic-gate 		 * null entry.  Indexes start at 1 to simplify hash lookup.
88*0Sstevel@tonic-gate 		 */
89*0Sstevel@tonic-gate 		crle->c_hashstrnum++;
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate 		/*
92*0Sstevel@tonic-gate 		 * Determine the hash table size.  Establish the number of
93*0Sstevel@tonic-gate 		 * buckets from the number of strings, the number of chains is
94*0Sstevel@tonic-gate 		 * equivalent to the number of objects, and two entries for the
95*0Sstevel@tonic-gate 		 * nbucket and nchain entries.
96*0Sstevel@tonic-gate 		 */
97*0Sstevel@tonic-gate 		for (ndx = 0; ndx < (sizeof (hashsize) / sizeof (int)); ndx++) {
98*0Sstevel@tonic-gate 			if (crle->c_hashstrnum > hashsize[ndx])
99*0Sstevel@tonic-gate 				continue;
100*0Sstevel@tonic-gate 			hashbkts = hashsize[ndx];
101*0Sstevel@tonic-gate 			break;
102*0Sstevel@tonic-gate 		}
103*0Sstevel@tonic-gate 		if (hashbkts == 0)
104*0Sstevel@tonic-gate 			hashbkts = MAXNBKTS;
105*0Sstevel@tonic-gate 		size += ((2 + hashbkts + crle->c_hashstrnum) * sizeof (Word));
106*0Sstevel@tonic-gate 		size = S_ROUND(size, sizeof (Lword));
107*0Sstevel@tonic-gate 		objoff = size;
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate 		/*
110*0Sstevel@tonic-gate 		 * Add the object table size (account for an 8-byte alignment
111*0Sstevel@tonic-gate 		 * requirement for each object).
112*0Sstevel@tonic-gate 		 */
113*0Sstevel@tonic-gate 		size += (crle->c_hashstrnum *
114*0Sstevel@tonic-gate 		    S_ROUND(sizeof (Rtc_obj), sizeof (Lword)));
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 		/*
117*0Sstevel@tonic-gate 		 * Add the file descriptor arrays.
118*0Sstevel@tonic-gate 		 */
119*0Sstevel@tonic-gate 		fileoff = size;
120*0Sstevel@tonic-gate 		size += S_ROUND((crle->c_filenum * sizeof (Rtc_file)),
121*0Sstevel@tonic-gate 		    sizeof (Word));
122*0Sstevel@tonic-gate 
123*0Sstevel@tonic-gate 		/*
124*0Sstevel@tonic-gate 		 * Add the directory descriptor array.
125*0Sstevel@tonic-gate 		 */
126*0Sstevel@tonic-gate 		diroff = size;
127*0Sstevel@tonic-gate 		size += S_ROUND((crle->c_dirnum * sizeof (Rtc_dir)),
128*0Sstevel@tonic-gate 		    sizeof (Word));
129*0Sstevel@tonic-gate 	}
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	/*
132*0Sstevel@tonic-gate 	 * Add any environment string array (insure zero last entry).
133*0Sstevel@tonic-gate 	 */
134*0Sstevel@tonic-gate 	if (crle->c_envnum) {
135*0Sstevel@tonic-gate 		envoff = size;
136*0Sstevel@tonic-gate 		size += S_ROUND(((crle->c_envnum + 1) * sizeof (Rtc_env)),
137*0Sstevel@tonic-gate 		    sizeof (Word));
138*0Sstevel@tonic-gate 	}
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	/*
141*0Sstevel@tonic-gate 	 * Add any filter/filtee association arrays (insure zero last entry for
142*0Sstevel@tonic-gate 	 * the filter array, the filtee arrays are already accounted for).
143*0Sstevel@tonic-gate 	 */
144*0Sstevel@tonic-gate 	if (crle->c_fltrnum) {
145*0Sstevel@tonic-gate 		fltroff = size;
146*0Sstevel@tonic-gate 		size += S_ROUND(((crle->c_fltrnum + 1) * sizeof (Rtc_fltr)),
147*0Sstevel@tonic-gate 		    sizeof (Word));
148*0Sstevel@tonic-gate 		flteoff = size;
149*0Sstevel@tonic-gate 		size += S_ROUND((crle->c_fltenum * sizeof (Rtc_flte)),
150*0Sstevel@tonic-gate 		    sizeof (Word));
151*0Sstevel@tonic-gate 	}
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	/*
154*0Sstevel@tonic-gate 	 * Add the string table size (this may contain library and/or secure
155*0Sstevel@tonic-gate 	 * path strings, in addition to any directory/file strings).
156*0Sstevel@tonic-gate 	 */
157*0Sstevel@tonic-gate 	if (crle->c_strsize) {
158*0Sstevel@tonic-gate 		stroff = size;
159*0Sstevel@tonic-gate 		size += S_ROUND(crle->c_strsize, sizeof (Word));
160*0Sstevel@tonic-gate 	}
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 	/*
163*0Sstevel@tonic-gate 	 * Truncate our temporary file now that we know its size and map it.
164*0Sstevel@tonic-gate 	 */
165*0Sstevel@tonic-gate 	if (ftruncate(crle->c_tempfd, size) == -1) {
166*0Sstevel@tonic-gate 		int err = errno;
167*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
168*0Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
169*0Sstevel@tonic-gate 		(void) close(crle->c_tempfd);
170*0Sstevel@tonic-gate 		return (1);
171*0Sstevel@tonic-gate 	}
172*0Sstevel@tonic-gate 	if ((addr = (Addr)mmap(0, size, (PROT_READ | PROT_WRITE), MAP_SHARED,
173*0Sstevel@tonic-gate 	    crle->c_tempfd, 0)) == (Addr)-1) {
174*0Sstevel@tonic-gate 		int err = errno;
175*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP),
176*0Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
177*0Sstevel@tonic-gate 		(void) close(crle->c_tempfd);
178*0Sstevel@tonic-gate 		return (1);
179*0Sstevel@tonic-gate 	}
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	/*
182*0Sstevel@tonic-gate 	 * Save the mapped files info for possible dldump(3dl) updates.
183*0Sstevel@tonic-gate 	 */
184*0Sstevel@tonic-gate 	crle->c_tempaddr = addr;
185*0Sstevel@tonic-gate 	crle->c_tempsize = size;
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 	/*
188*0Sstevel@tonic-gate 	 * Establish the real address of each of the structures within the file.
189*0Sstevel@tonic-gate 	 */
190*0Sstevel@tonic-gate 	head = (Rtc_head *)addr;
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate 	head->ch_hash = hashoff;
193*0Sstevel@tonic-gate 	/* LINTED */
194*0Sstevel@tonic-gate 	hashtbl = (Word *)((char *)head->ch_hash + addr);
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate 	head->ch_obj = objoff;
197*0Sstevel@tonic-gate 	/* LINTED */
198*0Sstevel@tonic-gate 	objtbl = (Rtc_obj *)((char *)head->ch_obj + addr);
199*0Sstevel@tonic-gate 	objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1), sizeof (Lword));
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	head->ch_file = fileoff;
202*0Sstevel@tonic-gate 	/* LINTED */
203*0Sstevel@tonic-gate 	filetbl = (Rtc_file *)((char *)head->ch_file + addr);
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	head->ch_dir = diroff;
206*0Sstevel@tonic-gate 	/* LINTED */
207*0Sstevel@tonic-gate 	dirtbl = (Rtc_dir *)((char *)head->ch_dir + addr);
208*0Sstevel@tonic-gate 
209*0Sstevel@tonic-gate 	head->ch_env = envoff;
210*0Sstevel@tonic-gate 	/* LINTED */
211*0Sstevel@tonic-gate 	envtbl = (Rtc_env *)((char *)head->ch_env + addr);
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	head->ch_fltr = fltroff;
214*0Sstevel@tonic-gate 	/* LINTED */
215*0Sstevel@tonic-gate 	fltrtbl = (Rtc_fltr *)((char *)head->ch_fltr + addr);
216*0Sstevel@tonic-gate 	head->ch_flte = flteoff;
217*0Sstevel@tonic-gate 	/* LINTED */
218*0Sstevel@tonic-gate 	fltetbl = _fltetbl = (Rtc_flte *)((char *)head->ch_flte + addr);
219*0Sstevel@tonic-gate 
220*0Sstevel@tonic-gate 	head->ch_str = stroff;
221*0Sstevel@tonic-gate 	strtbl = _strtbl = (char *)((char *)head->ch_str + addr);
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate 	/*
224*0Sstevel@tonic-gate 	 * Fill in additional basic header information.
225*0Sstevel@tonic-gate 	 */
226*0Sstevel@tonic-gate 	head->ch_version = RTC_VER_CURRENT;
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_ALTER)
229*0Sstevel@tonic-gate 		head->ch_cnflags |= RTC_HDR_ALTER;
230*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DUMP) {
231*0Sstevel@tonic-gate 		head->ch_cnflags |= RTC_HDR_IGNORE;
232*0Sstevel@tonic-gate 		head->ch_dlflags = crle->c_dlflags;
233*0Sstevel@tonic-gate 	}
234*0Sstevel@tonic-gate 	if (crle->c_class == ELFCLASS64)
235*0Sstevel@tonic-gate 		head->ch_cnflags |= RTC_HDR_64;
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
238*0Sstevel@tonic-gate 	head->ch_cnflags |= RTC_HDR_UPM;
239*0Sstevel@tonic-gate #endif
240*0Sstevel@tonic-gate 	/*
241*0Sstevel@tonic-gate 	 * If we have a hash table then there are directory and file entries
242*0Sstevel@tonic-gate 	 * to process.
243*0Sstevel@tonic-gate 	 */
244*0Sstevel@tonic-gate 	if (crle->c_hashstrnum) {
245*0Sstevel@tonic-gate 		hashtbl[0] = hashbkts;
246*0Sstevel@tonic-gate 		hashtbl[1] = crle->c_hashstrnum;
247*0Sstevel@tonic-gate 		hashbkt = &hashtbl[2];
248*0Sstevel@tonic-gate 		hashchn = &hashtbl[2 + hashbkts];
249*0Sstevel@tonic-gate 
250*0Sstevel@tonic-gate 		/*
251*0Sstevel@tonic-gate 		 * Insure all hash chain and directory/filename table entries
252*0Sstevel@tonic-gate 		 * are cleared.
253*0Sstevel@tonic-gate 		 */
254*0Sstevel@tonic-gate 		(void) memset(hashchn, 0, (crle->c_hashstrnum * sizeof (Word)));
255*0Sstevel@tonic-gate 		(void) memset(dirtbl, 0, (strtbl - (char *)dirtbl));
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 		/*
258*0Sstevel@tonic-gate 		 * Loop through the current string table list inspecting only
259*0Sstevel@tonic-gate 		 * directories.
260*0Sstevel@tonic-gate 		 */
261*0Sstevel@tonic-gate 		for (ndx = 1, bkt = 0; bkt < stbl->t_size; bkt++) {
262*0Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
263*0Sstevel@tonic-gate 				Word		hashval;
264*0Sstevel@tonic-gate 				Hash_obj	*obj = ent->e_obj;
265*0Sstevel@tonic-gate 				char		*dir = (char *)ent->e_key;
266*0Sstevel@tonic-gate 				Rtc_dir		*_dirtbl;
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate 				/*
269*0Sstevel@tonic-gate 				 * Skip any empty and non-directory entries.
270*0Sstevel@tonic-gate 				 */
271*0Sstevel@tonic-gate 				if ((obj == 0) ||
272*0Sstevel@tonic-gate 				    ((obj->o_flags & RTC_OBJ_DIRENT) == 0))
273*0Sstevel@tonic-gate 					continue;
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 				/*
276*0Sstevel@tonic-gate 				 * Assign basic object attributes.
277*0Sstevel@tonic-gate 				 */
278*0Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
279*0Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
280*0Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
281*0Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate 				ent->e_cobj = objtbl;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 				/*
286*0Sstevel@tonic-gate 				 * Assign the directory name (from its key),
287*0Sstevel@tonic-gate 				 * and copy its name to the string table.
288*0Sstevel@tonic-gate 				 */
289*0Sstevel@tonic-gate 				objtbl->co_name = (Addr)(_strtbl - strtbl);
290*0Sstevel@tonic-gate 				(void) strcpy(_strtbl, dir);
291*0Sstevel@tonic-gate 				_strtbl += strlen(dir) + 1;
292*0Sstevel@tonic-gate 
293*0Sstevel@tonic-gate 				/*
294*0Sstevel@tonic-gate 				 * Establish an entry in the directory table and
295*0Sstevel@tonic-gate 				 * reserve space for its associated filename
296*0Sstevel@tonic-gate 				 * entries (note, we add a trailing null file
297*0Sstevel@tonic-gate 				 * entry to simplify later inspection of the
298*0Sstevel@tonic-gate 				 * final configuration file.
299*0Sstevel@tonic-gate 				 */
300*0Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
301*0Sstevel@tonic-gate 				_dirtbl->cd_file =
302*0Sstevel@tonic-gate 				    (Word)((char *)filetbl - addr);
303*0Sstevel@tonic-gate 				_dirtbl->cd_obj =
304*0Sstevel@tonic-gate 				    (Word)((char *)objtbl - addr);
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate 				/* LINTED */
307*0Sstevel@tonic-gate 				filetbl = (Rtc_file *)((char *)filetbl +
308*0Sstevel@tonic-gate 				    ((ent->e_cnt + 1) * sizeof (Rtc_file)));
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 				/*
311*0Sstevel@tonic-gate 				 * Add this object to the hash table.
312*0Sstevel@tonic-gate 				 */
313*0Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
314*0Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
315*0Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 				/*
318*0Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
319*0Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
320*0Sstevel@tonic-gate 				 */
321*0Sstevel@tonic-gate 				objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1),
322*0Sstevel@tonic-gate 				    sizeof (Lword));
323*0Sstevel@tonic-gate 			}
324*0Sstevel@tonic-gate 		}
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate 		/*
327*0Sstevel@tonic-gate 		 * Now collect all pathnames.  These are typically full
328*0Sstevel@tonic-gate 		 * pathnames, but may also be relative.  Simple filenames are
329*0Sstevel@tonic-gate 		 * recorded as offsets into these pathnames, thus we need to
330*0Sstevel@tonic-gate 		 * establish the new pathname first.
331*0Sstevel@tonic-gate 		 */
332*0Sstevel@tonic-gate 		for (bkt = 0; bkt < stbl->t_size; bkt++) {
333*0Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
334*0Sstevel@tonic-gate 				Word		hashval;
335*0Sstevel@tonic-gate 				Hash_obj	*obj = ent->e_obj;
336*0Sstevel@tonic-gate 				char		*file = (char *)ent->e_key;
337*0Sstevel@tonic-gate 				char		*_str;
338*0Sstevel@tonic-gate 				Rtc_dir		*_dirtbl;
339*0Sstevel@tonic-gate 				Rtc_file	*_filetbl;
340*0Sstevel@tonic-gate 				int		_id;
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 				/*
343*0Sstevel@tonic-gate 				 * Skip empty and directory entries, and any
344*0Sstevel@tonic-gate 				 * simple filename entries.
345*0Sstevel@tonic-gate 				 */
346*0Sstevel@tonic-gate 				if ((obj == 0) ||
347*0Sstevel@tonic-gate 				    (obj->o_flags & RTC_OBJ_DIRENT) ||
348*0Sstevel@tonic-gate 				    (ent->e_off))
349*0Sstevel@tonic-gate 					continue;
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 				/*
352*0Sstevel@tonic-gate 				 * Assign basic object attributes.
353*0Sstevel@tonic-gate 				 */
354*0Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
355*0Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
356*0Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
357*0Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate 				ent->e_cobj = objtbl;
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 				/*
362*0Sstevel@tonic-gate 				 * Assign the file name (from its key),
363*0Sstevel@tonic-gate 				 * and copy its name to the string table.
364*0Sstevel@tonic-gate 				 */
365*0Sstevel@tonic-gate 				objtbl->co_name = (Addr)(_strtbl - strtbl);
366*0Sstevel@tonic-gate 				(void) strcpy(_strtbl, file);
367*0Sstevel@tonic-gate 				_strtbl += strlen(file) + 1;
368*0Sstevel@tonic-gate 
369*0Sstevel@tonic-gate 				/*
370*0Sstevel@tonic-gate 				 * Add this file to its associated directory.
371*0Sstevel@tonic-gate 				 */
372*0Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
373*0Sstevel@tonic-gate 				/* LINTED */
374*0Sstevel@tonic-gate 				_filetbl = (Rtc_file *)
375*0Sstevel@tonic-gate 				    ((char *)_dirtbl->cd_file + addr);
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate 				_id = --ent->e_dir->e_cnt;
378*0Sstevel@tonic-gate 				_filetbl[_id].cf_obj =
379*0Sstevel@tonic-gate 				    (Word)((char *)objtbl - addr);
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 				/*
382*0Sstevel@tonic-gate 				 * If object has an alternative, record it in
383*0Sstevel@tonic-gate 				 * the string table and assign the alternate
384*0Sstevel@tonic-gate 				 * pointer.  The new alternative offset is
385*0Sstevel@tonic-gate 				 * retained for reuse in other filename entries.
386*0Sstevel@tonic-gate 				 */
387*0Sstevel@tonic-gate 				if ((objtbl->co_flags & RTC_OBJ_ALTER) &&
388*0Sstevel@tonic-gate 				    (obj->o_calter == 0)) {
389*0Sstevel@tonic-gate 					_str = obj->o_alter;
390*0Sstevel@tonic-gate 					objtbl->co_alter = obj->o_calter =
391*0Sstevel@tonic-gate 					    (Addr)(_strtbl - strtbl);
392*0Sstevel@tonic-gate 					(void) strcpy(_strtbl, _str);
393*0Sstevel@tonic-gate 					_strtbl += strlen(_str) + 1;
394*0Sstevel@tonic-gate 				} else
395*0Sstevel@tonic-gate 					objtbl->co_alter = obj->o_calter;
396*0Sstevel@tonic-gate 
397*0Sstevel@tonic-gate 				/*
398*0Sstevel@tonic-gate 				 * If object identifies the specific application
399*0Sstevel@tonic-gate 				 * for which this cache is relevant, record it
400*0Sstevel@tonic-gate 				 * in the header.
401*0Sstevel@tonic-gate 				 */
402*0Sstevel@tonic-gate 				if ((objtbl->co_flags &
403*0Sstevel@tonic-gate 				    (RTC_OBJ_APP | RTC_OBJ_REALPTH)) ==
404*0Sstevel@tonic-gate 				    (RTC_OBJ_APP | RTC_OBJ_REALPTH))
405*0Sstevel@tonic-gate 					head->ch_app = _filetbl[_id].cf_obj;
406*0Sstevel@tonic-gate 
407*0Sstevel@tonic-gate 				/*
408*0Sstevel@tonic-gate 				 * Add this object to the hash table.
409*0Sstevel@tonic-gate 				 */
410*0Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
411*0Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
412*0Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 				/*
415*0Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
416*0Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
417*0Sstevel@tonic-gate 				 */
418*0Sstevel@tonic-gate 				objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1),
419*0Sstevel@tonic-gate 				    sizeof (Lword));
420*0Sstevel@tonic-gate 			}
421*0Sstevel@tonic-gate 		}
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate 		/*
424*0Sstevel@tonic-gate 		 * Finally pick off any simple filenames.
425*0Sstevel@tonic-gate 		 */
426*0Sstevel@tonic-gate 		for (bkt = 0; bkt < stbl->t_size; bkt++) {
427*0Sstevel@tonic-gate 			for (ent = stbl->t_entry[bkt]; ent; ent = ent->e_next) {
428*0Sstevel@tonic-gate 				Word		hashval;
429*0Sstevel@tonic-gate 				Hash_obj *	obj = ent->e_obj;
430*0Sstevel@tonic-gate 				Rtc_dir *	_dirtbl;
431*0Sstevel@tonic-gate 				Rtc_file *	_filetbl;
432*0Sstevel@tonic-gate 				int		_id;
433*0Sstevel@tonic-gate 
434*0Sstevel@tonic-gate 				/*
435*0Sstevel@tonic-gate 				 * Skip everything except simple filenames.
436*0Sstevel@tonic-gate 				 */
437*0Sstevel@tonic-gate 				if (ent->e_off == 0)
438*0Sstevel@tonic-gate 					continue;
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 				/*
441*0Sstevel@tonic-gate 				 * Assign basic object attributes.
442*0Sstevel@tonic-gate 				 */
443*0Sstevel@tonic-gate 				objtbl->co_hash = ent->e_hash;
444*0Sstevel@tonic-gate 				objtbl->co_id = ent->e_id;
445*0Sstevel@tonic-gate 				objtbl->co_flags = obj->o_flags | ent->e_flags;
446*0Sstevel@tonic-gate 				objtbl->co_info = obj->o_info;
447*0Sstevel@tonic-gate 				objtbl->co_alter = obj->o_calter;
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 				ent->e_cobj = objtbl;
450*0Sstevel@tonic-gate 
451*0Sstevel@tonic-gate 				/*
452*0Sstevel@tonic-gate 				 * Assign the file name from its full name.
453*0Sstevel@tonic-gate 				 */
454*0Sstevel@tonic-gate 				objtbl->co_name = (Addr)((char *)
455*0Sstevel@tonic-gate 				    ent->e_path->e_cobj->co_name + ent->e_off);
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 				/*
458*0Sstevel@tonic-gate 				 * Add this file to its associated directory.
459*0Sstevel@tonic-gate 				 */
460*0Sstevel@tonic-gate 				_dirtbl = &dirtbl[ent->e_id - 1];
461*0Sstevel@tonic-gate 				/* LINTED */
462*0Sstevel@tonic-gate 				_filetbl = (Rtc_file *)
463*0Sstevel@tonic-gate 				    ((char *)_dirtbl->cd_file + addr);
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 				_id = --ent->e_dir->e_cnt;
466*0Sstevel@tonic-gate 				_filetbl[_id].cf_obj =
467*0Sstevel@tonic-gate 				    (Word)((char *)objtbl - addr);
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 				/*
470*0Sstevel@tonic-gate 				 * Add this object to the hash table.
471*0Sstevel@tonic-gate 				 */
472*0Sstevel@tonic-gate 				hashval = ent->e_hash % hashbkts;
473*0Sstevel@tonic-gate 				hashchn[ndx] = hashbkt[hashval];
474*0Sstevel@tonic-gate 				hashbkt[hashval] = ndx++;
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 				/*
477*0Sstevel@tonic-gate 				 * Increment Rt_obj pointer (make sure pointer
478*0Sstevel@tonic-gate 				 * falls on an 8-byte boundary).
479*0Sstevel@tonic-gate 				 */
480*0Sstevel@tonic-gate 				objtbl = (Rtc_obj *)S_ROUND((int)(objtbl + 1),
481*0Sstevel@tonic-gate 				    sizeof (Lword));
482*0Sstevel@tonic-gate 			}
483*0Sstevel@tonic-gate 		}
484*0Sstevel@tonic-gate 	}
485*0Sstevel@tonic-gate 
486*0Sstevel@tonic-gate 	/*
487*0Sstevel@tonic-gate 	 * Add any library, or secure path definitions.
488*0Sstevel@tonic-gate 	 */
489*0Sstevel@tonic-gate 	if (crle->c_edlibpath) {
490*0Sstevel@tonic-gate 		head->ch_edlibpath = head->ch_str + (_strtbl - strtbl);
491*0Sstevel@tonic-gate 
492*0Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_edlibpath);
493*0Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_edlibpath) + 1;
494*0Sstevel@tonic-gate 	} else
495*0Sstevel@tonic-gate 		head->ch_edlibpath = 0;
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	if (crle->c_adlibpath) {
498*0Sstevel@tonic-gate 		head->ch_adlibpath = head->ch_str + (_strtbl - strtbl);
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_adlibpath);
501*0Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_adlibpath) + 1;
502*0Sstevel@tonic-gate 	} else
503*0Sstevel@tonic-gate 		head->ch_adlibpath = 0;
504*0Sstevel@tonic-gate 
505*0Sstevel@tonic-gate 	if (crle->c_eslibpath) {
506*0Sstevel@tonic-gate 		head->ch_eslibpath = head->ch_str + (_strtbl - strtbl);
507*0Sstevel@tonic-gate 
508*0Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_eslibpath);
509*0Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_eslibpath) + 1;
510*0Sstevel@tonic-gate 	} else
511*0Sstevel@tonic-gate 		head->ch_eslibpath = 0;
512*0Sstevel@tonic-gate 
513*0Sstevel@tonic-gate 	if (crle->c_aslibpath) {
514*0Sstevel@tonic-gate 		head->ch_aslibpath = head->ch_str + (_strtbl - strtbl);
515*0Sstevel@tonic-gate 
516*0Sstevel@tonic-gate 		(void) strcpy(_strtbl, crle->c_aslibpath);
517*0Sstevel@tonic-gate 		_strtbl += strlen((char *)crle->c_aslibpath) + 1;
518*0Sstevel@tonic-gate 	} else
519*0Sstevel@tonic-gate 		head->ch_aslibpath = 0;
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate 	/*
522*0Sstevel@tonic-gate 	 * Add any environment variable entries.
523*0Sstevel@tonic-gate 	 */
524*0Sstevel@tonic-gate 	if (crle->c_envnum) {
525*0Sstevel@tonic-gate 		Env_desc *	env;
526*0Sstevel@tonic-gate 		Listnode *	lnp;
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 		for (LIST_TRAVERSE(&(crle->c_env), lnp, env)) {
529*0Sstevel@tonic-gate 			envtbl->env_str = head->ch_str + (_strtbl - strtbl);
530*0Sstevel@tonic-gate 			envtbl->env_flags = env->e_flags;
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate 			(void) strcpy(_strtbl, env->e_str);
533*0Sstevel@tonic-gate 			_strtbl += env->e_totsz;
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate 			envtbl++;
536*0Sstevel@tonic-gate 		}
537*0Sstevel@tonic-gate 		envtbl->env_str = 0;
538*0Sstevel@tonic-gate 		envtbl->env_flags = 0;
539*0Sstevel@tonic-gate 	}
540*0Sstevel@tonic-gate 
541*0Sstevel@tonic-gate 	/*
542*0Sstevel@tonic-gate 	 * Add any filter/filtee association entries.
543*0Sstevel@tonic-gate 	 */
544*0Sstevel@tonic-gate 	if (crle->c_fltrnum) {
545*0Sstevel@tonic-gate 		Flt_desc *	flt;
546*0Sstevel@tonic-gate 		Listnode *	lnp1;
547*0Sstevel@tonic-gate 
548*0Sstevel@tonic-gate 		for (LIST_TRAVERSE(&(crle->c_flt), lnp1, flt)) {
549*0Sstevel@tonic-gate 			Hash_ent *	flte;
550*0Sstevel@tonic-gate 			Listnode *	lnp2;
551*0Sstevel@tonic-gate 
552*0Sstevel@tonic-gate 			/*
553*0Sstevel@tonic-gate 			 * Establish the filter name, and filtee string, as
554*0Sstevel@tonic-gate 			 * offsets into the configuration files string table.
555*0Sstevel@tonic-gate 			 * Establish the filtee as the offset into the filtee
556*0Sstevel@tonic-gate 			 * table.
557*0Sstevel@tonic-gate 			 */
558*0Sstevel@tonic-gate 			fltrtbl->fr_filter = flt->f_fent->e_cobj->co_name;
559*0Sstevel@tonic-gate 			fltrtbl->fr_string = _strtbl - strtbl;
560*0Sstevel@tonic-gate 			(void) strcpy(_strtbl, flt->f_str);
561*0Sstevel@tonic-gate 			_strtbl += flt->f_strsz;
562*0Sstevel@tonic-gate 			fltrtbl->fr_filtee = ((Word)_fltetbl - (Word)fltetbl);
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate 			for (LIST_TRAVERSE(&(flt->f_filtee), lnp2, flte)) {
565*0Sstevel@tonic-gate 				/*
566*0Sstevel@tonic-gate 				 * Establish the filtee name as the offset into
567*0Sstevel@tonic-gate 				 * the configuration files string table.
568*0Sstevel@tonic-gate 				 */
569*0Sstevel@tonic-gate 				_fltetbl->fe_filtee = flte->e_cobj->co_name;
570*0Sstevel@tonic-gate 				_fltetbl++;
571*0Sstevel@tonic-gate 			}
572*0Sstevel@tonic-gate 			_fltetbl->fe_filtee = 0;
573*0Sstevel@tonic-gate 			_fltetbl++, fltrtbl++;
574*0Sstevel@tonic-gate 		}
575*0Sstevel@tonic-gate 		fltrtbl->fr_filter = 0;
576*0Sstevel@tonic-gate 		fltrtbl->fr_filtee = 0;
577*0Sstevel@tonic-gate 	}
578*0Sstevel@tonic-gate 
579*0Sstevel@tonic-gate 	/*
580*0Sstevel@tonic-gate 	 * Flush everything out.
581*0Sstevel@tonic-gate 	 */
582*0Sstevel@tonic-gate 	(void) close(crle->c_tempfd);
583*0Sstevel@tonic-gate 	if (msync((void *)addr, size, MS_ASYNC) == -1) {
584*0Sstevel@tonic-gate 		int err = errno;
585*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
586*0Sstevel@tonic-gate 		    crle->c_name, crle->c_tempname, strerror(err));
587*0Sstevel@tonic-gate 		return (1);
588*0Sstevel@tonic-gate 	}
589*0Sstevel@tonic-gate 
590*0Sstevel@tonic-gate 	return (0);
591*0Sstevel@tonic-gate }
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate /*
594*0Sstevel@tonic-gate  * Update a configuration file.  If dldump()'ed images have been created then
595*0Sstevel@tonic-gate  * the memory reservation of those images is added to the configuration file.
596*0Sstevel@tonic-gate  * The temporary file is then moved into its final resting place.
597*0Sstevel@tonic-gate  */
598*0Sstevel@tonic-gate updateconfig(Crle_desc * crle)
599*0Sstevel@tonic-gate {
600*0Sstevel@tonic-gate 	Rtc_head *	head = (Rtc_head *)crle->c_tempaddr;
601*0Sstevel@tonic-gate 
602*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DUMP) {
603*0Sstevel@tonic-gate 		head->ch_cnflags &= ~RTC_HDR_IGNORE;
604*0Sstevel@tonic-gate 
605*0Sstevel@tonic-gate 		if (msync((void *)crle->c_tempaddr, crle->c_tempsize,
606*0Sstevel@tonic-gate 		    MS_ASYNC) == -1) {
607*0Sstevel@tonic-gate 			int err = errno;
608*0Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_TRUNC),
609*0Sstevel@tonic-gate 			    crle->c_name, crle->c_tempname, strerror(err));
610*0Sstevel@tonic-gate 			return (1);
611*0Sstevel@tonic-gate 		}
612*0Sstevel@tonic-gate 	}
613*0Sstevel@tonic-gate 
614*0Sstevel@tonic-gate 	/*
615*0Sstevel@tonic-gate 	 * If an original configuration file exists, remove it.
616*0Sstevel@tonic-gate 	 */
617*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_EXISTS)
618*0Sstevel@tonic-gate 		(void) unlink(crle->c_confil);
619*0Sstevel@tonic-gate 
620*0Sstevel@tonic-gate 	/*
621*0Sstevel@tonic-gate 	 * Move the config file to its final resting place.  If the two files
622*0Sstevel@tonic-gate 	 * exist on the same filesystem a rename is sufficient.
623*0Sstevel@tonic-gate 	 */
624*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_DIFFDEV) {
625*0Sstevel@tonic-gate 		int	fd;
626*0Sstevel@tonic-gate 
627*0Sstevel@tonic-gate 		if ((fd = open(crle->c_confil, (O_RDWR | O_CREAT | O_TRUNC),
628*0Sstevel@tonic-gate 		    0666)) == -1) {
629*0Sstevel@tonic-gate 			int err = errno;
630*0Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
631*0Sstevel@tonic-gate 			    crle->c_name, crle->c_confil, strerror(err));
632*0Sstevel@tonic-gate 			return (1);
633*0Sstevel@tonic-gate 		}
634*0Sstevel@tonic-gate 		if (write(fd, (void *)crle->c_tempaddr, crle->c_tempsize) !=
635*0Sstevel@tonic-gate 		    crle->c_tempsize) {
636*0Sstevel@tonic-gate 			int err = errno;
637*0Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_WRITE),
638*0Sstevel@tonic-gate 			    crle->c_name, crle->c_confil, strerror(err));
639*0Sstevel@tonic-gate 			return (1);
640*0Sstevel@tonic-gate 		}
641*0Sstevel@tonic-gate 		(void) close(fd);
642*0Sstevel@tonic-gate 		(void) unlink(crle->c_tempname);
643*0Sstevel@tonic-gate 	} else
644*0Sstevel@tonic-gate 		(void) rename(crle->c_tempname, crle->c_confil);
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	return (0);
647*0Sstevel@tonic-gate }
648