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