crle.c revision 7010c12ad3ac2cada55cf126121a8c46957d3632
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include <dlfcn.h>
#include <errno.h>
#include "_crle.h"
#include "conv.h"
#include "msg.h"
/*
* crle(1) entry point and argument processing.
*
* Two passes of the arguments are carried out; the first collects any single
* instance options and establishes defaults that might be appropriate for
* other arguments:
*
* -64 operate on, or apply, 64-bit objects (default is 32-bit).
*
* -c file defines the output configuration file.
*
* -f flag flags for dldump(3dl).
*
* -o dir defines the output directory for any dldump(3dl) objects
* that follow. For backward compatibility (RTC_VER_ONE only
* allowed one output directory) allow the first occurrence of this
* specification to catch any previous files. If not specified,
* the configuration files parent directory is used).
*
* -u update any existing configuration file. Any additional
* arguments supplied will be added to the new configuration
* information.
*
* -v verbose mode.
*
* The second pass collects all other options and constructs an internal
* string table which will be used to create the eventual configuration file.
*
* -a name add the individual name, with an alternative to the
* configuration cache. No alternative is created via dldump(3dl),
* it is the users responsibility to furnish the alternative.
*
* -A name add the individual name, with an optional alternative to the
* configuration cache. No alternative is created via dldump(3dl),
* it is the users responsibility to furnish the alternative.
*
* -e envar replaceable environment variable
*
* -E envar permanent environment variable
*
* -i name add the individual name to the configuration cache. If name
* is a directory each shared object within the directory is added
* to the cache.
*
* -I name same as -i, but in addition any ELF objects are dldump(3dl)'ed.
*
* -g name add the group name to the configuration cache. Each object is
* expanded to determine its dependencies and these are added to
* the cache. If name is a directory each shared object within the
* directory and its dependencies are added to the cache.
*
* -G app same as -g, but in addition any ELF objects are dldump(3dl)'ed.
*
* -l dir library search directory
*
* -s dir trusted (secure) directory
*
* -t type search directory type (ELF or AOUT).
*/
/*
* Establish a structure for maintaining current object directory attributes.
* We wish to validate the access of any object directory that will be written
* to (dldump(3dl), and thus by maintaining a current object directory and its
* intended use we can perform this validation later.
*/
typedef struct {
char *o_objdir;
unsigned int o_flags;
} Objdir;
/*ARGSUSED2*/
int
{
int c, error = 0;
char ** lib;
int c_class;
return (1);
/*
* Establish locale.
*/
/*
* Initialization configuration information.
*/
/*
* First argument pass.
*/
switch (c) {
case '6': /* operate on 64-bit objects */
if (optarg[0] != '4') {
error = 1;
}
break;
case 'A': /* create optional */
/* FALLTHROUGH */ /* alternative */
case 'a': /* create alternative */
break;
case 'c': /* define the config file */
error = 1;
}
break;
case 'e': /* replaceable env variable */
break;
case 'E': /* permanent env variable */
break;
case 'f': /* dldump(3dl) flags */
error = 1;
}
(const char *)optarg)) == 0)
error = 1;
break;
case 'G': /* group object */
/* FALLTHROUGH */
case 'g':
break;
case 'I': /* individual object */
/* FALLTHROUGH */
case 'i':
break;
case 'l': /* library search path */
else
break;
case 'o': /* define an object directory */
return (1);
return (1);
}
break;
case 's': /* trusted (secure) path */
else
break;
case 't': /* search path type */
MSG_ORIG(MSG_STR_ELF)) == 0)
MSG_ORIG(MSG_STR_AOUT)) == 0)
else {
error = 1;
}
break;
case 'u': /* update mode */
break;
case 'v': /* verbose mode */
break;
default:
error = 2;
}
}
error = 2;
/*
* Determine the configuration file, which in the case of an existing
* error condition is required in the final error message.
*/
if (c_class == ELFCLASS32) {
} else {
}
}
/*
* as we can, return if any fatal error conditions occurred.
*/
if (error) {
if (error == 2) {
}
return (1);
}
/*
* Apply any additional defaults.
*/
(void) elf_version(EV_CURRENT);
/*
* If we're updating an existing file or not creating a configuration
* file at all, investigate the original.
*/
case INSCFG_RET_OK:
return (0);
break;
case INSCFG_RET_FAIL:
return (1);
case INSCFG_RET_NEED64:
break;
}
}
/*
* Ensure that the right version (32 or 64-bit) of this program
* is running. The 32 and 64-bit compilers may align fields within
* structures differently. Using the right version of crle for
* the config file ensures that all linker components will see
* the same layout, without the need for special code.
*/
#ifdef _ELF64
if (c_class == ELFCLASS32) {
return (1);
}
#else
if (c_class == ELFCLASS64) {
/*
* conv_check_native() should not return, as we expect
* the 64-bit version to have executed on top of us.
* If it does, it means there is no 64-bit support
* available on this system.
*/
return (1);
}
#endif
/*
* Make sure the configuration file is accessible. Stat the file to
* determine its dev number - this is used to determine whether the
* temporary configuration file we're about to build can be renamed or
* must be copied to its final destination.
*/
(void) umask(022);
return (1);
}
return (1);
} else {
int fd;
/*
* Try opening the file now, if it works delete it, there may
* be a lot of processing ahead of us, so we'll come back and
* create the real thing later.
*/
0666)) == -1) {
return (1);
}
return (1);
}
}
/*
* If an object directory is required to hold dldump(3dl) output assign
* a default if necessary and insure we're able to write there.
*/
char *str;
/*
* Use the configuration files directory.
*/
(char *)MSG_ORIG(MSG_DIR_DOT);
else {
return (1);
}
}
}
/*
* If we're going to dldump(3dl) images ourself make sure we
* can access any directories.
*/
int err = 0;
continue;
}
}
if (err)
return (1);
}
}
/*
* Establish any initial object directory.
*/
/*
* Create a temporary file name in which to build the configuration
* information.
*/
return (1);
}
0666)) == -1) {
return (1);
}
return (1);
}
/*
* Second pass.
*/
error = 0;
optind = 1;
const char *str;
int flag = 0;
switch (c) {
case '6':
break;
case 'A': /* alternative is optional */
/* FALLTHROUGH */
case 'a': /* alternative required */
error = 1;
break;
case 'c':
break;
case 'e':
RTC_ENV_REPLACE)) == 0)
error = 1;
(const char *)optarg);
break;
case 'E':
RTC_ENV_PERMANT)) == 0)
error = 1;
(const char *)optarg);
break;
case 'f':
break;
case 'G': /* group object */
/* FALLTHROUGH */
case 'g':
error = 1;
break;
case 'I': /* individual object */
/* FALLTHROUGH */
case 'i':
flag |= RTC_OBJ_CMDLINE;
error = 1;
break;
case 'l': /* library search path */
} else {
}
error = 1;
break;
case 'o':
break;
case 's': /* trusted (secure) path */
} else {
}
error = 1;
break;
case 't': /* search path type */
MSG_ORIG(MSG_STR_ELF)) == 0)
else
break;
case 'u':
break;
case 'v':
break;
}
}
/*
* as we can, return if any fatal error conditions occurred.
*/
if (error) {
}
return (1);
}
/*
* Create a temporary configuration file.
*/
return (1);
}
/*
* If dldump(3dl) images are required spawn a process to create them.
*/
return (1);
}
}
/*
* Copy the finished temporary configuration file to its final home.
*/
if (updateconfig(&crle) != 0)
return (1);
return (0);
}