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 Waterland#define ERR_MEMORY "memory allocation failure"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_DUPPATH "duplicate pathname <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern int getmapmode(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void procinit(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int procassign(struct cfent *ept, char **server_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **client_path, char **map_path, int mapflag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ckdup(struct cfent *ept1, struct cfent *ept2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * initialize dynamic memory used to store
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path information which is read in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) pathdup((char *)0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function assigns appropriate values based upon the pkgmap entry
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the cfent structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandprocassign(struct cfent *ept, char **server_local, char **client_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **server_path, char **client_path, char **map_path, int mapflag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ept->pkg_class_idx = cl_idx(ept->pkg_class)) == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Generate local (delivered source) paths for files
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * which need them so that the install routine will know
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * where to get the file from the package. Note that we
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * do not resolve path environment variables here since
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * they won't be resolved in the reloc directory.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((mapflag > 1) && strchr("fve", ept->ftype)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Evaluate the destination path based upon available
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * environment, then produce a client-relative and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * server-relative canonized path.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland mappath(getmapmode(), ept->path); /* evaluate variables */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland canonize(ept->path); /* Fix path as necessary. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Deal with source for hard and soft links.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* check for hard link */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Default to server. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * For the paths (both source and target) that were too mundane to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * have been copied into dup space yet, do that.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function reads the prototype file and returns a pointer to a list of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * struct cfent representing the contents of that file.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland static char *server_path, *client_path, *map_path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland space = ar_create(EPTMALLOC, (unsigned)sizeof (struct cfent),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "prototype object");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Clear the buffer. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(&map_entry, '\000', sizeof (struct cfent));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break; /* no more entries in pkgmap */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (n < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext("bad entry read in pkgmap"));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A valid entry was found in the map, so allocate an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * official record.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept_ptr = (struct cfent **)ar_next_avail(space);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Transfer what we just read in. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memcpy(ept, &map_entry, sizeof (struct cfent));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (procassign(ept, &server_local, &client_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* It didn't take. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* setup a pointer array to point to malloc'd entries space */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptlist = (struct cfent **)ar_get_head(space);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function sorts the final list of cfent entries. If index = -1, the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * function is initialized. index = 0 doesn't get us anywhere because this
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sorts against index-1. Positive natural index values are compared and
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * sorted into the array appropriately. Yes, it does seem we should use a
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * quicksort on the whole array or something. The apparent reason for taking
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * this approach is that there are enough special considerations to be
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * applied to each package object that inserting them one-by-one doesn't cost
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (index < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Based on the index, this is the package object we're going to
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * review. It may stay where it is or it may be repositioned in the
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* quick comparison optimization for pre-sorted arrays */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept->path, eptlist[index-1]->path) > 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* do nothing */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland lower = 0; /* lower bound of the unsorted elements */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * NOTE: This does a binary sort on path. There are lots of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * other worthy items in the array, but path is the key into
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * the package database.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* remove the entry at index */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (n < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The path of interest is smaller than the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * under test. Move down array using the method of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Move up array */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* expand to insert at i */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = index; j > i; j--)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Check duplicate entries in the package object list. If it's a directory,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * this just merges them, if not, it returns a 0 to force further processing.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandckdup(struct cfent *ept1, struct cfent *ept2)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ept2 will be modified to contain "merged" entries */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ept1->ainfo.mode != ept2->ainfo.mode) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(ept2->ainfo.owner, ept1->ainfo.owner);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept1->ainfo.owner, ept2->ainfo.owner) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(ept2->ainfo.group, ept1->ainfo.group);