5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The contents of this file are subject to the terms of the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Common Development and Distribution License (the "License").
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You may not use this file except in compliance with the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * or http://www.opensolaris.org/os/licensing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * See the License for the specific language governing permissions
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and limitations under the License.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If applicable, add the following below this CDDL HEADER, with the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern char *basedir, *root, *rootlist[], **environ;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IMPORTANT NOTE: PLEASE SEE THE DEFINITION OF temp[] BELOW BEFORE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CHANGING THE DEFINITION OF PATH_LGTH!!!!
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_BPARAMC "parametric class specification for <%s> not allowed"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_SRCHLOC "no object for <%s> found in local path"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_SRCHSRCH "no object for <%s> found in search path"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_SRCHROOT "no object for <%s> found in root directory"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_CONTENTS "unable to process contents of object <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_WRITE "write of entry failed, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_GARBDEFLT "garbled default settings: %s"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_CHDIR "unable to change directory to <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_INCOMPLETE "processing of <%s> may be incomplete"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_NRECURS "too many levels of include (limit is %d)"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_RDINCLUDE "unable to process include file <%s>, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_IGNINCLUDE "ignoring include file <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define MSG_NODEVICE "device numbers cannot be determined for <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define WRN_BADATTR "WARNING: attributes set to %04o %s %s for <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define WRN_BADATTRM "WARNING: attributes set to %s %s %s for <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define WRN_FAKEBD "WARNING: parametric paths may ignore BASEDIR"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_TEMP "unable to obtain temporary file resources, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_ENVBUILD "unable to build parameter environment, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_MAXPARAMS "too many parameter definitions (limit is %d)"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_GETCWD "unable to get current directory, errno=%d"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_PATHVAR "cannot resolve all build parameters associated with " \
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern void attrpreset(int mode, char *owner, char *group);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *findfile(char *path, char *local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic char *srchroot(char *path, char *copy);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int popenv(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int doattrib(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void doinclude(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void dorsearch(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void dosearch(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void lputenv(char *s);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void translate(register char *pt, register char *copy);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandmkpkgmap(char *outfile, char *protofile, char **envparam)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NOTE: THE SIZE OF temp IS HARD CODED INTO CALLS TO fscanf.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * YOU *MUST* MAKE SURE TO CHANGE THOSE CALLS IF THE SIZE OF temp
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IS EVER CHANGED!!!!!!
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((tmpfp = fopen(outfile, "w")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland environ = params; /* use only local environ */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attrdefault(); /* assume no default attributes */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Environment parameters are optional, so variable
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * (envparam[i]) could be NULL.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (putenv(qstrdup(envparam[i]))) { /* bugid 1090920 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MAXPARAMS), MAXPARAMS);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (c == '#') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland do c = getc(fp); while ((c != EOF) && (c != '\n'));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (c == '!') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * LINE IF THE SIZE OF fscanf IS EVER CHANGED!!!
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* put this into the local environment */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fscanf(fp, "%*[^\n]"); /* rest of line */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fscanf(fp, "\n"); /* rest of line */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fscanf(fp, "%*[^\n]"); /* read of line */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fscanf(fp, "\n"); /* read of line */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break; /* done with file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* don't allow classname to be parametric */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * We don't need to search for things without any
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * contents in them.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path = findfile(entry.path, entry.ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Warn if attributes are not set correctly. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(entry.ainfo.owner, NOOWNER) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(entry.ainfo.owner, CUROWNER,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(entry.ainfo.group, NOGROUP) == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(entry.ainfo.group, CURGROUP,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Resolve build parameters (initial lower case) in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the link and target paths.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Warn if top level file or directory is an install
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (entry.path[0] == '$' && isupper(entry.path[1]))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland environ = envsave; /* restore environment */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * map any parameters specified in path to their corresponding values
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * and make sure the path is in its canonical form; any parmeters for
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which a value is not defined will be left unexpanded. Since this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * is an actual search for a real file (which will not end up in the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * package) - we map ALL variables (both build and Install).
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(temp, (local && local[0] ? local : path), sizeof (temp));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (rootlist[0] || (basedir && (*temp != '/'))) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * search for path in the pseudo-root/basedir directory; note
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * that package information files should NOT be included in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* looking for local object file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If it equals "/dev/null", that just means it's an empty
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file. Otherwise, we'll really be writing stuff, so we need
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * to verify the source.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(host, sizeof (host), "%s/%s", rootp[nfp][i],
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(host, sizeof (host), "%s/%s",
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* check current directory as a last resort */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(host, sizeof (host), "%s/%s", dname[nfp], basename);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((stat(host, &statbuf) == 0) && (statbuf.st_mode & S_IFREG))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char temp[PATH_MAX], lookpath[PATH_MAX], *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* make relative path an absolute directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char temp[PATH_MAX], lookpath[PATH_MAX], *pt;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* make relative path an absolute directory */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function reads the default mode, owner and group from the prototype
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file and makes that available.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *pt, attrib[PATH_MAX], *mode_ptr, *owner_ptr, *group_ptr, *eol;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char owner[ATRSIZ+1], group[ATRSIZ+1], attrib_save[(4*ATRSIZ)];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(attrib_save, attrib, sizeof (attrib_save));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Now resolve any variables that may be present. Start on group and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * move backward since that keeps the resolved string from
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * overwriting any of the other entries. This is required since
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * mapvar() writes the resolved string over the string provided.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* extra tokens on the line */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_GARBDEFLT), (eol) ? eol :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (group_ptr && mapvar(1, group_ptr) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (owner_ptr && mapvar(1, owner_ptr) == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * For mode, don't use scanf, since we want to force an octal
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * interpretation and need to limit the length of the owner and group
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * specifications.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_GARBDEFLT), (attrib_save) ?
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ((attrib_save[0]) ? attrib_save : gettext("none")) :
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* free any previous memory from qstrdup */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland attrpreset(d_mod[nfp], d_own[nfp], d_grp[nfp]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * IMPORTANT NOTE: THE SIZE OF temp IS HARD CODED INTO THE
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * FOLLOWING CALL TO fscanf -- YOU MUST CHANGE THIS LINE IF
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * THE SIZE OF fscanf IS EVER CHANGED!!!
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) snprintf(file, sizeof (file), "%s/%s", dname[nfp], temp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This does what mappath() does except that it does it for ALL variables
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * using whitespace as a token separator. This is used to resolve search
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * paths and assignment statements. It doesn't effect the build versus
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * install decision made for pkgmap variables.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandtranslate(register char *pt, register char *copy)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* eat white space */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) fprintf(stderr, gettext("ERROR in %s:\n"), lasterr);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Set up defaults and change to the build directory. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if ((fp = fopen(file, "r")) == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_RDINCLUDE), file, errno);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* upper level proto file */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* path is relative to the prototype file specified */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strlcpy(topdir, "/", sizeof (topdir));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* same directory as the last prototype */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return; /* no need to canonize() or chdir() */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland quit(1); /* must be able to cd to upper level */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_IGNINCLUDE), proto[nfp]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Restore defaults and return to the prior directory. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext(MSG_INCOMPLETE), proto[nfp]);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * If this parameter isn't already in place, put it into the local
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * environment. This means that command line directives override prototype
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * file directives.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < nrdonly; i++) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* convert with root & basedir info */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* make it pretty again */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (stat(copy, &statbuf) || !(statbuf.st_mode & S_IFREG)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue; /* host source must be a regular file */