1*9781SMoriah.Waterland@Sun.COM /* 2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START 3*9781SMoriah.Waterland@Sun.COM * 4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 7*9781SMoriah.Waterland@Sun.COM * 8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 11*9781SMoriah.Waterland@Sun.COM * and limitations under the License. 12*9781SMoriah.Waterland@Sun.COM * 13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9781SMoriah.Waterland@Sun.COM * 19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END 20*9781SMoriah.Waterland@Sun.COM */ 21*9781SMoriah.Waterland@Sun.COM 22*9781SMoriah.Waterland@Sun.COM /* 23*9781SMoriah.Waterland@Sun.COM * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 25*9781SMoriah.Waterland@Sun.COM */ 26*9781SMoriah.Waterland@Sun.COM 27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 29*9781SMoriah.Waterland@Sun.COM 30*9781SMoriah.Waterland@Sun.COM 31*9781SMoriah.Waterland@Sun.COM #include <stdio.h> 32*9781SMoriah.Waterland@Sun.COM #include <string.h> 33*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 34*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 35*9781SMoriah.Waterland@Sun.COM #include <dirent.h> 36*9781SMoriah.Waterland@Sun.COM #include <locale.h> 37*9781SMoriah.Waterland@Sun.COM #include <libintl.h> 38*9781SMoriah.Waterland@Sun.COM #include <errno.h> 39*9781SMoriah.Waterland@Sun.COM #include "pkglib.h" 40*9781SMoriah.Waterland@Sun.COM #include "install.h" 41*9781SMoriah.Waterland@Sun.COM #include "libadm.h" 42*9781SMoriah.Waterland@Sun.COM #include "libinst.h" 43*9781SMoriah.Waterland@Sun.COM #include "pkginstall.h" 44*9781SMoriah.Waterland@Sun.COM #include "messages.h" 45*9781SMoriah.Waterland@Sun.COM 46*9781SMoriah.Waterland@Sun.COM extern char instdir[], pkgbin[], pkgloc[], savlog[], *pkginst, **environ; 47*9781SMoriah.Waterland@Sun.COM extern char saveSpoolInstallDir[]; 48*9781SMoriah.Waterland@Sun.COM extern char pkgsav[]; /* pkginstall/main.c */ 49*9781SMoriah.Waterland@Sun.COM static char *infoloc; 50*9781SMoriah.Waterland@Sun.COM 51*9781SMoriah.Waterland@Sun.COM /* 52*9781SMoriah.Waterland@Sun.COM * flag definitions for each entry in table 53*9781SMoriah.Waterland@Sun.COM */ 54*9781SMoriah.Waterland@Sun.COM 55*9781SMoriah.Waterland@Sun.COM typedef unsigned int TBL_FLAG_T; 56*9781SMoriah.Waterland@Sun.COM 57*9781SMoriah.Waterland@Sun.COM /* no flag set */ 58*9781SMoriah.Waterland@Sun.COM #define FLAG_NONE ((TBL_FLAG_T)0x0000) 59*9781SMoriah.Waterland@Sun.COM 60*9781SMoriah.Waterland@Sun.COM /* exclude this attribute if found */ 61*9781SMoriah.Waterland@Sun.COM #define FLAG_EXCLUDE ((TBL_FLAG_T)0x0001) 62*9781SMoriah.Waterland@Sun.COM 63*9781SMoriah.Waterland@Sun.COM /* this attribute must not change if found */ 64*9781SMoriah.Waterland@Sun.COM #define FLAG_IDENTICAL ((TBL_FLAG_T)0x0002) 65*9781SMoriah.Waterland@Sun.COM 66*9781SMoriah.Waterland@Sun.COM /* 67*9781SMoriah.Waterland@Sun.COM * macro to generate an entry in the table: 68*9781SMoriah.Waterland@Sun.COM * TBL_ENTRY("PKGINFO_ATTRIBUTE=", FLAG_XXX) 69*9781SMoriah.Waterland@Sun.COM * where: 70*9781SMoriah.Waterland@Sun.COM * "PKGINFO_ATTRIBUTE=" is the attribute to look for 71*9781SMoriah.Waterland@Sun.COM * FLAG_XXX is the action to perform when the attribute is found 72*9781SMoriah.Waterland@Sun.COM */ 73*9781SMoriah.Waterland@Sun.COM 74*9781SMoriah.Waterland@Sun.COM #define TBL_ENTRY(_Y_, _F_) { (_Y_), ((sizeof ((_Y_)))-1), (_F_) } 75*9781SMoriah.Waterland@Sun.COM 76*9781SMoriah.Waterland@Sun.COM /* 77*9781SMoriah.Waterland@Sun.COM * table containing attributes that require special handling 78*9781SMoriah.Waterland@Sun.COM */ 79*9781SMoriah.Waterland@Sun.COM 80*9781SMoriah.Waterland@Sun.COM struct _namelist { 81*9781SMoriah.Waterland@Sun.COM char *_nlName; /* attribute name */ 82*9781SMoriah.Waterland@Sun.COM int _nlLen; /* attribute length */ 83*9781SMoriah.Waterland@Sun.COM TBL_FLAG_T _nlFlag; /* attribute disposition flag */ 84*9781SMoriah.Waterland@Sun.COM }; 85*9781SMoriah.Waterland@Sun.COM 86*9781SMoriah.Waterland@Sun.COM typedef struct _namelist NAMELIST_T; 87*9781SMoriah.Waterland@Sun.COM 88*9781SMoriah.Waterland@Sun.COM /* 89*9781SMoriah.Waterland@Sun.COM * These are attributes to be acted on in some way when a pkginfo file is 90*9781SMoriah.Waterland@Sun.COM * merged. This table MUST be in alphabetical order because it is searched 91*9781SMoriah.Waterland@Sun.COM * using a binary search algorithm. 92*9781SMoriah.Waterland@Sun.COM */ 93*9781SMoriah.Waterland@Sun.COM 94*9781SMoriah.Waterland@Sun.COM static NAMELIST_T attrTbl[] = { 95*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("BASEDIR=", FLAG_EXCLUDE), 96*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("CLASSES=", FLAG_EXCLUDE), 97*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("CLIENT_BASEDIR=", FLAG_EXCLUDE), 98*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("INST_DATADIR=", FLAG_EXCLUDE), 99*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("PKG_CAS_PASSRELATIVE=", FLAG_EXCLUDE), 100*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("PKG_DST_QKVERIFY=", FLAG_EXCLUDE), 101*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("PKG_INIT_INSTALL=", FLAG_EXCLUDE), 102*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("PKG_INSTALL_ROOT=", FLAG_EXCLUDE), 103*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("PKG_SRC_NOVERIFY=", FLAG_EXCLUDE), 104*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKGCOND_GLOBAL_DATA=", FLAG_EXCLUDE), 105*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKG_ALLZONES=", FLAG_IDENTICAL), 106*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKG_DIR=", FLAG_EXCLUDE), 107*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKG_HOLLOW=", FLAG_IDENTICAL), 108*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKG_INSTALL_ZONENAME=", FLAG_EXCLUDE), 109*9781SMoriah.Waterland@Sun.COM TBL_ENTRY("SUNW_PKG_THISZONE=", FLAG_IDENTICAL), 110*9781SMoriah.Waterland@Sun.COM }; 111*9781SMoriah.Waterland@Sun.COM 112*9781SMoriah.Waterland@Sun.COM #define ATTRTBL_SIZE (sizeof (attrTbl) / sizeof (NAMELIST_T)) 113*9781SMoriah.Waterland@Sun.COM 114*9781SMoriah.Waterland@Sun.COM /* 115*9781SMoriah.Waterland@Sun.COM * While pkgsav has to be set up with reference to the server for package 116*9781SMoriah.Waterland@Sun.COM * scripts, it has to be client-relative in the pkginfo file. This function 117*9781SMoriah.Waterland@Sun.COM * is used to set the client-relative value for use in the pkginfo file. 118*9781SMoriah.Waterland@Sun.COM */ 119*9781SMoriah.Waterland@Sun.COM void 120*9781SMoriah.Waterland@Sun.COM set_infoloc(char *path) 121*9781SMoriah.Waterland@Sun.COM { 122*9781SMoriah.Waterland@Sun.COM if (path && *path) { 123*9781SMoriah.Waterland@Sun.COM if (is_an_inst_root()) { 124*9781SMoriah.Waterland@Sun.COM /* Strip the server portion of the path. */ 125*9781SMoriah.Waterland@Sun.COM infoloc = orig_path(path); 126*9781SMoriah.Waterland@Sun.COM } else { 127*9781SMoriah.Waterland@Sun.COM infoloc = strdup(path); 128*9781SMoriah.Waterland@Sun.COM } 129*9781SMoriah.Waterland@Sun.COM } 130*9781SMoriah.Waterland@Sun.COM } 131*9781SMoriah.Waterland@Sun.COM 132*9781SMoriah.Waterland@Sun.COM void 133*9781SMoriah.Waterland@Sun.COM merginfo(struct cl_attr **pclass, int install_from_pspool) 134*9781SMoriah.Waterland@Sun.COM { 135*9781SMoriah.Waterland@Sun.COM DIR *pdirfp; 136*9781SMoriah.Waterland@Sun.COM FILE *fp; 137*9781SMoriah.Waterland@Sun.COM FILE *pkginfoFP; 138*9781SMoriah.Waterland@Sun.COM char path[PATH_MAX]; 139*9781SMoriah.Waterland@Sun.COM char cmd[PATH_MAX]; 140*9781SMoriah.Waterland@Sun.COM char pkginfoPath[PATH_MAX]; 141*9781SMoriah.Waterland@Sun.COM char temp[PATH_MAX]; 142*9781SMoriah.Waterland@Sun.COM int i; 143*9781SMoriah.Waterland@Sun.COM int nc; 144*9781SMoriah.Waterland@Sun.COM int out; 145*9781SMoriah.Waterland@Sun.COM 146*9781SMoriah.Waterland@Sun.COM /* remove savelog from previous attempts */ 147*9781SMoriah.Waterland@Sun.COM 148*9781SMoriah.Waterland@Sun.COM (void) unlink(savlog); 149*9781SMoriah.Waterland@Sun.COM 150*9781SMoriah.Waterland@Sun.COM /* 151*9781SMoriah.Waterland@Sun.COM * create path to appropriate pkginfo file for the package that is 152*9781SMoriah.Waterland@Sun.COM * already installed - is_spool_create() will be set (!= 0) if the 153*9781SMoriah.Waterland@Sun.COM * -t option is presented to pkginstall - the -t option is used to 154*9781SMoriah.Waterland@Sun.COM * disable save spool area creation; do not spool any partial package 155*9781SMoriah.Waterland@Sun.COM * contents, that is, suppress the creation and population of the 156*9781SMoriah.Waterland@Sun.COM * package save spool area (var/sadm/pkg/PKG/save/pspool/PKG). This 157*9781SMoriah.Waterland@Sun.COM * option is set only when a non-global zone is being created. 158*9781SMoriah.Waterland@Sun.COM */ 159*9781SMoriah.Waterland@Sun.COM 160*9781SMoriah.Waterland@Sun.COM if (is_spool_create() == 0) { 161*9781SMoriah.Waterland@Sun.COM /* 162*9781SMoriah.Waterland@Sun.COM * normal package install (not a non-global zone install); 163*9781SMoriah.Waterland@Sun.COM * use the standard installed pkginfo file for this package: 164*9781SMoriah.Waterland@Sun.COM * --> /var/sadm/pkg/PKGINST/pkginfo 165*9781SMoriah.Waterland@Sun.COM * as the source pkginfo file to scan. 166*9781SMoriah.Waterland@Sun.COM */ 167*9781SMoriah.Waterland@Sun.COM i = snprintf(pkginfoPath, sizeof (pkginfoPath), 168*9781SMoriah.Waterland@Sun.COM "%s/var/sadm/pkg/%s/%s", 169*9781SMoriah.Waterland@Sun.COM ((get_inst_root()) && 170*9781SMoriah.Waterland@Sun.COM (strcmp(get_inst_root(), "/") != 0)) ? 171*9781SMoriah.Waterland@Sun.COM get_inst_root() : "", pkginst, 172*9781SMoriah.Waterland@Sun.COM PKGINFO); 173*9781SMoriah.Waterland@Sun.COM if (i > sizeof (pkginfoPath)) { 174*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 175*9781SMoriah.Waterland@Sun.COM ((get_inst_root()) && 176*9781SMoriah.Waterland@Sun.COM (strcmp(get_inst_root(), "/") != 0)) ? 177*9781SMoriah.Waterland@Sun.COM get_inst_root() : "/", 178*9781SMoriah.Waterland@Sun.COM pkginst); 179*9781SMoriah.Waterland@Sun.COM quit(1); 180*9781SMoriah.Waterland@Sun.COM } 181*9781SMoriah.Waterland@Sun.COM } else { 182*9781SMoriah.Waterland@Sun.COM /* 183*9781SMoriah.Waterland@Sun.COM * non-global zone installation - use the "saved" pspool 184*9781SMoriah.Waterland@Sun.COM * pkginfo file in the global zone for this package: 185*9781SMoriah.Waterland@Sun.COM * --> /var/sadm/install/PKG/save/pspool/PKG/pkginfo 186*9781SMoriah.Waterland@Sun.COM * as the source pkginfo file to scan. 187*9781SMoriah.Waterland@Sun.COM */ 188*9781SMoriah.Waterland@Sun.COM i = snprintf(pkginfoPath, sizeof (pkginfoPath), "%s/%s", 189*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, PKGINFO); 190*9781SMoriah.Waterland@Sun.COM if (i > sizeof (pkginfoPath)) { 191*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, 192*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, PKGINFO); 193*9781SMoriah.Waterland@Sun.COM quit(1); 194*9781SMoriah.Waterland@Sun.COM } 195*9781SMoriah.Waterland@Sun.COM } 196*9781SMoriah.Waterland@Sun.COM 197*9781SMoriah.Waterland@Sun.COM i = snprintf(path, PATH_MAX, "%s/%s", pkgloc, PKGINFO); 198*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 199*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, pkgloc, PKGINFO); 200*9781SMoriah.Waterland@Sun.COM quit(1); 201*9781SMoriah.Waterland@Sun.COM } 202*9781SMoriah.Waterland@Sun.COM 203*9781SMoriah.Waterland@Sun.COM /* entry debugging info */ 204*9781SMoriah.Waterland@Sun.COM 205*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_ENTRY, 206*9781SMoriah.Waterland@Sun.COM instdir ? instdir : "??", 207*9781SMoriah.Waterland@Sun.COM ((get_inst_root()) && 208*9781SMoriah.Waterland@Sun.COM (strcmp(get_inst_root(), "/") != 0)) ? 209*9781SMoriah.Waterland@Sun.COM get_inst_root() : "??", 210*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir ? saveSpoolInstallDir : "??", 211*9781SMoriah.Waterland@Sun.COM pkgloc ? pkgloc : "??", is_spool_create(), 212*9781SMoriah.Waterland@Sun.COM get_info_basedir() ? get_info_basedir() : "??", 213*9781SMoriah.Waterland@Sun.COM pkginfoPath, path); 214*9781SMoriah.Waterland@Sun.COM 215*9781SMoriah.Waterland@Sun.COM /* 216*9781SMoriah.Waterland@Sun.COM * open the pkginfo file: 217*9781SMoriah.Waterland@Sun.COM * if the source pkginfo file to check is the same as the merged one 218*9781SMoriah.Waterland@Sun.COM * (e.g. /var/sadm/pkg/PKGINST/pkginfo) then do not open the source 219*9781SMoriah.Waterland@Sun.COM * pkginfo file to "verify" 220*9781SMoriah.Waterland@Sun.COM */ 221*9781SMoriah.Waterland@Sun.COM 222*9781SMoriah.Waterland@Sun.COM if (strcmp(pkginfoPath, path) == 0) { 223*9781SMoriah.Waterland@Sun.COM pkginfoFP = (FILE *)NULL; 224*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_SAME, path); 225*9781SMoriah.Waterland@Sun.COM } else { 226*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_DIFFERENT, pkginfoPath, path); 227*9781SMoriah.Waterland@Sun.COM pkginfoFP = fopen(pkginfoPath, "r"); 228*9781SMoriah.Waterland@Sun.COM 229*9781SMoriah.Waterland@Sun.COM if (pkginfoFP == (FILE *)NULL) { 230*9781SMoriah.Waterland@Sun.COM echoDebug(ERR_NO_PKG_INFOFILE, pkginst, pkginfoPath, 231*9781SMoriah.Waterland@Sun.COM strerror(errno)); 232*9781SMoriah.Waterland@Sun.COM } 233*9781SMoriah.Waterland@Sun.COM } 234*9781SMoriah.Waterland@Sun.COM 235*9781SMoriah.Waterland@Sun.COM /* 236*9781SMoriah.Waterland@Sun.COM * output packaging environment to create a pkginfo file in pkgloc[] 237*9781SMoriah.Waterland@Sun.COM */ 238*9781SMoriah.Waterland@Sun.COM 239*9781SMoriah.Waterland@Sun.COM if ((fp = fopen(path, "w")) == NULL) { 240*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_OPEN_FOR_WRITING, path, strerror(errno)); 241*9781SMoriah.Waterland@Sun.COM quit(99); 242*9781SMoriah.Waterland@Sun.COM } 243*9781SMoriah.Waterland@Sun.COM 244*9781SMoriah.Waterland@Sun.COM /* 245*9781SMoriah.Waterland@Sun.COM * output CLASSES attribute 246*9781SMoriah.Waterland@Sun.COM */ 247*9781SMoriah.Waterland@Sun.COM 248*9781SMoriah.Waterland@Sun.COM out = 0; 249*9781SMoriah.Waterland@Sun.COM (void) fputs("CLASSES=", fp); 250*9781SMoriah.Waterland@Sun.COM if (pclass) { 251*9781SMoriah.Waterland@Sun.COM (void) fputs(pclass[0]->name, fp); 252*9781SMoriah.Waterland@Sun.COM out++; 253*9781SMoriah.Waterland@Sun.COM for (i = 1; pclass[i]; i++) { 254*9781SMoriah.Waterland@Sun.COM (void) putc(' ', fp); 255*9781SMoriah.Waterland@Sun.COM (void) fputs(pclass[i]->name, fp); 256*9781SMoriah.Waterland@Sun.COM out++; 257*9781SMoriah.Waterland@Sun.COM } 258*9781SMoriah.Waterland@Sun.COM } 259*9781SMoriah.Waterland@Sun.COM nc = cl_getn(); 260*9781SMoriah.Waterland@Sun.COM for (i = 0; i < nc; i++) { 261*9781SMoriah.Waterland@Sun.COM int found = 0; 262*9781SMoriah.Waterland@Sun.COM 263*9781SMoriah.Waterland@Sun.COM if (pclass) { 264*9781SMoriah.Waterland@Sun.COM int j; 265*9781SMoriah.Waterland@Sun.COM 266*9781SMoriah.Waterland@Sun.COM for (j = 0; pclass[j]; ++j) { 267*9781SMoriah.Waterland@Sun.COM if (cl_nam(i) != NULL && 268*9781SMoriah.Waterland@Sun.COM strcmp(cl_nam(i), 269*9781SMoriah.Waterland@Sun.COM pclass[j]->name) == 0) { 270*9781SMoriah.Waterland@Sun.COM found++; 271*9781SMoriah.Waterland@Sun.COM break; 272*9781SMoriah.Waterland@Sun.COM } 273*9781SMoriah.Waterland@Sun.COM } 274*9781SMoriah.Waterland@Sun.COM } 275*9781SMoriah.Waterland@Sun.COM if (!found) { 276*9781SMoriah.Waterland@Sun.COM if (out > 0) { 277*9781SMoriah.Waterland@Sun.COM (void) putc(' ', fp); 278*9781SMoriah.Waterland@Sun.COM } 279*9781SMoriah.Waterland@Sun.COM (void) fputs(cl_nam(i), fp); 280*9781SMoriah.Waterland@Sun.COM out++; 281*9781SMoriah.Waterland@Sun.COM } 282*9781SMoriah.Waterland@Sun.COM } 283*9781SMoriah.Waterland@Sun.COM (void) putc('\n', fp); 284*9781SMoriah.Waterland@Sun.COM 285*9781SMoriah.Waterland@Sun.COM /* 286*9781SMoriah.Waterland@Sun.COM * NOTE : BASEDIR below is relative to the machine that 287*9781SMoriah.Waterland@Sun.COM * *runs* the package. If there's an install root, this 288*9781SMoriah.Waterland@Sun.COM * is actually the CLIENT_BASEDIR wrt the machine 289*9781SMoriah.Waterland@Sun.COM * doing the pkgadd'ing here. -- JST 290*9781SMoriah.Waterland@Sun.COM */ 291*9781SMoriah.Waterland@Sun.COM 292*9781SMoriah.Waterland@Sun.COM if (is_a_basedir()) { 293*9781SMoriah.Waterland@Sun.COM static char *txs1 = "BASEDIR="; 294*9781SMoriah.Waterland@Sun.COM 295*9781SMoriah.Waterland@Sun.COM (void) fputs(txs1, fp); 296*9781SMoriah.Waterland@Sun.COM (void) fputs(get_info_basedir(), fp); 297*9781SMoriah.Waterland@Sun.COM (void) putc('\n', fp); 298*9781SMoriah.Waterland@Sun.COM } else { 299*9781SMoriah.Waterland@Sun.COM (void) fputs("BASEDIR=/", fp); 300*9781SMoriah.Waterland@Sun.COM (void) putc('\n', fp); 301*9781SMoriah.Waterland@Sun.COM } 302*9781SMoriah.Waterland@Sun.COM 303*9781SMoriah.Waterland@Sun.COM /* 304*9781SMoriah.Waterland@Sun.COM * output all other environment attributes except those which 305*9781SMoriah.Waterland@Sun.COM * are relevant only to install. 306*9781SMoriah.Waterland@Sun.COM */ 307*9781SMoriah.Waterland@Sun.COM 308*9781SMoriah.Waterland@Sun.COM for (i = 0; environ[i] != (char *)NULL; i++) { 309*9781SMoriah.Waterland@Sun.COM char *ep = environ[i]; 310*9781SMoriah.Waterland@Sun.COM int attrPos = -1; 311*9781SMoriah.Waterland@Sun.COM int incr = (ATTRTBL_SIZE >> 1)+1; /* searches possible */ 312*9781SMoriah.Waterland@Sun.COM int pos = ATTRTBL_SIZE >> 1; /* start in middle */ 313*9781SMoriah.Waterland@Sun.COM NAMELIST_T *pp = (NAMELIST_T *)NULL; 314*9781SMoriah.Waterland@Sun.COM 315*9781SMoriah.Waterland@Sun.COM /* 316*9781SMoriah.Waterland@Sun.COM * find this attribute in the table - accept the attribute if it 317*9781SMoriah.Waterland@Sun.COM * is outside of the bounds of the table; otherwise, do a binary 318*9781SMoriah.Waterland@Sun.COM * search looking for this attribute. 319*9781SMoriah.Waterland@Sun.COM */ 320*9781SMoriah.Waterland@Sun.COM 321*9781SMoriah.Waterland@Sun.COM if (strncmp(ep, attrTbl[0]._nlName, attrTbl[0]._nlLen) < 0) { 322*9781SMoriah.Waterland@Sun.COM 323*9781SMoriah.Waterland@Sun.COM /* entry < first entry in attribute table */ 324*9781SMoriah.Waterland@Sun.COM 325*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_LESS_THAN, ep, 326*9781SMoriah.Waterland@Sun.COM attrTbl[0]._nlName); 327*9781SMoriah.Waterland@Sun.COM 328*9781SMoriah.Waterland@Sun.COM } else if (strncmp(ep, attrTbl[ATTRTBL_SIZE-1]._nlName, 329*9781SMoriah.Waterland@Sun.COM attrTbl[ATTRTBL_SIZE-1]._nlLen) > 0) { 330*9781SMoriah.Waterland@Sun.COM 331*9781SMoriah.Waterland@Sun.COM /* entry > last entry in attribute table */ 332*9781SMoriah.Waterland@Sun.COM 333*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_GREATER_THAN, ep, 334*9781SMoriah.Waterland@Sun.COM attrTbl[ATTRTBL_SIZE-1]._nlName); 335*9781SMoriah.Waterland@Sun.COM 336*9781SMoriah.Waterland@Sun.COM } else { 337*9781SMoriah.Waterland@Sun.COM /* first entry < entry < last entry in table: search */ 338*9781SMoriah.Waterland@Sun.COM 339*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_SEARCHING, ep, 340*9781SMoriah.Waterland@Sun.COM attrTbl[0]._nlName, 341*9781SMoriah.Waterland@Sun.COM attrTbl[ATTRTBL_SIZE-1]._nlName); 342*9781SMoriah.Waterland@Sun.COM 343*9781SMoriah.Waterland@Sun.COM while (incr > 0) { /* while possible to divide */ 344*9781SMoriah.Waterland@Sun.COM int r; 345*9781SMoriah.Waterland@Sun.COM 346*9781SMoriah.Waterland@Sun.COM pp = &attrTbl[pos]; 347*9781SMoriah.Waterland@Sun.COM 348*9781SMoriah.Waterland@Sun.COM /* compare current attr with this table entry */ 349*9781SMoriah.Waterland@Sun.COM r = strncmp(pp->_nlName, ep, pp->_nlLen); 350*9781SMoriah.Waterland@Sun.COM 351*9781SMoriah.Waterland@Sun.COM /* break out of loop if match */ 352*9781SMoriah.Waterland@Sun.COM if (r == 0) { 353*9781SMoriah.Waterland@Sun.COM /* save location/break if match found */ 354*9781SMoriah.Waterland@Sun.COM attrPos = pos; 355*9781SMoriah.Waterland@Sun.COM break; 356*9781SMoriah.Waterland@Sun.COM } 357*9781SMoriah.Waterland@Sun.COM 358*9781SMoriah.Waterland@Sun.COM /* no match search to next/prev half */ 359*9781SMoriah.Waterland@Sun.COM incr = incr >> 1; 360*9781SMoriah.Waterland@Sun.COM pos += (r < 0) ? incr : -incr; 361*9781SMoriah.Waterland@Sun.COM continue; 362*9781SMoriah.Waterland@Sun.COM } 363*9781SMoriah.Waterland@Sun.COM } 364*9781SMoriah.Waterland@Sun.COM 365*9781SMoriah.Waterland@Sun.COM /* handle excluded attribute found */ 366*9781SMoriah.Waterland@Sun.COM 367*9781SMoriah.Waterland@Sun.COM if ((attrPos >= 0) && (pp->_nlFlag == FLAG_EXCLUDE)) { 368*9781SMoriah.Waterland@Sun.COM /* attribute is excluded */ 369*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_EXCLUDING, ep); 370*9781SMoriah.Waterland@Sun.COM continue; 371*9781SMoriah.Waterland@Sun.COM } 372*9781SMoriah.Waterland@Sun.COM 373*9781SMoriah.Waterland@Sun.COM /* handle fixed attribute found */ 374*9781SMoriah.Waterland@Sun.COM 375*9781SMoriah.Waterland@Sun.COM if ((pkginfoFP != (FILE *)NULL) && (attrPos >= 0) && 376*9781SMoriah.Waterland@Sun.COM (pp->_nlFlag == FLAG_IDENTICAL)) { 377*9781SMoriah.Waterland@Sun.COM /* attribute must not change */ 378*9781SMoriah.Waterland@Sun.COM 379*9781SMoriah.Waterland@Sun.COM char *src = ep+pp->_nlLen; 380*9781SMoriah.Waterland@Sun.COM char *trg; 381*9781SMoriah.Waterland@Sun.COM char theAttr[PATH_MAX+1]; 382*9781SMoriah.Waterland@Sun.COM 383*9781SMoriah.Waterland@Sun.COM /* isolate attribute name only without '=' at end */ 384*9781SMoriah.Waterland@Sun.COM 385*9781SMoriah.Waterland@Sun.COM (void) strncpy(theAttr, pp->_nlName, pp->_nlLen-1); 386*9781SMoriah.Waterland@Sun.COM theAttr[pp->_nlLen-1] = '\0'; 387*9781SMoriah.Waterland@Sun.COM 388*9781SMoriah.Waterland@Sun.COM /* lookup attribute in installed package pkginfo file */ 389*9781SMoriah.Waterland@Sun.COM 390*9781SMoriah.Waterland@Sun.COM rewind(pkginfoFP); 391*9781SMoriah.Waterland@Sun.COM trg = fpkgparam(pkginfoFP, theAttr); 392*9781SMoriah.Waterland@Sun.COM 393*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_ATTRCOMP, theAttr, 394*9781SMoriah.Waterland@Sun.COM trg ? trg : ""); 395*9781SMoriah.Waterland@Sun.COM 396*9781SMoriah.Waterland@Sun.COM /* if target not found attribute is being added */ 397*9781SMoriah.Waterland@Sun.COM 398*9781SMoriah.Waterland@Sun.COM if (trg == (char *)NULL) { 399*9781SMoriah.Waterland@Sun.COM progerr(ERR_PKGINFO_ATTR_ADDED, pkginst, ep); 400*9781SMoriah.Waterland@Sun.COM quit(1); 401*9781SMoriah.Waterland@Sun.COM } 402*9781SMoriah.Waterland@Sun.COM 403*9781SMoriah.Waterland@Sun.COM /* error if two values are not the same */ 404*9781SMoriah.Waterland@Sun.COM 405*9781SMoriah.Waterland@Sun.COM if (strcmp(src, trg) != 0) { 406*9781SMoriah.Waterland@Sun.COM progerr(ERR_PKGINFO_ATTR_CHANGED, pkginst, 407*9781SMoriah.Waterland@Sun.COM theAttr, src, trg); 408*9781SMoriah.Waterland@Sun.COM quit(1); 409*9781SMoriah.Waterland@Sun.COM } 410*9781SMoriah.Waterland@Sun.COM } 411*9781SMoriah.Waterland@Sun.COM 412*9781SMoriah.Waterland@Sun.COM /* attribute not excluded/has not changed - process */ 413*9781SMoriah.Waterland@Sun.COM 414*9781SMoriah.Waterland@Sun.COM if ((strncmp(ep, "PKGSAV=", 7) == 0)) { 415*9781SMoriah.Waterland@Sun.COM (void) fputs("PKGSAV=", fp); 416*9781SMoriah.Waterland@Sun.COM (void) fputs(infoloc, fp); 417*9781SMoriah.Waterland@Sun.COM (void) putc('/', fp); 418*9781SMoriah.Waterland@Sun.COM (void) fputs(pkginst, fp); 419*9781SMoriah.Waterland@Sun.COM (void) fputs("/save\n", fp); 420*9781SMoriah.Waterland@Sun.COM continue; 421*9781SMoriah.Waterland@Sun.COM } 422*9781SMoriah.Waterland@Sun.COM 423*9781SMoriah.Waterland@Sun.COM if ((strncmp(ep, "UPDATE=", 7) == 0) && 424*9781SMoriah.Waterland@Sun.COM install_from_pspool != 0 && 425*9781SMoriah.Waterland@Sun.COM !isPatchUpdate() && 426*9781SMoriah.Waterland@Sun.COM !isUpdate()) { 427*9781SMoriah.Waterland@Sun.COM continue; 428*9781SMoriah.Waterland@Sun.COM } 429*9781SMoriah.Waterland@Sun.COM 430*9781SMoriah.Waterland@Sun.COM echoDebug(DBG_MERGINFO_FINAL, ep); 431*9781SMoriah.Waterland@Sun.COM 432*9781SMoriah.Waterland@Sun.COM (void) fputs(ep, fp); 433*9781SMoriah.Waterland@Sun.COM (void) putc('\n', fp); 434*9781SMoriah.Waterland@Sun.COM } 435*9781SMoriah.Waterland@Sun.COM 436*9781SMoriah.Waterland@Sun.COM (void) fclose(fp); 437*9781SMoriah.Waterland@Sun.COM (void) fclose(pkginfoFP); 438*9781SMoriah.Waterland@Sun.COM 439*9781SMoriah.Waterland@Sun.COM /* 440*9781SMoriah.Waterland@Sun.COM * copy all packaging scripts to appropriate directory 441*9781SMoriah.Waterland@Sun.COM */ 442*9781SMoriah.Waterland@Sun.COM 443*9781SMoriah.Waterland@Sun.COM i = snprintf(path, PATH_MAX, "%s/install", instdir); 444*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 445*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, instdir, "/install"); 446*9781SMoriah.Waterland@Sun.COM quit(1); 447*9781SMoriah.Waterland@Sun.COM } 448*9781SMoriah.Waterland@Sun.COM 449*9781SMoriah.Waterland@Sun.COM if ((pdirfp = opendir(path)) != NULL) { 450*9781SMoriah.Waterland@Sun.COM struct dirent *dp; 451*9781SMoriah.Waterland@Sun.COM 452*9781SMoriah.Waterland@Sun.COM while ((dp = readdir(pdirfp)) != NULL) { 453*9781SMoriah.Waterland@Sun.COM if (dp->d_name[0] == '.') 454*9781SMoriah.Waterland@Sun.COM continue; 455*9781SMoriah.Waterland@Sun.COM 456*9781SMoriah.Waterland@Sun.COM i = snprintf(path, PATH_MAX, "%s/install/%s", 457*9781SMoriah.Waterland@Sun.COM instdir, dp->d_name); 458*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 459*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_3, instdir, "/install/", 460*9781SMoriah.Waterland@Sun.COM dp->d_name); 461*9781SMoriah.Waterland@Sun.COM quit(1); 462*9781SMoriah.Waterland@Sun.COM } 463*9781SMoriah.Waterland@Sun.COM 464*9781SMoriah.Waterland@Sun.COM i = snprintf(temp, PATH_MAX, "%s/%s", pkgbin, 465*9781SMoriah.Waterland@Sun.COM dp->d_name); 466*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 467*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, pkgbin, dp->d_name); 468*9781SMoriah.Waterland@Sun.COM quit(1); 469*9781SMoriah.Waterland@Sun.COM } 470*9781SMoriah.Waterland@Sun.COM 471*9781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC|DIR_DISPLAY, path, temp, 0644)) { 472*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_COPY, dp->d_name, pkgbin); 473*9781SMoriah.Waterland@Sun.COM quit(99); 474*9781SMoriah.Waterland@Sun.COM } 475*9781SMoriah.Waterland@Sun.COM } 476*9781SMoriah.Waterland@Sun.COM (void) closedir(pdirfp); 477*9781SMoriah.Waterland@Sun.COM } 478*9781SMoriah.Waterland@Sun.COM 479*9781SMoriah.Waterland@Sun.COM /* 480*9781SMoriah.Waterland@Sun.COM * copy all packaging scripts to the partial spool directory 481*9781SMoriah.Waterland@Sun.COM */ 482*9781SMoriah.Waterland@Sun.COM 483*9781SMoriah.Waterland@Sun.COM if (!is_spool_create()) { 484*9781SMoriah.Waterland@Sun.COM /* packages are being spooled to ../save/pspool/.. */ 485*9781SMoriah.Waterland@Sun.COM i = snprintf(path, PATH_MAX, "%s/install", instdir); 486*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 487*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, instdir, "/install"); 488*9781SMoriah.Waterland@Sun.COM quit(1); 489*9781SMoriah.Waterland@Sun.COM } 490*9781SMoriah.Waterland@Sun.COM 491*9781SMoriah.Waterland@Sun.COM if (((pdirfp = opendir(path)) != NULL) && 492*9781SMoriah.Waterland@Sun.COM !isPatchUpdate()) { 493*9781SMoriah.Waterland@Sun.COM struct dirent *dp; 494*9781SMoriah.Waterland@Sun.COM 495*9781SMoriah.Waterland@Sun.COM 496*9781SMoriah.Waterland@Sun.COM while ((dp = readdir(pdirfp)) != NULL) { 497*9781SMoriah.Waterland@Sun.COM if (dp->d_name[0] == '.') 498*9781SMoriah.Waterland@Sun.COM continue; 499*9781SMoriah.Waterland@Sun.COM /* 500*9781SMoriah.Waterland@Sun.COM * Don't copy i.none since if it exists it 501*9781SMoriah.Waterland@Sun.COM * contains Class Archive Format procedure 502*9781SMoriah.Waterland@Sun.COM * for installing archives. Only Directory 503*9781SMoriah.Waterland@Sun.COM * Format packages can exist 504*9781SMoriah.Waterland@Sun.COM * in a global spooled area. 505*9781SMoriah.Waterland@Sun.COM */ 506*9781SMoriah.Waterland@Sun.COM if (strcmp(dp->d_name, "i.none") == 0) 507*9781SMoriah.Waterland@Sun.COM continue; 508*9781SMoriah.Waterland@Sun.COM 509*9781SMoriah.Waterland@Sun.COM i = snprintf(path, PATH_MAX, "%s/install/%s", 510*9781SMoriah.Waterland@Sun.COM instdir, dp->d_name); 511*9781SMoriah.Waterland@Sun.COM 512*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 513*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_3, instdir, 514*9781SMoriah.Waterland@Sun.COM "/install/", dp->d_name); 515*9781SMoriah.Waterland@Sun.COM quit(1); 516*9781SMoriah.Waterland@Sun.COM } 517*9781SMoriah.Waterland@Sun.COM 518*9781SMoriah.Waterland@Sun.COM i = snprintf(temp, PATH_MAX, "%s/install/%s", 519*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 520*9781SMoriah.Waterland@Sun.COM dp->d_name); 521*9781SMoriah.Waterland@Sun.COM 522*9781SMoriah.Waterland@Sun.COM if (i > PATH_MAX) { 523*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_3, 524*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, 525*9781SMoriah.Waterland@Sun.COM "/install/", dp->d_name); 526*9781SMoriah.Waterland@Sun.COM quit(1); 527*9781SMoriah.Waterland@Sun.COM } 528*9781SMoriah.Waterland@Sun.COM 529*9781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, path, temp, 0644)) { 530*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_COPY, path, temp); 531*9781SMoriah.Waterland@Sun.COM (void) closedir(pdirfp); 532*9781SMoriah.Waterland@Sun.COM quit(99); 533*9781SMoriah.Waterland@Sun.COM } 534*9781SMoriah.Waterland@Sun.COM } 535*9781SMoriah.Waterland@Sun.COM (void) closedir(pdirfp); 536*9781SMoriah.Waterland@Sun.COM } 537*9781SMoriah.Waterland@Sun.COM 538*9781SMoriah.Waterland@Sun.COM /* 539*9781SMoriah.Waterland@Sun.COM * Now copy the original pkginfo and pkgmap files from the 540*9781SMoriah.Waterland@Sun.COM * installing package to the spooled directory. 541*9781SMoriah.Waterland@Sun.COM */ 542*9781SMoriah.Waterland@Sun.COM 543*9781SMoriah.Waterland@Sun.COM i = snprintf(path, sizeof (path), "%s/%s", instdir, PKGINFO); 544*9781SMoriah.Waterland@Sun.COM if (i > sizeof (path)) { 545*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, instdir, PKGINFO); 546*9781SMoriah.Waterland@Sun.COM quit(1); 547*9781SMoriah.Waterland@Sun.COM } 548*9781SMoriah.Waterland@Sun.COM 549*9781SMoriah.Waterland@Sun.COM i = snprintf(temp, sizeof (temp), "%s/%s", 550*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir, PKGINFO); 551*9781SMoriah.Waterland@Sun.COM if (i > sizeof (temp)) { 552*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, saveSpoolInstallDir, 553*9781SMoriah.Waterland@Sun.COM PKGINFO); 554*9781SMoriah.Waterland@Sun.COM quit(1); 555*9781SMoriah.Waterland@Sun.COM } 556*9781SMoriah.Waterland@Sun.COM 557*9781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, path, temp, 0644)) { 558*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_COPY, path, temp); 559*9781SMoriah.Waterland@Sun.COM quit(99); 560*9781SMoriah.Waterland@Sun.COM } 561*9781SMoriah.Waterland@Sun.COM 562*9781SMoriah.Waterland@Sun.COM /* 563*9781SMoriah.Waterland@Sun.COM * Only want to copy the FCS pkgmap if this is not a 564*9781SMoriah.Waterland@Sun.COM * patch installation. 565*9781SMoriah.Waterland@Sun.COM */ 566*9781SMoriah.Waterland@Sun.COM 567*9781SMoriah.Waterland@Sun.COM if (!isPatchUpdate()) { 568*9781SMoriah.Waterland@Sun.COM i = snprintf(path, sizeof (path), "%s/pkgmap", instdir); 569*9781SMoriah.Waterland@Sun.COM if (i > sizeof (path)) { 570*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, instdir, "pkgmap"); 571*9781SMoriah.Waterland@Sun.COM quit(1); 572*9781SMoriah.Waterland@Sun.COM } 573*9781SMoriah.Waterland@Sun.COM 574*9781SMoriah.Waterland@Sun.COM i = snprintf(temp, sizeof (temp), "%s/pkgmap", 575*9781SMoriah.Waterland@Sun.COM saveSpoolInstallDir); 576*9781SMoriah.Waterland@Sun.COM if (i > sizeof (path)) { 577*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, saveSpoolInstallDir, 578*9781SMoriah.Waterland@Sun.COM "pkgmap"); 579*9781SMoriah.Waterland@Sun.COM quit(1); 580*9781SMoriah.Waterland@Sun.COM } 581*9781SMoriah.Waterland@Sun.COM 582*9781SMoriah.Waterland@Sun.COM if (cppath(MODE_SRC, path, temp, 0644)) { 583*9781SMoriah.Waterland@Sun.COM progerr(ERR_CANNOT_COPY, path, temp); 584*9781SMoriah.Waterland@Sun.COM quit(99); 585*9781SMoriah.Waterland@Sun.COM } 586*9781SMoriah.Waterland@Sun.COM } 587*9781SMoriah.Waterland@Sun.COM } 588*9781SMoriah.Waterland@Sun.COM 589*9781SMoriah.Waterland@Sun.COM /* 590*9781SMoriah.Waterland@Sun.COM * If we are installing from a spool directory 591*9781SMoriah.Waterland@Sun.COM * copy the save directory from it, it may have 592*9781SMoriah.Waterland@Sun.COM * been patched. Duplicate it only if this 593*9781SMoriah.Waterland@Sun.COM * installation isn't an update and is not to 594*9781SMoriah.Waterland@Sun.COM * an alternate root. 595*9781SMoriah.Waterland@Sun.COM */ 596*9781SMoriah.Waterland@Sun.COM if (strstr(instdir, "pspool") != NULL) { 597*9781SMoriah.Waterland@Sun.COM struct stat status; 598*9781SMoriah.Waterland@Sun.COM 599*9781SMoriah.Waterland@Sun.COM i = snprintf(path, sizeof (path), "%s/save", instdir); 600*9781SMoriah.Waterland@Sun.COM if (i > sizeof (path)) { 601*9781SMoriah.Waterland@Sun.COM progerr(ERR_CREATE_PATH_2, instdir, "save"); 602*9781SMoriah.Waterland@Sun.COM quit(1); 603*9781SMoriah.Waterland@Sun.COM } 604*9781SMoriah.Waterland@Sun.COM 605*9781SMoriah.Waterland@Sun.COM if ((stat(path, &status) == 0) && 606*9781SMoriah.Waterland@Sun.COM (status.st_mode & S_IFDIR) && 607*9781SMoriah.Waterland@Sun.COM !isPatchUpdate()) { 608*9781SMoriah.Waterland@Sun.COM i = snprintf(cmd, sizeof (cmd), "cp -pr %s/* %s", 609*9781SMoriah.Waterland@Sun.COM path, pkgsav); 610*9781SMoriah.Waterland@Sun.COM if (i > sizeof (cmd)) { 611*9781SMoriah.Waterland@Sun.COM progerr(ERR_SNPRINTF, "cp -pr %s/* %s"); 612*9781SMoriah.Waterland@Sun.COM quit(1); 613*9781SMoriah.Waterland@Sun.COM } 614*9781SMoriah.Waterland@Sun.COM 615*9781SMoriah.Waterland@Sun.COM if (system(cmd)) { 616*9781SMoriah.Waterland@Sun.COM progerr(ERR_PKGBINCP, path, pkgsav); 617*9781SMoriah.Waterland@Sun.COM quit(99); 618*9781SMoriah.Waterland@Sun.COM } 619*9781SMoriah.Waterland@Sun.COM } 620*9781SMoriah.Waterland@Sun.COM } 621*9781SMoriah.Waterland@Sun.COM } 622