5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER START
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *
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 *
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 *
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 *
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * CDDL HEADER END
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Use is subject to license terms.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* All Rights Reserved */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdio.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <limits.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <stdlib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <unistd.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <errno.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <string.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <sys/types.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkgstrct.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <locale.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libintl.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <pkglib.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <install.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#include <libinst.h>
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_MEMORY "memory allocation failure"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define ERR_DUPPATH "duplicate pathname <%s>"
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/* libpkg/gpkgmap */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandextern int getmapmode(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland#define EPTMALLOC 512
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic struct cfent **eptlist;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int eptnum;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int errflg;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int nparts;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int space = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void procinit(void);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int procassign(struct cfent *ept, char **server_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **client_local, char **server_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char **client_path, char **map_path, int mapflag,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nc);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int ckdup(struct cfent *ept1, struct cfent *ept2);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int sortentry(int index);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic void
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandprocinit(void)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg = nparts = eptnum = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (space != -1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ar_free(space);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland space = -1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * initialize dynamic memory used to store
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * path information which is read in
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) pathdup((char *)0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * This function assigns appropriate values based upon the pkgmap entry
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * in the cfent structure.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
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 int nc)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int path_duped = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int local_duped = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char source[PATH_MAX+1];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (nc >= 0 && ept->ftype != 'i')
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ept->pkg_class_idx = cl_idx(ept->pkg_class)) == -1)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept->volno > nparts)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nparts++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
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 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((mapflag > 1) && strchr("fve", ept->ftype)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept->ainfo.local == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland source[0] = '~';
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(&source[1], ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->ainfo.local = pathdup(source);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *server_local = ept->ainfo.local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *client_local = ept->ainfo.local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland local_duped = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
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 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (mapflag && (ept->ftype != 'i')) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland mappath(getmapmode(), ept->path); /* evaluate variables */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland canonize(ept->path); /* Fix path as necessary. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) eval_path(server_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland client_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland map_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path_duped = 1; /* eval_path dup's it */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->path = *server_path; /* default */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * Deal with source for hard and soft links.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strchr("sl", ept->ftype)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (mapflag) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland mappath(getmapmode(), ept->ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!RELATIVE(ept->ainfo.local)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland canonize(ept->ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* check for hard link */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept->ftype == 'l') {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) eval_path(
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland server_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland client_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland NULL,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland local_duped = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Default to server. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->ainfo.local = *server_local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
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 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!path_duped) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *server_path = pathdup(ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *client_path = *server_path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->path = *server_path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland path_duped = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept->ainfo.local != NULL)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!local_duped) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *server_local = pathdup(ept->ainfo.local);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->ainfo.local = *server_local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland *client_local = ept->ainfo.local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland local_duped = 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
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 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*ARGSUSED*/
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstruct cfent **
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandprocmap(VFP_T *vfp, int mapflag, char *ir)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent *ept = (struct cfent *)NULL;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent map_entry;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent **ept_ptr;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int n;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int nc;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland static char *server_local, *client_local;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland static char *server_path, *client_path, *map_path;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland procinit();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland space = ar_create(EPTMALLOC, (unsigned)sizeof (struct cfent),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland "prototype object");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (space == -1) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland nc = cl_getn();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (;;) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Clear the buffer. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memset(&map_entry, '\000', sizeof (struct cfent));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = gpkgmapvfp(&map_entry, vfp);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland break; /* no more entries in pkgmap */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (n < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland char *errstr = getErrstr();
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext("bad entry read in pkgmap"));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext("pathname=%s"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (ept && ept->path && *ept->path) ?
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->path : "Unknown");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland logerr(gettext("problem=%s"),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (errstr && *errstr) ? errstr : "Unknown");
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * A valid entry was found in the map, so allocate an
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * official record.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept_ptr = (struct cfent **)ar_next_avail(space);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept_ptr == NULL || *ept_ptr == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept = *ept_ptr;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Transfer what we just read in. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) memcpy(ept, &map_entry, sizeof (struct cfent));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (procassign(ept, &server_local, &client_local,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland &server_path, &client_path, &map_path,
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland mapflag, nc)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* It didn't take. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ar_delete(space, eptnum);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland continue;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptnum++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* setup a pointer array to point to malloc'd entries space */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptlist = (struct cfent **)ar_get_head(space);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (eptlist == NULL) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_MEMORY));
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (NULL);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) sortentry(-1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (i = 0; i < eptnum; /* void */) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!sortentry(i))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (errflg ? NULL : eptlist);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
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 * that much.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandsortentry(int index)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland struct cfent *ept, *ept_i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland static int last = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int i, n, j;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland int upper, lower;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (index == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland else if (index < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland last = 0;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
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 * array.
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept = eptlist[index];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
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 last = index-1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland lower = 0; /* lower bound of the unsorted elements */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland upper = index; /* upper bound */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = last;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland do {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
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 */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept_i = eptlist[i];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland n = strcmp(ept->path, ept_i->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (n == 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!ckdup(ept, ept_i)) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland progerr(gettext(ERR_DUPPATH),
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept->path);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland errflg++;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* remove the entry at index */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) ar_delete(space, index);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptnum--;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1); /* Use this index again. */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else if (n < 0) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /*
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * The path of interest is smaller than the path
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * under test. Move down array using the method of
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland * division
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland upper = i;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = lower + (upper-lower)/2;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } else {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* Move up array */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland lower = i+1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland i = upper - (upper-lower)/2 - 1;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland } while (upper != lower);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland last = i = upper;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* expand to insert at i */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland for (j = index; j > i; j--)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptlist[j] = eptlist[j-1];
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland eptlist[i] = ept;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland/*
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 Waterland */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandstatic int
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterlandckdup(struct cfent *ept1, struct cfent *ept2)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland{
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland /* ept2 will be modified to contain "merged" entries */
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!strchr("?dx", ept1->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (!strchr("?dx", ept2->ftype))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept2->ainfo.mode == BADMODE)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept2->ainfo.mode = ept1->ainfo.mode;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if ((ept1->ainfo.mode != ept2->ainfo.mode) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (ept1->ainfo.mode != BADMODE))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept2->ainfo.owner, "?") == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(ept2->ainfo.owner, ept1->ainfo.owner);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept1->ainfo.owner, ept2->ainfo.owner) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strcmp(ept1->ainfo.owner, "?"))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept2->ainfo.group, "?") == 0)
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland (void) strcpy(ept2->ainfo.group, ept1->ainfo.group);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (strcmp(ept1->ainfo.group, ept2->ainfo.group) &&
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland strcmp(ept1->ainfo.group, "?"))
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (0);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland if (ept1->pinfo) {
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept2->npkgs = ept1->npkgs;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland ept2->pinfo = ept1->pinfo;
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland }
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland return (1);
5c51f1241dbbdf2656d0e10011981411ed0c9673Moriah Waterland}