4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
43 * Display the command line required to regenerate the configuration file.
45 * Under normal mode the command is printed on one line to make it more
46 * available for grep(1) use. Under verbose mode the command is separated
47 * into each argument (a little more readable perhaps when the arguments are
48 * numerous of have long pathnames).
50 * Note that for version 1 configuration files we never used to generate any
51 * command-line information, and as the attempt to do so is only a best effort
52 * don't bother printing anything.
55 printcmd(Crle_desc
*crle
, Rtc_head
* head
, APlist
*cmdline
)
58 const char *fmto
, *fmtb
, *fmtm
, *fmte
;
62 if (crle
->c_flags
& CRLE_VERBOSE
) {
63 fmto
= MSG_INTL(MSG_DMP_CMD_ONE_V
);
64 fmtb
= MSG_INTL(MSG_DMP_CMD_BGN_V
);
65 fmtm
= MSG_INTL(MSG_DMP_CMD_MID_V
);
66 fmte
= MSG_INTL(MSG_DMP_CMD_END_V
);
68 } else if (head
->ch_version
> RTC_VER_ONE
) {
69 fmto
= MSG_INTL(MSG_DMP_CMD_ONE
);
70 fmtb
= MSG_INTL(MSG_DMP_CMD_BGN
);
71 fmtm
= MSG_INTL(MSG_DMP_CMD_MID
);
72 fmte
= MSG_INTL(MSG_DMP_CMD_END
);
75 (void) printf(MSG_ORIG(MSG_STR_NL
));
79 (void) printf(MSG_INTL(MSG_DMP_CMD_TITLE
));
81 lidx
= aplist_nitems(cmdline
) - 1;
82 for (APLIST_TRAVERSE(cmdline
, idx
, cmd
)) {
85 (void) printf(fmtb
, cmd
);
87 (void) printf(fmto
, cmd
);
90 (void) printf(fmtm
, cmd
);
92 (void) printf(fmte
, cmd
);
98 * Establish the argument required to generate the associated object.
101 getformat(Half flags
)
103 if (flags
& RTC_OBJ_ALTER
) {
104 if (flags
& RTC_OBJ_DUMP
) {
105 if (flags
& RTC_OBJ_GROUP
)
106 return (MSG_ORIG(MSG_CMD_DUMPGRP
));
108 return (MSG_ORIG(MSG_CMD_DUMPIND
));
110 if (flags
& RTC_OBJ_OPTINAL
)
111 return (MSG_ORIG(MSG_CMD_OPTIONAL
));
113 return (MSG_ORIG(MSG_CMD_ALTER
));
116 if (flags
& RTC_OBJ_GROUP
)
117 return (MSG_ORIG(MSG_CMD_GRP
));
119 return (MSG_ORIG(MSG_CMD_IND
));
124 * Fabricate a system default search path. If an update is requested, and
125 * new search paths are specified while no configuration file exists, or if a
126 * configuration file does exist but doesn't specify this particular search
127 * path, create any system defaults. The intent is to allow
128 * "crle -u -l/usr/local/lib" and have this append the search path to the
129 * system default, rather than have the user have to determine and specify
130 * this default themselves.
133 fablib(Crle_desc
* crle
, int flag
)
140 #if M_CLASS == ELFCLASS64
141 #ifndef SGS_PRE_UNIFIED_PROCESS
142 path
= MSG_ORIG(MSG_PTH_NEWDLP_64
);
144 path
= MSG_ORIG(MSG_PTH_OLDDLP_64
);
147 #ifndef SGS_PRE_UNIFIED_PROCESS
148 path
= MSG_ORIG(MSG_PTH_NEWDLP
);
150 path
= MSG_ORIG(MSG_PTH_OLDDLP
);
153 list
= &crle
->c_edlibpath
;
157 #if M_CLASS == ELFCLASS64
158 #ifndef SGS_PRE_UNIFIED_PROCESS
159 path
= MSG_ORIG(MSG_PTH_NEWTD_64
);
161 path
= MSG_ORIG(MSG_PTH_OLDTD_64
);
164 #ifndef SGS_PRE_UNIFIED_PROCESS
165 path
= MSG_ORIG(MSG_PTH_NEWTD
);
167 path
= MSG_ORIG(MSG_PTH_OLDTD
);
170 list
= &crle
->c_eslibpath
;
174 path
= MSG_ORIG(MSG_PTH_AOUTDLP
);
175 list
= &crle
->c_adlibpath
;
179 #ifndef SGS_PRE_UNIFIED_PROCESS
180 path
= MSG_ORIG(MSG_PTH_NEWTD
);
182 path
= MSG_ORIG(MSG_PTH_OLDTD
);
184 list
= &crle
->c_aslibpath
;
191 return (addlib(crle
, list
, path
));
195 * Establish the flags required to generate the associated object. Actually
196 * the flags are already part of the object being inspected from the present
197 * configuration file, but instead of using them all, which can cause some
198 * unsuspected propagation down the inspect() family, only use those flags that
199 * would have been contributed from crle()'s calls to inspect.
205 (RTC_OBJ_ALTER
| RTC_OBJ_DUMP
| RTC_OBJ_GROUP
| RTC_OBJ_OPTINAL
);
206 return (flags
| RTC_OBJ_CMDLINE
);
210 * Dump a configuration files information. This routine is very close to the
211 * scanconfig() in libcrle.
215 scanconfig(Crle_desc
* crle
, Addr addr
, int c_class
)
217 Conv_inv_buf_t inv_buf1
, inv_buf2
, inv_buf3
, inv_buf4
;
218 Conv_dl_flag_buf_t dl_flag_buf
;
223 Rtc_obj
*objtbl
, *obj
;
227 APlist
*cmdline
= NULL
;
228 char _cmd
[PATH_MAX
], *cmd
;
229 char _objdir
[PATH_MAX
], *objdir
= NULL
;
232 * If there is an Rtc_id present, the Rtc_head follows it.
233 * Otherwise, it is at the top.
235 if (RTC_ID_TEST(addr
)) {
236 id
= (Rtc_id
*) addr
;
237 addr
+= sizeof (*id
); /* Rtc_head follows */
241 * When updating an existing config file that is lacking
242 * the Rtc_id block, don't put one into the resulting file.
244 crle
->c_flags
&= ~CRLE_ADDID
;
246 head
= (Rtc_head
*) addr
;
250 * The rest of the configuration file can only be examined by
251 * a program of the same ELFCLASS, byte order, and hardware
252 * architecture as the one that created it.
255 /* 64-bit program with an existing 32-bit file? Abort. */
256 if (!(head
->ch_cnflags
& RTC_HDR_64
)) {
257 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_CLASS
),
258 crle
->c_name
, crle
->c_confil
);
259 return (INSCFG_RET_FAIL
);
262 /* 32-bit program with an existing 64-bit file? Restart. */
263 if (head
->ch_cnflags
& RTC_HDR_64
)
264 return (INSCFG_RET_NEED64
);
267 * 32-bit program with an existing 32-bit file, but the
268 * user specified the -64 option? Abort
270 if (c_class
!= ELFCLASS32
) {
271 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_CLASS
),
272 crle
->c_name
, crle
->c_confil
);
273 return (INSCFG_RET_FAIL
);
277 * Now that the ELFCLASS has been settled, ensure that the
278 * byte order and hardware match. Unlike ELFCLASS, where restarting
279 * the other version is an option, we cannot work around a mismatch
280 * of these attributes.
282 if (id
) { /* Rtc_id is present */
284 * Was the file produced by compatible hardware?
285 * ELFCLASS doesn't matter here, because we can
286 * adjust for that, but byte order and machine type do.
288 if ((id
->id_data
!= M_DATA
) || (id
->id_machine
!= M_MACH
)) {
289 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_WRONGARCH
),
290 crle
->c_name
, crle
->c_confil
,
291 conv_ehdr_data(id
->id_data
, CONV_FMT_ALT_FILE
,
293 conv_ehdr_mach(id
->id_machine
, CONV_FMT_ALT_FILE
,
295 conv_ehdr_data(M_DATA
, CONV_FMT_ALT_FILE
,
297 conv_ehdr_mach(M_MACH
, CONV_FMT_ALT_FILE
,
299 return (INSCFG_RET_FAIL
);
305 objtbl
= (Rtc_obj
*)(CAST_PTRINT(char *, head
->ch_obj
) + addr
);
306 strtbl
= (const char *)(CAST_PTRINT(char *, head
->ch_str
) + addr
);
309 * If the configuration file has a version higher than we
310 * recognise, we face two issues:
311 * (1) Updates are not possible because we have no
312 * way to recognise or propagate the new features.
313 * This has to be a fatal error.
314 * (2) Printing has the risk that we may have been
315 * handed something other than a real config file, as
316 * well as the fact that we can't display the information
317 * for the new features. So, we print a warning, but
318 * continue on to do the best we can with it.
320 if (head
->ch_version
> RTC_VER_CURRENT
) {
321 if (crle
->c_flags
& CRLE_UPDATE
) {
322 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_UPDATEVER
),
323 crle
->c_name
, crle
->c_confil
,
324 (int)head
->ch_version
, RTC_VER_CURRENT
);
325 return (INSCFG_RET_FAIL
);
327 (void) fprintf(stderr
, MSG_INTL(MSG_ARG_PRINTVER
),
328 crle
->c_name
, crle
->c_confil
,
329 (int)head
->ch_version
, RTC_VER_CURRENT
);
334 * If this is a version 1 configuration file we can't generate accurate
335 * update information, or the command-line used to create the file.
337 if (head
->ch_version
== RTC_VER_ONE
) {
338 (void) printf(MSG_INTL(MSG_ARG_UPDATE
), crle
->c_name
,
339 crle
->c_confil
, (int)head
->ch_version
);
343 if (!(crle
->c_flags
& CRLE_UPDATE
) && (head
->ch_cnflags
& RTC_HDR_64
)) {
345 * Construct the original command line argument.
347 cmd
= strdupa(MSG_ORIG(MSG_CMD_64
));
348 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
349 return (INSCFG_RET_FAIL
);
354 * Start analyzing the configuration files header information.
356 if ((crle
->c_flags
& CRLE_UPDATE
) == 0) {
359 if (head
->ch_dlflags
)
360 fmt
= conv_dl_flag(head
->ch_dlflags
, 0, &dl_flag_buf
);
362 fmt
= MSG_ORIG(MSG_STR_EMPTY
);
364 (void) printf(MSG_INTL(MSG_DMP_HEAD
), (int)head
->ch_version
,
365 crle
->c_confil
, fmt
);
368 * If the file has an id block, show the information
371 (void) printf(MSG_INTL(MSG_DMP_PLATFORM
),
372 conv_ehdr_class(id
->id_class
, CONV_FMT_ALT_FILE
,
374 conv_ehdr_data(id
->id_data
, CONV_FMT_ALT_FILE
,
376 conv_ehdr_mach(id
->id_machine
, CONV_FMT_ALT_FILE
,
380 * Construct the original command line argument.
382 (void) snprintf(_cmd
, PATH_MAX
, MSG_ORIG(MSG_CMD_CONF
),
385 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
386 return (INSCFG_RET_FAIL
);
389 * Construct any -f usage.
391 if (head
->ch_dlflags
&&
392 (head
->ch_dlflags
!= RTLD_REL_RELATIVE
)) {
393 (void) snprintf(_cmd
, PATH_MAX
, MSG_ORIG(MSG_CMD_FLAGS
),
394 conv_dl_flag(head
->ch_dlflags
, CONV_FMT_ALT_CRLE
,
397 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
398 return (INSCFG_RET_FAIL
);
402 * Establish any -f usage.
404 if (head
->ch_dlflags
&&
405 (head
->ch_dlflags
!= RTLD_REL_RELATIVE
))
406 crle
->c_dlflags
= head
->ch_dlflags
;
411 * Determine if this configuration file is only applicable to a specific
417 obj
= (Rtc_obj
*)(head
->ch_app
+ addr
);
420 * Determine the output directory for the files
423 alter
= (char *)(strtbl
+ obj
->co_alter
);
424 (void) strcpy(_objdir
, alter
);
425 alter
= strrchr(_objdir
, '/');
428 crle
->c_objdir
= objdir
= _objdir
;
430 if (crle
->c_flags
& CRLE_UPDATE
) {
431 if (inspect(crle
, (strtbl
+ obj
->co_name
),
432 (RTC_OBJ_DUMP
| RTC_OBJ_ALTER
|
433 RTC_OBJ_GROUP
| RTC_OBJ_CMDLINE
)) != 0)
434 return (INSCFG_RET_FAIL
);
436 (void) printf(MSG_INTL(MSG_DMP_APP
),
437 (strtbl
+ obj
->co_alter
), (strtbl
+ obj
->co_name
));
440 * Construct the original command line arguments.
442 (void) snprintf(_cmd
, PATH_MAX
,
443 MSG_ORIG(MSG_CMD_OUTPUT
), crle
->c_objdir
);
445 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
446 return (INSCFG_RET_FAIL
);
448 (void) snprintf(_cmd
, PATH_MAX
,
449 MSG_ORIG(MSG_CMD_DUMPGRP
), (strtbl
+ obj
->co_name
));
451 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
452 return (INSCFG_RET_FAIL
);
457 * Analyze any alternative library path and trusted directory entries.
459 if (head
->ch_edlibpath
) {
462 str
= (const char *)(head
->ch_edlibpath
+ addr
);
464 if (crle
->c_flags
& CRLE_UPDATE
) {
465 crle
->c_flags
&= ~CRLE_AOUT
;
467 #ifndef SGS_PRE_UNIFIED_PROCESS
468 if ((head
->ch_cnflags
& RTC_HDR_UPM
) == 0) {
469 if (head
->ch_cnflags
& RTC_HDR_64
)
470 str
= conv_config_upm(str
,
471 MSG_ORIG(MSG_PTH_OLDDLP_64
),
472 MSG_ORIG(MSG_PTH_UPDLP_64
),
473 MSG_PTH_UPDLP_64_SIZE
);
475 str
= conv_config_upm(str
,
476 MSG_ORIG(MSG_PTH_OLDDLP
),
477 MSG_ORIG(MSG_PTH_UPDLP
),
481 if (addlib(crle
, &crle
->c_edlibpath
, str
) != 0)
482 return (INSCFG_RET_FAIL
);
484 (void) printf(MSG_INTL(MSG_DMP_DLIBPTH
),
485 MSG_ORIG(MSG_STR_ELF
), str
);
487 (void) snprintf(_cmd
, PATH_MAX
,
488 MSG_ORIG(MSG_CMD_EDLIB
), str
);
490 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
491 return (INSCFG_RET_FAIL
);
494 if (crle
->c_flags
& CRLE_UPDATE
) {
495 if (crle
->c_flags
& CRLE_EDLIB
) {
497 * If we've been asked to update a configuration
498 * file, and no existing default ELF search
499 * path exists, but the user is going to add new
500 * entries, fabricate the system defaults so
501 * that the users get added to them.
503 if (fablib(crle
, CRLE_EDLIB
) != 0)
504 return (INSCFG_RET_FAIL
);
508 * Indicate any system default.
510 #if M_CLASS == ELFCLASS64
511 #ifndef SGS_PRE_UNIFIED_PROCESS
512 (void) printf(MSG_INTL(MSG_DEF_NEWDLP_64
));
514 (void) printf(MSG_INTL(MSG_DEF_OLDDLP_64
));
517 #ifndef SGS_PRE_UNIFIED_PROCESS
518 (void) printf(MSG_INTL(MSG_DEF_NEWDLP
));
520 (void) printf(MSG_INTL(MSG_DEF_OLDDLP
));
526 if (head
->ch_eslibpath
) {
529 str
= (const char *)(head
->ch_eslibpath
+ addr
);
531 if (crle
->c_flags
& CRLE_UPDATE
) {
532 crle
->c_flags
&= ~CRLE_AOUT
;
534 #ifndef SGS_PRE_UNIFIED_PROCESS
535 if ((head
->ch_cnflags
& RTC_HDR_UPM
) == 0) {
536 if (head
->ch_cnflags
& RTC_HDR_64
)
537 str
= conv_config_upm(str
,
538 MSG_ORIG(MSG_PTH_OLDTD_64
),
539 MSG_ORIG(MSG_PTH_UPTD_64
),
540 MSG_PTH_UPTD_64_SIZE
);
542 str
= conv_config_upm(str
,
543 MSG_ORIG(MSG_PTH_OLDTD
),
544 MSG_ORIG(MSG_PTH_UPTD
),
548 if (addlib(crle
, &crle
->c_eslibpath
, str
) != 0)
549 return (INSCFG_RET_FAIL
);
551 (void) printf(MSG_INTL(MSG_DMP_TLIBPTH
),
552 MSG_ORIG(MSG_STR_ELF
), str
);
554 (void) snprintf(_cmd
, PATH_MAX
,
555 MSG_ORIG(MSG_CMD_ESLIB
), str
);
557 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
558 return (INSCFG_RET_FAIL
);
561 if (crle
->c_flags
& CRLE_UPDATE
) {
562 if (crle
->c_flags
& CRLE_ESLIB
) {
564 * If we've been asked to update a configuration
565 * file, and no existing default ELF secure
566 * path exists, but the user is going to add new
567 * entries, fabricate the system defaults so
568 * that the users get added to them.
570 if (fablib(crle
, CRLE_ESLIB
) != 0)
571 return (INSCFG_RET_FAIL
);
575 * Indicate any system default.
577 #if M_CLASS == ELFCLASS64
578 #ifndef SGS_PRE_UNIFIED_PROCESS
579 (void) printf(MSG_INTL(MSG_DEF_NEWTD_64
));
581 (void) printf(MSG_INTL(MSG_DEF_OLDTD_64
));
584 #ifndef SGS_PRE_UNIFIED_PROCESS
585 (void) printf(MSG_INTL(MSG_DEF_NEWTD
));
587 (void) printf(MSG_INTL(MSG_DEF_OLDTD
));
593 if (head
->ch_adlibpath
) {
596 str
= (const char *)(head
->ch_adlibpath
+ addr
);
598 if (crle
->c_flags
& CRLE_UPDATE
) {
599 crle
->c_flags
|= CRLE_AOUT
;
600 if (addlib(crle
, &crle
->c_adlibpath
, str
) != 0)
601 return (INSCFG_RET_FAIL
);
603 (void) printf(MSG_INTL(MSG_DMP_DLIBPTH
),
604 MSG_ORIG(MSG_STR_AOUT
), str
);
606 (void) snprintf(_cmd
, PATH_MAX
,
607 MSG_ORIG(MSG_CMD_ADLIB
), str
);
609 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
610 return (INSCFG_RET_FAIL
);
613 if (crle
->c_flags
& CRLE_UPDATE
) {
614 if (crle
->c_flags
& CRLE_ADLIB
) {
616 * If we've been asked to update a configuration
617 * file, and no existing default AOUT search
618 * path exists, but the user is going to add new
619 * entries, fabricate the system defaults so
620 * that the users get added to them.
622 if (fablib(crle
, CRLE_ADLIB
) != 0)
623 return (INSCFG_RET_FAIL
);
625 } else if (crle
->c_flags
& CRLE_AOUT
) {
627 * Indicate any system default.
629 (void) printf(MSG_INTL(MSG_DEF_AOUTDLP
));
633 if (head
->ch_aslibpath
) {
636 str
= (const char *)(head
->ch_aslibpath
+ addr
);
638 if (crle
->c_flags
& CRLE_UPDATE
) {
639 crle
->c_flags
|= CRLE_AOUT
;
640 if (addlib(crle
, &crle
->c_aslibpath
, str
) != 0)
641 return (INSCFG_RET_FAIL
);
643 (void) printf(MSG_INTL(MSG_DMP_TLIBPTH
),
644 MSG_ORIG(MSG_STR_AOUT
), str
);
646 (void) snprintf(_cmd
, PATH_MAX
,
647 MSG_ORIG(MSG_CMD_ASLIB
), str
);
649 if (aplist_append(&cmdline
, cmd
, AL_CNT_CRLE
) == NULL
)
650 return (INSCFG_RET_FAIL
);
653 if (crle
->c_flags
& CRLE_UPDATE
) {
654 if (crle
->c_flags
& CRLE_ASLIB
) {
656 * If we've been asked to update a configuration
657 * file, and no existing default AOUT secure
658 * path exists, but the user is going to add new
659 * entries, fabricate the system defaults so
660 * that the users get added to them.
662 if (fablib(crle
, CRLE_ASLIB
) != 0)
663 return (INSCFG_RET_FAIL
);
665 } else if (crle
->c_flags
& CRLE_AOUT
) {
667 * Indicate any system default.
669 #ifndef SGS_PRE_UNIFIED_PROCESS
670 (void) printf(MSG_INTL(MSG_DEF_AOUTNEWTD
));
672 (void) printf(MSG_INTL(MSG_DEF_AOUTOLDTD
));
678 * Display any environment variables.
680 if ((head
->ch_version
>= RTC_VER_THREE
) && head
->ch_env
) {
683 if ((crle
->c_flags
& CRLE_UPDATE
) == 0)
684 (void) printf(MSG_INTL(MSG_ENV_TITLE
));
686 for (envtbl
= (Rtc_env
*)(head
->ch_env
+ addr
);
687 envtbl
->env_str
; envtbl
++) {
690 str
= (const char *)(envtbl
->env_str
+ addr
);
692 if (crle
->c_flags
& CRLE_UPDATE
) {
693 if (addenv(crle
, str
,
694 (envtbl
->env_flags
| RTC_ENV_CONFIG
)) == 0)
695 return (INSCFG_RET_FAIL
);
697 const char *pfmt
, *sfmt
;
699 if (envtbl
->env_flags
& RTC_ENV_PERMANT
) {
700 pfmt
= MSG_INTL(MSG_ENV_PRM
);
701 sfmt
= MSG_ORIG(MSG_CMD_PRMENV
);
703 pfmt
= MSG_INTL(MSG_ENV_RPL
);
704 sfmt
= MSG_ORIG(MSG_CMD_RPLENV
);
706 (void) printf(pfmt
, str
);
707 (void) snprintf(_cmd
, PATH_MAX
, sfmt
, str
);
709 if (aplist_append(&cmdline
, cmd
,
710 AL_CNT_CRLE
) == NULL
)
711 return (INSCFG_RET_FAIL
);
717 * Display any filter/filtee associations.
719 if ((head
->ch_version
>= RTC_VER_FOUR
) && head
->ch_fltr
) {
720 if ((crle
->c_flags
& CRLE_UPDATE
) == 0) {
725 fltrtbl
= (Rtc_fltr
*)
726 (CAST_PTRINT(char *, head
->ch_fltr
) + addr
);
728 fltetbl
= (Rtc_flte
*)
729 (CAST_PTRINT(char *, head
->ch_flte
) + addr
);
731 (void) printf(MSG_INTL(MSG_FLT_TITLE
));
733 while (fltrtbl
->fr_filter
) {
737 * Print the filter and filtee string pair.
739 (void) printf(MSG_INTL(MSG_FLT_FILTER
),
740 (strtbl
+ fltrtbl
->fr_filter
),
741 (strtbl
+ fltrtbl
->fr_string
));
747 for (_fltetbl
= (Rtc_flte
*)((char *)fltetbl
+
748 fltrtbl
->fr_filtee
); _fltetbl
->fe_filtee
;
750 (void) printf(MSG_INTL(MSG_FLT_FILTEE
),
751 (strtbl
+ _fltetbl
->fe_filtee
));
759 * Display any memory reservations required for any alternative
762 if (head
->ch_resbgn
&& ((crle
->c_flags
& CRLE_UPDATE
) == 0))
763 (void) printf(MSG_INTL(MSG_DMP_RESV
),
764 (u_longlong_t
)head
->ch_resbgn
,
765 (u_longlong_t
)head
->ch_resend
,
766 (u_longlong_t
)(head
->ch_resend
- head
->ch_resbgn
));
769 * If there's no hash table there's nothing else to process.
771 if (head
->ch_hash
== 0) {
772 if ((crle
->c_flags
& CRLE_UPDATE
) == 0)
773 printcmd(crle
, head
, cmdline
);
774 return (INSCFG_RET_OK
);
778 * Traverse the directory and filename arrays.
780 for (dirtbl
= (Rtc_dir
*)(head
->ch_dir
+ addr
);
781 dirtbl
->cd_obj
; dirtbl
++) {
786 dobj
= (Rtc_obj
*)(dirtbl
->cd_obj
+ addr
);
787 filetbl
= (Rtc_file
*)(dirtbl
->cd_file
+ addr
);
788 str
= strtbl
+ dobj
->co_name
;
791 * Simplify recreation by using any command-line directories.
792 * If we're dealing with a version 1 configuration file use
795 if ((dobj
->co_flags
& RTC_OBJ_CMDLINE
) ||
796 (head
->ch_version
== RTC_VER_ONE
)) {
797 if (crle
->c_flags
& CRLE_UPDATE
) {
798 if (inspect(crle
, str
,
799 getflags(dobj
->co_flags
)) != 0)
800 return (INSCFG_RET_FAIL
);
801 if ((dobj
->co_flags
&
802 (RTC_OBJ_NOEXIST
| RTC_OBJ_ALTER
)) ==
807 (void) snprintf(_cmd
, PATH_MAX
,
808 getformat(dobj
->co_flags
), str
);
810 if (aplist_append(&cmdline
, cmd
,
811 AL_CNT_CRLE
) == NULL
)
812 return (INSCFG_RET_FAIL
);
817 * If this isn't an update print the directory name. If the
818 * directory has no entries (possible if the directory is a
819 * symlink to another directory, in which case we record the
820 * real path also), don't bother printing it unless we're in
823 if ((crle
->c_flags
& CRLE_UPDATE
) == 0) {
824 if ((dobj
->co_flags
&
825 (RTC_OBJ_NOEXIST
| RTC_OBJ_ALTER
)) ==
827 (void) printf(MSG_INTL(MSG_DMP_DIR_2
), str
);
829 } else if (filetbl
->cf_obj
||
830 (crle
->c_flags
& CRLE_VERBOSE
))
831 (void) printf(MSG_INTL(MSG_DMP_DIR_1
), str
);
835 * Under verbose mode validate any real directory entry - the
836 * same test will be carried out by ld.so.1.
838 if (((crle
->c_flags
& CRLE_UPDATE
) == 0) &&
839 (crle
->c_flags
& CRLE_VERBOSE
) &&
840 (dobj
->co_flags
& RTC_OBJ_REALPTH
)) {
841 if (stat(str
, &status
) != 0) {
843 (void) printf(MSG_INTL(MSG_DMP_STAT
), str
,
845 } else if (status
.st_mtime
!= dobj
->co_info
) {
846 (void) printf(MSG_INTL(MSG_DMP_DCMP
), str
);
850 for (; filetbl
->cf_obj
; filetbl
++) {
854 fobj
= (Rtc_obj
*)(filetbl
->cf_obj
+ addr
);
855 str
= strtbl
+ fobj
->co_name
;
856 flags
= fobj
->co_flags
;
859 * Only update individual files that were originally
860 * specified on the command-line. Or, if this is a
861 * version 1 configuration file use every file that
862 * isn't part of an all-entries directory.
864 if (((flags
& RTC_OBJ_CMDLINE
) &&
865 ((fobj
->co_flags
& RTC_OBJ_APP
) == 0)) ||
866 ((head
->ch_version
== RTC_VER_ONE
) &&
867 ((dobj
->co_flags
& RTC_OBJ_ALLENTS
) == 0))) {
868 char *alter
= NULL
, altdir
[PATH_MAX
];
871 * Determine whether this file requires an
872 * alternative, and if so, and we haven't
873 * already an alternative in affect, create one.
875 if (fobj
->co_flags
& RTC_OBJ_ALTER
) {
876 alter
= (char *)(strtbl
+
878 (void) strcpy(altdir
, alter
);
879 alter
= strrchr(altdir
, '/');
882 if ((objdir
== NULL
) ||
883 (strcmp(objdir
, altdir
) != 0)) {
884 (void) strcpy(_objdir
, altdir
);
885 crle
->c_objdir
= alter
=
891 if (crle
->c_flags
& CRLE_UPDATE
) {
892 if (inspect(crle
, str
,
893 getflags(flags
)) != 0)
894 return (INSCFG_RET_FAIL
);
899 (void) snprintf(_cmd
, PATH_MAX
,
900 MSG_ORIG(MSG_CMD_OUTPUT
),
903 if (aplist_append(&cmdline
, cmd
,
904 AL_CNT_CRLE
) == NULL
)
905 return (INSCFG_RET_FAIL
);
909 (void) snprintf(_cmd
, PATH_MAX
,
910 getformat(flags
), str
);
912 if (aplist_append(&cmdline
, cmd
,
913 AL_CNT_CRLE
) == NULL
)
914 return (INSCFG_RET_FAIL
);
917 if (crle
->c_flags
& CRLE_UPDATE
)
921 * Although we record both full pathnames and their
922 * simple filenames (basename), only print the simple
923 * names unless we're under verbose mode.
925 if ((strchr(str
, '/') == 0) ||
926 (crle
->c_flags
& CRLE_VERBOSE
)) {
927 if (fobj
->co_flags
& RTC_OBJ_ALTER
)
928 (void) printf(MSG_INTL(MSG_DMP_FILE_2
),
929 str
, (strtbl
+ fobj
->co_alter
));
931 (void) printf(MSG_INTL(MSG_DMP_FILE_1
),
936 * Under verbose mode validate any real file entry - the
937 * same test will be carried out by ld.so.1.
939 if ((crle
->c_flags
& CRLE_VERBOSE
) &&
940 (fobj
->co_flags
& RTC_OBJ_REALPTH
)) {
941 if (stat(str
, &status
) != 0) {
943 (void) printf(MSG_INTL(MSG_DMP_STAT
),
945 } else if (status
.st_size
!= fobj
->co_info
) {
946 (void) printf(MSG_INTL(MSG_DMP_FCMP
),
953 if ((crle
->c_flags
& CRLE_UPDATE
) == 0)
954 printcmd(crle
, head
, cmdline
);
956 if ((crle
->c_flags
& CRLE_VERBOSE
) == 0)
957 return (INSCFG_RET_OK
);
960 * If we've in verbose mode scan the hash list.
963 hash
= (Word
*)(CAST_PTRINT(char *, head
->ch_hash
) + addr
);
965 chain
= &hash
[2 + bkts
];
968 (void) printf(MSG_INTL(MSG_DMP_HASH
));
971 * Scan the hash buckets looking for valid entries.
973 for (ndx
= 0; ndx
< bkts
; ndx
++, hash
++) {
974 Conv_config_obj_buf_t config_obj_buf
;
982 obj
= objtbl
+ *hash
;
983 str
= strtbl
+ obj
->co_name
;
985 (void) printf(MSG_INTL(MSG_DMP_HASHENT_1
), obj
->co_id
, ndx
,
986 str
, conv_config_obj(obj
->co_flags
, &config_obj_buf
));
989 * Determine whether there are other objects chained to this
992 for (_ndx
= chain
[*hash
]; _ndx
; _ndx
= chain
[_ndx
]) {
994 str
= strtbl
+ obj
->co_name
;
996 (void) printf(MSG_INTL(MSG_DMP_HASHENT_2
), obj
->co_id
,
997 str
, conv_config_obj(obj
->co_flags
,
1001 (void) printf(MSG_ORIG(MSG_STR_NL
));
1003 return (INSCFG_RET_OK
);
1008 inspectconfig(Crle_desc
* crle
, int c_class
)
1014 const char *caller
= crle
->c_name
, *file
= crle
->c_confil
;
1015 Conv_inv_buf_t inv_buf1
, inv_buf2
, inv_buf3
;
1018 * Open the configuration file, determine its size and map it in.
1020 if ((fd
= open(file
, O_RDONLY
, 0)) == -1) {
1023 if (err
== ENOENT
) {
1025 /* Must restart if user requested a 64-bit file */
1026 if (c_class
== ELFCLASS64
)
1027 return (INSCFG_RET_NEED64
);
1031 * To allow an update (-u) from scratch, fabricate any
1032 * default search and secure paths that the user
1033 * intends to add to.
1035 if (crle
->c_flags
& CRLE_UPDATE
) {
1036 if (crle
->c_flags
& CRLE_EDLIB
) {
1037 if (fablib(crle
, CRLE_EDLIB
))
1038 return (INSCFG_RET_FAIL
);
1040 if (crle
->c_flags
& CRLE_ESLIB
) {
1041 if (fablib(crle
, CRLE_ESLIB
))
1042 return (INSCFG_RET_FAIL
);
1044 if (crle
->c_flags
& CRLE_ADLIB
) {
1045 if (fablib(crle
, CRLE_ADLIB
))
1046 return (INSCFG_RET_FAIL
);
1048 if (crle
->c_flags
& CRLE_ASLIB
) {
1049 if (fablib(crle
, CRLE_ASLIB
))
1050 return (INSCFG_RET_FAIL
);
1052 return (INSCFG_RET_OK
);
1054 } else if (crle
->c_flags
& CRLE_CONFDEF
) {
1055 const char *fmt1
, *fmt2
;
1058 * Otherwise if the user is inspecting a default
1059 * configuration file that doesn't exist inform
1060 * them and display the ELF defaults.
1062 (void) printf(MSG_INTL(MSG_DEF_NOCONF
), file
);
1063 (void) printf(MSG_INTL(MSG_DMP_PLATFORM
),
1064 conv_ehdr_class(M_CLASS
,
1065 CONV_FMT_ALT_FILE
, &inv_buf1
),
1066 conv_ehdr_data(M_DATA
,
1067 CONV_FMT_ALT_FILE
, &inv_buf2
),
1068 conv_ehdr_mach(M_MACH
,
1069 CONV_FMT_ALT_FILE
, &inv_buf3
));
1072 if (crle
->c_flags
& CRLE_AOUT
) {
1073 fmt1
= MSG_INTL(MSG_DEF_AOUTDLP
);
1074 #ifndef SGS_PRE_UNIFIED_PROCESS
1075 fmt2
= MSG_INTL(MSG_DEF_AOUTNEWTD
);
1077 fmt2
= MSG_INTL(MSG_DEF_AOUTOLDTD
);
1080 #if M_CLASS == ELFCLASS64
1081 #ifndef SGS_PRE_UNIFIED_PROCESS
1082 fmt1
= MSG_INTL(MSG_DEF_NEWDLP_64
);
1083 fmt2
= MSG_INTL(MSG_DEF_NEWTD_64
);
1085 fmt1
= MSG_INTL(MSG_DEF_OLDDLP_64
);
1086 fmt2
= MSG_INTL(MSG_DEF_OLDTD_64
);
1089 #ifndef SGS_PRE_UNIFIED_PROCESS
1090 fmt1
= MSG_INTL(MSG_DEF_NEWDLP
);
1091 fmt2
= MSG_INTL(MSG_DEF_NEWTD
);
1093 fmt1
= MSG_INTL(MSG_DEF_OLDDLP
);
1094 fmt2
= MSG_INTL(MSG_DEF_OLDTD
);
1098 (void) printf(fmt1
);
1099 (void) printf(fmt2
);
1101 return (INSCFG_RET_OK
);
1106 * Otherwise there's an error condition in accessing the file.
1108 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_OPEN
), caller
, file
,
1111 return (INSCFG_RET_FAIL
);
1114 (void) fstat(fd
, &status
);
1115 if (status
.st_size
< sizeof (Rtc_head
)) {
1117 (void) fprintf(stderr
, MSG_INTL(MSG_COR_TRUNC
), caller
, file
);
1118 return (INSCFG_RET_FAIL
);
1120 if ((addr
= (Addr
)mmap(NULL
, status
.st_size
, PROT_READ
, MAP_SHARED
,
1121 fd
, 0)) == (Addr
)MAP_FAILED
) {
1123 (void) fprintf(stderr
, MSG_INTL(MSG_SYS_MMAP
), caller
, file
,
1126 return (INSCFG_RET_FAIL
);
1131 * Print the contents of the configuration file.
1133 error
= scanconfig(crle
, addr
, c_class
);
1135 (void) munmap((void *)addr
, status
.st_size
);