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*13093SRoger.Faulkner@Oracle.COM * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/stat.h>
280Sstevel@tonic-gate #include <sys/mman.h>
290Sstevel@tonic-gate #include <fcntl.h>
300Sstevel@tonic-gate #include <stdio.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <unistd.h>
330Sstevel@tonic-gate #include <errno.h>
340Sstevel@tonic-gate #include <limits.h>
350Sstevel@tonic-gate #include "sgs.h"
360Sstevel@tonic-gate #include "rtc.h"
370Sstevel@tonic-gate #include "conv.h"
380Sstevel@tonic-gate #include "_crle.h"
390Sstevel@tonic-gate #include "msg.h"
400Sstevel@tonic-gate
410Sstevel@tonic-gate
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate * Display the command line required to regenerate the configuration file.
440Sstevel@tonic-gate *
450Sstevel@tonic-gate * Under normal mode the command is printed on one line to make it more
460Sstevel@tonic-gate * available for grep(1) use. Under verbose mode the command is separated
470Sstevel@tonic-gate * into each argument (a little more readable perhaps when the arguments are
480Sstevel@tonic-gate * numerous of have long pathnames).
490Sstevel@tonic-gate *
500Sstevel@tonic-gate * Note that for version 1 configuration files we never used to generate any
510Sstevel@tonic-gate * command-line information, and as the attempt to do so is only a best effort
520Sstevel@tonic-gate * don't bother printing anything.
530Sstevel@tonic-gate */
540Sstevel@tonic-gate static void
printcmd(Crle_desc * crle,Rtc_head * head,APlist * cmdline)559131SRod.Evans@Sun.COM printcmd(Crle_desc *crle, Rtc_head * head, APlist *cmdline)
560Sstevel@tonic-gate {
579131SRod.Evans@Sun.COM Aliste idx, lidx;
580Sstevel@tonic-gate const char *fmto, *fmtb, *fmtm, *fmte;
590Sstevel@tonic-gate char *cmd;
600Sstevel@tonic-gate int output = 0;
610Sstevel@tonic-gate
620Sstevel@tonic-gate if (crle->c_flags & CRLE_VERBOSE) {
630Sstevel@tonic-gate fmto = MSG_INTL(MSG_DMP_CMD_ONE_V);
640Sstevel@tonic-gate fmtb = MSG_INTL(MSG_DMP_CMD_BGN_V);
650Sstevel@tonic-gate fmtm = MSG_INTL(MSG_DMP_CMD_MID_V);
660Sstevel@tonic-gate fmte = MSG_INTL(MSG_DMP_CMD_END_V);
670Sstevel@tonic-gate
680Sstevel@tonic-gate } else if (head->ch_version > RTC_VER_ONE) {
690Sstevel@tonic-gate fmto = MSG_INTL(MSG_DMP_CMD_ONE);
700Sstevel@tonic-gate fmtb = MSG_INTL(MSG_DMP_CMD_BGN);
710Sstevel@tonic-gate fmtm = MSG_INTL(MSG_DMP_CMD_MID);
720Sstevel@tonic-gate fmte = MSG_INTL(MSG_DMP_CMD_END);
730Sstevel@tonic-gate
740Sstevel@tonic-gate } else {
750Sstevel@tonic-gate (void) printf(MSG_ORIG(MSG_STR_NL));
760Sstevel@tonic-gate return;
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_CMD_TITLE));
809131SRod.Evans@Sun.COM
819131SRod.Evans@Sun.COM lidx = aplist_nitems(cmdline) - 1;
829131SRod.Evans@Sun.COM for (APLIST_TRAVERSE(cmdline, idx, cmd)) {
830Sstevel@tonic-gate if (output++ == 0) {
849131SRod.Evans@Sun.COM if (idx < lidx)
850Sstevel@tonic-gate (void) printf(fmtb, cmd);
860Sstevel@tonic-gate else
870Sstevel@tonic-gate (void) printf(fmto, cmd);
880Sstevel@tonic-gate } else {
899131SRod.Evans@Sun.COM if (idx < lidx)
900Sstevel@tonic-gate (void) printf(fmtm, cmd);
910Sstevel@tonic-gate else
920Sstevel@tonic-gate (void) printf(fmte, cmd);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate }
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
970Sstevel@tonic-gate /*
980Sstevel@tonic-gate * Establish the argument required to generate the associated object.
990Sstevel@tonic-gate */
1000Sstevel@tonic-gate static const char *
getformat(Half flags)1010Sstevel@tonic-gate getformat(Half flags)
1020Sstevel@tonic-gate {
1030Sstevel@tonic-gate if (flags & RTC_OBJ_ALTER) {
1040Sstevel@tonic-gate if (flags & RTC_OBJ_DUMP) {
1050Sstevel@tonic-gate if (flags & RTC_OBJ_GROUP)
1060Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_DUMPGRP));
1070Sstevel@tonic-gate else
1080Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_DUMPIND));
1090Sstevel@tonic-gate } else {
1100Sstevel@tonic-gate if (flags & RTC_OBJ_OPTINAL)
1110Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_OPTIONAL));
1120Sstevel@tonic-gate else
1130Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_ALTER));
1140Sstevel@tonic-gate }
1150Sstevel@tonic-gate } else {
1160Sstevel@tonic-gate if (flags & RTC_OBJ_GROUP)
1170Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_GRP));
1180Sstevel@tonic-gate else
1190Sstevel@tonic-gate return (MSG_ORIG(MSG_CMD_IND));
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate * Fabricate a system default search path. If an update is requested, and
1250Sstevel@tonic-gate * new search paths are specified while no configuration file exists, or if a
1260Sstevel@tonic-gate * configuration file does exist but doesn't specify this particular search
1270Sstevel@tonic-gate * path, create any system defaults. The intent is to allow
1280Sstevel@tonic-gate * "crle -u -l/usr/local/lib" and have this append the search path to the
1290Sstevel@tonic-gate * system default, rather than have the user have to determine and specify
1300Sstevel@tonic-gate * this default themselves.
1310Sstevel@tonic-gate */
1320Sstevel@tonic-gate static int
fablib(Crle_desc * crle,int flag)1330Sstevel@tonic-gate fablib(Crle_desc * crle, int flag)
1340Sstevel@tonic-gate {
1350Sstevel@tonic-gate const char *path;
1360Sstevel@tonic-gate char **list;
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate switch (flag) {
1390Sstevel@tonic-gate case CRLE_EDLIB:
1401976Sab196087 #if M_CLASS == ELFCLASS64
1410Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
1421976Sab196087 path = MSG_ORIG(MSG_PTH_NEWDLP_64);
1430Sstevel@tonic-gate #else
1441976Sab196087 path = MSG_ORIG(MSG_PTH_OLDDLP_64);
1450Sstevel@tonic-gate #endif
1461976Sab196087 #else
1470Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
1481976Sab196087 path = MSG_ORIG(MSG_PTH_NEWDLP);
1490Sstevel@tonic-gate #else
1501976Sab196087 path = MSG_ORIG(MSG_PTH_OLDDLP);
1510Sstevel@tonic-gate #endif
1521976Sab196087 #endif
1530Sstevel@tonic-gate list = &crle->c_edlibpath;
1540Sstevel@tonic-gate break;
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate case CRLE_ESLIB:
1571976Sab196087 #if M_CLASS == ELFCLASS64
1580Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
1591976Sab196087 path = MSG_ORIG(MSG_PTH_NEWTD_64);
1600Sstevel@tonic-gate #else
1611976Sab196087 path = MSG_ORIG(MSG_PTH_OLDTD_64);
1620Sstevel@tonic-gate #endif
1631976Sab196087 #else
1640Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
1651976Sab196087 path = MSG_ORIG(MSG_PTH_NEWTD);
1660Sstevel@tonic-gate #else
1671976Sab196087 path = MSG_ORIG(MSG_PTH_OLDTD);
1680Sstevel@tonic-gate #endif
1691976Sab196087 #endif
1700Sstevel@tonic-gate list = &crle->c_eslibpath;
1710Sstevel@tonic-gate break;
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate case CRLE_ADLIB:
1740Sstevel@tonic-gate path = MSG_ORIG(MSG_PTH_AOUTDLP);
1750Sstevel@tonic-gate list = &crle->c_adlibpath;
1760Sstevel@tonic-gate break;
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate case CRLE_ASLIB:
1797785SRod.Evans@Sun.COM #ifndef SGS_PRE_UNIFIED_PROCESS
1807785SRod.Evans@Sun.COM path = MSG_ORIG(MSG_PTH_NEWTD);
1817785SRod.Evans@Sun.COM #else
1827785SRod.Evans@Sun.COM path = MSG_ORIG(MSG_PTH_OLDTD);
1837785SRod.Evans@Sun.COM #endif
1840Sstevel@tonic-gate list = &crle->c_aslibpath;
1850Sstevel@tonic-gate break;
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate default:
1880Sstevel@tonic-gate return (1);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate return (addlib(crle, list, path));
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate /*
1950Sstevel@tonic-gate * Establish the flags required to generate the associated object. Actually
1960Sstevel@tonic-gate * the flags are already part of the object being inspected from the present
1970Sstevel@tonic-gate * configuration file, but instead of using them all, which can cause some
1980Sstevel@tonic-gate * unsuspected propagation down the inspect() family, only use those flags that
1990Sstevel@tonic-gate * would have been contributed from crle()'s calls to inspect.
2000Sstevel@tonic-gate */
2010Sstevel@tonic-gate static Half
getflags(Half flags)2020Sstevel@tonic-gate getflags(Half flags)
2030Sstevel@tonic-gate {
2040Sstevel@tonic-gate flags &=
2050Sstevel@tonic-gate (RTC_OBJ_ALTER | RTC_OBJ_DUMP | RTC_OBJ_GROUP | RTC_OBJ_OPTINAL);
2060Sstevel@tonic-gate return (flags | RTC_OBJ_CMDLINE);
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate /*
2100Sstevel@tonic-gate * Dump a configuration files information. This routine is very close to the
2110Sstevel@tonic-gate * scanconfig() in libcrle.
2120Sstevel@tonic-gate */
2132056Sab196087 /*ARGSUSED2*/
2141976Sab196087 static INSCFG_RET
scanconfig(Crle_desc * crle,Addr addr,int c_class)2152056Sab196087 scanconfig(Crle_desc * crle, Addr addr, int c_class)
2160Sstevel@tonic-gate {
2174734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2, inv_buf3, inv_buf4;
2184734Sab196087 Conv_dl_flag_buf_t dl_flag_buf;
2191976Sab196087 Rtc_id *id;
2201976Sab196087 Rtc_head *head;
2210Sstevel@tonic-gate Rtc_dir *dirtbl;
2220Sstevel@tonic-gate Rtc_file *filetbl;
2239131SRod.Evans@Sun.COM Rtc_obj *objtbl, *obj;
2249131SRod.Evans@Sun.COM Word *hash, *chain;
2250Sstevel@tonic-gate const char *strtbl;
2260Sstevel@tonic-gate int ndx, bkts;
2279131SRod.Evans@Sun.COM APlist *cmdline = NULL;
2289131SRod.Evans@Sun.COM char _cmd[PATH_MAX], *cmd;
2299131SRod.Evans@Sun.COM char _objdir[PATH_MAX], *objdir = NULL;
2301976Sab196087
2311976Sab196087 /*
2321976Sab196087 * If there is an Rtc_id present, the Rtc_head follows it.
2331976Sab196087 * Otherwise, it is at the top.
2341976Sab196087 */
2351976Sab196087 if (RTC_ID_TEST(addr)) {
2361976Sab196087 id = (Rtc_id *) addr;
2371976Sab196087 addr += sizeof (*id); /* Rtc_head follows */
2381976Sab196087 } else {
2391976Sab196087 id = NULL;
2401976Sab196087 /*
2411976Sab196087 * When updating an existing config file that is lacking
2421976Sab196087 * the Rtc_id block, don't put one into the resulting file.
2431976Sab196087 */
2441976Sab196087 crle->c_flags &= ~CRLE_ADDID;
2451976Sab196087 }
2461976Sab196087 head = (Rtc_head *) addr;
2471976Sab196087
2481976Sab196087
2491976Sab196087 /*
2501976Sab196087 * The rest of the configuration file can only be examined by
2511976Sab196087 * a program of the same ELFCLASS, byte order, and hardware
2521976Sab196087 * architecture as the one that created it.
2531976Sab196087 */
2541976Sab196087 #ifdef _ELF64
2551976Sab196087 /* 64-bit program with an existing 32-bit file? Abort. */
2561976Sab196087 if (!(head->ch_cnflags & RTC_HDR_64)) {
2571976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
2584734Sab196087 crle->c_name, crle->c_confil);
2591976Sab196087 return (INSCFG_RET_FAIL);
2601976Sab196087 }
2611976Sab196087 #else
2621976Sab196087 /* 32-bit program with an existing 64-bit file? Restart. */
2631976Sab196087 if (head->ch_cnflags & RTC_HDR_64)
2641976Sab196087 return (INSCFG_RET_NEED64);
2652056Sab196087
2662056Sab196087 /*
2672056Sab196087 * 32-bit program with an existing 32-bit file, but the
2682056Sab196087 * user specified the -64 option? Abort
2692056Sab196087 */
2702056Sab196087 if (c_class != ELFCLASS32) {
2712056Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
2724734Sab196087 crle->c_name, crle->c_confil);
2732056Sab196087 return (INSCFG_RET_FAIL);
2742056Sab196087 }
2751976Sab196087 #endif
2761976Sab196087 /*
2771976Sab196087 * Now that the ELFCLASS has been settled, ensure that the
2781976Sab196087 * byte order and hardware match. Unlike ELFCLASS, where restarting
2791976Sab196087 * the other version is an option, we cannot work around a mismatch
2801976Sab196087 * of these attributes.
2811976Sab196087 */
2821976Sab196087 if (id) { /* Rtc_id is present */
2831976Sab196087 /*
2841976Sab196087 * Was the file produced by compatible hardware?
2851976Sab196087 * ELFCLASS doesn't matter here, because we can
2861976Sab196087 * adjust for that, but byte order and machine type do.
2871976Sab196087 */
2881976Sab196087 if ((id->id_data != M_DATA) || (id->id_machine != M_MACH)) {
2891976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_WRONGARCH),
2901976Sab196087 crle->c_name, crle->c_confil,
2915088Sab196087 conv_ehdr_data(id->id_data, CONV_FMT_ALT_FILE,
2924734Sab196087 &inv_buf1),
2935088Sab196087 conv_ehdr_mach(id->id_machine, CONV_FMT_ALT_FILE,
2944734Sab196087 &inv_buf2),
2955088Sab196087 conv_ehdr_data(M_DATA, CONV_FMT_ALT_FILE,
2965088Sab196087 &inv_buf3),
2975088Sab196087 conv_ehdr_mach(M_MACH, CONV_FMT_ALT_FILE,
2984734Sab196087 &inv_buf4));
2991976Sab196087 return (INSCFG_RET_FAIL);
3001976Sab196087 }
3011976Sab196087 }
3021976Sab196087
3031976Sab196087
3040Sstevel@tonic-gate /* LINTED */
3051976Sab196087 objtbl = (Rtc_obj *)(CAST_PTRINT(char *, head->ch_obj) + addr);
3061976Sab196087 strtbl = (const char *)(CAST_PTRINT(char *, head->ch_str) + addr);
3071976Sab196087
3081976Sab196087 /*
3091976Sab196087 * If the configuration file has a version higher than we
3101976Sab196087 * recognise, we face two issues:
3111976Sab196087 * (1) Updates are not possible because we have no
3121976Sab196087 * way to recognise or propagate the new features.
3131976Sab196087 * This has to be a fatal error.
3141976Sab196087 * (2) Printing has the risk that we may have been
3151976Sab196087 * handed something other than a real config file, as
3161976Sab196087 * well as the fact that we can't display the information
3171976Sab196087 * for the new features. So, we print a warning, but
3181976Sab196087 * continue on to do the best we can with it.
3191976Sab196087 */
3201976Sab196087 if (head->ch_version > RTC_VER_CURRENT) {
3211976Sab196087 if (crle->c_flags & CRLE_UPDATE) {
3221976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_UPDATEVER),
3234734Sab196087 crle->c_name, crle->c_confil,
3244734Sab196087 (int)head->ch_version, RTC_VER_CURRENT);
3251976Sab196087 return (INSCFG_RET_FAIL);
3261976Sab196087 } else {
3271976Sab196087 (void) fprintf(stderr, MSG_INTL(MSG_ARG_PRINTVER),
3284734Sab196087 crle->c_name, crle->c_confil,
3294734Sab196087 (int)head->ch_version, RTC_VER_CURRENT);
3301976Sab196087 }
3311976Sab196087 }
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate /*
3340Sstevel@tonic-gate * If this is a version 1 configuration file we can't generate accurate
3350Sstevel@tonic-gate * update information, or the command-line used to create the file.
3360Sstevel@tonic-gate */
3370Sstevel@tonic-gate if (head->ch_version == RTC_VER_ONE) {
3380Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_ARG_UPDATE), crle->c_name,
3392056Sab196087 crle->c_confil, (int)head->ch_version);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate
3421976Sab196087
3431976Sab196087 if (!(crle->c_flags & CRLE_UPDATE) && (head->ch_cnflags & RTC_HDR_64)) {
3441976Sab196087 /*
3451976Sab196087 * Construct the original command line argument.
3461976Sab196087 */
347*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(MSG_ORIG(MSG_CMD_64));
3489131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
3491976Sab196087 return (INSCFG_RET_FAIL);
3500Sstevel@tonic-gate }
3510Sstevel@tonic-gate
3521976Sab196087
3530Sstevel@tonic-gate /*
3540Sstevel@tonic-gate * Start analyzing the configuration files header information.
3550Sstevel@tonic-gate */
3560Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) {
3570Sstevel@tonic-gate const char *fmt;
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate if (head->ch_dlflags)
3604734Sab196087 fmt = conv_dl_flag(head->ch_dlflags, 0, &dl_flag_buf);
3610Sstevel@tonic-gate else
3620Sstevel@tonic-gate fmt = MSG_ORIG(MSG_STR_EMPTY);
3630Sstevel@tonic-gate
3642056Sab196087 (void) printf(MSG_INTL(MSG_DMP_HEAD), (int)head->ch_version,
3650Sstevel@tonic-gate crle->c_confil, fmt);
3660Sstevel@tonic-gate
3670Sstevel@tonic-gate /*
3681976Sab196087 * If the file has an id block, show the information
3691976Sab196087 */
3701976Sab196087 if (id)
3714734Sab196087 (void) printf(MSG_INTL(MSG_DMP_PLATFORM),
3725088Sab196087 conv_ehdr_class(id->id_class, CONV_FMT_ALT_FILE,
3734734Sab196087 &inv_buf1),
3745088Sab196087 conv_ehdr_data(id->id_data, CONV_FMT_ALT_FILE,
3754734Sab196087 &inv_buf2),
3765088Sab196087 conv_ehdr_mach(id->id_machine, CONV_FMT_ALT_FILE,
3774734Sab196087 &inv_buf3));
3781976Sab196087
3791976Sab196087 /*
3800Sstevel@tonic-gate * Construct the original command line argument.
3810Sstevel@tonic-gate */
3820Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_CONF),
3830Sstevel@tonic-gate crle->c_confil);
384*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
3859131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
3861976Sab196087 return (INSCFG_RET_FAIL);
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate /*
3890Sstevel@tonic-gate * Construct any -f usage.
3900Sstevel@tonic-gate */
3910Sstevel@tonic-gate if (head->ch_dlflags &&
3920Sstevel@tonic-gate (head->ch_dlflags != RTLD_REL_RELATIVE)) {
3930Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, MSG_ORIG(MSG_CMD_FLAGS),
3945088Sab196087 conv_dl_flag(head->ch_dlflags, CONV_FMT_ALT_CRLE,
3954734Sab196087 &dl_flag_buf));
396*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
3979131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
3981976Sab196087 return (INSCFG_RET_FAIL);
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate } else {
4010Sstevel@tonic-gate /*
4020Sstevel@tonic-gate * Establish any -f usage.
4030Sstevel@tonic-gate */
4040Sstevel@tonic-gate if (head->ch_dlflags &&
4050Sstevel@tonic-gate (head->ch_dlflags != RTLD_REL_RELATIVE))
4060Sstevel@tonic-gate crle->c_dlflags = head->ch_dlflags;
4070Sstevel@tonic-gate }
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate /*
4110Sstevel@tonic-gate * Determine if this configuration file is only applicable to a specific
4120Sstevel@tonic-gate * application.
4130Sstevel@tonic-gate */
4140Sstevel@tonic-gate if (head->ch_app) {
4150Sstevel@tonic-gate char *alter;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate obj = (Rtc_obj *)(head->ch_app + addr);
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate /*
4200Sstevel@tonic-gate * Determine the output directory for the files
4210Sstevel@tonic-gate * alternative name.
4220Sstevel@tonic-gate */
4230Sstevel@tonic-gate alter = (char *)(strtbl + obj->co_alter);
4240Sstevel@tonic-gate (void) strcpy(_objdir, alter);
4250Sstevel@tonic-gate alter = strrchr(_objdir, '/');
4260Sstevel@tonic-gate *alter = '\0';
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate crle->c_objdir = objdir = _objdir;
4290Sstevel@tonic-gate
4300Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
4310Sstevel@tonic-gate if (inspect(crle, (strtbl + obj->co_name),
4320Sstevel@tonic-gate (RTC_OBJ_DUMP | RTC_OBJ_ALTER |
4330Sstevel@tonic-gate RTC_OBJ_GROUP | RTC_OBJ_CMDLINE)) != 0)
4341976Sab196087 return (INSCFG_RET_FAIL);
4350Sstevel@tonic-gate } else {
4360Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_APP),
4370Sstevel@tonic-gate (strtbl + obj->co_alter), (strtbl + obj->co_name));
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate /*
4400Sstevel@tonic-gate * Construct the original command line arguments.
4410Sstevel@tonic-gate */
4420Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
4430Sstevel@tonic-gate MSG_ORIG(MSG_CMD_OUTPUT), crle->c_objdir);
444*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
4459131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
4461976Sab196087 return (INSCFG_RET_FAIL);
4470Sstevel@tonic-gate
4480Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
4490Sstevel@tonic-gate MSG_ORIG(MSG_CMD_DUMPGRP), (strtbl + obj->co_name));
450*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
4519131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
4521976Sab196087 return (INSCFG_RET_FAIL);
4530Sstevel@tonic-gate }
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate
4560Sstevel@tonic-gate /*
4570Sstevel@tonic-gate * Analyze any alternative library path and trusted directory entries.
4580Sstevel@tonic-gate */
4590Sstevel@tonic-gate if (head->ch_edlibpath) {
4600Sstevel@tonic-gate const char *str;
4610Sstevel@tonic-gate
4620Sstevel@tonic-gate str = (const char *)(head->ch_edlibpath + addr);
4630Sstevel@tonic-gate
4640Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
4650Sstevel@tonic-gate crle->c_flags &= ~CRLE_AOUT;
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
4680Sstevel@tonic-gate if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
4690Sstevel@tonic-gate if (head->ch_cnflags & RTC_HDR_64)
4701618Srie str = conv_config_upm(str,
4710Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDDLP_64),
4720Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPDLP_64),
4730Sstevel@tonic-gate MSG_PTH_UPDLP_64_SIZE);
4740Sstevel@tonic-gate else
4751618Srie str = conv_config_upm(str,
4760Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDDLP),
4770Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPDLP),
4780Sstevel@tonic-gate MSG_PTH_UPDLP_SIZE);
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate #endif
4810Sstevel@tonic-gate if (addlib(crle, &crle->c_edlibpath, str) != 0)
4821976Sab196087 return (INSCFG_RET_FAIL);
4830Sstevel@tonic-gate } else {
4840Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
4850Sstevel@tonic-gate MSG_ORIG(MSG_STR_ELF), str);
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
4880Sstevel@tonic-gate MSG_ORIG(MSG_CMD_EDLIB), str);
489*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
4909131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
4911976Sab196087 return (INSCFG_RET_FAIL);
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate } else {
4940Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
4950Sstevel@tonic-gate if (crle->c_flags & CRLE_EDLIB) {
4960Sstevel@tonic-gate /*
4970Sstevel@tonic-gate * If we've been asked to update a configuration
4980Sstevel@tonic-gate * file, and no existing default ELF search
4990Sstevel@tonic-gate * path exists, but the user is going to add new
5000Sstevel@tonic-gate * entries, fabricate the system defaults so
5010Sstevel@tonic-gate * that the users get added to them.
5020Sstevel@tonic-gate */
5030Sstevel@tonic-gate if (fablib(crle, CRLE_EDLIB) != 0)
5041976Sab196087 return (INSCFG_RET_FAIL);
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate } else {
5070Sstevel@tonic-gate /*
5080Sstevel@tonic-gate * Indicate any system default.
5090Sstevel@tonic-gate */
5101976Sab196087 #if M_CLASS == ELFCLASS64
5110Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
5121976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWDLP_64));
5130Sstevel@tonic-gate #else
5141976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDDLP_64));
5150Sstevel@tonic-gate #endif
5161976Sab196087 #else
5170Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
5181976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWDLP));
5190Sstevel@tonic-gate #else
5201976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDDLP));
5210Sstevel@tonic-gate #endif
5221976Sab196087 #endif
5230Sstevel@tonic-gate }
5240Sstevel@tonic-gate }
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate if (head->ch_eslibpath) {
5270Sstevel@tonic-gate const char *str;
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate str = (const char *)(head->ch_eslibpath + addr);
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
5320Sstevel@tonic-gate crle->c_flags &= ~CRLE_AOUT;
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
5350Sstevel@tonic-gate if ((head->ch_cnflags & RTC_HDR_UPM) == 0) {
5360Sstevel@tonic-gate if (head->ch_cnflags & RTC_HDR_64)
5371618Srie str = conv_config_upm(str,
5380Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDTD_64),
5390Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPTD_64),
5400Sstevel@tonic-gate MSG_PTH_UPTD_64_SIZE);
5410Sstevel@tonic-gate else
5421618Srie str = conv_config_upm(str,
5430Sstevel@tonic-gate MSG_ORIG(MSG_PTH_OLDTD),
5440Sstevel@tonic-gate MSG_ORIG(MSG_PTH_UPTD),
5450Sstevel@tonic-gate MSG_PTH_UPTD_SIZE);
5460Sstevel@tonic-gate }
5470Sstevel@tonic-gate #endif
5480Sstevel@tonic-gate if (addlib(crle, &crle->c_eslibpath, str) != 0)
5491976Sab196087 return (INSCFG_RET_FAIL);
5500Sstevel@tonic-gate } else {
5510Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
5520Sstevel@tonic-gate MSG_ORIG(MSG_STR_ELF), str);
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
5550Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ESLIB), str);
556*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
5579131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
5581976Sab196087 return (INSCFG_RET_FAIL);
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate } else {
5610Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
5620Sstevel@tonic-gate if (crle->c_flags & CRLE_ESLIB) {
5630Sstevel@tonic-gate /*
5640Sstevel@tonic-gate * If we've been asked to update a configuration
5650Sstevel@tonic-gate * file, and no existing default ELF secure
5660Sstevel@tonic-gate * path exists, but the user is going to add new
5670Sstevel@tonic-gate * entries, fabricate the system defaults so
5680Sstevel@tonic-gate * that the users get added to them.
5690Sstevel@tonic-gate */
5700Sstevel@tonic-gate if (fablib(crle, CRLE_ESLIB) != 0)
5711976Sab196087 return (INSCFG_RET_FAIL);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate } else {
5740Sstevel@tonic-gate /*
5750Sstevel@tonic-gate * Indicate any system default.
5760Sstevel@tonic-gate */
5771976Sab196087 #if M_CLASS == ELFCLASS64
5780Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
5791976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWTD_64));
5800Sstevel@tonic-gate #else
5811976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDTD_64));
5820Sstevel@tonic-gate #endif
5831976Sab196087 #else
5840Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
5851976Sab196087 (void) printf(MSG_INTL(MSG_DEF_NEWTD));
5860Sstevel@tonic-gate #else
5871976Sab196087 (void) printf(MSG_INTL(MSG_DEF_OLDTD));
5880Sstevel@tonic-gate #endif
5891976Sab196087 #endif
5900Sstevel@tonic-gate }
5910Sstevel@tonic-gate }
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate if (head->ch_adlibpath) {
5940Sstevel@tonic-gate const char *str;
5950Sstevel@tonic-gate
5960Sstevel@tonic-gate str = (const char *)(head->ch_adlibpath + addr);
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
5990Sstevel@tonic-gate crle->c_flags |= CRLE_AOUT;
6000Sstevel@tonic-gate if (addlib(crle, &crle->c_adlibpath, str) != 0)
6011976Sab196087 return (INSCFG_RET_FAIL);
6020Sstevel@tonic-gate } else {
6030Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DLIBPTH),
6040Sstevel@tonic-gate MSG_ORIG(MSG_STR_AOUT), str);
6050Sstevel@tonic-gate
6060Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
6070Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ADLIB), str);
608*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
6099131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
6101976Sab196087 return (INSCFG_RET_FAIL);
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate } else {
6130Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
6140Sstevel@tonic-gate if (crle->c_flags & CRLE_ADLIB) {
6150Sstevel@tonic-gate /*
6160Sstevel@tonic-gate * If we've been asked to update a configuration
6170Sstevel@tonic-gate * file, and no existing default AOUT search
6180Sstevel@tonic-gate * path exists, but the user is going to add new
6190Sstevel@tonic-gate * entries, fabricate the system defaults so
6200Sstevel@tonic-gate * that the users get added to them.
6210Sstevel@tonic-gate */
6220Sstevel@tonic-gate if (fablib(crle, CRLE_ADLIB) != 0)
6231976Sab196087 return (INSCFG_RET_FAIL);
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate } else if (crle->c_flags & CRLE_AOUT) {
6260Sstevel@tonic-gate /*
6270Sstevel@tonic-gate * Indicate any system default.
6280Sstevel@tonic-gate */
6290Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DEF_AOUTDLP));
6300Sstevel@tonic-gate }
6310Sstevel@tonic-gate }
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate if (head->ch_aslibpath) {
6340Sstevel@tonic-gate const char *str;
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate str = (const char *)(head->ch_aslibpath + addr);
6370Sstevel@tonic-gate
6380Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
6390Sstevel@tonic-gate crle->c_flags |= CRLE_AOUT;
6400Sstevel@tonic-gate if (addlib(crle, &crle->c_aslibpath, str) != 0)
6411976Sab196087 return (INSCFG_RET_FAIL);
6420Sstevel@tonic-gate } else {
6430Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_TLIBPTH),
6440Sstevel@tonic-gate MSG_ORIG(MSG_STR_AOUT), str);
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
6470Sstevel@tonic-gate MSG_ORIG(MSG_CMD_ASLIB), str);
648*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
6499131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd, AL_CNT_CRLE) == NULL)
6501976Sab196087 return (INSCFG_RET_FAIL);
6510Sstevel@tonic-gate }
6520Sstevel@tonic-gate } else {
6530Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
6540Sstevel@tonic-gate if (crle->c_flags & CRLE_ASLIB) {
6550Sstevel@tonic-gate /*
6560Sstevel@tonic-gate * If we've been asked to update a configuration
6570Sstevel@tonic-gate * file, and no existing default AOUT secure
6580Sstevel@tonic-gate * path exists, but the user is going to add new
6590Sstevel@tonic-gate * entries, fabricate the system defaults so
6600Sstevel@tonic-gate * that the users get added to them.
6610Sstevel@tonic-gate */
6620Sstevel@tonic-gate if (fablib(crle, CRLE_ASLIB) != 0)
6631976Sab196087 return (INSCFG_RET_FAIL);
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate } else if (crle->c_flags & CRLE_AOUT) {
6660Sstevel@tonic-gate /*
6670Sstevel@tonic-gate * Indicate any system default.
6680Sstevel@tonic-gate */
6697785SRod.Evans@Sun.COM #ifndef SGS_PRE_UNIFIED_PROCESS
6707785SRod.Evans@Sun.COM (void) printf(MSG_INTL(MSG_DEF_AOUTNEWTD));
6717785SRod.Evans@Sun.COM #else
6727785SRod.Evans@Sun.COM (void) printf(MSG_INTL(MSG_DEF_AOUTOLDTD));
6737785SRod.Evans@Sun.COM #endif
6740Sstevel@tonic-gate }
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate
6770Sstevel@tonic-gate /*
6780Sstevel@tonic-gate * Display any environment variables.
6790Sstevel@tonic-gate */
6800Sstevel@tonic-gate if ((head->ch_version >= RTC_VER_THREE) && head->ch_env) {
6819131SRod.Evans@Sun.COM Rtc_env *envtbl;
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0)
6840Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_ENV_TITLE));
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate for (envtbl = (Rtc_env *)(head->ch_env + addr);
6870Sstevel@tonic-gate envtbl->env_str; envtbl++) {
6880Sstevel@tonic-gate const char *str;
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate str = (const char *)(envtbl->env_str + addr);
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
6930Sstevel@tonic-gate if (addenv(crle, str,
6940Sstevel@tonic-gate (envtbl->env_flags | RTC_ENV_CONFIG)) == 0)
6951976Sab196087 return (INSCFG_RET_FAIL);
6960Sstevel@tonic-gate } else {
6970Sstevel@tonic-gate const char *pfmt, *sfmt;
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate if (envtbl->env_flags & RTC_ENV_PERMANT) {
7000Sstevel@tonic-gate pfmt = MSG_INTL(MSG_ENV_PRM);
7010Sstevel@tonic-gate sfmt = MSG_ORIG(MSG_CMD_PRMENV);
7020Sstevel@tonic-gate } else {
7030Sstevel@tonic-gate pfmt = MSG_INTL(MSG_ENV_RPL);
7040Sstevel@tonic-gate sfmt = MSG_ORIG(MSG_CMD_RPLENV);
7050Sstevel@tonic-gate }
7060Sstevel@tonic-gate (void) printf(pfmt, str);
7070Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX, sfmt, str);
708*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
7099131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd,
7109131SRod.Evans@Sun.COM AL_CNT_CRLE) == NULL)
7111976Sab196087 return (INSCFG_RET_FAIL);
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate }
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate
7160Sstevel@tonic-gate /*
7170Sstevel@tonic-gate * Display any filter/filtee associations.
7180Sstevel@tonic-gate */
7190Sstevel@tonic-gate if ((head->ch_version >= RTC_VER_FOUR) && head->ch_fltr) {
7200Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) {
7219131SRod.Evans@Sun.COM Rtc_fltr *fltrtbl;
7229131SRod.Evans@Sun.COM Rtc_flte *fltetbl;
7230Sstevel@tonic-gate
7240Sstevel@tonic-gate /* LINTED */
7251976Sab196087 fltrtbl = (Rtc_fltr *)
7264734Sab196087 (CAST_PTRINT(char *, head->ch_fltr) + addr);
7270Sstevel@tonic-gate /* LINTED */
7281976Sab196087 fltetbl = (Rtc_flte *)
7294734Sab196087 (CAST_PTRINT(char *, head->ch_flte) + addr);
7300Sstevel@tonic-gate
7310Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_TITLE));
7320Sstevel@tonic-gate
7330Sstevel@tonic-gate while (fltrtbl->fr_filter) {
7340Sstevel@tonic-gate Rtc_flte *_fltetbl;
7350Sstevel@tonic-gate
7360Sstevel@tonic-gate /*
7370Sstevel@tonic-gate * Print the filter and filtee string pair.
7380Sstevel@tonic-gate */
7390Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_FILTER),
7400Sstevel@tonic-gate (strtbl + fltrtbl->fr_filter),
7410Sstevel@tonic-gate (strtbl + fltrtbl->fr_string));
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate /*
7440Sstevel@tonic-gate * Print each filtee.
7450Sstevel@tonic-gate */
7460Sstevel@tonic-gate /* LINTED */
7470Sstevel@tonic-gate for (_fltetbl = (Rtc_flte *)((char *)fltetbl +
7480Sstevel@tonic-gate fltrtbl->fr_filtee); _fltetbl->fe_filtee;
7490Sstevel@tonic-gate _fltetbl++) {
7500Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_FLT_FILTEE),
7510Sstevel@tonic-gate (strtbl + _fltetbl->fe_filtee));
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate fltrtbl++;
7540Sstevel@tonic-gate }
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate }
7570Sstevel@tonic-gate
7580Sstevel@tonic-gate /*
7590Sstevel@tonic-gate * Display any memory reservations required for any alternative
7600Sstevel@tonic-gate * objects.
7610Sstevel@tonic-gate */
7620Sstevel@tonic-gate if (head->ch_resbgn && ((crle->c_flags & CRLE_UPDATE) == 0))
7632056Sab196087 (void) printf(MSG_INTL(MSG_DMP_RESV),
7644734Sab196087 (u_longlong_t)head->ch_resbgn,
7654734Sab196087 (u_longlong_t)head->ch_resend,
7664734Sab196087 (u_longlong_t)(head->ch_resend - head->ch_resbgn));
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate /*
7690Sstevel@tonic-gate * If there's no hash table there's nothing else to process.
7700Sstevel@tonic-gate */
7710Sstevel@tonic-gate if (head->ch_hash == 0) {
7720Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0)
7739131SRod.Evans@Sun.COM printcmd(crle, head, cmdline);
7741976Sab196087 return (INSCFG_RET_OK);
7750Sstevel@tonic-gate }
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate /*
7780Sstevel@tonic-gate * Traverse the directory and filename arrays.
7790Sstevel@tonic-gate */
7800Sstevel@tonic-gate for (dirtbl = (Rtc_dir *)(head->ch_dir + addr);
7810Sstevel@tonic-gate dirtbl->cd_obj; dirtbl++) {
7820Sstevel@tonic-gate struct stat status;
7830Sstevel@tonic-gate Rtc_obj *dobj;
7840Sstevel@tonic-gate const char *str;
7850Sstevel@tonic-gate
7860Sstevel@tonic-gate dobj = (Rtc_obj *)(dirtbl->cd_obj + addr);
7870Sstevel@tonic-gate filetbl = (Rtc_file *)(dirtbl->cd_file + addr);
7880Sstevel@tonic-gate str = strtbl + dobj->co_name;
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate /*
7910Sstevel@tonic-gate * Simplify recreation by using any command-line directories.
7920Sstevel@tonic-gate * If we're dealing with a version 1 configuration file use
7930Sstevel@tonic-gate * every directory.
7940Sstevel@tonic-gate */
7950Sstevel@tonic-gate if ((dobj->co_flags & RTC_OBJ_CMDLINE) ||
7960Sstevel@tonic-gate (head->ch_version == RTC_VER_ONE)) {
7970Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
7980Sstevel@tonic-gate if (inspect(crle, str,
7990Sstevel@tonic-gate getflags(dobj->co_flags)) != 0)
8001976Sab196087 return (INSCFG_RET_FAIL);
8010Sstevel@tonic-gate if ((dobj->co_flags &
8020Sstevel@tonic-gate (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
8030Sstevel@tonic-gate RTC_OBJ_NOEXIST)
8040Sstevel@tonic-gate continue;
8050Sstevel@tonic-gate } else {
8060Sstevel@tonic-gate /* LINTED */
8070Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
8080Sstevel@tonic-gate getformat(dobj->co_flags), str);
809*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
8109131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd,
8119131SRod.Evans@Sun.COM AL_CNT_CRLE) == NULL)
8121976Sab196087 return (INSCFG_RET_FAIL);
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate }
8150Sstevel@tonic-gate
8160Sstevel@tonic-gate /*
8170Sstevel@tonic-gate * If this isn't an update print the directory name. If the
8180Sstevel@tonic-gate * directory has no entries (possible if the directory is a
8190Sstevel@tonic-gate * symlink to another directory, in which case we record the
8200Sstevel@tonic-gate * real path also), don't bother printing it unless we're in
8210Sstevel@tonic-gate * verbose mode.
8220Sstevel@tonic-gate */
8230Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0) {
8240Sstevel@tonic-gate if ((dobj->co_flags &
8250Sstevel@tonic-gate (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
8260Sstevel@tonic-gate RTC_OBJ_NOEXIST) {
8270Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DIR_2), str);
8280Sstevel@tonic-gate continue;
8290Sstevel@tonic-gate } else if (filetbl->cf_obj ||
8300Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE))
8310Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DIR_1), str);
8320Sstevel@tonic-gate }
8330Sstevel@tonic-gate
8340Sstevel@tonic-gate /*
8350Sstevel@tonic-gate * Under verbose mode validate any real directory entry - the
8360Sstevel@tonic-gate * same test will be carried out by ld.so.1.
8370Sstevel@tonic-gate */
8380Sstevel@tonic-gate if (((crle->c_flags & CRLE_UPDATE) == 0) &&
8390Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE) &&
8400Sstevel@tonic-gate (dobj->co_flags & RTC_OBJ_REALPTH)) {
8410Sstevel@tonic-gate if (stat(str, &status) != 0) {
8420Sstevel@tonic-gate int err = errno;
8430Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_STAT), str,
8440Sstevel@tonic-gate strerror(err));
8450Sstevel@tonic-gate } else if (status.st_mtime != dobj->co_info) {
8460Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_DCMP), str);
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate }
8490Sstevel@tonic-gate
8500Sstevel@tonic-gate for (; filetbl->cf_obj; filetbl++) {
8519131SRod.Evans@Sun.COM Rtc_obj *fobj;
8529131SRod.Evans@Sun.COM Half flags;
8530Sstevel@tonic-gate
8540Sstevel@tonic-gate fobj = (Rtc_obj *)(filetbl->cf_obj + addr);
8550Sstevel@tonic-gate str = strtbl + fobj->co_name;
8560Sstevel@tonic-gate flags = fobj->co_flags;
8570Sstevel@tonic-gate
8580Sstevel@tonic-gate /*
8590Sstevel@tonic-gate * Only update individual files that were originally
8600Sstevel@tonic-gate * specified on the command-line. Or, if this is a
8610Sstevel@tonic-gate * version 1 configuration file use every file that
8620Sstevel@tonic-gate * isn't part of an all-entries directory.
8630Sstevel@tonic-gate */
8640Sstevel@tonic-gate if (((flags & RTC_OBJ_CMDLINE) &&
8650Sstevel@tonic-gate ((fobj->co_flags & RTC_OBJ_APP) == 0)) ||
8660Sstevel@tonic-gate ((head->ch_version == RTC_VER_ONE) &&
8670Sstevel@tonic-gate ((dobj->co_flags & RTC_OBJ_ALLENTS) == 0))) {
8689131SRod.Evans@Sun.COM char *alter = NULL, altdir[PATH_MAX];
8690Sstevel@tonic-gate
8700Sstevel@tonic-gate /*
8710Sstevel@tonic-gate * Determine whether this file requires an
8720Sstevel@tonic-gate * alternative, and if so, and we haven't
8730Sstevel@tonic-gate * already an alternative in affect, create one.
8740Sstevel@tonic-gate */
8750Sstevel@tonic-gate if (fobj->co_flags & RTC_OBJ_ALTER) {
8760Sstevel@tonic-gate alter = (char *)(strtbl +
8770Sstevel@tonic-gate fobj->co_alter);
8780Sstevel@tonic-gate (void) strcpy(altdir, alter);
8790Sstevel@tonic-gate alter = strrchr(altdir, '/');
8800Sstevel@tonic-gate *alter = '\0';
8810Sstevel@tonic-gate
8829131SRod.Evans@Sun.COM if ((objdir == NULL) ||
8830Sstevel@tonic-gate (strcmp(objdir, altdir) != 0)) {
8840Sstevel@tonic-gate (void) strcpy(_objdir, altdir);
8850Sstevel@tonic-gate crle->c_objdir = alter =
8860Sstevel@tonic-gate objdir = _objdir;
8870Sstevel@tonic-gate } else
8889131SRod.Evans@Sun.COM alter = NULL;
8890Sstevel@tonic-gate }
8900Sstevel@tonic-gate
8910Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
8920Sstevel@tonic-gate if (inspect(crle, str,
8930Sstevel@tonic-gate getflags(flags)) != 0)
8941976Sab196087 return (INSCFG_RET_FAIL);
8950Sstevel@tonic-gate continue;
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate
8980Sstevel@tonic-gate if (alter) {
8990Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
9000Sstevel@tonic-gate MSG_ORIG(MSG_CMD_OUTPUT),
9010Sstevel@tonic-gate crle->c_objdir);
902*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
9039131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd,
9049131SRod.Evans@Sun.COM AL_CNT_CRLE) == NULL)
9051976Sab196087 return (INSCFG_RET_FAIL);
9060Sstevel@tonic-gate }
9070Sstevel@tonic-gate
9080Sstevel@tonic-gate /* LINTED */
9090Sstevel@tonic-gate (void) snprintf(_cmd, PATH_MAX,
9100Sstevel@tonic-gate getformat(flags), str);
911*13093SRoger.Faulkner@Oracle.COM cmd = strdupa(_cmd);
9129131SRod.Evans@Sun.COM if (aplist_append(&cmdline, cmd,
9139131SRod.Evans@Sun.COM AL_CNT_CRLE) == NULL)
9141976Sab196087 return (INSCFG_RET_FAIL);
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate
9170Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE)
9180Sstevel@tonic-gate continue;
9190Sstevel@tonic-gate
9200Sstevel@tonic-gate /*
9210Sstevel@tonic-gate * Although we record both full pathnames and their
9220Sstevel@tonic-gate * simple filenames (basename), only print the simple
9230Sstevel@tonic-gate * names unless we're under verbose mode.
9240Sstevel@tonic-gate */
9250Sstevel@tonic-gate if ((strchr(str, '/') == 0) ||
9260Sstevel@tonic-gate (crle->c_flags & CRLE_VERBOSE)) {
9270Sstevel@tonic-gate if (fobj->co_flags & RTC_OBJ_ALTER)
9280Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FILE_2),
9290Sstevel@tonic-gate str, (strtbl + fobj->co_alter));
9300Sstevel@tonic-gate else
9310Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FILE_1),
9320Sstevel@tonic-gate str);
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate /*
9360Sstevel@tonic-gate * Under verbose mode validate any real file entry - the
9370Sstevel@tonic-gate * same test will be carried out by ld.so.1.
9380Sstevel@tonic-gate */
9390Sstevel@tonic-gate if ((crle->c_flags & CRLE_VERBOSE) &&
9400Sstevel@tonic-gate (fobj->co_flags & RTC_OBJ_REALPTH)) {
9410Sstevel@tonic-gate if (stat(str, &status) != 0) {
9420Sstevel@tonic-gate int err = errno;
9430Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_STAT),
9440Sstevel@tonic-gate str, strerror(err));
9450Sstevel@tonic-gate } else if (status.st_size != fobj->co_info) {
9460Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_FCMP),
9470Sstevel@tonic-gate str);
9480Sstevel@tonic-gate }
9490Sstevel@tonic-gate }
9500Sstevel@tonic-gate }
9510Sstevel@tonic-gate }
9520Sstevel@tonic-gate
9530Sstevel@tonic-gate if ((crle->c_flags & CRLE_UPDATE) == 0)
9549131SRod.Evans@Sun.COM printcmd(crle, head, cmdline);
9550Sstevel@tonic-gate
9560Sstevel@tonic-gate if ((crle->c_flags & CRLE_VERBOSE) == 0)
9571976Sab196087 return (INSCFG_RET_OK);
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate /*
9600Sstevel@tonic-gate * If we've in verbose mode scan the hash list.
9610Sstevel@tonic-gate */
9620Sstevel@tonic-gate /* LINTED */
9631976Sab196087 hash = (Word *)(CAST_PTRINT(char *, head->ch_hash) + addr);
9640Sstevel@tonic-gate bkts = hash[0];
9650Sstevel@tonic-gate chain = &hash[2 + bkts];
9660Sstevel@tonic-gate hash += 2;
9670Sstevel@tonic-gate
9680Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASH));
9690Sstevel@tonic-gate
9700Sstevel@tonic-gate /*
9710Sstevel@tonic-gate * Scan the hash buckets looking for valid entries.
9720Sstevel@tonic-gate */
9730Sstevel@tonic-gate for (ndx = 0; ndx < bkts; ndx++, hash++) {
9744734Sab196087 Conv_config_obj_buf_t config_obj_buf;
9754734Sab196087 Rtc_obj *obj;
9764734Sab196087 const char *str;
9774734Sab196087 Word _ndx;
9780Sstevel@tonic-gate
9799131SRod.Evans@Sun.COM if (*hash == NULL)
9800Sstevel@tonic-gate continue;
9810Sstevel@tonic-gate
9820Sstevel@tonic-gate obj = objtbl + *hash;
9830Sstevel@tonic-gate str = strtbl + obj->co_name;
9840Sstevel@tonic-gate
9850Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASHENT_1), obj->co_id, ndx,
9864734Sab196087 str, conv_config_obj(obj->co_flags, &config_obj_buf));
9870Sstevel@tonic-gate
9880Sstevel@tonic-gate /*
9890Sstevel@tonic-gate * Determine whether there are other objects chained to this
9900Sstevel@tonic-gate * bucket.
9910Sstevel@tonic-gate */
9920Sstevel@tonic-gate for (_ndx = chain[*hash]; _ndx; _ndx = chain[_ndx]) {
9930Sstevel@tonic-gate obj = objtbl + _ndx;
9940Sstevel@tonic-gate str = strtbl + obj->co_name;
9950Sstevel@tonic-gate
9960Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DMP_HASHENT_2), obj->co_id,
9974734Sab196087 str, conv_config_obj(obj->co_flags,
9984734Sab196087 &config_obj_buf));
9990Sstevel@tonic-gate }
10000Sstevel@tonic-gate }
10010Sstevel@tonic-gate (void) printf(MSG_ORIG(MSG_STR_NL));
10020Sstevel@tonic-gate
10031976Sab196087 return (INSCFG_RET_OK);
10040Sstevel@tonic-gate }
10050Sstevel@tonic-gate
10060Sstevel@tonic-gate
10071976Sab196087 INSCFG_RET
inspectconfig(Crle_desc * crle,int c_class)10082056Sab196087 inspectconfig(Crle_desc * crle, int c_class)
10090Sstevel@tonic-gate {
10101976Sab196087 INSCFG_RET error;
10111976Sab196087 int fd;
10120Sstevel@tonic-gate Addr addr;
10130Sstevel@tonic-gate struct stat status;
10140Sstevel@tonic-gate const char *caller = crle->c_name, *file = crle->c_confil;
10154734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2, inv_buf3;
10160Sstevel@tonic-gate
10170Sstevel@tonic-gate /*
10180Sstevel@tonic-gate * Open the configuration file, determine its size and map it in.
10190Sstevel@tonic-gate */
10200Sstevel@tonic-gate if ((fd = open(file, O_RDONLY, 0)) == -1) {
10210Sstevel@tonic-gate int err = errno;
10220Sstevel@tonic-gate
10232056Sab196087 if (err == ENOENT) {
10242056Sab196087 #ifndef _ELF64
10252056Sab196087 /* Must restart if user requested a 64-bit file */
10262056Sab196087 if (c_class == ELFCLASS64)
10272056Sab196087 return (INSCFG_RET_NEED64);
10282056Sab196087 #endif
10292056Sab196087
10300Sstevel@tonic-gate /*
10310Sstevel@tonic-gate * To allow an update (-u) from scratch, fabricate any
10320Sstevel@tonic-gate * default search and secure paths that the user
10330Sstevel@tonic-gate * intends to add to.
10340Sstevel@tonic-gate */
10350Sstevel@tonic-gate if (crle->c_flags & CRLE_UPDATE) {
10360Sstevel@tonic-gate if (crle->c_flags & CRLE_EDLIB) {
10370Sstevel@tonic-gate if (fablib(crle, CRLE_EDLIB))
10382056Sab196087 return (INSCFG_RET_FAIL);
10390Sstevel@tonic-gate }
10400Sstevel@tonic-gate if (crle->c_flags & CRLE_ESLIB) {
10410Sstevel@tonic-gate if (fablib(crle, CRLE_ESLIB))
10422056Sab196087 return (INSCFG_RET_FAIL);
10430Sstevel@tonic-gate }
10440Sstevel@tonic-gate if (crle->c_flags & CRLE_ADLIB) {
10450Sstevel@tonic-gate if (fablib(crle, CRLE_ADLIB))
10462056Sab196087 return (INSCFG_RET_FAIL);
10470Sstevel@tonic-gate }
10480Sstevel@tonic-gate if (crle->c_flags & CRLE_ASLIB) {
10490Sstevel@tonic-gate if (fablib(crle, CRLE_ASLIB))
10502056Sab196087 return (INSCFG_RET_FAIL);
10510Sstevel@tonic-gate }
10522056Sab196087 return (INSCFG_RET_OK);
10530Sstevel@tonic-gate
10540Sstevel@tonic-gate } else if (crle->c_flags & CRLE_CONFDEF) {
10550Sstevel@tonic-gate const char *fmt1, *fmt2;
10560Sstevel@tonic-gate
10570Sstevel@tonic-gate /*
10580Sstevel@tonic-gate * Otherwise if the user is inspecting a default
10590Sstevel@tonic-gate * configuration file that doesn't exist inform
10600Sstevel@tonic-gate * them and display the ELF defaults.
10610Sstevel@tonic-gate */
10620Sstevel@tonic-gate (void) printf(MSG_INTL(MSG_DEF_NOCONF), file);
10632056Sab196087 (void) printf(MSG_INTL(MSG_DMP_PLATFORM),
10644734Sab196087 conv_ehdr_class(M_CLASS,
10655088Sab196087 CONV_FMT_ALT_FILE, &inv_buf1),
10664734Sab196087 conv_ehdr_data(M_DATA,
10675088Sab196087 CONV_FMT_ALT_FILE, &inv_buf2),
10684734Sab196087 conv_ehdr_mach(M_MACH,
10695088Sab196087 CONV_FMT_ALT_FILE, &inv_buf3));
10702056Sab196087
10710Sstevel@tonic-gate
10720Sstevel@tonic-gate if (crle->c_flags & CRLE_AOUT) {
10730Sstevel@tonic-gate fmt1 = MSG_INTL(MSG_DEF_AOUTDLP);
10747785SRod.Evans@Sun.COM #ifndef SGS_PRE_UNIFIED_PROCESS
10757785SRod.Evans@Sun.COM fmt2 = MSG_INTL(MSG_DEF_AOUTNEWTD);
10767785SRod.Evans@Sun.COM #else
10777785SRod.Evans@Sun.COM fmt2 = MSG_INTL(MSG_DEF_AOUTOLDTD);
10787785SRod.Evans@Sun.COM #endif
10790Sstevel@tonic-gate } else {
10801976Sab196087 #if M_CLASS == ELFCLASS64
10810Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
10821976Sab196087 fmt1 = MSG_INTL(MSG_DEF_NEWDLP_64);
10831976Sab196087 fmt2 = MSG_INTL(MSG_DEF_NEWTD_64);
10840Sstevel@tonic-gate #else
10851976Sab196087 fmt1 = MSG_INTL(MSG_DEF_OLDDLP_64);
10861976Sab196087 fmt2 = MSG_INTL(MSG_DEF_OLDTD_64);
10870Sstevel@tonic-gate #endif
10881976Sab196087 #else
10890Sstevel@tonic-gate #ifndef SGS_PRE_UNIFIED_PROCESS
10901976Sab196087 fmt1 = MSG_INTL(MSG_DEF_NEWDLP);
10911976Sab196087 fmt2 = MSG_INTL(MSG_DEF_NEWTD);
10920Sstevel@tonic-gate #else
10931976Sab196087 fmt1 = MSG_INTL(MSG_DEF_OLDDLP);
10941976Sab196087 fmt2 = MSG_INTL(MSG_DEF_OLDTD);
10950Sstevel@tonic-gate #endif
10961976Sab196087 #endif
10970Sstevel@tonic-gate }
10980Sstevel@tonic-gate (void) printf(fmt1);
10990Sstevel@tonic-gate (void) printf(fmt2);
11000Sstevel@tonic-gate
11012056Sab196087 return (INSCFG_RET_OK);
11020Sstevel@tonic-gate }
11030Sstevel@tonic-gate }
11040Sstevel@tonic-gate
11050Sstevel@tonic-gate /*
11060Sstevel@tonic-gate * Otherwise there's an error condition in accessing the file.
11070Sstevel@tonic-gate */
11080Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN), caller, file,
11090Sstevel@tonic-gate strerror(err));
11100Sstevel@tonic-gate
11112056Sab196087 return (INSCFG_RET_FAIL);
11120Sstevel@tonic-gate }
11130Sstevel@tonic-gate
11140Sstevel@tonic-gate (void) fstat(fd, &status);
11150Sstevel@tonic-gate if (status.st_size < sizeof (Rtc_head)) {
11160Sstevel@tonic-gate (void) close(fd);
11170Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_COR_TRUNC), caller, file);
11182056Sab196087 return (INSCFG_RET_FAIL);
11190Sstevel@tonic-gate }
11200Sstevel@tonic-gate if ((addr = (Addr)mmap(0, status.st_size, PROT_READ, MAP_SHARED,
11210Sstevel@tonic-gate fd, 0)) == (Addr)MAP_FAILED) {
11220Sstevel@tonic-gate int err = errno;
11230Sstevel@tonic-gate (void) fprintf(stderr, MSG_INTL(MSG_SYS_MMAP), caller, file,
11240Sstevel@tonic-gate strerror(err));
11250Sstevel@tonic-gate (void) close(fd);
11262056Sab196087 return (INSCFG_RET_FAIL);
11270Sstevel@tonic-gate }
11280Sstevel@tonic-gate (void) close(fd);
11290Sstevel@tonic-gate
11300Sstevel@tonic-gate /*
11310Sstevel@tonic-gate * Print the contents of the configuration file.
11320Sstevel@tonic-gate */
11332056Sab196087 error = scanconfig(crle, addr, c_class);
11340Sstevel@tonic-gate
11350Sstevel@tonic-gate (void) munmap((void *)addr, status.st_size);
11360Sstevel@tonic-gate return (error);
11370Sstevel@tonic-gate }
1138