xref: /titanic_44/usr/src/cmd/sgs/crle/common/crle.c (revision 57ef7aa924e4bfdf3118d9b5b4285dfc94b632f3)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5c13de8f6Sab196087  * Common Development and Distribution License (the "License").
6c13de8f6Sab196087  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*57ef7aa9SRod Evans  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include	<sys/types.h>
277c478bd9Sstevel@tonic-gate #include	<sys/stat.h>
287c478bd9Sstevel@tonic-gate #include	<fcntl.h>
297c478bd9Sstevel@tonic-gate #include	<stdio.h>
307c478bd9Sstevel@tonic-gate #include	<string.h>
317c478bd9Sstevel@tonic-gate #include	<unistd.h>
327c478bd9Sstevel@tonic-gate #include	<locale.h>
337c478bd9Sstevel@tonic-gate #include	<dlfcn.h>
347c478bd9Sstevel@tonic-gate #include	<errno.h>
357c478bd9Sstevel@tonic-gate #include	"_crle.h"
36c13de8f6Sab196087 #include	"conv.h"
377c478bd9Sstevel@tonic-gate #include	"msg.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * crle(1) entry point and argument processing.
427c478bd9Sstevel@tonic-gate  *
437c478bd9Sstevel@tonic-gate  * Two passes of the arguments are carried out; the first collects any single
447c478bd9Sstevel@tonic-gate  * instance options and establishes defaults that might be appropriate for
457c478bd9Sstevel@tonic-gate  * other arguments:
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  *  -64		operate on, or apply, 64-bit objects (default is 32-bit).
487c478bd9Sstevel@tonic-gate  *
497c478bd9Sstevel@tonic-gate  *  -c file	defines the output configuration file.
507c478bd9Sstevel@tonic-gate  *
517c478bd9Sstevel@tonic-gate  *  -f flag	flags for dldump(3dl).
527c478bd9Sstevel@tonic-gate  *
537c478bd9Sstevel@tonic-gate  *  -o dir	defines the output directory for any dldump(3dl) objects
547c478bd9Sstevel@tonic-gate  *		that follow.  For backward compatibility (RTC_VER_ONE only
557c478bd9Sstevel@tonic-gate  * 		allowed one output directory) allow the first occurrence of this
567c478bd9Sstevel@tonic-gate  *		specification to catch any previous files.  If not specified,
577c478bd9Sstevel@tonic-gate  *		the configuration files parent directory is used).
587c478bd9Sstevel@tonic-gate  *
597c478bd9Sstevel@tonic-gate  *  -u		update any existing configuration file.  Any additional
607c478bd9Sstevel@tonic-gate  *		arguments supplied will be added to the new configuration
617c478bd9Sstevel@tonic-gate  *		information.
627c478bd9Sstevel@tonic-gate  *
637c478bd9Sstevel@tonic-gate  *  -v		verbose mode.
647c478bd9Sstevel@tonic-gate  *
657c478bd9Sstevel@tonic-gate  * The second pass collects all other options and constructs an internal
667c478bd9Sstevel@tonic-gate  * string table which will be used to create the eventual configuration file.
677c478bd9Sstevel@tonic-gate  *
687c478bd9Sstevel@tonic-gate  *  -a name	add the individual name, with an alternative to the
697c478bd9Sstevel@tonic-gate  *		configuration cache.  No alternative is created via dldump(3dl),
707c478bd9Sstevel@tonic-gate  *		it is the users responsibility to furnish the alternative.
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  *  -A name	add the individual name, with an optional alternative to the
737c478bd9Sstevel@tonic-gate  *		configuration cache.  No alternative is created via dldump(3dl),
747c478bd9Sstevel@tonic-gate  *		it is the users responsibility to furnish the alternative.
757c478bd9Sstevel@tonic-gate  *
767c478bd9Sstevel@tonic-gate  *  -e envar	replaceable environment variable
777c478bd9Sstevel@tonic-gate  *
787c478bd9Sstevel@tonic-gate  *  -E envar	permanent environment variable
797c478bd9Sstevel@tonic-gate  *
807c478bd9Sstevel@tonic-gate  *  -i name	add the individual name to the configuration cache.  If name
817c478bd9Sstevel@tonic-gate  *		is a directory each shared object within the directory is added
827c478bd9Sstevel@tonic-gate  *		to the cache.
837c478bd9Sstevel@tonic-gate  *
847c478bd9Sstevel@tonic-gate  *  -I name	same as -i, but in addition any ELF objects are dldump(3dl)'ed.
857c478bd9Sstevel@tonic-gate  *
867c478bd9Sstevel@tonic-gate  *  -g name	add the group name to the configuration cache.  Each object is
877c478bd9Sstevel@tonic-gate  * 		expanded to determine its dependencies and these are added to
887c478bd9Sstevel@tonic-gate  *		the cache.  If name is a directory each shared object within the
897c478bd9Sstevel@tonic-gate  *		directory and its dependencies are added to the cache.
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  *  -G app	same as -g, but in addition any ELF objects are dldump(3dl)'ed.
927c478bd9Sstevel@tonic-gate  *
937c478bd9Sstevel@tonic-gate  *  -l dir	library search directory
947c478bd9Sstevel@tonic-gate  *
957c478bd9Sstevel@tonic-gate  *  -s dir	trusted (secure) directory
967c478bd9Sstevel@tonic-gate  *
977c478bd9Sstevel@tonic-gate  *  -t type	search directory type (ELF or AOUT).
987c478bd9Sstevel@tonic-gate  */
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /*
1017c478bd9Sstevel@tonic-gate  * Establish a structure for maintaining current object directory attributes.
1027c478bd9Sstevel@tonic-gate  * We wish to validate the access of any object directory that will be written
1037c478bd9Sstevel@tonic-gate  * to (dldump(3dl), and thus by maintaining a current object directory and its
1047c478bd9Sstevel@tonic-gate  * intended use we can perform this validation later.
1057c478bd9Sstevel@tonic-gate  */
1067c478bd9Sstevel@tonic-gate typedef struct {
1077c478bd9Sstevel@tonic-gate 	char	*o_objdir;
108*57ef7aa9SRod Evans 	uint_t	o_flags;
1097c478bd9Sstevel@tonic-gate } Objdir;
1107c478bd9Sstevel@tonic-gate 
111587032cfSab196087 /*ARGSUSED2*/
112b3fbe5e6Sseizo int
main(int argc,char ** argv,char ** envp)113c13de8f6Sab196087 main(int argc, char **argv, char **envp)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate 	Crle_desc	crle = { 0 };
1167c478bd9Sstevel@tonic-gate 	int		c, error = 0;
1177c478bd9Sstevel@tonic-gate 	char		**lib;
118*57ef7aa9SRod Evans 	Alist		*objdirs = NULL;
119*57ef7aa9SRod Evans 	Objdir		*objdir, *iobjdir;
1207c478bd9Sstevel@tonic-gate 	struct stat	ostatus, nstatus;
121c13de8f6Sab196087 	int 		c_class;
1227c478bd9Sstevel@tonic-gate 
123*57ef7aa9SRod Evans 	if ((objdir = iobjdir = alist_append(&objdirs, NULL, sizeof (Objdir),
124*57ef7aa9SRod Evans 	    AL_CNT_CRLE)) == NULL)
1257c478bd9Sstevel@tonic-gate 		return (1);
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate 	/*
1287c478bd9Sstevel@tonic-gate 	 * Establish locale.
1297c478bd9Sstevel@tonic-gate 	 */
1307c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_MESSAGES, MSG_ORIG(MSG_STR_EMPTY));
1317c478bd9Sstevel@tonic-gate 	(void) textdomain(MSG_ORIG(MSG_SUNW_OST_SGS));
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	/*
1347c478bd9Sstevel@tonic-gate 	 * Initialization configuration information.
1357c478bd9Sstevel@tonic-gate 	 */
1367c478bd9Sstevel@tonic-gate 	crle.c_name = argv[0];
137c13de8f6Sab196087 	crle.c_flags |= CRLE_ADDID;
1387c478bd9Sstevel@tonic-gate 	crle.c_strbkts = 503;
1397c478bd9Sstevel@tonic-gate 	crle.c_inobkts = 251;
140c13de8f6Sab196087 	c_class = M_CLASS;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	/*
1437c478bd9Sstevel@tonic-gate 	 * First argument pass.
1447c478bd9Sstevel@tonic-gate 	 */
1457c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, MSG_ORIG(MSG_ARG_OPTIONS))) != -1) {
1467c478bd9Sstevel@tonic-gate 		switch (c) {
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 		case '6':			/* operate on 64-bit objects */
1497c478bd9Sstevel@tonic-gate 			if (optarg[0] != '4') {
1507c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
1517c478bd9Sstevel@tonic-gate 				    MSG_INTL(MSG_ARG_ILLEGAL), crle.c_name,
1527c478bd9Sstevel@tonic-gate 				    MSG_ORIG(MSG_ARG_6), optarg);
1537c478bd9Sstevel@tonic-gate 				error = 1;
1547c478bd9Sstevel@tonic-gate 			}
155c13de8f6Sab196087 
156c13de8f6Sab196087 			c_class = ELFCLASS64;
1577c478bd9Sstevel@tonic-gate 			break;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 		case 'A':			/* create optional */
1607c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */	/*	alternative */
1617c478bd9Sstevel@tonic-gate 		case 'a':			/* create alternative */
1627c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_CREAT | CRLE_ALTER);
163*57ef7aa9SRod Evans 			objdir->o_flags |= (CRLE_CREAT | CRLE_ALTER);
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate 		case 'c':			/* define the config file */
1677c478bd9Sstevel@tonic-gate 			if (crle.c_confil) {
1687c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, MSG_INTL(MSG_ARG_MULT),
1697c478bd9Sstevel@tonic-gate 				    crle.c_name, MSG_ORIG(MSG_ARG_C));
1707c478bd9Sstevel@tonic-gate 				error = 1;
1717c478bd9Sstevel@tonic-gate 			}
1727c478bd9Sstevel@tonic-gate 			crle.c_confil = optarg;
1737c478bd9Sstevel@tonic-gate 			break;
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate 		case 'e':			/* replaceable env variable */
1767c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_RPLENV | CRLE_CREAT);
1777c478bd9Sstevel@tonic-gate 			break;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 		case 'E':			/* permanent env variable */
1807c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_PRMENV | CRLE_CREAT);
1817c478bd9Sstevel@tonic-gate 			break;
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate 		case 'f':			/* dldump(3dl) flags */
1847c478bd9Sstevel@tonic-gate 			if (crle.c_dlflags) {
1857c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, MSG_INTL(MSG_ARG_MULT),
1867c478bd9Sstevel@tonic-gate 				    crle.c_name, MSG_ORIG(MSG_ARG_F));
1877c478bd9Sstevel@tonic-gate 				error = 1;
1887c478bd9Sstevel@tonic-gate 			}
1897c478bd9Sstevel@tonic-gate 			if ((crle.c_dlflags = dlflags(&crle,
1907c478bd9Sstevel@tonic-gate 			    (const char *)optarg)) == 0)
1917c478bd9Sstevel@tonic-gate 				error = 1;
1927c478bd9Sstevel@tonic-gate 			break;
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 		case 'G':			/* group object */
1957c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_DUMP | CRLE_ALTER);
196*57ef7aa9SRod Evans 			objdir->o_flags |= (CRLE_DUMP | CRLE_ALTER);
1977c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
1987c478bd9Sstevel@tonic-gate 		case 'g':
1997c478bd9Sstevel@tonic-gate 			crle.c_flags |= CRLE_CREAT;
200*57ef7aa9SRod Evans 			objdir->o_flags |= CRLE_CREAT;
2017c478bd9Sstevel@tonic-gate 			break;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 		case 'I':			/* individual object */
2047c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_DUMP | CRLE_ALTER);
205*57ef7aa9SRod Evans 			objdir->o_flags |= (CRLE_DUMP | CRLE_ALTER);
2067c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
2077c478bd9Sstevel@tonic-gate 		case 'i':
2087c478bd9Sstevel@tonic-gate 			crle.c_flags |= CRLE_CREAT;
209*57ef7aa9SRod Evans 			objdir->o_flags |= CRLE_CREAT;
2107c478bd9Sstevel@tonic-gate 			break;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 		case 'l':			/* library search path */
2137c478bd9Sstevel@tonic-gate 			if (crle.c_flags & CRLE_AOUT)
2147c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_ADLIB;
2157c478bd9Sstevel@tonic-gate 			else
2167c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_EDLIB;
2177c478bd9Sstevel@tonic-gate 			crle.c_flags |= CRLE_CREAT;
2187c478bd9Sstevel@tonic-gate 			break;
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 		case 'o':			/* define an object directory */
221*57ef7aa9SRod Evans 			if (objdir->o_objdir) {
222*57ef7aa9SRod Evans 				if ((objdir = alist_append(&objdirs, NULL,
223*57ef7aa9SRod Evans 				    sizeof (Objdir), AL_CNT_CRLE)) == NULL)
2247c478bd9Sstevel@tonic-gate 					return (1);
2257c478bd9Sstevel@tonic-gate 			}
226*57ef7aa9SRod Evans 			objdir->o_objdir = optarg;
2277c478bd9Sstevel@tonic-gate 			break;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 		case 's':			/* trusted (secure) path */
2307c478bd9Sstevel@tonic-gate 			if (crle.c_flags & CRLE_AOUT)
2317c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_ASLIB;
2327c478bd9Sstevel@tonic-gate 			else
2337c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_ESLIB;
2347c478bd9Sstevel@tonic-gate 			crle.c_flags |= CRLE_CREAT;
2357c478bd9Sstevel@tonic-gate 			break;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 		case 't':			/* search path type */
2387c478bd9Sstevel@tonic-gate 			if (strcmp((const char *)optarg,
2397c478bd9Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF)) == 0)
2407c478bd9Sstevel@tonic-gate 				crle.c_flags &= ~CRLE_AOUT;
2417c478bd9Sstevel@tonic-gate 			else if (strcmp((const char *)optarg,
2427c478bd9Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_AOUT)) == 0)
2437c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_AOUT;
2447c478bd9Sstevel@tonic-gate 			else {
2457c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, MSG_INTL(MSG_ARG_TYPE),
2467c478bd9Sstevel@tonic-gate 				    crle.c_name, optarg);
2477c478bd9Sstevel@tonic-gate 				error = 1;
2487c478bd9Sstevel@tonic-gate 			}
2497c478bd9Sstevel@tonic-gate 			break;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 		case 'u':			/* update mode */
2527c478bd9Sstevel@tonic-gate 			crle.c_flags |= (CRLE_CREAT | CRLE_UPDATE);
2537c478bd9Sstevel@tonic-gate 			break;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 		case 'v':			/* verbose mode */
2567c478bd9Sstevel@tonic-gate 			crle.c_flags |= CRLE_VERBOSE;
2577c478bd9Sstevel@tonic-gate 			break;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 		default:
2607c478bd9Sstevel@tonic-gate 			error = 2;
2617c478bd9Sstevel@tonic-gate 		}
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	if (optind != argc)
2657c478bd9Sstevel@tonic-gate 		error = 2;
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	/*
2687c478bd9Sstevel@tonic-gate 	 * Determine the configuration file, which in the case of an existing
2697c478bd9Sstevel@tonic-gate 	 * error condition is required in the final error message.
2707c478bd9Sstevel@tonic-gate 	 */
271*57ef7aa9SRod Evans 	if (crle.c_confil == NULL) {
2727c478bd9Sstevel@tonic-gate 		crle.c_flags |= CRLE_CONFDEF;
273c13de8f6Sab196087 		if (c_class == ELFCLASS32) {
2747c478bd9Sstevel@tonic-gate 			crle.c_confil = (char *)MSG_ORIG(MSG_PTH_CONFIG);
275c13de8f6Sab196087 		} else {
2767c478bd9Sstevel@tonic-gate 			crle.c_confil = (char *)MSG_ORIG(MSG_PTH_CONFIG_64);
2777c478bd9Sstevel@tonic-gate 		}
278c13de8f6Sab196087 	}
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	/*
2817c478bd9Sstevel@tonic-gate 	 * Now that we've generated as many file/directory processing errors
2827c478bd9Sstevel@tonic-gate 	 * as we can, return if any fatal error conditions occurred.
2837c478bd9Sstevel@tonic-gate 	 */
2847c478bd9Sstevel@tonic-gate 	if (error) {
2857c478bd9Sstevel@tonic-gate 		if (error == 2) {
2867c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_ARG_USAGE),
2877c478bd9Sstevel@tonic-gate 			    crle.c_name);
2887c478bd9Sstevel@tonic-gate 		} else if (crle.c_flags & CRLE_CREAT) {
2897c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_GEN_CREATE),
2907c478bd9Sstevel@tonic-gate 			    crle.c_name, crle.c_confil);
2917c478bd9Sstevel@tonic-gate 		}
2927c478bd9Sstevel@tonic-gate 		return (1);
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	/*
2967c478bd9Sstevel@tonic-gate 	 * Apply any additional defaults.
2977c478bd9Sstevel@tonic-gate 	 */
2987c478bd9Sstevel@tonic-gate 	if (crle.c_dlflags == 0)
2997c478bd9Sstevel@tonic-gate 		crle.c_dlflags = RTLD_REL_RELATIVE;
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	crle.c_audit = (char *)MSG_ORIG(MSG_ENV_LD_AUDIT);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	(void) elf_version(EV_CURRENT);
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	/*
3067c478bd9Sstevel@tonic-gate 	 * If we're updating an existing file or not creating a configuration
3077c478bd9Sstevel@tonic-gate 	 * file at all, investigate the original.
3087c478bd9Sstevel@tonic-gate 	 */
3097c478bd9Sstevel@tonic-gate 	if ((crle.c_flags & CRLE_UPDATE) ||
3107c478bd9Sstevel@tonic-gate 	    ((crle.c_flags & CRLE_CREAT) == 0)) {
311587032cfSab196087 		switch (inspectconfig(&crle, c_class)) {
312c13de8f6Sab196087 		case INSCFG_RET_OK:
3137c478bd9Sstevel@tonic-gate 			if ((crle.c_flags & CRLE_UPDATE) == 0)
3147c478bd9Sstevel@tonic-gate 				return (0);
315c13de8f6Sab196087 			break;
316c13de8f6Sab196087 		case INSCFG_RET_FAIL:
317c13de8f6Sab196087 			return (1);
318c13de8f6Sab196087 		case INSCFG_RET_NEED64:
319c13de8f6Sab196087 			c_class = ELFCLASS64;
320c13de8f6Sab196087 			break;
3217c478bd9Sstevel@tonic-gate 		}
322c13de8f6Sab196087 	}
323c13de8f6Sab196087 
324c13de8f6Sab196087 	/*
325c13de8f6Sab196087 	 * Ensure that the right version (32 or 64-bit) of this program
326c13de8f6Sab196087 	 * is running. The 32 and 64-bit compilers may align fields within
327c13de8f6Sab196087 	 * structures differently. Using the right version of crle for
328c13de8f6Sab196087 	 * the config file ensures that all linker components will see
329c13de8f6Sab196087 	 * the same layout, without the need for special code.
330c13de8f6Sab196087 	 */
331c13de8f6Sab196087 #ifdef _ELF64
332c13de8f6Sab196087 	if (c_class == ELFCLASS32) {
333c13de8f6Sab196087 		(void) fprintf(stderr, MSG_INTL(MSG_ARG_CLASS),
334c13de8f6Sab196087 		    crle.c_name, crle.c_confil);
335c13de8f6Sab196087 		return (1);
336c13de8f6Sab196087 	}
337c13de8f6Sab196087 #else
338c13de8f6Sab196087 	if (c_class == ELFCLASS64) {
3397010c12aSrie 		(void) conv_check_native(argv, envp);
340c13de8f6Sab196087 
341c13de8f6Sab196087 		/*
342c13de8f6Sab196087 		 * conv_check_native() should not return, as we expect
343c13de8f6Sab196087 		 * the 64-bit version to have executed on top of us.
344c13de8f6Sab196087 		 * If it does, it means there is no 64-bit support
345c13de8f6Sab196087 		 * available on this system.
346c13de8f6Sab196087 		 */
347c13de8f6Sab196087 		(void) fprintf(stderr, MSG_INTL(MSG_ISA32_NO64SUP),
348c13de8f6Sab196087 		    crle.c_name);
349c13de8f6Sab196087 		return (1);
350c13de8f6Sab196087 	}
351c13de8f6Sab196087 #endif
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	if (crle.c_flags & CRLE_VERBOSE)
3547c478bd9Sstevel@tonic-gate 		(void) printf(MSG_INTL(MSG_DIA_CONFILE), crle.c_confil);
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 	/*
3577c478bd9Sstevel@tonic-gate 	 * Make sure the configuration file is accessible.  Stat the file to
3587c478bd9Sstevel@tonic-gate 	 * determine its dev number - this is used to determine whether the
3597c478bd9Sstevel@tonic-gate 	 * temporary configuration file we're about to build can be renamed or
3607c478bd9Sstevel@tonic-gate 	 * must be copied to its final destination.
3617c478bd9Sstevel@tonic-gate 	 */
3627c478bd9Sstevel@tonic-gate 	(void) umask(022);
3637c478bd9Sstevel@tonic-gate 	if (access(crle.c_confil, (R_OK | W_OK)) == 0) {
3647c478bd9Sstevel@tonic-gate 		crle.c_flags |= CRLE_EXISTS;
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 		if (stat(crle.c_confil, &ostatus) != 0) {
3677c478bd9Sstevel@tonic-gate 			int err = errno;
3687c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
3697c478bd9Sstevel@tonic-gate 			    crle.c_name, crle.c_confil, strerror(err));
3707c478bd9Sstevel@tonic-gate 			return (1);
3717c478bd9Sstevel@tonic-gate 		}
3727c478bd9Sstevel@tonic-gate 	} else if (errno != ENOENT) {
3737c478bd9Sstevel@tonic-gate 		int err = errno;
3747c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_ACCESS), crle.c_name,
3757c478bd9Sstevel@tonic-gate 		    crle.c_confil, strerror(err));
3767c478bd9Sstevel@tonic-gate 		return (1);
3777c478bd9Sstevel@tonic-gate 	} else {
3787c478bd9Sstevel@tonic-gate 		int	fd;
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 		/*
3817c478bd9Sstevel@tonic-gate 		 * Try opening the file now, if it works delete it, there may
3827c478bd9Sstevel@tonic-gate 		 * be a lot of processing ahead of us, so we'll come back and
3837c478bd9Sstevel@tonic-gate 		 * create the real thing later.
3847c478bd9Sstevel@tonic-gate 		 */
3857c478bd9Sstevel@tonic-gate 		if ((fd = open(crle.c_confil, (O_RDWR | O_CREAT | O_TRUNC),
3867c478bd9Sstevel@tonic-gate 		    0666)) == -1) {
3877c478bd9Sstevel@tonic-gate 			int err = errno;
3887c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
3897c478bd9Sstevel@tonic-gate 			    crle.c_name, crle.c_confil, strerror(err));
3907c478bd9Sstevel@tonic-gate 			return (1);
3917c478bd9Sstevel@tonic-gate 		}
3927c478bd9Sstevel@tonic-gate 		if (fstat(fd, &ostatus) != 0) {
3937c478bd9Sstevel@tonic-gate 			int err = errno;
3947c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
3957c478bd9Sstevel@tonic-gate 			    crle.c_name, crle.c_confil, strerror(err));
3967c478bd9Sstevel@tonic-gate 			return (1);
3977c478bd9Sstevel@tonic-gate 		}
3987c478bd9Sstevel@tonic-gate 		(void) close(fd);
3997c478bd9Sstevel@tonic-gate 		(void) unlink(crle.c_confil);
4007c478bd9Sstevel@tonic-gate 	}
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	/*
4037c478bd9Sstevel@tonic-gate 	 * If an object directory is required to hold dldump(3dl) output assign
4047c478bd9Sstevel@tonic-gate 	 * a default if necessary and insure we're able to write there.
4057c478bd9Sstevel@tonic-gate 	 */
4067c478bd9Sstevel@tonic-gate 	if (crle.c_flags & CRLE_ALTER) {
407*57ef7aa9SRod Evans 		if (objdir->o_objdir == NULL) {
4087c478bd9Sstevel@tonic-gate 			char	*str;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 			/*
4117c478bd9Sstevel@tonic-gate 			 * Use the configuration files directory.
4127c478bd9Sstevel@tonic-gate 			 */
4137c478bd9Sstevel@tonic-gate 			if ((str = strrchr(crle.c_confil, '/')) == NULL)
414*57ef7aa9SRod Evans 				objdir->o_objdir =
4157c478bd9Sstevel@tonic-gate 				    (char *)MSG_ORIG(MSG_DIR_DOT);
4167c478bd9Sstevel@tonic-gate 			else {
4177c478bd9Sstevel@tonic-gate 				int	len = str - crle.c_confil;
4187c478bd9Sstevel@tonic-gate 
419*57ef7aa9SRod Evans 				if ((objdir->o_objdir =
420*57ef7aa9SRod Evans 				    malloc(len + 1)) == NULL) {
4217c478bd9Sstevel@tonic-gate 					int err = errno;
4227c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
4237c478bd9Sstevel@tonic-gate 					    MSG_INTL(MSG_SYS_MALLOC),
4247c478bd9Sstevel@tonic-gate 					    crle.c_name, strerror(err));
4257c478bd9Sstevel@tonic-gate 					return (1);
4267c478bd9Sstevel@tonic-gate 				}
427*57ef7aa9SRod Evans 				(void) strncpy(objdir->o_objdir,
4287c478bd9Sstevel@tonic-gate 				    crle.c_confil, len);
429*57ef7aa9SRod Evans 				objdir->o_objdir[len] = '\0';
4307c478bd9Sstevel@tonic-gate 			}
4317c478bd9Sstevel@tonic-gate 		}
4327c478bd9Sstevel@tonic-gate 
4337c478bd9Sstevel@tonic-gate 		/*
4347c478bd9Sstevel@tonic-gate 		 * If we're going to dldump(3dl) images ourself make sure we
4357c478bd9Sstevel@tonic-gate 		 * can access any directories.
4367c478bd9Sstevel@tonic-gate 		 */
4377c478bd9Sstevel@tonic-gate 		if (crle.c_flags & CRLE_DUMP) {
4387c478bd9Sstevel@tonic-gate 			Objdir	*objdir;
439*57ef7aa9SRod Evans 			Aliste	idx;
4407c478bd9Sstevel@tonic-gate 			int	err = 0;
4417c478bd9Sstevel@tonic-gate 
442*57ef7aa9SRod Evans 			for (ALIST_TRAVERSE(objdirs, idx, objdir)) {
4437c478bd9Sstevel@tonic-gate 				if (crle.c_flags & CRLE_VERBOSE)
4447c478bd9Sstevel@tonic-gate 					(void) printf(MSG_INTL(MSG_DIA_OBJDIR),
4457c478bd9Sstevel@tonic-gate 					    objdir->o_objdir);
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 				if ((objdir->o_flags & CRLE_DUMP) == 0)
4487c478bd9Sstevel@tonic-gate 					continue;
4497c478bd9Sstevel@tonic-gate 
4507c478bd9Sstevel@tonic-gate 				if (access(objdir->o_objdir,
4517c478bd9Sstevel@tonic-gate 				    (R_OK | W_OK)) != 0) {
4527c478bd9Sstevel@tonic-gate 					err = errno;
4537c478bd9Sstevel@tonic-gate 					(void) fprintf(stderr,
4547c478bd9Sstevel@tonic-gate 					    MSG_INTL(MSG_SYS_ACCESS),
4557c478bd9Sstevel@tonic-gate 					    crle.c_name, objdir->o_objdir,
4567c478bd9Sstevel@tonic-gate 					    strerror(err));
4577c478bd9Sstevel@tonic-gate 				}
4587c478bd9Sstevel@tonic-gate 			}
4597c478bd9Sstevel@tonic-gate 			if (err)
4607c478bd9Sstevel@tonic-gate 				return (1);
4617c478bd9Sstevel@tonic-gate 		}
4627c478bd9Sstevel@tonic-gate 	}
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 	/*
4657c478bd9Sstevel@tonic-gate 	 * Establish any initial object directory.
4667c478bd9Sstevel@tonic-gate 	 */
467*57ef7aa9SRod Evans 	crle.c_objdir = iobjdir->o_objdir;
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 	/*
4707c478bd9Sstevel@tonic-gate 	 * Create a temporary file name in which to build the configuration
4717c478bd9Sstevel@tonic-gate 	 * information.
4727c478bd9Sstevel@tonic-gate 	 */
4737c478bd9Sstevel@tonic-gate 	if ((crle.c_tempname = tempnam(MSG_ORIG(MSG_TMP_DIR),
4747c478bd9Sstevel@tonic-gate 	    MSG_ORIG(MSG_TMP_PFX))) == NULL) {
4757c478bd9Sstevel@tonic-gate 		int err = errno;
4767c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_TEMPNAME),
4777c478bd9Sstevel@tonic-gate 		    crle.c_name, strerror(err));
4787c478bd9Sstevel@tonic-gate 		return (1);
4797c478bd9Sstevel@tonic-gate 	}
4807c478bd9Sstevel@tonic-gate 	if ((crle.c_tempfd = open(crle.c_tempname, (O_RDWR | O_CREAT),
4817c478bd9Sstevel@tonic-gate 	    0666)) == -1) {
4827c478bd9Sstevel@tonic-gate 		int err = errno;
4837c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
4847c478bd9Sstevel@tonic-gate 		    crle.c_name, crle.c_tempname, strerror(err));
4857c478bd9Sstevel@tonic-gate 		return (1);
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 	if (stat(crle.c_tempname, &nstatus) != 0) {
4887c478bd9Sstevel@tonic-gate 		int err = errno;
4897c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, MSG_INTL(MSG_SYS_OPEN),
4907c478bd9Sstevel@tonic-gate 		    crle.c_name, crle.c_tempname, strerror(err));
4917c478bd9Sstevel@tonic-gate 		return (1);
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate 	if (ostatus.st_dev != nstatus.st_dev)
4947c478bd9Sstevel@tonic-gate 		crle.c_flags |= CRLE_DIFFDEV;
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	/*
4977c478bd9Sstevel@tonic-gate 	 * Second pass.
4987c478bd9Sstevel@tonic-gate 	 */
4997c478bd9Sstevel@tonic-gate 	error = 0;
5007c478bd9Sstevel@tonic-gate 	optind = 1;
5017c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, MSG_ORIG(MSG_ARG_OPTIONS))) != -1) {
5027c478bd9Sstevel@tonic-gate 		const char	*str;
5037c478bd9Sstevel@tonic-gate 		int		flag = 0;
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 		switch (c) {
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate 		case '6':
5087c478bd9Sstevel@tonic-gate 			break;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 		case 'A':			/* alternative is optional */
5117c478bd9Sstevel@tonic-gate 			flag = RTC_OBJ_OPTINAL;
5127c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
5137c478bd9Sstevel@tonic-gate 		case 'a':			/* alternative required */
5147c478bd9Sstevel@tonic-gate 			flag |= (RTC_OBJ_ALTER | RTC_OBJ_CMDLINE);
5157c478bd9Sstevel@tonic-gate 			if (inspect(&crle, (const char *)optarg, flag) != 0)
5167c478bd9Sstevel@tonic-gate 				error = 1;
5177c478bd9Sstevel@tonic-gate 			break;
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 		case 'c':
5207c478bd9Sstevel@tonic-gate 			break;
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 		case 'e':
5237c478bd9Sstevel@tonic-gate 			if ((flag = addenv(&crle, (const char *)optarg,
5247c478bd9Sstevel@tonic-gate 			    RTC_ENV_REPLACE)) == 0)
5257c478bd9Sstevel@tonic-gate 				error = 1;
5267c478bd9Sstevel@tonic-gate 			else if ((crle.c_flags & CRLE_VERBOSE) && (flag == 1))
5277c478bd9Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DIA_RPLENV),
5287c478bd9Sstevel@tonic-gate 				    (const char *)optarg);
5297c478bd9Sstevel@tonic-gate 			break;
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate 		case 'E':
5327c478bd9Sstevel@tonic-gate 			if ((flag = addenv(&crle, (const char *)optarg,
5337c478bd9Sstevel@tonic-gate 			    RTC_ENV_PERMANT)) == 0)
5347c478bd9Sstevel@tonic-gate 				error = 1;
5357c478bd9Sstevel@tonic-gate 			else if ((crle.c_flags & CRLE_VERBOSE) && (flag == 1))
5367c478bd9Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DIA_PRMENV),
5377c478bd9Sstevel@tonic-gate 				    (const char *)optarg);
5387c478bd9Sstevel@tonic-gate 			break;
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 		case 'f':
5417c478bd9Sstevel@tonic-gate 			break;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 		case 'G':			/* group object */
5447c478bd9Sstevel@tonic-gate 			flag = (RTC_OBJ_DUMP | RTC_OBJ_ALTER);
5457c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
5467c478bd9Sstevel@tonic-gate 		case 'g':
5477c478bd9Sstevel@tonic-gate 			flag |= (RTC_OBJ_GROUP | RTC_OBJ_CMDLINE);
5487c478bd9Sstevel@tonic-gate 			if (inspect(&crle, (const char *)optarg, flag) != 0)
5497c478bd9Sstevel@tonic-gate 				error = 1;
5507c478bd9Sstevel@tonic-gate 			break;
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate 		case 'I':			/* individual object */
5537c478bd9Sstevel@tonic-gate 			flag = (RTC_OBJ_DUMP | RTC_OBJ_ALTER);
5547c478bd9Sstevel@tonic-gate 			/* FALLTHROUGH */
5557c478bd9Sstevel@tonic-gate 		case 'i':
5567c478bd9Sstevel@tonic-gate 			flag |= RTC_OBJ_CMDLINE;
5577c478bd9Sstevel@tonic-gate 			if (inspect(&crle, (const char *)optarg, flag) != 0)
5587c478bd9Sstevel@tonic-gate 				error = 1;
5597c478bd9Sstevel@tonic-gate 			break;
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate 		case 'l':			/* library search path */
5627c478bd9Sstevel@tonic-gate 			if (crle.c_flags & CRLE_AOUT) {
5637c478bd9Sstevel@tonic-gate 				str = MSG_ORIG(MSG_STR_AOUT);
5647c478bd9Sstevel@tonic-gate 				lib = &crle.c_adlibpath;
5657c478bd9Sstevel@tonic-gate 			} else {
5667c478bd9Sstevel@tonic-gate 				str = MSG_ORIG(MSG_STR_ELF);
5677c478bd9Sstevel@tonic-gate 				lib = &crle.c_edlibpath;
5687c478bd9Sstevel@tonic-gate 			}
5697c478bd9Sstevel@tonic-gate 			if (addlib(&crle, lib, (const char *)optarg) != 0)
5707c478bd9Sstevel@tonic-gate 				error = 1;
5717c478bd9Sstevel@tonic-gate 			else if (crle.c_flags & CRLE_VERBOSE)
5727c478bd9Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DIA_DLIBPTH),
5737c478bd9Sstevel@tonic-gate 				    str, (const char *)optarg);
5747c478bd9Sstevel@tonic-gate 			break;
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 		case 'o':
5777c478bd9Sstevel@tonic-gate 			crle.c_objdir = optarg;
5787c478bd9Sstevel@tonic-gate 			break;
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 		case 's':			/* trusted (secure) path */
5817c478bd9Sstevel@tonic-gate 			if (crle.c_flags & CRLE_AOUT) {
5827c478bd9Sstevel@tonic-gate 				str = MSG_ORIG(MSG_STR_AOUT);
5837c478bd9Sstevel@tonic-gate 				lib = &crle.c_aslibpath;
5847c478bd9Sstevel@tonic-gate 			} else {
5857c478bd9Sstevel@tonic-gate 				str = MSG_ORIG(MSG_STR_ELF);
5867c478bd9Sstevel@tonic-gate 				lib = &crle.c_eslibpath;
5877c478bd9Sstevel@tonic-gate 			}
5887c478bd9Sstevel@tonic-gate 			if (addlib(&crle, lib, (const char *)optarg) != 0)
5897c478bd9Sstevel@tonic-gate 				error = 1;
5907c478bd9Sstevel@tonic-gate 			else if (crle.c_flags & CRLE_VERBOSE)
5917c478bd9Sstevel@tonic-gate 				(void) printf(MSG_INTL(MSG_DIA_TLIBPTH),
5927c478bd9Sstevel@tonic-gate 				    str, (const char *)optarg);
5937c478bd9Sstevel@tonic-gate 			break;
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 		case 't':			/* search path type */
5967c478bd9Sstevel@tonic-gate 			if (strcmp((const char *)optarg,
5977c478bd9Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_ELF)) == 0)
5987c478bd9Sstevel@tonic-gate 				crle.c_flags &= ~CRLE_AOUT;
5997c478bd9Sstevel@tonic-gate 			else
6007c478bd9Sstevel@tonic-gate 				crle.c_flags |= CRLE_AOUT;
6017c478bd9Sstevel@tonic-gate 			break;
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate 		case 'u':
6047c478bd9Sstevel@tonic-gate 			break;
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 		case 'v':
6077c478bd9Sstevel@tonic-gate 			break;
6087c478bd9Sstevel@tonic-gate 		}
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	/*
6127c478bd9Sstevel@tonic-gate 	 * Now that we've generated as many file/directory processing errors
6137c478bd9Sstevel@tonic-gate 	 * as we can, return if any fatal error conditions occurred.
6147c478bd9Sstevel@tonic-gate 	 */
6157c478bd9Sstevel@tonic-gate 	if (error) {
6167c478bd9Sstevel@tonic-gate 		(void) unlink(crle.c_tempname);
6177c478bd9Sstevel@tonic-gate 		if (crle.c_flags & CRLE_CREAT) {
6187c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, MSG_INTL(MSG_GEN_CREATE),
6197c478bd9Sstevel@tonic-gate 			    crle.c_name, crle.c_confil);
6207c478bd9Sstevel@tonic-gate 		}
6217c478bd9Sstevel@tonic-gate 		return (1);
6227c478bd9Sstevel@tonic-gate 	}
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 	/*
6257c478bd9Sstevel@tonic-gate 	 * Create a temporary configuration file.
6267c478bd9Sstevel@tonic-gate 	 */
6277c478bd9Sstevel@tonic-gate 	if (genconfig(&crle) != 0) {
6287c478bd9Sstevel@tonic-gate 		(void) unlink(crle.c_tempname);
6297c478bd9Sstevel@tonic-gate 		return (1);
6307c478bd9Sstevel@tonic-gate 	}
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	/*
6337c478bd9Sstevel@tonic-gate 	 * If dldump(3dl) images are required spawn a process to create them.
6347c478bd9Sstevel@tonic-gate 	 */
6357c478bd9Sstevel@tonic-gate 	if (crle.c_flags & CRLE_DUMP) {
6367c478bd9Sstevel@tonic-gate 		if (dump(&crle) != 0) {
6377c478bd9Sstevel@tonic-gate 			(void) unlink(crle.c_tempname);
6387c478bd9Sstevel@tonic-gate 			return (1);
6397c478bd9Sstevel@tonic-gate 		}
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	/*
6437c478bd9Sstevel@tonic-gate 	 * Copy the finished temporary configuration file to its final home.
6447c478bd9Sstevel@tonic-gate 	 */
6457c478bd9Sstevel@tonic-gate 	if (updateconfig(&crle) != 0)
6467c478bd9Sstevel@tonic-gate 		return (1);
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	return (0);
6497c478bd9Sstevel@tonic-gate }
650