xref: /onnv-gate/usr/src/cmd/sgs/crle/common/print.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/types.h>
29*0Sstevel@tonic-gate #include	<sys/stat.h>
30*0Sstevel@tonic-gate #include	<sys/mman.h>
31*0Sstevel@tonic-gate #include	<fcntl.h>
32*0Sstevel@tonic-gate #include	<stdio.h>
33*0Sstevel@tonic-gate #include	<string.h>
34*0Sstevel@tonic-gate #include	<unistd.h>
35*0Sstevel@tonic-gate #include	<errno.h>
36*0Sstevel@tonic-gate #include	<limits.h>
37*0Sstevel@tonic-gate #include	<alloca.h>
38*0Sstevel@tonic-gate #include	"sgs.h"
39*0Sstevel@tonic-gate #include	"rtc.h"
40*0Sstevel@tonic-gate #include	"conv.h"
41*0Sstevel@tonic-gate #include	"_crle.h"
42*0Sstevel@tonic-gate #include	"msg.h"
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /*
46*0Sstevel@tonic-gate  * Display the command line required to regenerate the configuration file.
47*0Sstevel@tonic-gate  *
48*0Sstevel@tonic-gate  * Under normal mode the command is printed on one line to make it more
49*0Sstevel@tonic-gate  * available for grep(1) use.  Under verbose mode the command is separated
50*0Sstevel@tonic-gate  * into each argument (a little more readable perhaps when the arguments are
51*0Sstevel@tonic-gate  * numerous of have long pathnames).
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * Note that for version 1 configuration files we never used to generate any
54*0Sstevel@tonic-gate  * command-line information, and as the attempt to do so is only a best effort
55*0Sstevel@tonic-gate  * don't bother printing anything.
56*0Sstevel@tonic-gate  */
57*0Sstevel@tonic-gate static void
58*0Sstevel@tonic-gate printcmd(Crle_desc * crle, Rtc_head * head, List * cmdline)
59*0Sstevel@tonic-gate {
60*0Sstevel@tonic-gate 	Listnode	*lnp;
61*0Sstevel@tonic-gate 	const char	*fmto, *fmtb, *fmtm, *fmte;
62*0Sstevel@tonic-gate 	char		*cmd;
63*0Sstevel@tonic-gate 	int		output = 0;
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_VERBOSE) {
66*0Sstevel@tonic-gate 		fmto = MSG_INTL(MSG_DMP_CMD_ONE_V);
67*0Sstevel@tonic-gate 		fmtb = MSG_INTL(MSG_DMP_CMD_BGN_V);
68*0Sstevel@tonic-gate 		fmtm = MSG_INTL(MSG_DMP_CMD_MID_V);
69*0Sstevel@tonic-gate 		fmte = MSG_INTL(MSG_DMP_CMD_END_V);
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 	} else if (head->ch_version > RTC_VER_ONE) {
72*0Sstevel@tonic-gate 		fmto = MSG_INTL(MSG_DMP_CMD_ONE);
73*0Sstevel@tonic-gate 		fmtb = MSG_INTL(MSG_DMP_CMD_BGN);
74*0Sstevel@tonic-gate 		fmtm = MSG_INTL(MSG_DMP_CMD_MID);
75*0Sstevel@tonic-gate 		fmte = MSG_INTL(MSG_DMP_CMD_END);
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	} else {
78*0Sstevel@tonic-gate 		(void) printf(MSG_ORIG(MSG_STR_NL));
79*0Sstevel@tonic-gate 		return;
80*0Sstevel@tonic-gate 	}
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_DMP_CMD_TITLE));
83*0Sstevel@tonic-gate 	for (LIST_TRAVERSE(cmdline, lnp, cmd)) {
84*0Sstevel@tonic-gate 		if (output++ == 0) {
85*0Sstevel@tonic-gate 			if (lnp->next)
86*0Sstevel@tonic-gate 				(void) printf(fmtb, cmd);
87*0Sstevel@tonic-gate 			else
88*0Sstevel@tonic-gate 				(void) printf(fmto, cmd);
89*0Sstevel@tonic-gate 		} else {
90*0Sstevel@tonic-gate 			if (lnp->next)
91*0Sstevel@tonic-gate 				(void) printf(fmtm, cmd);
92*0Sstevel@tonic-gate 			else
93*0Sstevel@tonic-gate 				(void) printf(fmte, cmd);
94*0Sstevel@tonic-gate 		}
95*0Sstevel@tonic-gate 	}
96*0Sstevel@tonic-gate }
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate /*
99*0Sstevel@tonic-gate  * Establish the argument required to generate the associated object.
100*0Sstevel@tonic-gate  */
101*0Sstevel@tonic-gate static const char *
102*0Sstevel@tonic-gate getformat(Half flags)
103*0Sstevel@tonic-gate {
104*0Sstevel@tonic-gate 	if (flags & RTC_OBJ_ALTER) {
105*0Sstevel@tonic-gate 		if (flags & RTC_OBJ_DUMP) {
106*0Sstevel@tonic-gate 			if (flags & RTC_OBJ_GROUP)
107*0Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_DUMPGRP));
108*0Sstevel@tonic-gate 			else
109*0Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_DUMPIND));
110*0Sstevel@tonic-gate 		} else {
111*0Sstevel@tonic-gate 			if (flags & RTC_OBJ_OPTINAL)
112*0Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_OPTIONAL));
113*0Sstevel@tonic-gate 			else
114*0Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_ALTER));
115*0Sstevel@tonic-gate 		}
116*0Sstevel@tonic-gate 	} else {
117*0Sstevel@tonic-gate 		if (flags & RTC_OBJ_GROUP)
118*0Sstevel@tonic-gate 			return (MSG_ORIG(MSG_CMD_GRP));
119*0Sstevel@tonic-gate 		else
120*0Sstevel@tonic-gate 			return (MSG_ORIG(MSG_CMD_IND));
121*0Sstevel@tonic-gate 	}
122*0Sstevel@tonic-gate }
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate /*
125*0Sstevel@tonic-gate  * Fabricate a system default search path.  If an update is requested, and
126*0Sstevel@tonic-gate  * new search paths are specified while no configuration file exists, or if a
127*0Sstevel@tonic-gate  * configuration file does exist but doesn't specify this particular search
128*0Sstevel@tonic-gate  * path, create any system defaults.  The intent is to allow
129*0Sstevel@tonic-gate  * "crle -u -l/usr/local/lib" and have this append the search path to the
130*0Sstevel@tonic-gate  * system default, rather than have the user have to determine and specify
131*0Sstevel@tonic-gate  * this default themselves.
132*0Sstevel@tonic-gate  */
133*0Sstevel@tonic-gate static int
134*0Sstevel@tonic-gate fablib(Crle_desc * crle, int flag)
135*0Sstevel@tonic-gate {
136*0Sstevel@tonic-gate 	const char	*path;
137*0Sstevel@tonic-gate 	char		**list;
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 	switch (flag) {
140*0Sstevel@tonic-gate 	case CRLE_EDLIB:
141*0Sstevel@tonic-gate 		if (crle->c_class == ELFCLASS64) {
142*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
143*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_NEWDLP_64);
144*0Sstevel@tonic-gate #else
145*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_OLDDLP_64);
146*0Sstevel@tonic-gate #endif
147*0Sstevel@tonic-gate 		} else {
148*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
149*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_NEWDLP);
150*0Sstevel@tonic-gate #else
151*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_OLDDLP);
152*0Sstevel@tonic-gate #endif
153*0Sstevel@tonic-gate 		}
154*0Sstevel@tonic-gate 		list = &crle->c_edlibpath;
155*0Sstevel@tonic-gate 		break;
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate 	case CRLE_ESLIB:
158*0Sstevel@tonic-gate 		if (crle->c_class == ELFCLASS64) {
159*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
160*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_NEWTD_64);
161*0Sstevel@tonic-gate #else
162*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_OLDTD_64);
163*0Sstevel@tonic-gate #endif
164*0Sstevel@tonic-gate 		} else {
165*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
166*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_NEWTD);
167*0Sstevel@tonic-gate #else
168*0Sstevel@tonic-gate 			path = MSG_ORIG(MSG_PTH_OLDTD);
169*0Sstevel@tonic-gate #endif
170*0Sstevel@tonic-gate 		}
171*0Sstevel@tonic-gate 		list = &crle->c_eslibpath;
172*0Sstevel@tonic-gate 		break;
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	case CRLE_ADLIB:
175*0Sstevel@tonic-gate 		path = MSG_ORIG(MSG_PTH_AOUTDLP);
176*0Sstevel@tonic-gate 		list = &crle->c_adlibpath;
177*0Sstevel@tonic-gate 		break;
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 	case CRLE_ASLIB:
180*0Sstevel@tonic-gate 		path = MSG_ORIG(MSG_PTH_AOUTTD);
181*0Sstevel@tonic-gate 		list = &crle->c_aslibpath;
182*0Sstevel@tonic-gate 		break;
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate 	default:
185*0Sstevel@tonic-gate 		return (1);
186*0Sstevel@tonic-gate 	}
187*0Sstevel@tonic-gate 
188*0Sstevel@tonic-gate 	return (addlib(crle, list, path));
189*0Sstevel@tonic-gate }
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate /*
192*0Sstevel@tonic-gate  * Establish the flags required to generate the associated object.  Actually
193*0Sstevel@tonic-gate  * the flags are already part of the object being inspected from the present
194*0Sstevel@tonic-gate  * configuration file, but instead of using them all, which can cause some
195*0Sstevel@tonic-gate  * unsuspected propagation down the inspect() family, only use those flags that
196*0Sstevel@tonic-gate  * would have been contributed from crle()'s calls to inspect.
197*0Sstevel@tonic-gate  */
198*0Sstevel@tonic-gate static Half
199*0Sstevel@tonic-gate getflags(Half flags)
200*0Sstevel@tonic-gate {
201*0Sstevel@tonic-gate 	flags &=
202*0Sstevel@tonic-gate 	    (RTC_OBJ_ALTER | RTC_OBJ_DUMP | RTC_OBJ_GROUP | RTC_OBJ_OPTINAL);
203*0Sstevel@tonic-gate 	return (flags | RTC_OBJ_CMDLINE);
204*0Sstevel@tonic-gate }
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate /*
207*0Sstevel@tonic-gate  * Dump a configuration files information.  This routine is very close to the
208*0Sstevel@tonic-gate  * scanconfig() in libcrle.
209*0Sstevel@tonic-gate  */
210*0Sstevel@tonic-gate static int
211*0Sstevel@tonic-gate scanconfig(Crle_desc * crle, Addr addr)
212*0Sstevel@tonic-gate {
213*0Sstevel@tonic-gate 	Rtc_head	*head = (Rtc_head *)addr;
214*0Sstevel@tonic-gate 	Rtc_dir		*dirtbl;
215*0Sstevel@tonic-gate 	Rtc_file	*filetbl;
216*0Sstevel@tonic-gate 	Rtc_obj		*objtbl, * obj;
217*0Sstevel@tonic-gate 	Word		*hash, * chain;
218*0Sstevel@tonic-gate 	const char	*strtbl;
219*0Sstevel@tonic-gate 	int		ndx, bkts;
220*0Sstevel@tonic-gate 	List		cmdline = { 0 };
221*0Sstevel@tonic-gate 	char		_cmd[PATH_MAX], * cmd;
222*0Sstevel@tonic-gate 	char		_objdir[PATH_MAX], * objdir = 0;
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate 	/* LINTED */
225*0Sstevel@tonic-gate 	objtbl = (Rtc_obj *)((char *)head->ch_obj + addr);
226*0Sstevel@tonic-gate 	strtbl = (const char *)((char *)head->ch_str + addr);
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	/*
229*0Sstevel@tonic-gate 	 * If this is a version 1 configuration file we can't generate accurate
230*0Sstevel@tonic-gate 	 * update information, or the command-line used to create the file.
231*0Sstevel@tonic-gate 	 */
232*0Sstevel@tonic-gate 	if (head->ch_version == RTC_VER_ONE) {
233*0Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_ARG_UPDATE), crle->c_name,
234*0Sstevel@tonic-gate 		    crle->c_confil, head->ch_version);
235*0Sstevel@tonic-gate 	}
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 	/*
238*0Sstevel@tonic-gate 	 * If we're updating an existing configuration file make sure we're
239*0Sstevel@tonic-gate 	 * dealing with the same class of file.
240*0Sstevel@tonic-gate 	 */
241*0Sstevel@tonic-gate 	if (crle->c_flags & CRLE_UPDATE) {
242*0Sstevel@tonic-gate 		if (head->ch_cnflags & RTC_HDR_64)
243*0Sstevel@tonic-gate 			crle->c_class = ELFCLASS64;
244*0Sstevel@tonic-gate 		else if (crle->c_class == ELFCLASS64) {
245*0Sstevel@tonic-gate 		    (void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
246*0Sstevel@tonic-gate 			crle->c_name, crle->c_confil);
247*0Sstevel@tonic-gate 			return (1);
248*0Sstevel@tonic-gate 		}
249*0Sstevel@tonic-gate 	} else {
250*0Sstevel@tonic-gate 		if (head->ch_cnflags & RTC_HDR_64) {
251*0Sstevel@tonic-gate 			/*
252*0Sstevel@tonic-gate 			 * Construct the original command line argument.
253*0Sstevel@tonic-gate 			 */
254*0Sstevel@tonic-gate 			cmd = strcpy(alloca(MSG_CMD_64_SIZE + 1),
255*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_64));
256*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
257*0Sstevel@tonic-gate 				return (1);
258*0Sstevel@tonic-gate 		}
259*0Sstevel@tonic-gate 	}
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate 	/*
262*0Sstevel@tonic-gate 	 * Start analyzing the configuration files header information.
263*0Sstevel@tonic-gate 	 */
264*0Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_UPDATE) == 0) {
265*0Sstevel@tonic-gate 		const char	*fmt;
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate 		if (head->ch_dlflags)
268*0Sstevel@tonic-gate 			fmt = conv_dlflag_str(head->ch_dlflags, 0);
269*0Sstevel@tonic-gate 		else
270*0Sstevel@tonic-gate 			fmt = MSG_ORIG(MSG_STR_EMPTY);
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_DMP_HEAD), head->ch_version,
273*0Sstevel@tonic-gate 		    crle->c_confil, fmt);
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 		/*
276*0Sstevel@tonic-gate 		 * Construct the original command line argument.
277*0Sstevel@tonic-gate 		 */
278*0Sstevel@tonic-gate 		(void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_CONF),
279*0Sstevel@tonic-gate 		    crle->c_confil);
280*0Sstevel@tonic-gate 		cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
281*0Sstevel@tonic-gate 		if (list_append(&cmdline, cmd) == 0)
282*0Sstevel@tonic-gate 			return (1);
283*0Sstevel@tonic-gate 
284*0Sstevel@tonic-gate 		/*
285*0Sstevel@tonic-gate 		 * Construct any -f usage.
286*0Sstevel@tonic-gate 		 */
287*0Sstevel@tonic-gate 		if (head->ch_dlflags &&
288*0Sstevel@tonic-gate 		    (head->ch_dlflags != RTLD_REL_RELATIVE)) {
289*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_FLAGS),
290*0Sstevel@tonic-gate 			    conv_dlflag_str(head->ch_dlflags, 1));
291*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
292*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
293*0Sstevel@tonic-gate 				return (1);
294*0Sstevel@tonic-gate 		}
295*0Sstevel@tonic-gate 	} else {
296*0Sstevel@tonic-gate 		/*
297*0Sstevel@tonic-gate 		 * Establish any -f usage.
298*0Sstevel@tonic-gate 		 */
299*0Sstevel@tonic-gate 		if (head->ch_dlflags &&
300*0Sstevel@tonic-gate 		    (head->ch_dlflags != RTLD_REL_RELATIVE))
301*0Sstevel@tonic-gate 			crle->c_dlflags = head->ch_dlflags;
302*0Sstevel@tonic-gate 	}
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 
305*0Sstevel@tonic-gate 	/*
306*0Sstevel@tonic-gate 	 * Determine if this configuration file is only applicable to a specific
307*0Sstevel@tonic-gate 	 * application.
308*0Sstevel@tonic-gate 	 */
309*0Sstevel@tonic-gate 	if (head->ch_app) {
310*0Sstevel@tonic-gate 		char	*alter;
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 		obj = (Rtc_obj *)(head->ch_app + addr);
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 		/*
315*0Sstevel@tonic-gate 		 * Determine the output directory for the files
316*0Sstevel@tonic-gate 		 * alternative name.
317*0Sstevel@tonic-gate 		 */
318*0Sstevel@tonic-gate 		alter = (char *)(strtbl + obj->co_alter);
319*0Sstevel@tonic-gate 		(void) strcpy(_objdir, alter);
320*0Sstevel@tonic-gate 		alter = strrchr(_objdir, '/');
321*0Sstevel@tonic-gate 		*alter = '\0';
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate 		crle->c_objdir = objdir = _objdir;
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
326*0Sstevel@tonic-gate 			if (inspect(crle, (strtbl + obj->co_name),
327*0Sstevel@tonic-gate 			    (RTC_OBJ_DUMP | RTC_OBJ_ALTER |
328*0Sstevel@tonic-gate 			    RTC_OBJ_GROUP | RTC_OBJ_CMDLINE)) != 0)
329*0Sstevel@tonic-gate 				return (1);
330*0Sstevel@tonic-gate 		} else {
331*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_APP),
332*0Sstevel@tonic-gate 			    (strtbl + obj->co_alter), (strtbl + obj->co_name));
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 			/*
335*0Sstevel@tonic-gate 			 * Construct the original command line arguments.
336*0Sstevel@tonic-gate 			 */
337*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
338*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_OUTPUT), crle->c_objdir);
339*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
340*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
341*0Sstevel@tonic-gate 				return (1);
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
344*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_DUMPGRP), (strtbl + obj->co_name));
345*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
346*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
347*0Sstevel@tonic-gate 				return (1);
348*0Sstevel@tonic-gate 		}
349*0Sstevel@tonic-gate 	}
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	/*
352*0Sstevel@tonic-gate 	 * Analyze any alternative library path and trusted directory entries.
353*0Sstevel@tonic-gate 	 */
354*0Sstevel@tonic-gate 	if (head->ch_edlibpath) {
355*0Sstevel@tonic-gate 		const char	*str;
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 		str = (const char *)(head->ch_edlibpath + addr);
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
360*0Sstevel@tonic-gate 			crle->c_flags &= ~CRLE_AOUT;
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
363*0Sstevel@tonic-gate 			if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
364*0Sstevel@tonic-gate 				if (head->ch_cnflags & RTC_HDR_64)
365*0Sstevel@tonic-gate 					str = conv_upm_string(str,
366*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDDLP_64),
367*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPDLP_64),
368*0Sstevel@tonic-gate 					    MSG_PTH_UPDLP_64_SIZE);
369*0Sstevel@tonic-gate 				else
370*0Sstevel@tonic-gate 					str = conv_upm_string(str,
371*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDDLP),
372*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPDLP),
373*0Sstevel@tonic-gate 					    MSG_PTH_UPDLP_SIZE);
374*0Sstevel@tonic-gate 			}
375*0Sstevel@tonic-gate #endif
376*0Sstevel@tonic-gate 			if (addlib(crle, &crle->c_edlibpath, str) != 0)
377*0Sstevel@tonic-gate 				return (1);
378*0Sstevel@tonic-gate 		} else {
379*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
380*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF), str);
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
383*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_EDLIB), str);
384*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
385*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
386*0Sstevel@tonic-gate 				return (1);
387*0Sstevel@tonic-gate 		}
388*0Sstevel@tonic-gate 	} else {
389*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
390*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_EDLIB) {
391*0Sstevel@tonic-gate 				/*
392*0Sstevel@tonic-gate 				 * If we've been asked to update a configuration
393*0Sstevel@tonic-gate 				 * file, and no existing default ELF search
394*0Sstevel@tonic-gate 				 * path exists, but the user is going to add new
395*0Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
396*0Sstevel@tonic-gate 				 * that the users get added to them.
397*0Sstevel@tonic-gate 				 */
398*0Sstevel@tonic-gate 				if (fablib(crle, CRLE_EDLIB) != 0)
399*0Sstevel@tonic-gate 					return (1);
400*0Sstevel@tonic-gate 			}
401*0Sstevel@tonic-gate 		} else {
402*0Sstevel@tonic-gate 			/*
403*0Sstevel@tonic-gate 			 * Indicate any system default.
404*0Sstevel@tonic-gate 			 */
405*0Sstevel@tonic-gate 			if (crle->c_class == ELFCLASS64) {
406*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
407*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NEWDLP_64));
408*0Sstevel@tonic-gate #else
409*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_OLDDLP_64));
410*0Sstevel@tonic-gate #endif
411*0Sstevel@tonic-gate 			} else {
412*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
413*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NEWDLP));
414*0Sstevel@tonic-gate #else
415*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_OLDDLP));
416*0Sstevel@tonic-gate #endif
417*0Sstevel@tonic-gate 			}
418*0Sstevel@tonic-gate 		}
419*0Sstevel@tonic-gate 	}
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	if (head->ch_eslibpath) {
422*0Sstevel@tonic-gate 		const char	*str;
423*0Sstevel@tonic-gate 
424*0Sstevel@tonic-gate 		str = (const char *)(head->ch_eslibpath + addr);
425*0Sstevel@tonic-gate 
426*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
427*0Sstevel@tonic-gate 			crle->c_flags &= ~CRLE_AOUT;
428*0Sstevel@tonic-gate 
429*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
430*0Sstevel@tonic-gate 			if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
431*0Sstevel@tonic-gate 				if (head->ch_cnflags & RTC_HDR_64)
432*0Sstevel@tonic-gate 					str = conv_upm_string(str,
433*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDTD_64),
434*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPTD_64),
435*0Sstevel@tonic-gate 					    MSG_PTH_UPTD_64_SIZE);
436*0Sstevel@tonic-gate 				else
437*0Sstevel@tonic-gate 					str = conv_upm_string(str,
438*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDTD),
439*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPTD),
440*0Sstevel@tonic-gate 					    MSG_PTH_UPTD_SIZE);
441*0Sstevel@tonic-gate 			}
442*0Sstevel@tonic-gate #endif
443*0Sstevel@tonic-gate 			if (addlib(crle, &crle->c_eslibpath, str) != 0)
444*0Sstevel@tonic-gate 				return (1);
445*0Sstevel@tonic-gate 		} else {
446*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
447*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF), str);
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
450*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ESLIB), str);
451*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
452*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
453*0Sstevel@tonic-gate 				return (1);
454*0Sstevel@tonic-gate 		}
455*0Sstevel@tonic-gate 	} else {
456*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
457*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ESLIB) {
458*0Sstevel@tonic-gate 				/*
459*0Sstevel@tonic-gate 				 * If we've been asked to update a configuration
460*0Sstevel@tonic-gate 				 * file, and no existing default ELF secure
461*0Sstevel@tonic-gate 				 * path exists, but the user is going to add new
462*0Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
463*0Sstevel@tonic-gate 				 * that the users get added to them.
464*0Sstevel@tonic-gate 				 */
465*0Sstevel@tonic-gate 				if (fablib(crle, CRLE_ESLIB) != 0)
466*0Sstevel@tonic-gate 					return (1);
467*0Sstevel@tonic-gate 			}
468*0Sstevel@tonic-gate 		} else {
469*0Sstevel@tonic-gate 			/*
470*0Sstevel@tonic-gate 			 * Indicate any system default.
471*0Sstevel@tonic-gate 			 */
472*0Sstevel@tonic-gate 			if (crle->c_class == ELFCLASS64) {
473*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
474*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NEWTD_64));
475*0Sstevel@tonic-gate #else
476*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_OLDTD_64));
477*0Sstevel@tonic-gate #endif
478*0Sstevel@tonic-gate 			} else {
479*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
480*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NEWTD));
481*0Sstevel@tonic-gate #else
482*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_OLDTD));
483*0Sstevel@tonic-gate #endif
484*0Sstevel@tonic-gate 			}
485*0Sstevel@tonic-gate 		}
486*0Sstevel@tonic-gate 	}
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate 	if (head->ch_adlibpath) {
489*0Sstevel@tonic-gate 		const char	*str;
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate 		str = (const char *)(head->ch_adlibpath + addr);
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
494*0Sstevel@tonic-gate 			crle->c_flags |= CRLE_AOUT;
495*0Sstevel@tonic-gate 			if (addlib(crle, &crle->c_adlibpath, str) != 0)
496*0Sstevel@tonic-gate 				return (1);
497*0Sstevel@tonic-gate 		} else {
498*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
499*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_AOUT), str);
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
502*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ADLIB), str);
503*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
504*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
505*0Sstevel@tonic-gate 				return (1);
506*0Sstevel@tonic-gate 		}
507*0Sstevel@tonic-gate 	} else {
508*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
509*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ADLIB) {
510*0Sstevel@tonic-gate 				/*
511*0Sstevel@tonic-gate 				 * If we've been asked to update a configuration
512*0Sstevel@tonic-gate 				 * file, and no existing default AOUT search
513*0Sstevel@tonic-gate 				 * path exists, but the user is going to add new
514*0Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
515*0Sstevel@tonic-gate 				 * that the users get added to them.
516*0Sstevel@tonic-gate 				 */
517*0Sstevel@tonic-gate 				if (fablib(crle, CRLE_ADLIB) != 0)
518*0Sstevel@tonic-gate 					return (1);
519*0Sstevel@tonic-gate 			}
520*0Sstevel@tonic-gate 		} else if (crle->c_flags & CRLE_AOUT) {
521*0Sstevel@tonic-gate 			/*
522*0Sstevel@tonic-gate 			 * Indicate any system default.
523*0Sstevel@tonic-gate 			 */
524*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DEF_AOUTDLP));
525*0Sstevel@tonic-gate 		}
526*0Sstevel@tonic-gate 	}
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 	if (head->ch_aslibpath) {
529*0Sstevel@tonic-gate 		const char	*str;
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 		str = (const char *)(head->ch_aslibpath + addr);
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
534*0Sstevel@tonic-gate 			crle->c_flags |= CRLE_AOUT;
535*0Sstevel@tonic-gate 			if (addlib(crle, &crle->c_aslibpath, str) != 0)
536*0Sstevel@tonic-gate 				return (1);
537*0Sstevel@tonic-gate 		} else {
538*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
539*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_AOUT), str);
540*0Sstevel@tonic-gate 
541*0Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
542*0Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ASLIB), str);
543*0Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
544*0Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
545*0Sstevel@tonic-gate 				return (1);
546*0Sstevel@tonic-gate 		}
547*0Sstevel@tonic-gate 	} else {
548*0Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
549*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ASLIB) {
550*0Sstevel@tonic-gate 				/*
551*0Sstevel@tonic-gate 				 * If we've been asked to update a configuration
552*0Sstevel@tonic-gate 				 * file, and no existing default AOUT secure
553*0Sstevel@tonic-gate 				 * path exists, but the user is going to add new
554*0Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
555*0Sstevel@tonic-gate 				 * that the users get added to them.
556*0Sstevel@tonic-gate 				 */
557*0Sstevel@tonic-gate 				if (fablib(crle, CRLE_ASLIB) != 0)
558*0Sstevel@tonic-gate 					return (1);
559*0Sstevel@tonic-gate 			}
560*0Sstevel@tonic-gate 		} else if (crle->c_flags & CRLE_AOUT) {
561*0Sstevel@tonic-gate 			/*
562*0Sstevel@tonic-gate 			 * Indicate any system default.
563*0Sstevel@tonic-gate 			 */
564*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DEF_AOUTTD));
565*0Sstevel@tonic-gate 		}
566*0Sstevel@tonic-gate 	}
567*0Sstevel@tonic-gate 
568*0Sstevel@tonic-gate 	/*
569*0Sstevel@tonic-gate 	 * Display any environment variables.
570*0Sstevel@tonic-gate 	 */
571*0Sstevel@tonic-gate 	if ((head->ch_version >= RTC_VER_THREE) && head->ch_env) {
572*0Sstevel@tonic-gate 		Rtc_env *	envtbl;
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0)
575*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_ENV_TITLE));
576*0Sstevel@tonic-gate 
577*0Sstevel@tonic-gate 		for (envtbl = (Rtc_env *)(head->ch_env + addr);
578*0Sstevel@tonic-gate 		    envtbl->env_str; envtbl++) {
579*0Sstevel@tonic-gate 			const char	*str;
580*0Sstevel@tonic-gate 
581*0Sstevel@tonic-gate 			str = (const char *)(envtbl->env_str + addr);
582*0Sstevel@tonic-gate 
583*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
584*0Sstevel@tonic-gate 				if (addenv(crle, str,
585*0Sstevel@tonic-gate 				    (envtbl->env_flags | RTC_ENV_CONFIG)) == 0)
586*0Sstevel@tonic-gate 					return (1);
587*0Sstevel@tonic-gate 			} else {
588*0Sstevel@tonic-gate 				const char	*pfmt, *sfmt;
589*0Sstevel@tonic-gate 
590*0Sstevel@tonic-gate 				if (envtbl->env_flags & RTC_ENV_PERMANT) {
591*0Sstevel@tonic-gate 					pfmt = MSG_INTL(MSG_ENV_PRM);
592*0Sstevel@tonic-gate 					sfmt = MSG_ORIG(MSG_CMD_PRMENV);
593*0Sstevel@tonic-gate 				} else {
594*0Sstevel@tonic-gate 					pfmt = MSG_INTL(MSG_ENV_RPL);
595*0Sstevel@tonic-gate 					sfmt = MSG_ORIG(MSG_CMD_RPLENV);
596*0Sstevel@tonic-gate 				}
597*0Sstevel@tonic-gate 				(void) printf(pfmt, str);
598*0Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX, sfmt, str);
599*0Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
600*0Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
601*0Sstevel@tonic-gate 					return (1);
602*0Sstevel@tonic-gate 			}
603*0Sstevel@tonic-gate 		}
604*0Sstevel@tonic-gate 	}
605*0Sstevel@tonic-gate 
606*0Sstevel@tonic-gate 	/*
607*0Sstevel@tonic-gate 	 * Display any filter/filtee associations.
608*0Sstevel@tonic-gate 	 */
609*0Sstevel@tonic-gate 	if ((head->ch_version >= RTC_VER_FOUR) && head->ch_fltr) {
610*0Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0) {
611*0Sstevel@tonic-gate 			Rtc_fltr *	fltrtbl;
612*0Sstevel@tonic-gate 			Rtc_flte *	fltetbl;
613*0Sstevel@tonic-gate 
614*0Sstevel@tonic-gate 			/* LINTED */
615*0Sstevel@tonic-gate 			fltrtbl = (Rtc_fltr *)((char *)head->ch_fltr + addr);
616*0Sstevel@tonic-gate 			/* LINTED */
617*0Sstevel@tonic-gate 			fltetbl = (Rtc_flte *)((char *)head->ch_flte + addr);
618*0Sstevel@tonic-gate 
619*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_FLT_TITLE));
620*0Sstevel@tonic-gate 
621*0Sstevel@tonic-gate 			while (fltrtbl->fr_filter) {
622*0Sstevel@tonic-gate 				Rtc_flte	*_fltetbl;
623*0Sstevel@tonic-gate 
624*0Sstevel@tonic-gate 				/*
625*0Sstevel@tonic-gate 				 * Print the filter and filtee string pair.
626*0Sstevel@tonic-gate 				 */
627*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_FLT_FILTER),
628*0Sstevel@tonic-gate 				    (strtbl + fltrtbl->fr_filter),
629*0Sstevel@tonic-gate 				    (strtbl + fltrtbl->fr_string));
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 				/*
632*0Sstevel@tonic-gate 				 * Print each filtee.
633*0Sstevel@tonic-gate 				 */
634*0Sstevel@tonic-gate 				/* LINTED */
635*0Sstevel@tonic-gate 				for (_fltetbl = (Rtc_flte *)((char *)fltetbl +
636*0Sstevel@tonic-gate 				    fltrtbl->fr_filtee); _fltetbl->fe_filtee;
637*0Sstevel@tonic-gate 				    _fltetbl++) {
638*0Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_FLT_FILTEE),
639*0Sstevel@tonic-gate 					    (strtbl + _fltetbl->fe_filtee));
640*0Sstevel@tonic-gate 				}
641*0Sstevel@tonic-gate 				fltrtbl++;
642*0Sstevel@tonic-gate 			}
643*0Sstevel@tonic-gate 		}
644*0Sstevel@tonic-gate 	}
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	/*
647*0Sstevel@tonic-gate 	 * Display any memory reservations required for any alternative
648*0Sstevel@tonic-gate 	 * objects.
649*0Sstevel@tonic-gate 	 */
650*0Sstevel@tonic-gate 	if (head->ch_resbgn && ((crle->c_flags & CRLE_UPDATE) == 0))
651*0Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_DMP_RESV), head->ch_resbgn,
652*0Sstevel@tonic-gate 		    head->ch_resend, (head->ch_resend - head->ch_resbgn));
653*0Sstevel@tonic-gate 
654*0Sstevel@tonic-gate 	/*
655*0Sstevel@tonic-gate 	 * If there's no hash table there's nothing else to process.
656*0Sstevel@tonic-gate 	 */
657*0Sstevel@tonic-gate 	if (head->ch_hash == 0) {
658*0Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0)
659*0Sstevel@tonic-gate 			printcmd(crle, head, &cmdline);
660*0Sstevel@tonic-gate 		return (0);
661*0Sstevel@tonic-gate 	}
662*0Sstevel@tonic-gate 
663*0Sstevel@tonic-gate 	/*
664*0Sstevel@tonic-gate 	 * Traverse the directory and filename arrays.
665*0Sstevel@tonic-gate 	 */
666*0Sstevel@tonic-gate 	for (dirtbl = (Rtc_dir *)(head->ch_dir + addr);
667*0Sstevel@tonic-gate 	    dirtbl->cd_obj; dirtbl++) {
668*0Sstevel@tonic-gate 		struct stat	status;
669*0Sstevel@tonic-gate 		Rtc_obj		*dobj;
670*0Sstevel@tonic-gate 		const char	*str;
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate 		dobj = (Rtc_obj *)(dirtbl->cd_obj + addr);
673*0Sstevel@tonic-gate 		filetbl = (Rtc_file *)(dirtbl->cd_file + addr);
674*0Sstevel@tonic-gate 		str = strtbl + dobj->co_name;
675*0Sstevel@tonic-gate 
676*0Sstevel@tonic-gate 		/*
677*0Sstevel@tonic-gate 		 * Simplify recreation by using any command-line directories.
678*0Sstevel@tonic-gate 		 * If we're dealing with a version 1 configuration file use
679*0Sstevel@tonic-gate 		 * every directory.
680*0Sstevel@tonic-gate 		 */
681*0Sstevel@tonic-gate 		if ((dobj->co_flags & RTC_OBJ_CMDLINE) ||
682*0Sstevel@tonic-gate 		    (head->ch_version == RTC_VER_ONE)) {
683*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
684*0Sstevel@tonic-gate 				if (inspect(crle, str,
685*0Sstevel@tonic-gate 				    getflags(dobj->co_flags)) != 0)
686*0Sstevel@tonic-gate 					return (1);
687*0Sstevel@tonic-gate 				if ((dobj->co_flags &
688*0Sstevel@tonic-gate 				    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
689*0Sstevel@tonic-gate 				    RTC_OBJ_NOEXIST)
690*0Sstevel@tonic-gate 					continue;
691*0Sstevel@tonic-gate 			} else {
692*0Sstevel@tonic-gate 				/* LINTED */
693*0Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX,
694*0Sstevel@tonic-gate 				    getformat(dobj->co_flags), str);
695*0Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
696*0Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
697*0Sstevel@tonic-gate 					return (1);
698*0Sstevel@tonic-gate 			}
699*0Sstevel@tonic-gate 		}
700*0Sstevel@tonic-gate 
701*0Sstevel@tonic-gate 		/*
702*0Sstevel@tonic-gate 		 * If this isn't an update print the directory name.  If the
703*0Sstevel@tonic-gate 		 * directory has no entries (possible if the directory is a
704*0Sstevel@tonic-gate 		 * symlink to another directory, in which case we record the
705*0Sstevel@tonic-gate 		 * real path also), don't bother printing it unless we're in
706*0Sstevel@tonic-gate 		 * verbose mode.
707*0Sstevel@tonic-gate 		 */
708*0Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0) {
709*0Sstevel@tonic-gate 			if ((dobj->co_flags &
710*0Sstevel@tonic-gate 			    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
711*0Sstevel@tonic-gate 			    RTC_OBJ_NOEXIST) {
712*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DIR_2), str);
713*0Sstevel@tonic-gate 				continue;
714*0Sstevel@tonic-gate 			} else if (filetbl->cf_obj ||
715*0Sstevel@tonic-gate 			    (crle->c_flags & CRLE_VERBOSE))
716*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DIR_1), str);
717*0Sstevel@tonic-gate 		}
718*0Sstevel@tonic-gate 
719*0Sstevel@tonic-gate 		/*
720*0Sstevel@tonic-gate 		 * Under verbose mode validate any real directory entry - the
721*0Sstevel@tonic-gate 		 * same test will be carried out by ld.so.1.
722*0Sstevel@tonic-gate 		 */
723*0Sstevel@tonic-gate 		if (((crle->c_flags & CRLE_UPDATE) == 0) &&
724*0Sstevel@tonic-gate 		    (crle->c_flags & CRLE_VERBOSE) &&
725*0Sstevel@tonic-gate 		    (dobj->co_flags & RTC_OBJ_REALPTH)) {
726*0Sstevel@tonic-gate 			if (stat(str, &status) != 0) {
727*0Sstevel@tonic-gate 				int err = errno;
728*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_STAT), str,
729*0Sstevel@tonic-gate 				    strerror(err));
730*0Sstevel@tonic-gate 			} else if (status.st_mtime != dobj->co_info) {
731*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DCMP), str);
732*0Sstevel@tonic-gate 			}
733*0Sstevel@tonic-gate 		}
734*0Sstevel@tonic-gate 
735*0Sstevel@tonic-gate 		for (; filetbl->cf_obj; filetbl++) {
736*0Sstevel@tonic-gate 			Rtc_obj *	fobj;
737*0Sstevel@tonic-gate 			Half		flags;
738*0Sstevel@tonic-gate 
739*0Sstevel@tonic-gate 			fobj = (Rtc_obj *)(filetbl->cf_obj + addr);
740*0Sstevel@tonic-gate 			str = strtbl + fobj->co_name;
741*0Sstevel@tonic-gate 			flags = fobj->co_flags;
742*0Sstevel@tonic-gate 
743*0Sstevel@tonic-gate 			/*
744*0Sstevel@tonic-gate 			 * Only update individual files that were originally
745*0Sstevel@tonic-gate 			 * specified on the command-line.  Or, if this is a
746*0Sstevel@tonic-gate 			 * version 1 configuration file use every file that
747*0Sstevel@tonic-gate 			 * isn't part of an all-entries directory.
748*0Sstevel@tonic-gate 			 */
749*0Sstevel@tonic-gate 			if (((flags & RTC_OBJ_CMDLINE) &&
750*0Sstevel@tonic-gate 			    ((fobj->co_flags & RTC_OBJ_APP) == 0)) ||
751*0Sstevel@tonic-gate 			    ((head->ch_version == RTC_VER_ONE) &&
752*0Sstevel@tonic-gate 			    ((dobj->co_flags & RTC_OBJ_ALLENTS) == 0))) {
753*0Sstevel@tonic-gate 				char	*alter = 0, altdir[PATH_MAX];
754*0Sstevel@tonic-gate 
755*0Sstevel@tonic-gate 				/*
756*0Sstevel@tonic-gate 				 * Determine whether this file requires an
757*0Sstevel@tonic-gate 				 * alternative, and if so, and we haven't
758*0Sstevel@tonic-gate 				 * already an alternative in affect, create one.
759*0Sstevel@tonic-gate 				 */
760*0Sstevel@tonic-gate 				if (fobj->co_flags & RTC_OBJ_ALTER) {
761*0Sstevel@tonic-gate 					alter = (char *)(strtbl +
762*0Sstevel@tonic-gate 					    fobj->co_alter);
763*0Sstevel@tonic-gate 					(void) strcpy(altdir, alter);
764*0Sstevel@tonic-gate 					alter = strrchr(altdir, '/');
765*0Sstevel@tonic-gate 					*alter = '\0';
766*0Sstevel@tonic-gate 
767*0Sstevel@tonic-gate 					if ((objdir == 0) ||
768*0Sstevel@tonic-gate 					    (strcmp(objdir, altdir) != 0)) {
769*0Sstevel@tonic-gate 						(void) strcpy(_objdir, altdir);
770*0Sstevel@tonic-gate 						crle->c_objdir = alter =
771*0Sstevel@tonic-gate 						    objdir = _objdir;
772*0Sstevel@tonic-gate 					} else
773*0Sstevel@tonic-gate 						alter = 0;
774*0Sstevel@tonic-gate 				}
775*0Sstevel@tonic-gate 
776*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_UPDATE) {
777*0Sstevel@tonic-gate 					if (inspect(crle, str,
778*0Sstevel@tonic-gate 					    getflags(flags)) != 0)
779*0Sstevel@tonic-gate 						return (1);
780*0Sstevel@tonic-gate 					continue;
781*0Sstevel@tonic-gate 				}
782*0Sstevel@tonic-gate 
783*0Sstevel@tonic-gate 				if (alter) {
784*0Sstevel@tonic-gate 					(void) snprintf(_cmd, PATH_MAX,
785*0Sstevel@tonic-gate 					    MSG_ORIG(MSG_CMD_OUTPUT),
786*0Sstevel@tonic-gate 					    crle->c_objdir);
787*0Sstevel@tonic-gate 					cmd = strcpy(alloca(strlen(_cmd) + 1),
788*0Sstevel@tonic-gate 					    _cmd);
789*0Sstevel@tonic-gate 					if (list_append(&cmdline, cmd) == 0)
790*0Sstevel@tonic-gate 						return (1);
791*0Sstevel@tonic-gate 				}
792*0Sstevel@tonic-gate 
793*0Sstevel@tonic-gate 				/* LINTED */
794*0Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX,
795*0Sstevel@tonic-gate 				    getformat(flags), str);
796*0Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
797*0Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
798*0Sstevel@tonic-gate 					return (1);
799*0Sstevel@tonic-gate 			}
800*0Sstevel@tonic-gate 
801*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE)
802*0Sstevel@tonic-gate 				continue;
803*0Sstevel@tonic-gate 
804*0Sstevel@tonic-gate 			/*
805*0Sstevel@tonic-gate 			 * Although we record both full pathnames and their
806*0Sstevel@tonic-gate 			 * simple filenames (basename), only print the simple
807*0Sstevel@tonic-gate 			 * names unless we're under verbose mode.
808*0Sstevel@tonic-gate 			 */
809*0Sstevel@tonic-gate 			if ((strchr(str, '/') == 0) ||
810*0Sstevel@tonic-gate 			    (crle->c_flags & CRLE_VERBOSE)) {
811*0Sstevel@tonic-gate 				if (fobj->co_flags & RTC_OBJ_ALTER)
812*0Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FILE_2),
813*0Sstevel@tonic-gate 					    str, (strtbl + fobj->co_alter));
814*0Sstevel@tonic-gate 				else
815*0Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FILE_1),
816*0Sstevel@tonic-gate 					    str);
817*0Sstevel@tonic-gate 			}
818*0Sstevel@tonic-gate 
819*0Sstevel@tonic-gate 			/*
820*0Sstevel@tonic-gate 			 * Under verbose mode validate any real file entry - the
821*0Sstevel@tonic-gate 			 * same test will be carried out by ld.so.1.
822*0Sstevel@tonic-gate 			 */
823*0Sstevel@tonic-gate 			if ((crle->c_flags & CRLE_VERBOSE) &&
824*0Sstevel@tonic-gate 			    (fobj->co_flags & RTC_OBJ_REALPTH)) {
825*0Sstevel@tonic-gate 				if (stat(str, &status) != 0) {
826*0Sstevel@tonic-gate 					int err = errno;
827*0Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_STAT),
828*0Sstevel@tonic-gate 					    str, strerror(err));
829*0Sstevel@tonic-gate 				} else if (status.st_size != fobj->co_info) {
830*0Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FCMP),
831*0Sstevel@tonic-gate 					    str);
832*0Sstevel@tonic-gate 				}
833*0Sstevel@tonic-gate 			}
834*0Sstevel@tonic-gate 		}
835*0Sstevel@tonic-gate 	}
836*0Sstevel@tonic-gate 
837*0Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_UPDATE) == 0)
838*0Sstevel@tonic-gate 		printcmd(crle, head, &cmdline);
839*0Sstevel@tonic-gate 
840*0Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_VERBOSE) == 0)
841*0Sstevel@tonic-gate 		return (0);
842*0Sstevel@tonic-gate 
843*0Sstevel@tonic-gate 	/*
844*0Sstevel@tonic-gate 	 * If we've in verbose mode scan the hash list.
845*0Sstevel@tonic-gate 	 */
846*0Sstevel@tonic-gate 	/* LINTED */
847*0Sstevel@tonic-gate 	hash = (Word *)((char *)head->ch_hash + addr);
848*0Sstevel@tonic-gate 	bkts = hash[0];
849*0Sstevel@tonic-gate 	chain = &hash[2 + bkts];
850*0Sstevel@tonic-gate 	hash += 2;
851*0Sstevel@tonic-gate 
852*0Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_DMP_HASH));
853*0Sstevel@tonic-gate 
854*0Sstevel@tonic-gate 	/*
855*0Sstevel@tonic-gate 	 * Scan the hash buckets looking for valid entries.
856*0Sstevel@tonic-gate 	 */
857*0Sstevel@tonic-gate 	for (ndx = 0; ndx < bkts; ndx++, hash++) {
858*0Sstevel@tonic-gate 		Rtc_obj		*obj;
859*0Sstevel@tonic-gate 		const char	*str;
860*0Sstevel@tonic-gate 		Word		_ndx;
861*0Sstevel@tonic-gate 
862*0Sstevel@tonic-gate 		if (*hash == 0)
863*0Sstevel@tonic-gate 			continue;
864*0Sstevel@tonic-gate 
865*0Sstevel@tonic-gate 		obj = objtbl + *hash;
866*0Sstevel@tonic-gate 		str = strtbl + obj->co_name;
867*0Sstevel@tonic-gate 
868*0Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_DMP_HASHENT_1), obj->co_id, ndx,
869*0Sstevel@tonic-gate 			str, conv_config_obj(obj->co_flags));
870*0Sstevel@tonic-gate 
871*0Sstevel@tonic-gate 		/*
872*0Sstevel@tonic-gate 		 * Determine whether there are other objects chained to this
873*0Sstevel@tonic-gate 		 * bucket.
874*0Sstevel@tonic-gate 		 */
875*0Sstevel@tonic-gate 		for (_ndx = chain[*hash]; _ndx; _ndx = chain[_ndx]) {
876*0Sstevel@tonic-gate 			obj = objtbl + _ndx;
877*0Sstevel@tonic-gate 			str = strtbl + obj->co_name;
878*0Sstevel@tonic-gate 
879*0Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_HASHENT_2), obj->co_id,
880*0Sstevel@tonic-gate 			    str, conv_config_obj(obj->co_flags));
881*0Sstevel@tonic-gate 		}
882*0Sstevel@tonic-gate 	}
883*0Sstevel@tonic-gate 	(void) printf(MSG_ORIG(MSG_STR_NL));
884*0Sstevel@tonic-gate 
885*0Sstevel@tonic-gate 	return (0);
886*0Sstevel@tonic-gate }
887*0Sstevel@tonic-gate 
888*0Sstevel@tonic-gate 
889*0Sstevel@tonic-gate int
890*0Sstevel@tonic-gate inspectconfig(Crle_desc * crle)
891*0Sstevel@tonic-gate {
892*0Sstevel@tonic-gate 	int		error, fd;
893*0Sstevel@tonic-gate 	Addr		addr;
894*0Sstevel@tonic-gate 	struct stat	status;
895*0Sstevel@tonic-gate 	const char	*caller = crle->c_name, *file = crle->c_confil;
896*0Sstevel@tonic-gate 
897*0Sstevel@tonic-gate 	/*
898*0Sstevel@tonic-gate 	 * Open the configuration file, determine its size and map it in.
899*0Sstevel@tonic-gate 	 */
900*0Sstevel@tonic-gate 	if ((fd = open(file, O_RDONLY, 0)) == -1) {
901*0Sstevel@tonic-gate 		int	err = errno;
902*0Sstevel@tonic-gate 
903*0Sstevel@tonic-gate 		if ((err == ENOENT)) {
904*0Sstevel@tonic-gate 			/*
905*0Sstevel@tonic-gate 			 * To allow an update (-u) from scratch, fabricate any
906*0Sstevel@tonic-gate 			 * default search and secure paths that the user
907*0Sstevel@tonic-gate 			 * intends to add to.
908*0Sstevel@tonic-gate 			 */
909*0Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
910*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_EDLIB) {
911*0Sstevel@tonic-gate 					if (fablib(crle, CRLE_EDLIB))
912*0Sstevel@tonic-gate 						return (1);
913*0Sstevel@tonic-gate 				}
914*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ESLIB) {
915*0Sstevel@tonic-gate 					if (fablib(crle, CRLE_ESLIB))
916*0Sstevel@tonic-gate 						return (1);
917*0Sstevel@tonic-gate 				}
918*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ADLIB) {
919*0Sstevel@tonic-gate 					if (fablib(crle, CRLE_ADLIB))
920*0Sstevel@tonic-gate 						return (1);
921*0Sstevel@tonic-gate 				}
922*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ASLIB) {
923*0Sstevel@tonic-gate 					if (fablib(crle, CRLE_ASLIB))
924*0Sstevel@tonic-gate 						return (1);
925*0Sstevel@tonic-gate 				}
926*0Sstevel@tonic-gate 				return (0);
927*0Sstevel@tonic-gate 
928*0Sstevel@tonic-gate 			} else if (crle->c_flags & CRLE_CONFDEF) {
929*0Sstevel@tonic-gate 				const char	*fmt1, *fmt2;
930*0Sstevel@tonic-gate 
931*0Sstevel@tonic-gate 				/*
932*0Sstevel@tonic-gate 				 * Otherwise if the user is inspecting a default
933*0Sstevel@tonic-gate 				 * configuration file that doesn't exist inform
934*0Sstevel@tonic-gate 				 * them and display the ELF defaults.
935*0Sstevel@tonic-gate 				 */
936*0Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NOCONF), file);
937*0Sstevel@tonic-gate 
938*0Sstevel@tonic-gate 				if (crle->c_flags & CRLE_AOUT) {
939*0Sstevel@tonic-gate 					fmt1 = MSG_INTL(MSG_DEF_AOUTDLP);
940*0Sstevel@tonic-gate 					fmt2 = MSG_INTL(MSG_DEF_AOUTTD);
941*0Sstevel@tonic-gate 				} else {
942*0Sstevel@tonic-gate 					if (crle->c_class == ELFCLASS64) {
943*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
944*0Sstevel@tonic-gate 					    fmt1 = MSG_INTL(MSG_DEF_NEWDLP_64);
945*0Sstevel@tonic-gate 					    fmt2 = MSG_INTL(MSG_DEF_NEWTD_64);
946*0Sstevel@tonic-gate #else
947*0Sstevel@tonic-gate 					    fmt1 = MSG_INTL(MSG_DEF_OLDDLP_64);
948*0Sstevel@tonic-gate 					    fmt2 = MSG_INTL(MSG_DEF_OLDTD_64);
949*0Sstevel@tonic-gate #endif
950*0Sstevel@tonic-gate 					} else {
951*0Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
952*0Sstevel@tonic-gate 					    fmt1 = MSG_INTL(MSG_DEF_NEWDLP);
953*0Sstevel@tonic-gate 					    fmt2 = MSG_INTL(MSG_DEF_NEWTD);
954*0Sstevel@tonic-gate #else
955*0Sstevel@tonic-gate 					    fmt1 = MSG_INTL(MSG_DEF_OLDDLP);
956*0Sstevel@tonic-gate 					    fmt2 = MSG_INTL(MSG_DEF_OLDTD);
957*0Sstevel@tonic-gate #endif
958*0Sstevel@tonic-gate 					}
959*0Sstevel@tonic-gate 				}
960*0Sstevel@tonic-gate 				(void) printf(fmt1);
961*0Sstevel@tonic-gate 				(void) printf(fmt2);
962*0Sstevel@tonic-gate 
963*0Sstevel@tonic-gate 				return (0);
964*0Sstevel@tonic-gate 			}
965*0Sstevel@tonic-gate 		}
966*0Sstevel@tonic-gate 
967*0Sstevel@tonic-gate 		/*
968*0Sstevel@tonic-gate 		 * Otherwise there's an error condition in accessing the file.
969*0Sstevel@tonic-gate 		 */
970*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), caller, file,
971*0Sstevel@tonic-gate 		    strerror(err));
972*0Sstevel@tonic-gate 
973*0Sstevel@tonic-gate 		return (1);
974*0Sstevel@tonic-gate 	}
975*0Sstevel@tonic-gate 
976*0Sstevel@tonic-gate 	(void) fstat(fd, &status);
977*0Sstevel@tonic-gate 	if (status.st_size < sizeof (Rtc_head)) {
978*0Sstevel@tonic-gate 		(void) close(fd);
979*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_COR_TRUNC), caller, file);
980*0Sstevel@tonic-gate 		return (1);
981*0Sstevel@tonic-gate 	}
982*0Sstevel@tonic-gate 	if ((addr = (Addr)mmap(0, status.st_size, PROT_READ, MAP_SHARED,
983*0Sstevel@tonic-gate 	    fd, 0)) == (Addr)MAP_FAILED) {
984*0Sstevel@tonic-gate 		int err = errno;
985*0Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP), caller, file,
986*0Sstevel@tonic-gate 		    strerror(err));
987*0Sstevel@tonic-gate 		(void) close(fd);
988*0Sstevel@tonic-gate 		return (1);
989*0Sstevel@tonic-gate 	}
990*0Sstevel@tonic-gate 	(void) close(fd);
991*0Sstevel@tonic-gate 
992*0Sstevel@tonic-gate 	/*
993*0Sstevel@tonic-gate 	 * Print the contents of the configuration file.
994*0Sstevel@tonic-gate 	 */
995*0Sstevel@tonic-gate 	error = scanconfig(crle, addr);
996*0Sstevel@tonic-gate 
997*0Sstevel@tonic-gate 	(void) munmap((void *)addr, status.st_size);
998*0Sstevel@tonic-gate 	return (error);
999*0Sstevel@tonic-gate }
1000