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