xref: /onnv-gate/usr/src/cmd/sgs/crle/common/print.c (revision 4734:a4708faa3e85)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51618Srie  * Common Development and Distribution License (the "License").
61618Srie  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211618Srie 
220Sstevel@tonic-gate /*
23*4734Sab196087  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate #include	<sys/types.h>
290Sstevel@tonic-gate #include	<sys/stat.h>
300Sstevel@tonic-gate #include	<sys/mman.h>
310Sstevel@tonic-gate #include	<fcntl.h>
320Sstevel@tonic-gate #include	<stdio.h>
330Sstevel@tonic-gate #include	<string.h>
340Sstevel@tonic-gate #include	<unistd.h>
350Sstevel@tonic-gate #include	<errno.h>
360Sstevel@tonic-gate #include	<limits.h>
370Sstevel@tonic-gate #include	<alloca.h>
380Sstevel@tonic-gate #include	"sgs.h"
390Sstevel@tonic-gate #include	"rtc.h"
400Sstevel@tonic-gate #include	"conv.h"
410Sstevel@tonic-gate #include	"_crle.h"
420Sstevel@tonic-gate #include	"msg.h"
430Sstevel@tonic-gate 
440Sstevel@tonic-gate 
450Sstevel@tonic-gate /*
460Sstevel@tonic-gate  * Display the command line required to regenerate the configuration file.
470Sstevel@tonic-gate  *
480Sstevel@tonic-gate  * Under normal mode the command is printed on one line to make it more
490Sstevel@tonic-gate  * available for grep(1) use.  Under verbose mode the command is separated
500Sstevel@tonic-gate  * into each argument (a little more readable perhaps when the arguments are
510Sstevel@tonic-gate  * numerous of have long pathnames).
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * Note that for version 1 configuration files we never used to generate any
540Sstevel@tonic-gate  * command-line information, and as the attempt to do so is only a best effort
550Sstevel@tonic-gate  * don't bother printing anything.
560Sstevel@tonic-gate  */
570Sstevel@tonic-gate static void
580Sstevel@tonic-gate printcmd(Crle_desc * crle, Rtc_head * head, List * cmdline)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate 	Listnode	*lnp;
610Sstevel@tonic-gate 	const char	*fmto, *fmtb, *fmtm, *fmte;
620Sstevel@tonic-gate 	char		*cmd;
630Sstevel@tonic-gate 	int		output = 0;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	if (crle->c_flags & CRLE_VERBOSE) {
660Sstevel@tonic-gate 		fmto = MSG_INTL(MSG_DMP_CMD_ONE_V);
670Sstevel@tonic-gate 		fmtb = MSG_INTL(MSG_DMP_CMD_BGN_V);
680Sstevel@tonic-gate 		fmtm = MSG_INTL(MSG_DMP_CMD_MID_V);
690Sstevel@tonic-gate 		fmte = MSG_INTL(MSG_DMP_CMD_END_V);
700Sstevel@tonic-gate 
710Sstevel@tonic-gate 	} else if (head->ch_version > RTC_VER_ONE) {
720Sstevel@tonic-gate 		fmto = MSG_INTL(MSG_DMP_CMD_ONE);
730Sstevel@tonic-gate 		fmtb = MSG_INTL(MSG_DMP_CMD_BGN);
740Sstevel@tonic-gate 		fmtm = MSG_INTL(MSG_DMP_CMD_MID);
750Sstevel@tonic-gate 		fmte = MSG_INTL(MSG_DMP_CMD_END);
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	} else {
780Sstevel@tonic-gate 		(void) printf(MSG_ORIG(MSG_STR_NL));
790Sstevel@tonic-gate 		return;
800Sstevel@tonic-gate 	}
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_DMP_CMD_TITLE));
830Sstevel@tonic-gate 	for (LIST_TRAVERSE(cmdline, lnp, cmd)) {
840Sstevel@tonic-gate 		if (output++ == 0) {
850Sstevel@tonic-gate 			if (lnp->next)
860Sstevel@tonic-gate 				(void) printf(fmtb, cmd);
870Sstevel@tonic-gate 			else
880Sstevel@tonic-gate 				(void) printf(fmto, cmd);
890Sstevel@tonic-gate 		} else {
900Sstevel@tonic-gate 			if (lnp->next)
910Sstevel@tonic-gate 				(void) printf(fmtm, cmd);
920Sstevel@tonic-gate 			else
930Sstevel@tonic-gate 				(void) printf(fmte, cmd);
940Sstevel@tonic-gate 		}
950Sstevel@tonic-gate 	}
960Sstevel@tonic-gate }
970Sstevel@tonic-gate 
980Sstevel@tonic-gate /*
990Sstevel@tonic-gate  * Establish the argument required to generate the associated object.
1000Sstevel@tonic-gate  */
1010Sstevel@tonic-gate static const char *
1020Sstevel@tonic-gate getformat(Half flags)
1030Sstevel@tonic-gate {
1040Sstevel@tonic-gate 	if (flags & RTC_OBJ_ALTER) {
1050Sstevel@tonic-gate 		if (flags & RTC_OBJ_DUMP) {
1060Sstevel@tonic-gate 			if (flags & RTC_OBJ_GROUP)
1070Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_DUMPGRP));
1080Sstevel@tonic-gate 			else
1090Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_DUMPIND));
1100Sstevel@tonic-gate 		} else {
1110Sstevel@tonic-gate 			if (flags & RTC_OBJ_OPTINAL)
1120Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_OPTIONAL));
1130Sstevel@tonic-gate 			else
1140Sstevel@tonic-gate 				return (MSG_ORIG(MSG_CMD_ALTER));
1150Sstevel@tonic-gate 		}
1160Sstevel@tonic-gate 	} else {
1170Sstevel@tonic-gate 		if (flags & RTC_OBJ_GROUP)
1180Sstevel@tonic-gate 			return (MSG_ORIG(MSG_CMD_GRP));
1190Sstevel@tonic-gate 		else
1200Sstevel@tonic-gate 			return (MSG_ORIG(MSG_CMD_IND));
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate /*
1250Sstevel@tonic-gate  * Fabricate a system default search path.  If an update is requested, and
1260Sstevel@tonic-gate  * new search paths are specified while no configuration file exists, or if a
1270Sstevel@tonic-gate  * configuration file does exist but doesn't specify this particular search
1280Sstevel@tonic-gate  * path, create any system defaults.  The intent is to allow
1290Sstevel@tonic-gate  * "crle -u -l/usr/local/lib" and have this append the search path to the
1300Sstevel@tonic-gate  * system default, rather than have the user have to determine and specify
1310Sstevel@tonic-gate  * this default themselves.
1320Sstevel@tonic-gate  */
1330Sstevel@tonic-gate static int
1340Sstevel@tonic-gate fablib(Crle_desc * crle, int flag)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate 	const char	*path;
1370Sstevel@tonic-gate 	char		**list;
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 	switch (flag) {
1400Sstevel@tonic-gate 	case CRLE_EDLIB:
1411976Sab196087 #if M_CLASS == ELFCLASS64
1420Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
1431976Sab196087 		path = MSG_ORIG(MSG_PTH_NEWDLP_64);
1440Sstevel@tonic-gate #else
1451976Sab196087 		path = MSG_ORIG(MSG_PTH_OLDDLP_64);
1460Sstevel@tonic-gate #endif
1471976Sab196087 #else
1480Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
1491976Sab196087 		path = MSG_ORIG(MSG_PTH_NEWDLP);
1500Sstevel@tonic-gate #else
1511976Sab196087 		path = MSG_ORIG(MSG_PTH_OLDDLP);
1520Sstevel@tonic-gate #endif
1531976Sab196087 #endif
1540Sstevel@tonic-gate 		list = &crle->c_edlibpath;
1550Sstevel@tonic-gate 		break;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	case CRLE_ESLIB:
1581976Sab196087 #if M_CLASS == ELFCLASS64
1590Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
1601976Sab196087 		path = MSG_ORIG(MSG_PTH_NEWTD_64);
1610Sstevel@tonic-gate #else
1621976Sab196087 		path = MSG_ORIG(MSG_PTH_OLDTD_64);
1630Sstevel@tonic-gate #endif
1641976Sab196087 #else
1650Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
1661976Sab196087 		path = MSG_ORIG(MSG_PTH_NEWTD);
1670Sstevel@tonic-gate #else
1681976Sab196087 		path = MSG_ORIG(MSG_PTH_OLDTD);
1690Sstevel@tonic-gate #endif
1701976Sab196087 #endif
1710Sstevel@tonic-gate 		list = &crle->c_eslibpath;
1720Sstevel@tonic-gate 		break;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	case CRLE_ADLIB:
1750Sstevel@tonic-gate 		path = MSG_ORIG(MSG_PTH_AOUTDLP);
1760Sstevel@tonic-gate 		list = &crle->c_adlibpath;
1770Sstevel@tonic-gate 		break;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	case CRLE_ASLIB:
1800Sstevel@tonic-gate 		path = MSG_ORIG(MSG_PTH_AOUTTD);
1810Sstevel@tonic-gate 		list = &crle->c_aslibpath;
1820Sstevel@tonic-gate 		break;
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate 	default:
1850Sstevel@tonic-gate 		return (1);
1860Sstevel@tonic-gate 	}
1870Sstevel@tonic-gate 
1880Sstevel@tonic-gate 	return (addlib(crle, list, path));
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /*
1920Sstevel@tonic-gate  * Establish the flags required to generate the associated object.  Actually
1930Sstevel@tonic-gate  * the flags are already part of the object being inspected from the present
1940Sstevel@tonic-gate  * configuration file, but instead of using them all, which can cause some
1950Sstevel@tonic-gate  * unsuspected propagation down the inspect() family, only use those flags that
1960Sstevel@tonic-gate  * would have been contributed from crle()'s calls to inspect.
1970Sstevel@tonic-gate  */
1980Sstevel@tonic-gate static Half
1990Sstevel@tonic-gate getflags(Half flags)
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate 	flags &=
2020Sstevel@tonic-gate 	    (RTC_OBJ_ALTER | RTC_OBJ_DUMP | RTC_OBJ_GROUP | RTC_OBJ_OPTINAL);
2030Sstevel@tonic-gate 	return (flags | RTC_OBJ_CMDLINE);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate /*
2070Sstevel@tonic-gate  * Dump a configuration files information.  This routine is very close to the
2080Sstevel@tonic-gate  * scanconfig() in libcrle.
2090Sstevel@tonic-gate  */
2102056Sab196087 /*ARGSUSED2*/
2111976Sab196087 static INSCFG_RET
2122056Sab196087 scanconfig(Crle_desc * crle, Addr addr, int c_class)
2130Sstevel@tonic-gate {
214*4734Sab196087 	Conv_inv_buf_t 		inv_buf1, inv_buf2, inv_buf3, inv_buf4;
215*4734Sab196087 	Conv_dl_flag_buf_t	dl_flag_buf;
2161976Sab196087 	Rtc_id		*id;
2171976Sab196087 	Rtc_head	*head;
2180Sstevel@tonic-gate 	Rtc_dir		*dirtbl;
2190Sstevel@tonic-gate 	Rtc_file	*filetbl;
2200Sstevel@tonic-gate 	Rtc_obj		*objtbl, * obj;
2210Sstevel@tonic-gate 	Word		*hash, * chain;
2220Sstevel@tonic-gate 	const char	*strtbl;
2230Sstevel@tonic-gate 	int		ndx, bkts;
2240Sstevel@tonic-gate 	List		cmdline = { 0 };
2250Sstevel@tonic-gate 	char		_cmd[PATH_MAX], * cmd;
2260Sstevel@tonic-gate 	char		_objdir[PATH_MAX], * objdir = 0;
2270Sstevel@tonic-gate 
2281976Sab196087 
2291976Sab196087 	/*
2301976Sab196087 	 * If there is an Rtc_id present, the Rtc_head follows it.
2311976Sab196087 	 * Otherwise, it is at the top.
2321976Sab196087 	 */
2331976Sab196087 	if (RTC_ID_TEST(addr)) {
2341976Sab196087 		id = (Rtc_id *) addr;
2351976Sab196087 		addr += sizeof (*id);	/* Rtc_head follows */
2361976Sab196087 	} else {
2371976Sab196087 		id = NULL;
2381976Sab196087 		/*
2391976Sab196087 		 * When updating an existing config file that is lacking
2401976Sab196087 		 * the Rtc_id block, don't put one into the resulting file.
2411976Sab196087 		 */
2421976Sab196087 		crle->c_flags &= ~CRLE_ADDID;
2431976Sab196087 	}
2441976Sab196087 	head = (Rtc_head *) addr;
2451976Sab196087 
2461976Sab196087 
2471976Sab196087 	/*
2481976Sab196087 	 * The rest of the configuration file can only be examined by
2491976Sab196087 	 * a program of the same ELFCLASS, byte order, and hardware
2501976Sab196087 	 * architecture as the one that created it.
2511976Sab196087 	 */
2521976Sab196087 #ifdef _ELF64
2531976Sab196087 	/* 64-bit program with an existing 32-bit file? Abort. */
2541976Sab196087 	if (!(head->ch_cnflags & RTC_HDR_64)) {
2551976Sab196087 		(void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
256*4734Sab196087 		    crle->c_name, crle->c_confil);
2571976Sab196087 		return (INSCFG_RET_FAIL);
2581976Sab196087 	}
2591976Sab196087 #else
2601976Sab196087 	/* 32-bit program with an existing 64-bit file? Restart. */
2611976Sab196087 	if (head->ch_cnflags & RTC_HDR_64)
2621976Sab196087 		return (INSCFG_RET_NEED64);
2632056Sab196087 
2642056Sab196087 	/*
2652056Sab196087 	 * 32-bit program with an existing 32-bit file, but the
2662056Sab196087 	 * user specified the -64 option? Abort
2672056Sab196087 	 */
2682056Sab196087 	if (c_class != ELFCLASS32) {
2692056Sab196087 		(void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
270*4734Sab196087 		    crle->c_name, crle->c_confil);
2712056Sab196087 		return (INSCFG_RET_FAIL);
2722056Sab196087 	}
2731976Sab196087 #endif
2741976Sab196087 	/*
2751976Sab196087 	 * Now that the ELFCLASS has been settled, ensure that the
2761976Sab196087 	 * byte order and hardware match. Unlike ELFCLASS, where restarting
2771976Sab196087 	 * the other version is an option, we cannot work around a mismatch
2781976Sab196087 	 * of these attributes.
2791976Sab196087 	 */
2801976Sab196087 	if (id) {		/* Rtc_id is present */
2811976Sab196087 		/*
2821976Sab196087 		 * Was the file produced by compatible hardware?
2831976Sab196087 		 * ELFCLASS doesn't matter here, because we can
2841976Sab196087 		 * adjust for that, but byte order and machine type do.
2851976Sab196087 		 */
2861976Sab196087 		if ((id->id_data != M_DATA) || (id->id_machine != M_MACH)) {
2871976Sab196087 			(void) fprintf(stderr, MSG_INTL(MSG_ARG_WRONGARCH),
2881976Sab196087 			    crle->c_name, crle->c_confil,
289*4734Sab196087 			    conv_ehdr_data(id->id_data, CONV_FMT_ALTFILE,
290*4734Sab196087 			    &inv_buf1),
291*4734Sab196087 			    conv_ehdr_mach(id->id_machine, CONV_FMT_ALTFILE,
292*4734Sab196087 			    &inv_buf2),
293*4734Sab196087 			    conv_ehdr_data(M_DATA, CONV_FMT_ALTFILE, &inv_buf3),
294*4734Sab196087 			    conv_ehdr_mach(M_MACH, CONV_FMT_ALTFILE,
295*4734Sab196087 			    &inv_buf4));
2961976Sab196087 			return (INSCFG_RET_FAIL);
2971976Sab196087 		}
2981976Sab196087 	}
2991976Sab196087 
3001976Sab196087 
3010Sstevel@tonic-gate 	/* LINTED */
3021976Sab196087 	objtbl = (Rtc_obj *)(CAST_PTRINT(char *, head->ch_obj) + addr);
3031976Sab196087 	strtbl = (const char *)(CAST_PTRINT(char *, head->ch_str) + addr);
3041976Sab196087 
3051976Sab196087 	/*
3061976Sab196087 	 * If the configuration file has a version higher than we
3071976Sab196087 	 * recognise, we face two issues:
3081976Sab196087 	 *	(1) Updates are not possible because we have no
3091976Sab196087 	 *		way to recognise or propagate the new features.
3101976Sab196087 	 *		This has to be a fatal error.
3111976Sab196087 	 *	(2) Printing has the risk that we may have been
3121976Sab196087 	 *		handed something other than a real config file, as
3131976Sab196087 	 *		well as the fact that we can't display the information
3141976Sab196087 	 *		for the new features. So, we print a warning, but
3151976Sab196087 	 *		continue on to do the best we can with it.
3161976Sab196087 	 */
3171976Sab196087 	if (head->ch_version > RTC_VER_CURRENT) {
3181976Sab196087 		if (crle->c_flags & CRLE_UPDATE) {
3191976Sab196087 			(void) fprintf(stderr, MSG_INTL(MSG_ARG_UPDATEVER),
320*4734Sab196087 			    crle->c_name, crle->c_confil,
321*4734Sab196087 			    (int)head->ch_version, RTC_VER_CURRENT);
3221976Sab196087 			return (INSCFG_RET_FAIL);
3231976Sab196087 		} else {
3241976Sab196087 			(void) fprintf(stderr, MSG_INTL(MSG_ARG_PRINTVER),
325*4734Sab196087 			    crle->c_name, crle->c_confil,
326*4734Sab196087 			    (int)head->ch_version, RTC_VER_CURRENT);
3271976Sab196087 		}
3281976Sab196087 	}
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate 	/*
3310Sstevel@tonic-gate 	 * If this is a version 1 configuration file we can't generate accurate
3320Sstevel@tonic-gate 	 * update information, or the command-line used to create the file.
3330Sstevel@tonic-gate 	 */
3340Sstevel@tonic-gate 	if (head->ch_version == RTC_VER_ONE) {
3350Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_ARG_UPDATE), crle->c_name,
3362056Sab196087 		    crle->c_confil, (int)head->ch_version);
3370Sstevel@tonic-gate 	}
3380Sstevel@tonic-gate 
3391976Sab196087 
3401976Sab196087 	if (!(crle->c_flags & CRLE_UPDATE) && (head->ch_cnflags & RTC_HDR_64)) {
3411976Sab196087 		/*
3421976Sab196087 		 * Construct the original command line argument.
3431976Sab196087 		 */
3441976Sab196087 		cmd = strcpy(alloca(MSG_CMD_64_SIZE + 1), MSG_ORIG(MSG_CMD_64));
3451976Sab196087 		if (list_append(&cmdline, cmd) == 0)
3461976Sab196087 			return (INSCFG_RET_FAIL);
3470Sstevel@tonic-gate 	}
3480Sstevel@tonic-gate 
3491976Sab196087 
3500Sstevel@tonic-gate 	/*
3510Sstevel@tonic-gate 	 * Start analyzing the configuration files header information.
3520Sstevel@tonic-gate 	 */
3530Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_UPDATE) == 0) {
3540Sstevel@tonic-gate 		const char	*fmt;
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate 		if (head->ch_dlflags)
357*4734Sab196087 			fmt = conv_dl_flag(head->ch_dlflags, 0, &dl_flag_buf);
3580Sstevel@tonic-gate 		else
3590Sstevel@tonic-gate 			fmt = MSG_ORIG(MSG_STR_EMPTY);
3600Sstevel@tonic-gate 
3612056Sab196087 		(void) printf(MSG_INTL(MSG_DMP_HEAD), (int)head->ch_version,
3620Sstevel@tonic-gate 		    crle->c_confil, fmt);
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 		/*
3651976Sab196087 		 * If the file has an id block, show the information
3661976Sab196087 		 */
3671976Sab196087 		if (id)
368*4734Sab196087 			(void) printf(MSG_INTL(MSG_DMP_PLATFORM),
369*4734Sab196087 			    conv_ehdr_class(id->id_class, CONV_FMT_ALTFILE,
370*4734Sab196087 			    &inv_buf1),
371*4734Sab196087 			    conv_ehdr_data(id->id_data, CONV_FMT_ALTFILE,
372*4734Sab196087 			    &inv_buf2),
373*4734Sab196087 			    conv_ehdr_mach(id->id_machine, CONV_FMT_ALTFILE,
374*4734Sab196087 			    &inv_buf3));
3751976Sab196087 
3761976Sab196087 		/*
3770Sstevel@tonic-gate 		 * Construct the original command line argument.
3780Sstevel@tonic-gate 		 */
3790Sstevel@tonic-gate 		(void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_CONF),
3800Sstevel@tonic-gate 		    crle->c_confil);
3810Sstevel@tonic-gate 		cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
3820Sstevel@tonic-gate 		if (list_append(&cmdline, cmd) == 0)
3831976Sab196087 			return (INSCFG_RET_FAIL);
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 		/*
3860Sstevel@tonic-gate 		 * Construct any -f usage.
3870Sstevel@tonic-gate 		 */
3880Sstevel@tonic-gate 		if (head->ch_dlflags &&
3890Sstevel@tonic-gate 		    (head->ch_dlflags != RTLD_REL_RELATIVE)) {
3900Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_FLAGS),
391*4734Sab196087 			    conv_dl_flag(head->ch_dlflags, CONV_FMT_ALTCRLE,
392*4734Sab196087 			    &dl_flag_buf));
3930Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
3940Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
3951976Sab196087 				return (INSCFG_RET_FAIL);
3960Sstevel@tonic-gate 		}
3970Sstevel@tonic-gate 	} else {
3980Sstevel@tonic-gate 		/*
3990Sstevel@tonic-gate 		 * Establish any -f usage.
4000Sstevel@tonic-gate 		 */
4010Sstevel@tonic-gate 		if (head->ch_dlflags &&
4020Sstevel@tonic-gate 		    (head->ch_dlflags != RTLD_REL_RELATIVE))
4030Sstevel@tonic-gate 			crle->c_dlflags = head->ch_dlflags;
4040Sstevel@tonic-gate 	}
4050Sstevel@tonic-gate 
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	/*
4080Sstevel@tonic-gate 	 * Determine if this configuration file is only applicable to a specific
4090Sstevel@tonic-gate 	 * application.
4100Sstevel@tonic-gate 	 */
4110Sstevel@tonic-gate 	if (head->ch_app) {
4120Sstevel@tonic-gate 		char	*alter;
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 		obj = (Rtc_obj *)(head->ch_app + addr);
4150Sstevel@tonic-gate 
4160Sstevel@tonic-gate 		/*
4170Sstevel@tonic-gate 		 * Determine the output directory for the files
4180Sstevel@tonic-gate 		 * alternative name.
4190Sstevel@tonic-gate 		 */
4200Sstevel@tonic-gate 		alter = (char *)(strtbl + obj->co_alter);
4210Sstevel@tonic-gate 		(void) strcpy(_objdir, alter);
4220Sstevel@tonic-gate 		alter = strrchr(_objdir, '/');
4230Sstevel@tonic-gate 		*alter = '\0';
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate 		crle->c_objdir = objdir = _objdir;
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
4280Sstevel@tonic-gate 			if (inspect(crle, (strtbl + obj->co_name),
4290Sstevel@tonic-gate 			    (RTC_OBJ_DUMP | RTC_OBJ_ALTER |
4300Sstevel@tonic-gate 			    RTC_OBJ_GROUP | RTC_OBJ_CMDLINE)) != 0)
4311976Sab196087 				return (INSCFG_RET_FAIL);
4320Sstevel@tonic-gate 		} else {
4330Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_APP),
4340Sstevel@tonic-gate 			    (strtbl + obj->co_alter), (strtbl + obj->co_name));
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate 			/*
4370Sstevel@tonic-gate 			 * Construct the original command line arguments.
4380Sstevel@tonic-gate 			 */
4390Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
4400Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_OUTPUT), crle->c_objdir);
4410Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
4420Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
4431976Sab196087 				return (INSCFG_RET_FAIL);
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
4460Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_DUMPGRP), (strtbl + obj->co_name));
4470Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
4480Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
4491976Sab196087 				return (INSCFG_RET_FAIL);
4500Sstevel@tonic-gate 		}
4510Sstevel@tonic-gate 	}
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	/*
4540Sstevel@tonic-gate 	 * Analyze any alternative library path and trusted directory entries.
4550Sstevel@tonic-gate 	 */
4560Sstevel@tonic-gate 	if (head->ch_edlibpath) {
4570Sstevel@tonic-gate 		const char	*str;
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 		str = (const char *)(head->ch_edlibpath + addr);
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
4620Sstevel@tonic-gate 			crle->c_flags &= ~CRLE_AOUT;
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
4650Sstevel@tonic-gate 			if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
4660Sstevel@tonic-gate 				if (head->ch_cnflags & RTC_HDR_64)
4671618Srie 					str = conv_config_upm(str,
4680Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDDLP_64),
4690Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPDLP_64),
4700Sstevel@tonic-gate 					    MSG_PTH_UPDLP_64_SIZE);
4710Sstevel@tonic-gate 				else
4721618Srie 					str = conv_config_upm(str,
4730Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDDLP),
4740Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPDLP),
4750Sstevel@tonic-gate 					    MSG_PTH_UPDLP_SIZE);
4760Sstevel@tonic-gate 			}
4770Sstevel@tonic-gate #endif
4780Sstevel@tonic-gate 			if (addlib(crle, &crle->c_edlibpath, str) != 0)
4791976Sab196087 				return (INSCFG_RET_FAIL);
4800Sstevel@tonic-gate 		} else {
4810Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
4820Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF), str);
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
4850Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_EDLIB), str);
4860Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
4870Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
4881976Sab196087 				return (INSCFG_RET_FAIL);
4890Sstevel@tonic-gate 		}
4900Sstevel@tonic-gate 	} else {
4910Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
4920Sstevel@tonic-gate 			if (crle->c_flags & CRLE_EDLIB) {
4930Sstevel@tonic-gate 				/*
4940Sstevel@tonic-gate 				 * If we've been asked to update a configuration
4950Sstevel@tonic-gate 				 * file, and no existing default ELF search
4960Sstevel@tonic-gate 				 * path exists, but the user is going to add new
4970Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
4980Sstevel@tonic-gate 				 * that the users get added to them.
4990Sstevel@tonic-gate 				 */
5000Sstevel@tonic-gate 				if (fablib(crle, CRLE_EDLIB) != 0)
5011976Sab196087 					return (INSCFG_RET_FAIL);
5020Sstevel@tonic-gate 			}
5030Sstevel@tonic-gate 		} else {
5040Sstevel@tonic-gate 			/*
5050Sstevel@tonic-gate 			 * Indicate any system default.
5060Sstevel@tonic-gate 			 */
5071976Sab196087 #if M_CLASS == ELFCLASS64
5080Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
5091976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_NEWDLP_64));
5100Sstevel@tonic-gate #else
5111976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_OLDDLP_64));
5120Sstevel@tonic-gate #endif
5131976Sab196087 #else
5140Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
5151976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_NEWDLP));
5160Sstevel@tonic-gate #else
5171976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_OLDDLP));
5180Sstevel@tonic-gate #endif
5191976Sab196087 #endif
5200Sstevel@tonic-gate 		}
5210Sstevel@tonic-gate 	}
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 	if (head->ch_eslibpath) {
5240Sstevel@tonic-gate 		const char	*str;
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate 		str = (const char *)(head->ch_eslibpath + addr);
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
5290Sstevel@tonic-gate 			crle->c_flags &= ~CRLE_AOUT;
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
5320Sstevel@tonic-gate 			if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
5330Sstevel@tonic-gate 				if (head->ch_cnflags & RTC_HDR_64)
5341618Srie 					str = conv_config_upm(str,
5350Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDTD_64),
5360Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPTD_64),
5370Sstevel@tonic-gate 					    MSG_PTH_UPTD_64_SIZE);
5380Sstevel@tonic-gate 				else
5391618Srie 					str = conv_config_upm(str,
5400Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_OLDTD),
5410Sstevel@tonic-gate 					    MSG_ORIG(MSG_PTH_UPTD),
5420Sstevel@tonic-gate 					    MSG_PTH_UPTD_SIZE);
5430Sstevel@tonic-gate 			}
5440Sstevel@tonic-gate #endif
5450Sstevel@tonic-gate 			if (addlib(crle, &crle->c_eslibpath, str) != 0)
5461976Sab196087 				return (INSCFG_RET_FAIL);
5470Sstevel@tonic-gate 		} else {
5480Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
5490Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF), str);
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
5520Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ESLIB), str);
5530Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
5540Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
5551976Sab196087 				return (INSCFG_RET_FAIL);
5560Sstevel@tonic-gate 		}
5570Sstevel@tonic-gate 	} else {
5580Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
5590Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ESLIB) {
5600Sstevel@tonic-gate 				/*
5610Sstevel@tonic-gate 				 * If we've been asked to update a configuration
5620Sstevel@tonic-gate 				 * file, and no existing default ELF secure
5630Sstevel@tonic-gate 				 * path exists, but the user is going to add new
5640Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
5650Sstevel@tonic-gate 				 * that the users get added to them.
5660Sstevel@tonic-gate 				 */
5670Sstevel@tonic-gate 				if (fablib(crle, CRLE_ESLIB) != 0)
5681976Sab196087 					return (INSCFG_RET_FAIL);
5690Sstevel@tonic-gate 			}
5700Sstevel@tonic-gate 		} else {
5710Sstevel@tonic-gate 			/*
5720Sstevel@tonic-gate 			 * Indicate any system default.
5730Sstevel@tonic-gate 			 */
5741976Sab196087 #if M_CLASS == ELFCLASS64
5750Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
5761976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_NEWTD_64));
5770Sstevel@tonic-gate #else
5781976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_OLDTD_64));
5790Sstevel@tonic-gate #endif
5801976Sab196087 #else
5810Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
5821976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_NEWTD));
5830Sstevel@tonic-gate #else
5841976Sab196087 			(void) printf(MSG_INTL(MSG_DEF_OLDTD));
5850Sstevel@tonic-gate #endif
5861976Sab196087 #endif
5870Sstevel@tonic-gate 		}
5880Sstevel@tonic-gate 	}
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	if (head->ch_adlibpath) {
5910Sstevel@tonic-gate 		const char	*str;
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 		str = (const char *)(head->ch_adlibpath + addr);
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
5960Sstevel@tonic-gate 			crle->c_flags |= CRLE_AOUT;
5970Sstevel@tonic-gate 			if (addlib(crle, &crle->c_adlibpath, str) != 0)
5981976Sab196087 				return (INSCFG_RET_FAIL);
5990Sstevel@tonic-gate 		} else {
6000Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
6010Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_AOUT), str);
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
6040Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ADLIB), str);
6050Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
6060Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
6071976Sab196087 				return (INSCFG_RET_FAIL);
6080Sstevel@tonic-gate 		}
6090Sstevel@tonic-gate 	} else {
6100Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
6110Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ADLIB) {
6120Sstevel@tonic-gate 				/*
6130Sstevel@tonic-gate 				 * If we've been asked to update a configuration
6140Sstevel@tonic-gate 				 * file, and no existing default AOUT search
6150Sstevel@tonic-gate 				 * path exists, but the user is going to add new
6160Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
6170Sstevel@tonic-gate 				 * that the users get added to them.
6180Sstevel@tonic-gate 				 */
6190Sstevel@tonic-gate 				if (fablib(crle, CRLE_ADLIB) != 0)
6201976Sab196087 					return (INSCFG_RET_FAIL);
6210Sstevel@tonic-gate 			}
6220Sstevel@tonic-gate 		} else if (crle->c_flags & CRLE_AOUT) {
6230Sstevel@tonic-gate 			/*
6240Sstevel@tonic-gate 			 * Indicate any system default.
6250Sstevel@tonic-gate 			 */
6260Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DEF_AOUTDLP));
6270Sstevel@tonic-gate 		}
6280Sstevel@tonic-gate 	}
6290Sstevel@tonic-gate 
6300Sstevel@tonic-gate 	if (head->ch_aslibpath) {
6310Sstevel@tonic-gate 		const char	*str;
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 		str = (const char *)(head->ch_aslibpath + addr);
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
6360Sstevel@tonic-gate 			crle->c_flags |= CRLE_AOUT;
6370Sstevel@tonic-gate 			if (addlib(crle, &crle->c_aslibpath, str) != 0)
6381976Sab196087 				return (INSCFG_RET_FAIL);
6390Sstevel@tonic-gate 		} else {
6400Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
6410Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_AOUT), str);
6420Sstevel@tonic-gate 
6430Sstevel@tonic-gate 			(void) snprintf(_cmd, PATH_MAX,
6440Sstevel@tonic-gate 			    MSG_ORIG(MSG_CMD_ASLIB), str);
6450Sstevel@tonic-gate 			cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
6460Sstevel@tonic-gate 			if (list_append(&cmdline, cmd) == 0)
6471976Sab196087 				return (INSCFG_RET_FAIL);
6480Sstevel@tonic-gate 		}
6490Sstevel@tonic-gate 	} else {
6500Sstevel@tonic-gate 		if (crle->c_flags & CRLE_UPDATE) {
6510Sstevel@tonic-gate 			if (crle->c_flags & CRLE_ASLIB) {
6520Sstevel@tonic-gate 				/*
6530Sstevel@tonic-gate 				 * If we've been asked to update a configuration
6540Sstevel@tonic-gate 				 * file, and no existing default AOUT secure
6550Sstevel@tonic-gate 				 * path exists, but the user is going to add new
6560Sstevel@tonic-gate 				 * entries, fabricate the system defaults so
6570Sstevel@tonic-gate 				 * that the users get added to them.
6580Sstevel@tonic-gate 				 */
6590Sstevel@tonic-gate 				if (fablib(crle, CRLE_ASLIB) != 0)
6601976Sab196087 					return (INSCFG_RET_FAIL);
6610Sstevel@tonic-gate 			}
6620Sstevel@tonic-gate 		} else if (crle->c_flags & CRLE_AOUT) {
6630Sstevel@tonic-gate 			/*
6640Sstevel@tonic-gate 			 * Indicate any system default.
6650Sstevel@tonic-gate 			 */
6660Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DEF_AOUTTD));
6670Sstevel@tonic-gate 		}
6680Sstevel@tonic-gate 	}
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate 	/*
6710Sstevel@tonic-gate 	 * Display any environment variables.
6720Sstevel@tonic-gate 	 */
6730Sstevel@tonic-gate 	if ((head->ch_version >= RTC_VER_THREE) && head->ch_env) {
6740Sstevel@tonic-gate 		Rtc_env *	envtbl;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0)
6770Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_ENV_TITLE));
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 		for (envtbl = (Rtc_env *)(head->ch_env + addr);
6800Sstevel@tonic-gate 		    envtbl->env_str; envtbl++) {
6810Sstevel@tonic-gate 			const char	*str;
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 			str = (const char *)(envtbl->env_str + addr);
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
6860Sstevel@tonic-gate 				if (addenv(crle, str,
6870Sstevel@tonic-gate 				    (envtbl->env_flags | RTC_ENV_CONFIG)) == 0)
6881976Sab196087 					return (INSCFG_RET_FAIL);
6890Sstevel@tonic-gate 			} else {
6900Sstevel@tonic-gate 				const char	*pfmt, *sfmt;
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 				if (envtbl->env_flags & RTC_ENV_PERMANT) {
6930Sstevel@tonic-gate 					pfmt = MSG_INTL(MSG_ENV_PRM);
6940Sstevel@tonic-gate 					sfmt = MSG_ORIG(MSG_CMD_PRMENV);
6950Sstevel@tonic-gate 				} else {
6960Sstevel@tonic-gate 					pfmt = MSG_INTL(MSG_ENV_RPL);
6970Sstevel@tonic-gate 					sfmt = MSG_ORIG(MSG_CMD_RPLENV);
6980Sstevel@tonic-gate 				}
6990Sstevel@tonic-gate 				(void) printf(pfmt, str);
7000Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX, sfmt, str);
7010Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
7020Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
7031976Sab196087 					return (INSCFG_RET_FAIL);
7040Sstevel@tonic-gate 			}
7050Sstevel@tonic-gate 		}
7060Sstevel@tonic-gate 	}
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate 	/*
7090Sstevel@tonic-gate 	 * Display any filter/filtee associations.
7100Sstevel@tonic-gate 	 */
7110Sstevel@tonic-gate 	if ((head->ch_version >= RTC_VER_FOUR) && head->ch_fltr) {
7120Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0) {
7130Sstevel@tonic-gate 			Rtc_fltr *	fltrtbl;
7140Sstevel@tonic-gate 			Rtc_flte *	fltetbl;
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 			/* LINTED */
7171976Sab196087 			fltrtbl = (Rtc_fltr *)
718*4734Sab196087 			    (CAST_PTRINT(char *, head->ch_fltr) + addr);
7190Sstevel@tonic-gate 			/* LINTED */
7201976Sab196087 			fltetbl = (Rtc_flte *)
721*4734Sab196087 			    (CAST_PTRINT(char *, head->ch_flte) + addr);
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_FLT_TITLE));
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate 			while (fltrtbl->fr_filter) {
7260Sstevel@tonic-gate 				Rtc_flte	*_fltetbl;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 				/*
7290Sstevel@tonic-gate 				 * Print the filter and filtee string pair.
7300Sstevel@tonic-gate 				 */
7310Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_FLT_FILTER),
7320Sstevel@tonic-gate 				    (strtbl + fltrtbl->fr_filter),
7330Sstevel@tonic-gate 				    (strtbl + fltrtbl->fr_string));
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 				/*
7360Sstevel@tonic-gate 				 * Print each filtee.
7370Sstevel@tonic-gate 				 */
7380Sstevel@tonic-gate 				/* LINTED */
7390Sstevel@tonic-gate 				for (_fltetbl = (Rtc_flte *)((char *)fltetbl +
7400Sstevel@tonic-gate 				    fltrtbl->fr_filtee); _fltetbl->fe_filtee;
7410Sstevel@tonic-gate 				    _fltetbl++) {
7420Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_FLT_FILTEE),
7430Sstevel@tonic-gate 					    (strtbl + _fltetbl->fe_filtee));
7440Sstevel@tonic-gate 				}
7450Sstevel@tonic-gate 				fltrtbl++;
7460Sstevel@tonic-gate 			}
7470Sstevel@tonic-gate 		}
7480Sstevel@tonic-gate 	}
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate 	/*
7510Sstevel@tonic-gate 	 * Display any memory reservations required for any alternative
7520Sstevel@tonic-gate 	 * objects.
7530Sstevel@tonic-gate 	 */
7540Sstevel@tonic-gate 	if (head->ch_resbgn && ((crle->c_flags & CRLE_UPDATE) == 0))
7552056Sab196087 		(void) printf(MSG_INTL(MSG_DMP_RESV),
756*4734Sab196087 		    (u_longlong_t)head->ch_resbgn,
757*4734Sab196087 		    (u_longlong_t)head->ch_resend,
758*4734Sab196087 		    (u_longlong_t)(head->ch_resend - head->ch_resbgn));
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 	/*
7610Sstevel@tonic-gate 	 * If there's no hash table there's nothing else to process.
7620Sstevel@tonic-gate 	 */
7630Sstevel@tonic-gate 	if (head->ch_hash == 0) {
7640Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0)
7650Sstevel@tonic-gate 			printcmd(crle, head, &cmdline);
7661976Sab196087 		return (INSCFG_RET_OK);
7670Sstevel@tonic-gate 	}
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate 	/*
7700Sstevel@tonic-gate 	 * Traverse the directory and filename arrays.
7710Sstevel@tonic-gate 	 */
7720Sstevel@tonic-gate 	for (dirtbl = (Rtc_dir *)(head->ch_dir + addr);
7730Sstevel@tonic-gate 	    dirtbl->cd_obj; dirtbl++) {
7740Sstevel@tonic-gate 		struct stat	status;
7750Sstevel@tonic-gate 		Rtc_obj		*dobj;
7760Sstevel@tonic-gate 		const char	*str;
7770Sstevel@tonic-gate 
7780Sstevel@tonic-gate 		dobj = (Rtc_obj *)(dirtbl->cd_obj + addr);
7790Sstevel@tonic-gate 		filetbl = (Rtc_file *)(dirtbl->cd_file + addr);
7800Sstevel@tonic-gate 		str = strtbl + dobj->co_name;
7810Sstevel@tonic-gate 
7820Sstevel@tonic-gate 		/*
7830Sstevel@tonic-gate 		 * Simplify recreation by using any command-line directories.
7840Sstevel@tonic-gate 		 * If we're dealing with a version 1 configuration file use
7850Sstevel@tonic-gate 		 * every directory.
7860Sstevel@tonic-gate 		 */
7870Sstevel@tonic-gate 		if ((dobj->co_flags & RTC_OBJ_CMDLINE) ||
7880Sstevel@tonic-gate 		    (head->ch_version == RTC_VER_ONE)) {
7890Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
7900Sstevel@tonic-gate 				if (inspect(crle, str,
7910Sstevel@tonic-gate 				    getflags(dobj->co_flags)) != 0)
7921976Sab196087 					return (INSCFG_RET_FAIL);
7930Sstevel@tonic-gate 				if ((dobj->co_flags &
7940Sstevel@tonic-gate 				    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
7950Sstevel@tonic-gate 				    RTC_OBJ_NOEXIST)
7960Sstevel@tonic-gate 					continue;
7970Sstevel@tonic-gate 			} else {
7980Sstevel@tonic-gate 				/* LINTED */
7990Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX,
8000Sstevel@tonic-gate 				    getformat(dobj->co_flags), str);
8010Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
8020Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
8031976Sab196087 					return (INSCFG_RET_FAIL);
8040Sstevel@tonic-gate 			}
8050Sstevel@tonic-gate 		}
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 		/*
8080Sstevel@tonic-gate 		 * If this isn't an update print the directory name.  If the
8090Sstevel@tonic-gate 		 * directory has no entries (possible if the directory is a
8100Sstevel@tonic-gate 		 * symlink to another directory, in which case we record the
8110Sstevel@tonic-gate 		 * real path also), don't bother printing it unless we're in
8120Sstevel@tonic-gate 		 * verbose mode.
8130Sstevel@tonic-gate 		 */
8140Sstevel@tonic-gate 		if ((crle->c_flags & CRLE_UPDATE) == 0) {
8150Sstevel@tonic-gate 			if ((dobj->co_flags &
8160Sstevel@tonic-gate 			    (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
8170Sstevel@tonic-gate 			    RTC_OBJ_NOEXIST) {
8180Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DIR_2), str);
8190Sstevel@tonic-gate 				continue;
8200Sstevel@tonic-gate 			} else if (filetbl->cf_obj ||
8210Sstevel@tonic-gate 			    (crle->c_flags & CRLE_VERBOSE))
8220Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DIR_1), str);
8230Sstevel@tonic-gate 		}
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate 		/*
8260Sstevel@tonic-gate 		 * Under verbose mode validate any real directory entry - the
8270Sstevel@tonic-gate 		 * same test will be carried out by ld.so.1.
8280Sstevel@tonic-gate 		 */
8290Sstevel@tonic-gate 		if (((crle->c_flags & CRLE_UPDATE) == 0) &&
8300Sstevel@tonic-gate 		    (crle->c_flags & CRLE_VERBOSE) &&
8310Sstevel@tonic-gate 		    (dobj->co_flags & RTC_OBJ_REALPTH)) {
8320Sstevel@tonic-gate 			if (stat(str, &status) != 0) {
8330Sstevel@tonic-gate 				int err = errno;
8340Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_STAT), str,
8350Sstevel@tonic-gate 				    strerror(err));
8360Sstevel@tonic-gate 			} else if (status.st_mtime != dobj->co_info) {
8370Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DMP_DCMP), str);
8380Sstevel@tonic-gate 			}
8390Sstevel@tonic-gate 		}
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 		for (; filetbl->cf_obj; filetbl++) {
8420Sstevel@tonic-gate 			Rtc_obj *	fobj;
8430Sstevel@tonic-gate 			Half		flags;
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate 			fobj = (Rtc_obj *)(filetbl->cf_obj + addr);
8460Sstevel@tonic-gate 			str = strtbl + fobj->co_name;
8470Sstevel@tonic-gate 			flags = fobj->co_flags;
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 			/*
8500Sstevel@tonic-gate 			 * Only update individual files that were originally
8510Sstevel@tonic-gate 			 * specified on the command-line.  Or, if this is a
8520Sstevel@tonic-gate 			 * version 1 configuration file use every file that
8530Sstevel@tonic-gate 			 * isn't part of an all-entries directory.
8540Sstevel@tonic-gate 			 */
8550Sstevel@tonic-gate 			if (((flags & RTC_OBJ_CMDLINE) &&
8560Sstevel@tonic-gate 			    ((fobj->co_flags & RTC_OBJ_APP) == 0)) ||
8570Sstevel@tonic-gate 			    ((head->ch_version == RTC_VER_ONE) &&
8580Sstevel@tonic-gate 			    ((dobj->co_flags & RTC_OBJ_ALLENTS) == 0))) {
8590Sstevel@tonic-gate 				char	*alter = 0, altdir[PATH_MAX];
8600Sstevel@tonic-gate 
8610Sstevel@tonic-gate 				/*
8620Sstevel@tonic-gate 				 * Determine whether this file requires an
8630Sstevel@tonic-gate 				 * alternative, and if so, and we haven't
8640Sstevel@tonic-gate 				 * already an alternative in affect, create one.
8650Sstevel@tonic-gate 				 */
8660Sstevel@tonic-gate 				if (fobj->co_flags & RTC_OBJ_ALTER) {
8670Sstevel@tonic-gate 					alter = (char *)(strtbl +
8680Sstevel@tonic-gate 					    fobj->co_alter);
8690Sstevel@tonic-gate 					(void) strcpy(altdir, alter);
8700Sstevel@tonic-gate 					alter = strrchr(altdir, '/');
8710Sstevel@tonic-gate 					*alter = '\0';
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 					if ((objdir == 0) ||
8740Sstevel@tonic-gate 					    (strcmp(objdir, altdir) != 0)) {
8750Sstevel@tonic-gate 						(void) strcpy(_objdir, altdir);
8760Sstevel@tonic-gate 						crle->c_objdir = alter =
8770Sstevel@tonic-gate 						    objdir = _objdir;
8780Sstevel@tonic-gate 					} else
8790Sstevel@tonic-gate 						alter = 0;
8800Sstevel@tonic-gate 				}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 				if (crle->c_flags & CRLE_UPDATE) {
8830Sstevel@tonic-gate 					if (inspect(crle, str,
8840Sstevel@tonic-gate 					    getflags(flags)) != 0)
8851976Sab196087 						return (INSCFG_RET_FAIL);
8860Sstevel@tonic-gate 					continue;
8870Sstevel@tonic-gate 				}
8880Sstevel@tonic-gate 
8890Sstevel@tonic-gate 				if (alter) {
8900Sstevel@tonic-gate 					(void) snprintf(_cmd, PATH_MAX,
8910Sstevel@tonic-gate 					    MSG_ORIG(MSG_CMD_OUTPUT),
8920Sstevel@tonic-gate 					    crle->c_objdir);
8930Sstevel@tonic-gate 					cmd = strcpy(alloca(strlen(_cmd) + 1),
8940Sstevel@tonic-gate 					    _cmd);
8950Sstevel@tonic-gate 					if (list_append(&cmdline, cmd) == 0)
8961976Sab196087 						return (INSCFG_RET_FAIL);
8970Sstevel@tonic-gate 				}
8980Sstevel@tonic-gate 
8990Sstevel@tonic-gate 				/* LINTED */
9000Sstevel@tonic-gate 				(void) snprintf(_cmd, PATH_MAX,
9010Sstevel@tonic-gate 				    getformat(flags), str);
9020Sstevel@tonic-gate 				cmd = strcpy(alloca(strlen(_cmd) + 1), _cmd);
9030Sstevel@tonic-gate 				if (list_append(&cmdline, cmd) == 0)
9041976Sab196087 					return (INSCFG_RET_FAIL);
9050Sstevel@tonic-gate 			}
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE)
9080Sstevel@tonic-gate 				continue;
9090Sstevel@tonic-gate 
9100Sstevel@tonic-gate 			/*
9110Sstevel@tonic-gate 			 * Although we record both full pathnames and their
9120Sstevel@tonic-gate 			 * simple filenames (basename), only print the simple
9130Sstevel@tonic-gate 			 * names unless we're under verbose mode.
9140Sstevel@tonic-gate 			 */
9150Sstevel@tonic-gate 			if ((strchr(str, '/') == 0) ||
9160Sstevel@tonic-gate 			    (crle->c_flags & CRLE_VERBOSE)) {
9170Sstevel@tonic-gate 				if (fobj->co_flags & RTC_OBJ_ALTER)
9180Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FILE_2),
9190Sstevel@tonic-gate 					    str, (strtbl + fobj->co_alter));
9200Sstevel@tonic-gate 				else
9210Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FILE_1),
9220Sstevel@tonic-gate 					    str);
9230Sstevel@tonic-gate 			}
9240Sstevel@tonic-gate 
9250Sstevel@tonic-gate 			/*
9260Sstevel@tonic-gate 			 * Under verbose mode validate any real file entry - the
9270Sstevel@tonic-gate 			 * same test will be carried out by ld.so.1.
9280Sstevel@tonic-gate 			 */
9290Sstevel@tonic-gate 			if ((crle->c_flags & CRLE_VERBOSE) &&
9300Sstevel@tonic-gate 			    (fobj->co_flags & RTC_OBJ_REALPTH)) {
9310Sstevel@tonic-gate 				if (stat(str, &status) != 0) {
9320Sstevel@tonic-gate 					int err = errno;
9330Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_STAT),
9340Sstevel@tonic-gate 					    str, strerror(err));
9350Sstevel@tonic-gate 				} else if (status.st_size != fobj->co_info) {
9360Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DMP_FCMP),
9370Sstevel@tonic-gate 					    str);
9380Sstevel@tonic-gate 				}
9390Sstevel@tonic-gate 			}
9400Sstevel@tonic-gate 		}
9410Sstevel@tonic-gate 	}
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_UPDATE) == 0)
9440Sstevel@tonic-gate 		printcmd(crle, head, &cmdline);
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	if ((crle->c_flags & CRLE_VERBOSE) == 0)
9471976Sab196087 		return (INSCFG_RET_OK);
9480Sstevel@tonic-gate 
9490Sstevel@tonic-gate 	/*
9500Sstevel@tonic-gate 	 * If we've in verbose mode scan the hash list.
9510Sstevel@tonic-gate 	 */
9520Sstevel@tonic-gate 	/* LINTED */
9531976Sab196087 	hash = (Word *)(CAST_PTRINT(char *, head->ch_hash) + addr);
9540Sstevel@tonic-gate 	bkts = hash[0];
9550Sstevel@tonic-gate 	chain = &hash[2 + bkts];
9560Sstevel@tonic-gate 	hash += 2;
9570Sstevel@tonic-gate 
9580Sstevel@tonic-gate 	(void) printf(MSG_INTL(MSG_DMP_HASH));
9590Sstevel@tonic-gate 
9600Sstevel@tonic-gate 	/*
9610Sstevel@tonic-gate 	 * Scan the hash buckets looking for valid entries.
9620Sstevel@tonic-gate 	 */
9630Sstevel@tonic-gate 	for (ndx = 0; ndx < bkts; ndx++, hash++) {
964*4734Sab196087 		Conv_config_obj_buf_t	config_obj_buf;
965*4734Sab196087 		Rtc_obj			*obj;
966*4734Sab196087 		const char		*str;
967*4734Sab196087 		Word			_ndx;
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 		if (*hash == 0)
9700Sstevel@tonic-gate 			continue;
9710Sstevel@tonic-gate 
9720Sstevel@tonic-gate 		obj = objtbl + *hash;
9730Sstevel@tonic-gate 		str = strtbl + obj->co_name;
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_DMP_HASHENT_1), obj->co_id, ndx,
976*4734Sab196087 		    str, conv_config_obj(obj->co_flags, &config_obj_buf));
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 		/*
9790Sstevel@tonic-gate 		 * Determine whether there are other objects chained to this
9800Sstevel@tonic-gate 		 * bucket.
9810Sstevel@tonic-gate 		 */
9820Sstevel@tonic-gate 		for (_ndx = chain[*hash]; _ndx; _ndx = chain[_ndx]) {
9830Sstevel@tonic-gate 			obj = objtbl + _ndx;
9840Sstevel@tonic-gate 			str = strtbl + obj->co_name;
9850Sstevel@tonic-gate 
9860Sstevel@tonic-gate 			(void) printf(MSG_INTL(MSG_DMP_HASHENT_2), obj->co_id,
987*4734Sab196087 			    str, conv_config_obj(obj->co_flags,
988*4734Sab196087 			    &config_obj_buf));
9890Sstevel@tonic-gate 		}
9900Sstevel@tonic-gate 	}
9910Sstevel@tonic-gate 	(void) printf(MSG_ORIG(MSG_STR_NL));
9920Sstevel@tonic-gate 
9931976Sab196087 	return (INSCFG_RET_OK);
9940Sstevel@tonic-gate }
9950Sstevel@tonic-gate 
9960Sstevel@tonic-gate 
9971976Sab196087 INSCFG_RET
9982056Sab196087 inspectconfig(Crle_desc * crle, int c_class)
9990Sstevel@tonic-gate {
10001976Sab196087 	INSCFG_RET	error;
10011976Sab196087 	int		fd;
10020Sstevel@tonic-gate 	Addr		addr;
10030Sstevel@tonic-gate 	struct stat	status;
10040Sstevel@tonic-gate 	const char	*caller = crle->c_name, *file = crle->c_confil;
1005*4734Sab196087 	Conv_inv_buf_t	inv_buf1, inv_buf2, inv_buf3;
10060Sstevel@tonic-gate 
10070Sstevel@tonic-gate 	/*
10080Sstevel@tonic-gate 	 * Open the configuration file, determine its size and map it in.
10090Sstevel@tonic-gate 	 */
10100Sstevel@tonic-gate 	if ((fd = open(file, O_RDONLY, 0)) == -1) {
10110Sstevel@tonic-gate 		int	err = errno;
10120Sstevel@tonic-gate 
10132056Sab196087 		if (err == ENOENT) {
10142056Sab196087 #ifndef _ELF64
10152056Sab196087 			/* Must restart if user requested a 64-bit file */
10162056Sab196087 			if (c_class == ELFCLASS64)
10172056Sab196087 				return (INSCFG_RET_NEED64);
10182056Sab196087 #endif
10192056Sab196087 
10200Sstevel@tonic-gate 			/*
10210Sstevel@tonic-gate 			 * To allow an update (-u) from scratch, fabricate any
10220Sstevel@tonic-gate 			 * default search and secure paths that the user
10230Sstevel@tonic-gate 			 * intends to add to.
10240Sstevel@tonic-gate 			 */
10250Sstevel@tonic-gate 			if (crle->c_flags & CRLE_UPDATE) {
10260Sstevel@tonic-gate 				if (crle->c_flags & CRLE_EDLIB) {
10270Sstevel@tonic-gate 					if (fablib(crle, CRLE_EDLIB))
10282056Sab196087 						return (INSCFG_RET_FAIL);
10290Sstevel@tonic-gate 				}
10300Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ESLIB) {
10310Sstevel@tonic-gate 					if (fablib(crle, CRLE_ESLIB))
10322056Sab196087 						return (INSCFG_RET_FAIL);
10330Sstevel@tonic-gate 				}
10340Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ADLIB) {
10350Sstevel@tonic-gate 					if (fablib(crle, CRLE_ADLIB))
10362056Sab196087 						return (INSCFG_RET_FAIL);
10370Sstevel@tonic-gate 				}
10380Sstevel@tonic-gate 				if (crle->c_flags & CRLE_ASLIB) {
10390Sstevel@tonic-gate 					if (fablib(crle, CRLE_ASLIB))
10402056Sab196087 						return (INSCFG_RET_FAIL);
10410Sstevel@tonic-gate 				}
10422056Sab196087 				return (INSCFG_RET_OK);
10430Sstevel@tonic-gate 
10440Sstevel@tonic-gate 			} else if (crle->c_flags & CRLE_CONFDEF) {
10450Sstevel@tonic-gate 				const char	*fmt1, *fmt2;
10460Sstevel@tonic-gate 
10470Sstevel@tonic-gate 				/*
10480Sstevel@tonic-gate 				 * Otherwise if the user is inspecting a default
10490Sstevel@tonic-gate 				 * configuration file that doesn't exist inform
10500Sstevel@tonic-gate 				 * them and display the ELF defaults.
10510Sstevel@tonic-gate 				 */
10520Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DEF_NOCONF), file);
10532056Sab196087 				(void) printf(MSG_INTL(MSG_DMP_PLATFORM),
1054*4734Sab196087 				    conv_ehdr_class(M_CLASS,
1055*4734Sab196087 				    CONV_FMT_ALTFILE, &inv_buf1),
1056*4734Sab196087 				    conv_ehdr_data(M_DATA,
1057*4734Sab196087 				    CONV_FMT_ALTFILE, &inv_buf2),
1058*4734Sab196087 				    conv_ehdr_mach(M_MACH,
1059*4734Sab196087 				    CONV_FMT_ALTFILE, &inv_buf3));
10602056Sab196087 
10610Sstevel@tonic-gate 
10620Sstevel@tonic-gate 				if (crle->c_flags & CRLE_AOUT) {
10630Sstevel@tonic-gate 					fmt1 = MSG_INTL(MSG_DEF_AOUTDLP);
10640Sstevel@tonic-gate 					fmt2 = MSG_INTL(MSG_DEF_AOUTTD);
10650Sstevel@tonic-gate 				} else {
10661976Sab196087 #if M_CLASS == ELFCLASS64
10670Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
10681976Sab196087 					fmt1 = MSG_INTL(MSG_DEF_NEWDLP_64);
10691976Sab196087 					fmt2 = MSG_INTL(MSG_DEF_NEWTD_64);
10700Sstevel@tonic-gate #else
10711976Sab196087 					fmt1 = MSG_INTL(MSG_DEF_OLDDLP_64);
10721976Sab196087 					fmt2 = MSG_INTL(MSG_DEF_OLDTD_64);
10730Sstevel@tonic-gate #endif
10741976Sab196087 #else
10750Sstevel@tonic-gate #ifndef	SGS_PRE_UNIFIED_PROCESS
10761976Sab196087 					fmt1 = MSG_INTL(MSG_DEF_NEWDLP);
10771976Sab196087 					fmt2 = MSG_INTL(MSG_DEF_NEWTD);
10780Sstevel@tonic-gate #else
10791976Sab196087 					fmt1 = MSG_INTL(MSG_DEF_OLDDLP);
10801976Sab196087 					fmt2 = MSG_INTL(MSG_DEF_OLDTD);
10810Sstevel@tonic-gate #endif
10821976Sab196087 #endif
10830Sstevel@tonic-gate 				}
10840Sstevel@tonic-gate 				(void) printf(fmt1);
10850Sstevel@tonic-gate 				(void) printf(fmt2);
10860Sstevel@tonic-gate 
10872056Sab196087 				return (INSCFG_RET_OK);
10880Sstevel@tonic-gate 			}
10890Sstevel@tonic-gate 		}
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 		/*
10920Sstevel@tonic-gate 		 * Otherwise there's an error condition in accessing the file.
10930Sstevel@tonic-gate 		 */
10940Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), caller, file,
10950Sstevel@tonic-gate 		    strerror(err));
10960Sstevel@tonic-gate 
10972056Sab196087 		return (INSCFG_RET_FAIL);
10980Sstevel@tonic-gate 	}
10990Sstevel@tonic-gate 
11000Sstevel@tonic-gate 	(void) fstat(fd, &status);
11010Sstevel@tonic-gate 	if (status.st_size < sizeof (Rtc_head)) {
11020Sstevel@tonic-gate 		(void) close(fd);
11030Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_COR_TRUNC), caller, file);
11042056Sab196087 		return (INSCFG_RET_FAIL);
11050Sstevel@tonic-gate 	}
11060Sstevel@tonic-gate 	if ((addr = (Addr)mmap(0, status.st_size, PROT_READ, MAP_SHARED,
11070Sstevel@tonic-gate 	    fd, 0)) == (Addr)MAP_FAILED) {
11080Sstevel@tonic-gate 		int err = errno;
11090Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP), caller, file,
11100Sstevel@tonic-gate 		    strerror(err));
11110Sstevel@tonic-gate 		(void) close(fd);
11122056Sab196087 		return (INSCFG_RET_FAIL);
11130Sstevel@tonic-gate 	}
11140Sstevel@tonic-gate 	(void) close(fd);
11150Sstevel@tonic-gate 
11160Sstevel@tonic-gate 	/*
11170Sstevel@tonic-gate 	 * Print the contents of the configuration file.
11180Sstevel@tonic-gate 	 */
11192056Sab196087 	error = scanconfig(crle, addr, c_class);
11200Sstevel@tonic-gate 
11210Sstevel@tonic-gate 	(void) munmap((void *)addr, status.st_size);
11220Sstevel@tonic-gate 	return (error);
11230Sstevel@tonic-gate }
1124