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 2009 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 <signal.h> 33*5c51f124SMoriah Waterland #include <string.h> 34*5c51f124SMoriah Waterland #include <errno.h> 35*5c51f124SMoriah Waterland #include <unistd.h> 36*5c51f124SMoriah Waterland #include <stdlib.h> 37*5c51f124SMoriah Waterland #include <assert.h> 38*5c51f124SMoriah Waterland #include <pkgstrct.h> 39*5c51f124SMoriah Waterland #include <sys/stat.h> 40*5c51f124SMoriah Waterland #include <locale.h> 41*5c51f124SMoriah Waterland #include <libintl.h> 42*5c51f124SMoriah Waterland #include <pkginfo.h> 43*5c51f124SMoriah Waterland #include <instzones_api.h> 44*5c51f124SMoriah Waterland #include <pkglib.h> 45*5c51f124SMoriah Waterland #include <libinst.h> 46*5c51f124SMoriah Waterland #include <messages.h> 47*5c51f124SMoriah Waterland 48*5c51f124SMoriah Waterland /* merg() return codes */ 49*5c51f124SMoriah Waterland #define MRG_SAME 0 50*5c51f124SMoriah Waterland #define MRG_DIFFERENT 1 51*5c51f124SMoriah Waterland #define MRG_REPLACE 2 52*5c51f124SMoriah Waterland 53*5c51f124SMoriah Waterland /* typechg() return codes */ 54*5c51f124SMoriah Waterland #define TYPE_OK 0 55*5c51f124SMoriah Waterland #define TYPE_WARNING 1 56*5c51f124SMoriah Waterland #define TYPE_IGNORED 2 57*5c51f124SMoriah Waterland #define TYPE_REPLACE 3 58*5c51f124SMoriah Waterland #define TYPE_FATAL 4 59*5c51f124SMoriah Waterland 60*5c51f124SMoriah Waterland /* message pool */ 61*5c51f124SMoriah Waterland #define ERR_OUTPUT "unable to update package database" 62*5c51f124SMoriah Waterland #define ERR_PINFO "missing pinfo structure for <%s>" 63*5c51f124SMoriah Waterland #define INFO_PROCESS " %2ld%% of information processed; continuing ..." 64*5c51f124SMoriah Waterland 65*5c51f124SMoriah Waterland #define WRN_NOTFILE "WARNING: %s <no longer a regular file>" 66*5c51f124SMoriah Waterland #define WRN_NOTSYMLN "WARNING: %s <no longer a symbolic link>" 67*5c51f124SMoriah Waterland #define WRN_NOTLINK "WARNING: %s <no longer a linked file>" 68*5c51f124SMoriah Waterland #define WRN_NOTDIR "WARNING: %s <no longer a directory>" 69*5c51f124SMoriah Waterland #define WRN_NOTCHAR "WARNING: %s <no longer a character special device>" 70*5c51f124SMoriah Waterland #define WRN_NOTBLOCK "WARNING: %s <no longer a block special device>" 71*5c51f124SMoriah Waterland #define WRN_NOTPIPE "WARNING: %s <no longer a named pipe>" 72*5c51f124SMoriah Waterland #define WRN_TOEXCL "WARNING: cannot convert %s to an exclusive directory." 73*5c51f124SMoriah Waterland #define WRN_ODDVERIFY "WARNING: quick verify disabled for class %s." 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland #define MSG_TYPIGN "Object type change ignored." 76*5c51f124SMoriah Waterland #define MSG_TYPE_ERR "Package attempts fatal object type change." 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland extern char *pkginst; 79*5c51f124SMoriah Waterland extern int nosetuid, nocnflct, otherstoo; 80*5c51f124SMoriah Waterland 81*5c51f124SMoriah Waterland /* pkgobjmap.c */ 82*5c51f124SMoriah Waterland extern int cp_cfent(struct cfent *cf_ent, struct cfextra *el_ent); 83*5c51f124SMoriah Waterland 84*5c51f124SMoriah Waterland /* setlist.c */ 85*5c51f124SMoriah Waterland extern void cl_def_dverify(int idx); 86*5c51f124SMoriah Waterland 87*5c51f124SMoriah Waterland char dbst = '\0'; /* usually set by installf() or removef() */ 88*5c51f124SMoriah Waterland 89*5c51f124SMoriah Waterland int files_installed(void); /* return number of files installed. */ 90*5c51f124SMoriah Waterland 91*5c51f124SMoriah Waterland static int errflg = 0; 92*5c51f124SMoriah Waterland static int eptnum; 93*5c51f124SMoriah Waterland static VFP_T *fpvfp = {(VFP_T *)NULL}; 94*5c51f124SMoriah Waterland static long sizetot; 95*5c51f124SMoriah Waterland static int seconds; 96*5c51f124SMoriah Waterland static int installed; /* # of files, already properly installed. */ 97*5c51f124SMoriah Waterland static struct pinfo *pkgpinfo = (struct pinfo *)0; 98*5c51f124SMoriah Waterland 99*5c51f124SMoriah Waterland static int is_setuid(struct cfent *ent); 100*5c51f124SMoriah Waterland static int is_setgid(struct cfent *ent); 101*5c51f124SMoriah Waterland static int merg(struct cfextra *el_ent, struct cfent *cf_ent); 102*5c51f124SMoriah Waterland static int do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, 103*5c51f124SMoriah Waterland struct cfent *cf_ent, int ctrl); 104*5c51f124SMoriah Waterland static int do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl); 105*5c51f124SMoriah Waterland static int typechg(struct cfent *el_ent, struct cfent *cf_ent, 106*5c51f124SMoriah Waterland struct mergstat *mstat); 107*5c51f124SMoriah Waterland 108*5c51f124SMoriah Waterland static void set_change(struct cfextra *el_ent); 109*5c51f124SMoriah Waterland static void chgclass(struct cfent *cf_ent, struct pinfo *pinfo); 110*5c51f124SMoriah Waterland static void output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo); 111*5c51f124SMoriah Waterland 112*5c51f124SMoriah Waterland /* ARGSUNUSED */ 113*5c51f124SMoriah Waterland void 114*5c51f124SMoriah Waterland notice(int n) 115*5c51f124SMoriah Waterland { 116*5c51f124SMoriah Waterland #ifdef lint 117*5c51f124SMoriah Waterland int i = n; 118*5c51f124SMoriah Waterland n = i; 119*5c51f124SMoriah Waterland #endif /* lint */ 120*5c51f124SMoriah Waterland (void) signal(SIGALRM, SIG_IGN); 121*5c51f124SMoriah Waterland if (sizetot != 0) { 122*5c51f124SMoriah Waterland echo(gettext(INFO_PROCESS), 123*5c51f124SMoriah Waterland vfpGetBytesRemaining(fpvfp) * 100L / sizetot); 124*5c51f124SMoriah Waterland } 125*5c51f124SMoriah Waterland (void) signal(SIGALRM, notice); 126*5c51f124SMoriah Waterland (void) alarm(seconds); 127*5c51f124SMoriah Waterland } 128*5c51f124SMoriah Waterland 129*5c51f124SMoriah Waterland /* ARGSUSED */ 130*5c51f124SMoriah Waterland 131*5c51f124SMoriah Waterland /* 132*5c51f124SMoriah Waterland * This scans the extlist (pkgmap) and the package database to the end, 133*5c51f124SMoriah Waterland * copying out the merged contents to the file at tmpfp. It updates the mergstat 134*5c51f124SMoriah Waterland * structures and deals with administrative defaults regarding setuid and 135*5c51f124SMoriah Waterland * conflict. 136*5c51f124SMoriah Waterland * 137*5c51f124SMoriah Waterland * Since both the extlist and the package database entries are in numerical 138*5c51f124SMoriah Waterland * order, they both scan unidirectionally. If the entry in the extlist is 139*5c51f124SMoriah Waterland * found in the package database (by pathname) then do_like_ent() is called. 140*5c51f124SMoriah Waterland * If the extlist entry is not found in the package database then 141*5c51f124SMoriah Waterland * do_new_ent() is called. srchcfile() is responsible for copying out 142*5c51f124SMoriah Waterland * non-matching package database entries. At package database EOF, the 143*5c51f124SMoriah Waterland * eocontents flag is set and the rest of the extlist are assumed to be new 144*5c51f124SMoriah Waterland * entries. At the end of the extlist, the eoextlist flag is set and the 145*5c51f124SMoriah Waterland * remaining package database ends up copied out by srchcfile(). 146*5c51f124SMoriah Waterland */ 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland int 149*5c51f124SMoriah Waterland pkgdbmerg(VFP_T *mapvfp, VFP_T *tmpvfp, struct cfextra **extlist, int notify) 150*5c51f124SMoriah Waterland { 151*5c51f124SMoriah Waterland static struct cfent cf_ent; /* scratch area */ 152*5c51f124SMoriah Waterland struct cfextra *el_ent; /* extlist entry under review */ 153*5c51f124SMoriah Waterland int eocontents = 0; 154*5c51f124SMoriah Waterland int eoextlist = 0; 155*5c51f124SMoriah Waterland int n; 156*5c51f124SMoriah Waterland int changed; 157*5c51f124SMoriah Waterland int assume_ok = 0; 158*5c51f124SMoriah Waterland 159*5c51f124SMoriah Waterland cf_ent.pinfo = (NULL); 160*5c51f124SMoriah Waterland errflg = 0; 161*5c51f124SMoriah Waterland eptnum = 0; 162*5c51f124SMoriah Waterland installed = changed = 0; 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland fpvfp = mapvfp; /* for notice function ...arg! */ 165*5c51f124SMoriah Waterland 166*5c51f124SMoriah Waterland if (notify) { 167*5c51f124SMoriah Waterland seconds = notify; 168*5c51f124SMoriah Waterland (void) signal(SIGALRM, notice); 169*5c51f124SMoriah Waterland (void) alarm(seconds); 170*5c51f124SMoriah Waterland } 171*5c51f124SMoriah Waterland 172*5c51f124SMoriah Waterland (void) sighold(SIGALRM); 173*5c51f124SMoriah Waterland 174*5c51f124SMoriah Waterland sizetot = (((ptrdiff_t)(mapvfp->_vfpEnd)) - 175*5c51f124SMoriah Waterland ((ptrdiff_t)(mapvfp->_vfpStart))); 176*5c51f124SMoriah Waterland vfpRewind(mapvfp); 177*5c51f124SMoriah Waterland vfpRewind(tmpvfp); 178*5c51f124SMoriah Waterland 179*5c51f124SMoriah Waterland (void) sigrelse(SIGALRM); 180*5c51f124SMoriah Waterland 181*5c51f124SMoriah Waterland do { 182*5c51f124SMoriah Waterland (void) sighold(SIGALRM); 183*5c51f124SMoriah Waterland 184*5c51f124SMoriah Waterland /* 185*5c51f124SMoriah Waterland * If there's an entry in the extlist at this position, 186*5c51f124SMoriah Waterland * process that entry. 187*5c51f124SMoriah Waterland */ 188*5c51f124SMoriah Waterland if (!eoextlist && (el_ent = extlist[eptnum])) { 189*5c51f124SMoriah Waterland 190*5c51f124SMoriah Waterland /* Metafiles don't get merged. */ 191*5c51f124SMoriah Waterland if ((el_ent->cf_ent.ftype == 'i') || 192*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'n')) { 193*5c51f124SMoriah Waterland continue; 194*5c51f124SMoriah Waterland } 195*5c51f124SMoriah Waterland 196*5c51f124SMoriah Waterland /* 197*5c51f124SMoriah Waterland * Copy cfextra structure for duplicated paths. 198*5c51f124SMoriah Waterland * This is not just an optimization, it is 199*5c51f124SMoriah Waterland * necessary for correct operation of algorithm. 200*5c51f124SMoriah Waterland */ 201*5c51f124SMoriah Waterland if ((eptnum > 0) && (strncmp(el_ent->cf_ent.path, 202*5c51f124SMoriah Waterland extlist[eptnum-1]->cf_ent.path, PATH_MAX) == 0)) { 203*5c51f124SMoriah Waterland memcpy(extlist[eptnum], extlist[eptnum-1], 204*5c51f124SMoriah Waterland sizeof (struct cfextra)); 205*5c51f124SMoriah Waterland continue; 206*5c51f124SMoriah Waterland } 207*5c51f124SMoriah Waterland 208*5c51f124SMoriah Waterland /* 209*5c51f124SMoriah Waterland * Normally dbst comes to us from installf() or 210*5c51f124SMoriah Waterland * removef() in order to specify their special 211*5c51f124SMoriah Waterland * database status codes. They cannot implement a 212*5c51f124SMoriah Waterland * quick verify (it just doesn't make sense). For 213*5c51f124SMoriah Waterland * that reason, we can test to see if we already have 214*5c51f124SMoriah Waterland * a special database status. If we don't (it's from 215*5c51f124SMoriah Waterland * pkgadd) then we can test to see if this is calling 216*5c51f124SMoriah Waterland * for a quick verify wherein we assume the install 217*5c51f124SMoriah Waterland * will work and fix it if it doesn't. In that case 218*5c51f124SMoriah Waterland * we set our own dbst to be ENTRY_OK. 219*5c51f124SMoriah Waterland */ 220*5c51f124SMoriah Waterland if (dbst == '\0') { 221*5c51f124SMoriah Waterland if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) == 222*5c51f124SMoriah Waterland QKVERIFY) { 223*5c51f124SMoriah Waterland assume_ok = 1; 224*5c51f124SMoriah Waterland } 225*5c51f124SMoriah Waterland } else { 226*5c51f124SMoriah Waterland /* 227*5c51f124SMoriah Waterland * If we DO end up with an installf/quick 228*5c51f124SMoriah Waterland * verify combination, we fix that by simply 229*5c51f124SMoriah Waterland * denying the quick verify for this class. 230*5c51f124SMoriah Waterland * This forces everything to come out alright 231*5c51f124SMoriah Waterland * by forcing the standard assumptions as 232*5c51f124SMoriah Waterland * regards package database for the rest of 233*5c51f124SMoriah Waterland * the load. 234*5c51f124SMoriah Waterland */ 235*5c51f124SMoriah Waterland if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) == 236*5c51f124SMoriah Waterland QKVERIFY) { 237*5c51f124SMoriah Waterland logerr(gettext(WRN_ODDVERIFY), 238*5c51f124SMoriah Waterland cl_nam( 239*5c51f124SMoriah Waterland el_ent->cf_ent.pkg_class_idx)); 240*5c51f124SMoriah Waterland /* 241*5c51f124SMoriah Waterland * Set destination verification to 242*5c51f124SMoriah Waterland * default. 243*5c51f124SMoriah Waterland */ 244*5c51f124SMoriah Waterland cl_def_dverify( 245*5c51f124SMoriah Waterland el_ent->cf_ent.pkg_class_idx); 246*5c51f124SMoriah Waterland } 247*5c51f124SMoriah Waterland } 248*5c51f124SMoriah Waterland 249*5c51f124SMoriah Waterland /* 250*5c51f124SMoriah Waterland * Comply with administrative requirements regarding 251*5c51f124SMoriah Waterland * setuid/setgid processes. 252*5c51f124SMoriah Waterland */ 253*5c51f124SMoriah Waterland if (is_setuid(&(el_ent->cf_ent))) { 254*5c51f124SMoriah Waterland el_ent->mstat.setuid = 1; 255*5c51f124SMoriah Waterland } 256*5c51f124SMoriah Waterland if (is_setgid(&(el_ent->cf_ent))) { 257*5c51f124SMoriah Waterland el_ent->mstat.setgid = 1; 258*5c51f124SMoriah Waterland } 259*5c51f124SMoriah Waterland 260*5c51f124SMoriah Waterland /* 261*5c51f124SMoriah Waterland * If setuid/setgid processes are not allowed, reset 262*5c51f124SMoriah Waterland * those bits. 263*5c51f124SMoriah Waterland */ 264*5c51f124SMoriah Waterland if (nosetuid && (el_ent->mstat.setgid || 265*5c51f124SMoriah Waterland el_ent->mstat.setuid)) { 266*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode &= 267*5c51f124SMoriah Waterland ~(S_ISUID | S_ISGID); 268*5c51f124SMoriah Waterland } 269*5c51f124SMoriah Waterland } else { 270*5c51f124SMoriah Waterland eoextlist = 1; /* end of extlist[] */ 271*5c51f124SMoriah Waterland } 272*5c51f124SMoriah Waterland 273*5c51f124SMoriah Waterland /* 274*5c51f124SMoriah Waterland * If we're not at the end of the package database, get the 275*5c51f124SMoriah Waterland * next entry for comparison. 276*5c51f124SMoriah Waterland */ 277*5c51f124SMoriah Waterland if (!eocontents) { 278*5c51f124SMoriah Waterland 279*5c51f124SMoriah Waterland /* Search package database for this entry. */ 280*5c51f124SMoriah Waterland n = srchcfile(&cf_ent, el_ent ? 281*5c51f124SMoriah Waterland el_ent->cf_ent.path : NULL, 282*5c51f124SMoriah Waterland mapvfp, tmpvfp); 283*5c51f124SMoriah Waterland 284*5c51f124SMoriah Waterland /* 285*5c51f124SMoriah Waterland * If there was an error, note it and return an error 286*5c51f124SMoriah Waterland * flag. 287*5c51f124SMoriah Waterland */ 288*5c51f124SMoriah Waterland if (n < 0) { 289*5c51f124SMoriah Waterland char *errstr = getErrstr(); 290*5c51f124SMoriah Waterland logerr(gettext( 291*5c51f124SMoriah Waterland "bad entry read from contents file")); 292*5c51f124SMoriah Waterland logerr(gettext("- pathname: %s"), 293*5c51f124SMoriah Waterland (cf_ent.path && *cf_ent.path) ? 294*5c51f124SMoriah Waterland cf_ent.path : "Unknown"); 295*5c51f124SMoriah Waterland logerr(gettext("- problem: %s"), 296*5c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 297*5c51f124SMoriah Waterland return (-1); 298*5c51f124SMoriah Waterland /* 299*5c51f124SMoriah Waterland * If there was a match, then merge them into a 300*5c51f124SMoriah Waterland * single entry. 301*5c51f124SMoriah Waterland */ 302*5c51f124SMoriah Waterland } else if (n == 1) { 303*5c51f124SMoriah Waterland /* 304*5c51f124SMoriah Waterland * If this package is overwriting a setuid or 305*5c51f124SMoriah Waterland * setgid process, set the status bits so we 306*5c51f124SMoriah Waterland * can inform the administrator. 307*5c51f124SMoriah Waterland */ 308*5c51f124SMoriah Waterland if (is_setuid(&cf_ent)) { 309*5c51f124SMoriah Waterland el_ent->mstat.osetuid = 1; 310*5c51f124SMoriah Waterland } 311*5c51f124SMoriah Waterland 312*5c51f124SMoriah Waterland if (is_setgid(&cf_ent)) { 313*5c51f124SMoriah Waterland el_ent->mstat.osetgid = 1; 314*5c51f124SMoriah Waterland } 315*5c51f124SMoriah Waterland /* 316*5c51f124SMoriah Waterland * Detect if a symlink has changed to directory 317*5c51f124SMoriah Waterland * If so mark all the files/dir supposed to be 318*5c51f124SMoriah Waterland * iniside this dir, so that they are not miss 319*5c51f124SMoriah Waterland * understood by do_new_ent later as already 320*5c51f124SMoriah Waterland * installed. 321*5c51f124SMoriah Waterland */ 322*5c51f124SMoriah Waterland if ((!eoextlist) && (cf_ent.ftype == 's') && 323*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'd')) { 324*5c51f124SMoriah Waterland int i; 325*5c51f124SMoriah Waterland int plen = strlen(el_ent->cf_ent.path); 326*5c51f124SMoriah Waterland for (i = eptnum + 1; extlist[i]; i++) { 327*5c51f124SMoriah Waterland if (strncmp(el_ent->cf_ent.path, 328*5c51f124SMoriah Waterland extlist[i]->cf_ent.path, 329*5c51f124SMoriah Waterland plen) != 0) 330*5c51f124SMoriah Waterland break; 331*5c51f124SMoriah Waterland extlist[i]->mstat.parentsyml2dir 332*5c51f124SMoriah Waterland = 1; 333*5c51f124SMoriah Waterland } 334*5c51f124SMoriah Waterland } 335*5c51f124SMoriah Waterland 336*5c51f124SMoriah Waterland if (do_like_ent(tmpvfp, el_ent, &cf_ent, 337*5c51f124SMoriah Waterland assume_ok)) { 338*5c51f124SMoriah Waterland changed++; 339*5c51f124SMoriah Waterland } 340*5c51f124SMoriah Waterland 341*5c51f124SMoriah Waterland /* 342*5c51f124SMoriah Waterland * If the alphabetical position in the package 343*5c51f124SMoriah Waterland * database is unfilled, then this will be a new 344*5c51f124SMoriah Waterland * entry. If n == 0, then we're also at the end of 345*5c51f124SMoriah Waterland * the contents file. 346*5c51f124SMoriah Waterland */ 347*5c51f124SMoriah Waterland } else { 348*5c51f124SMoriah Waterland if (n == 0) { 349*5c51f124SMoriah Waterland eocontents++; 350*5c51f124SMoriah Waterland } 351*5c51f124SMoriah Waterland 352*5c51f124SMoriah Waterland /* 353*5c51f124SMoriah Waterland * If there is an extlist entry in the 354*5c51f124SMoriah Waterland * hopper, insert it at the end of the 355*5c51f124SMoriah Waterland * package database. 356*5c51f124SMoriah Waterland */ 357*5c51f124SMoriah Waterland if (!eoextlist) { 358*5c51f124SMoriah Waterland if (do_new_ent(tmpvfp, el_ent, 359*5c51f124SMoriah Waterland assume_ok)) { 360*5c51f124SMoriah Waterland changed++; 361*5c51f124SMoriah Waterland } 362*5c51f124SMoriah Waterland } 363*5c51f124SMoriah Waterland } 364*5c51f124SMoriah Waterland /* 365*5c51f124SMoriah Waterland * We have passed the last entry in the package database, 366*5c51f124SMoriah Waterland * tagging these extlist entries onto the end. 367*5c51f124SMoriah Waterland */ 368*5c51f124SMoriah Waterland } else if (!eoextlist) { 369*5c51f124SMoriah Waterland if (do_new_ent(tmpvfp, el_ent, assume_ok)) { 370*5c51f124SMoriah Waterland changed++; 371*5c51f124SMoriah Waterland } 372*5c51f124SMoriah Waterland } 373*5c51f124SMoriah Waterland /* Else, we'll drop out of the loop. */ 374*5c51f124SMoriah Waterland 375*5c51f124SMoriah Waterland (void) sigrelse(SIGALRM); 376*5c51f124SMoriah Waterland } while (eptnum++, (!eocontents || !eoextlist)); 377*5c51f124SMoriah Waterland 378*5c51f124SMoriah Waterland if (notify) { 379*5c51f124SMoriah Waterland (void) alarm(0); 380*5c51f124SMoriah Waterland (void) signal(SIGALRM, SIG_IGN); 381*5c51f124SMoriah Waterland } 382*5c51f124SMoriah Waterland 383*5c51f124SMoriah Waterland return (errflg ? -1 : changed); 384*5c51f124SMoriah Waterland } 385*5c51f124SMoriah Waterland 386*5c51f124SMoriah Waterland /* 387*5c51f124SMoriah Waterland * Merge a new entry with an installed package object of the same name and 388*5c51f124SMoriah Waterland * insert that object into the package database. Obey administrative defaults 389*5c51f124SMoriah Waterland * as regards conflicting files. 390*5c51f124SMoriah Waterland */ 391*5c51f124SMoriah Waterland 392*5c51f124SMoriah Waterland static int 393*5c51f124SMoriah Waterland do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, struct cfent *cf_ent, int ctrl) 394*5c51f124SMoriah Waterland { 395*5c51f124SMoriah Waterland int stflag, ignore, changed, mrg_result; 396*5c51f124SMoriah Waterland 397*5c51f124SMoriah Waterland ignore = changed = 0; 398*5c51f124SMoriah Waterland 399*5c51f124SMoriah Waterland /* 400*5c51f124SMoriah Waterland * Construct the record defining the current package. If there are 401*5c51f124SMoriah Waterland * other packages involved, this will be appended to the existing 402*5c51f124SMoriah Waterland * list. If this is an update of the same package, it will get merged 403*5c51f124SMoriah Waterland * with the existing record. If this is a preloaded record (like from 404*5c51f124SMoriah Waterland * a dryrun file), it will keep it's current pinfo pointer and will 405*5c51f124SMoriah Waterland * pass it on to the record from the contents file - because on the 406*5c51f124SMoriah Waterland * final continuation, the contents file will be wrong. 407*5c51f124SMoriah Waterland */ 408*5c51f124SMoriah Waterland if (el_ent->mstat.preloaded) { 409*5c51f124SMoriah Waterland struct pinfo *pkginfo; 410*5c51f124SMoriah Waterland 411*5c51f124SMoriah Waterland /* Contents file is not to be trusted for this list. */ 412*5c51f124SMoriah Waterland pkginfo = cf_ent->pinfo; 413*5c51f124SMoriah Waterland 414*5c51f124SMoriah Waterland /* Free the potentially bogus list. */ 415*5c51f124SMoriah Waterland while (pkginfo) { 416*5c51f124SMoriah Waterland struct pinfo *next; 417*5c51f124SMoriah Waterland next = pkginfo->next; 418*5c51f124SMoriah Waterland free(pkginfo); 419*5c51f124SMoriah Waterland pkginfo = next; 420*5c51f124SMoriah Waterland } 421*5c51f124SMoriah Waterland 422*5c51f124SMoriah Waterland cf_ent->pinfo = el_ent->cf_ent.pinfo; 423*5c51f124SMoriah Waterland } 424*5c51f124SMoriah Waterland 425*5c51f124SMoriah Waterland pkgpinfo = eptstat(cf_ent, pkginst, DUP_ENTRY); 426*5c51f124SMoriah Waterland 427*5c51f124SMoriah Waterland stflag = pkgpinfo->status; 428*5c51f124SMoriah Waterland 429*5c51f124SMoriah Waterland if (otherstoo) 430*5c51f124SMoriah Waterland el_ent->mstat.shared = 1; 431*5c51f124SMoriah Waterland 432*5c51f124SMoriah Waterland /* If it's marked for erasure, make it official */ 433*5c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == RM_RDY) { 434*5c51f124SMoriah Waterland if (!errflg) { 435*5c51f124SMoriah Waterland pkgpinfo = eptstat(cf_ent, pkginst, RM_RDY); 436*5c51f124SMoriah Waterland 437*5c51f124SMoriah Waterland /* 438*5c51f124SMoriah Waterland * Get copy of status character in case the object is 439*5c51f124SMoriah Waterland * "shared" by a server, in which case we need to 440*5c51f124SMoriah Waterland * maintain the shared status after the entry is 441*5c51f124SMoriah Waterland * written to the package database with RM_RDY 442*5c51f124SMoriah Waterland * status. This is needed to support the `removef' 443*5c51f124SMoriah Waterland * command. 444*5c51f124SMoriah Waterland */ 445*5c51f124SMoriah Waterland stflag = pkgpinfo->status; 446*5c51f124SMoriah Waterland pkgpinfo->status = RM_RDY; 447*5c51f124SMoriah Waterland 448*5c51f124SMoriah Waterland if (putcvfpfile(cf_ent, vfpo)) { 449*5c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 450*5c51f124SMoriah Waterland quit(99); 451*5c51f124SMoriah Waterland } 452*5c51f124SMoriah Waterland 453*5c51f124SMoriah Waterland /* 454*5c51f124SMoriah Waterland * If object is provided by a server, allocate an 455*5c51f124SMoriah Waterland * info block and set the status to indicate this. 456*5c51f124SMoriah Waterland * This is needed to support the `removef' command. 457*5c51f124SMoriah Waterland */ 458*5c51f124SMoriah Waterland if (stflag == SERVED_FILE) { 459*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo = 460*5c51f124SMoriah Waterland (struct pinfo *)calloc(1, 461*5c51f124SMoriah Waterland sizeof (struct pinfo)); 462*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo->next = NULL; 463*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo->status = SERVED_FILE; 464*5c51f124SMoriah Waterland } 465*5c51f124SMoriah Waterland } 466*5c51f124SMoriah Waterland return (1); 467*5c51f124SMoriah Waterland } 468*5c51f124SMoriah Waterland 469*5c51f124SMoriah Waterland /* 470*5c51f124SMoriah Waterland * If there is no package associated with it, there's something 471*5c51f124SMoriah Waterland * very wrong. 472*5c51f124SMoriah Waterland */ 473*5c51f124SMoriah Waterland if (!pkgpinfo) { 474*5c51f124SMoriah Waterland progerr(gettext(ERR_PINFO), cf_ent->path); 475*5c51f124SMoriah Waterland quit(99); 476*5c51f124SMoriah Waterland } 477*5c51f124SMoriah Waterland 478*5c51f124SMoriah Waterland /* 479*5c51f124SMoriah Waterland * Do not allow installation if nocnflct is set and other packages 480*5c51f124SMoriah Waterland * reference this pathname. The cp_cfent() function below writes the 481*5c51f124SMoriah Waterland * information from the installed file over the new entry, so the 482*5c51f124SMoriah Waterland * package database will be unchanged. 483*5c51f124SMoriah Waterland * 484*5c51f124SMoriah Waterland * By the way, ftype "e" is often shared and that's OK, so ftype 485*5c51f124SMoriah Waterland * "e" doesn't count here. 486*5c51f124SMoriah Waterland */ 487*5c51f124SMoriah Waterland if ((nocnflct && el_ent->mstat.shared && el_ent->cf_ent.ftype != 'e')) { 488*5c51f124SMoriah Waterland /* 489*5c51f124SMoriah Waterland * First set the attrchg and contchg entries for proper 490*5c51f124SMoriah Waterland * messaging in the install phase. 491*5c51f124SMoriah Waterland */ 492*5c51f124SMoriah Waterland set_change(el_ent); 493*5c51f124SMoriah Waterland 494*5c51f124SMoriah Waterland /* 495*5c51f124SMoriah Waterland * Now overwrite the new entry with the entry for the 496*5c51f124SMoriah Waterland * currently installed object. 497*5c51f124SMoriah Waterland */ 498*5c51f124SMoriah Waterland if (cp_cfent(cf_ent, el_ent) == 0) 499*5c51f124SMoriah Waterland quit(99); 500*5c51f124SMoriah Waterland 501*5c51f124SMoriah Waterland ignore++; 502*5c51f124SMoriah Waterland } else { 503*5c51f124SMoriah Waterland mrg_result = merg(el_ent, cf_ent); 504*5c51f124SMoriah Waterland 505*5c51f124SMoriah Waterland switch (mrg_result) { 506*5c51f124SMoriah Waterland case MRG_SAME: 507*5c51f124SMoriah Waterland break; 508*5c51f124SMoriah Waterland 509*5c51f124SMoriah Waterland case MRG_DIFFERENT: 510*5c51f124SMoriah Waterland changed++; 511*5c51f124SMoriah Waterland break; 512*5c51f124SMoriah Waterland 513*5c51f124SMoriah Waterland case MRG_REPLACE: 514*5c51f124SMoriah Waterland /* 515*5c51f124SMoriah Waterland * We'll pick one or the other later. For now, cf_ent 516*5c51f124SMoriah Waterland * will have the fault value and el_ent will retain 517*5c51f124SMoriah Waterland * the other value. This is the only state that allows 518*5c51f124SMoriah Waterland * the database and the pkgmap to differ. 519*5c51f124SMoriah Waterland */ 520*5c51f124SMoriah Waterland 521*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; /* subject to change */ 522*5c51f124SMoriah Waterland ignore++; 523*5c51f124SMoriah Waterland break; 524*5c51f124SMoriah Waterland 525*5c51f124SMoriah Waterland default: 526*5c51f124SMoriah Waterland break; 527*5c51f124SMoriah Waterland } 528*5c51f124SMoriah Waterland } 529*5c51f124SMoriah Waterland 530*5c51f124SMoriah Waterland /* el_ent structure now contains updated entry */ 531*5c51f124SMoriah Waterland if (!el_ent->mstat.contchg && !ignore) { 532*5c51f124SMoriah Waterland /* 533*5c51f124SMoriah Waterland * We know the DB entry matches the pkgmap, so now we need to 534*5c51f124SMoriah Waterland * see if the actual object matches the pkgmap. 535*5c51f124SMoriah Waterland */ 536*5c51f124SMoriah Waterland set_change(el_ent); 537*5c51f124SMoriah Waterland } 538*5c51f124SMoriah Waterland 539*5c51f124SMoriah Waterland if (!errflg) { 540*5c51f124SMoriah Waterland if (ctrl == 1) { /* quick verify assumes OK */ 541*5c51f124SMoriah Waterland /* 542*5c51f124SMoriah Waterland * The pkgpinfo entry is already correctly 543*5c51f124SMoriah Waterland * constructed. Look into dropping this soon. 544*5c51f124SMoriah Waterland */ 545*5c51f124SMoriah Waterland pkgpinfo = eptstat(&(el_ent->cf_ent), pkginst, 546*5c51f124SMoriah Waterland ENTRY_OK); 547*5c51f124SMoriah Waterland 548*5c51f124SMoriah Waterland if (stflag != DUP_ENTRY) { 549*5c51f124SMoriah Waterland changed++; 550*5c51f124SMoriah Waterland } 551*5c51f124SMoriah Waterland 552*5c51f124SMoriah Waterland /* 553*5c51f124SMoriah Waterland * We could trust the prior pkginfo entry, but things 554*5c51f124SMoriah Waterland * could have changed and we need to update the 555*5c51f124SMoriah Waterland * fs_tab[] anyway. We check for a server object 556*5c51f124SMoriah Waterland * here. 557*5c51f124SMoriah Waterland */ 558*5c51f124SMoriah Waterland if (is_served(el_ent->server_path, 559*5c51f124SMoriah Waterland &(el_ent->fsys_value))) 560*5c51f124SMoriah Waterland pkgpinfo->status = SERVED_FILE; 561*5c51f124SMoriah Waterland } else { 562*5c51f124SMoriah Waterland if (!ignore && el_ent->mstat.contchg) { 563*5c51f124SMoriah Waterland pkgpinfo = 564*5c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 565*5c51f124SMoriah Waterland (dbst ? dbst : CONFIRM_CONT)); 566*5c51f124SMoriah Waterland } else if (!ignore && el_ent->mstat.attrchg) { 567*5c51f124SMoriah Waterland pkgpinfo = 568*5c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 569*5c51f124SMoriah Waterland (dbst ? dbst : CONFIRM_ATTR)); 570*5c51f124SMoriah Waterland } else if (!ignore && el_ent->mstat.shared) { 571*5c51f124SMoriah Waterland pkgpinfo = 572*5c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 573*5c51f124SMoriah Waterland dbst); 574*5c51f124SMoriah Waterland changed++; 575*5c51f124SMoriah Waterland } else if (stflag != DUP_ENTRY) { 576*5c51f124SMoriah Waterland pkgpinfo = eptstat(&(el_ent->cf_ent), 577*5c51f124SMoriah Waterland pkginst, '\0'); 578*5c51f124SMoriah Waterland if (stflag != ENTRY_OK) { 579*5c51f124SMoriah Waterland changed++; 580*5c51f124SMoriah Waterland } 581*5c51f124SMoriah Waterland } 582*5c51f124SMoriah Waterland } 583*5c51f124SMoriah Waterland 584*5c51f124SMoriah Waterland if (mrg_result == MRG_REPLACE) { 585*5c51f124SMoriah Waterland /* 586*5c51f124SMoriah Waterland * Put the original package database entry back into 587*5c51f124SMoriah Waterland * the package database for now. 588*5c51f124SMoriah Waterland */ 589*5c51f124SMoriah Waterland output(vfpo, cf_ent, pkgpinfo); 590*5c51f124SMoriah Waterland } else { 591*5c51f124SMoriah Waterland /* Put the merged entry into the package database. */ 592*5c51f124SMoriah Waterland output(vfpo, &(el_ent->cf_ent), pkgpinfo); 593*5c51f124SMoriah Waterland } 594*5c51f124SMoriah Waterland } 595*5c51f124SMoriah Waterland 596*5c51f124SMoriah Waterland if (pkgpinfo->aclass[0] != '\0') { 597*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.pkg_class, pkgpinfo->aclass); 598*5c51f124SMoriah Waterland } 599*5c51f124SMoriah Waterland 600*5c51f124SMoriah Waterland /* 601*5c51f124SMoriah Waterland * If a sym link entry exists in the contents file and 602*5c51f124SMoriah Waterland * and the destination of the link does not exist on the the system 603*5c51f124SMoriah Waterland * then the contents file needs to be updated appropriately so a 604*5c51f124SMoriah Waterland * subsequent invocation of "installf -f" will create the destination. 605*5c51f124SMoriah Waterland */ 606*5c51f124SMoriah Waterland if (el_ent->mstat.contchg && pkgpinfo->status == INST_RDY) { 607*5c51f124SMoriah Waterland changed++; 608*5c51f124SMoriah Waterland } 609*5c51f124SMoriah Waterland 610*5c51f124SMoriah Waterland if (!(el_ent->mstat.preloaded)) 611*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo = NULL; 612*5c51f124SMoriah Waterland 613*5c51f124SMoriah Waterland /* 614*5c51f124SMoriah Waterland * If no change during the merg and we don't have a case where types 615*5c51f124SMoriah Waterland * were different in odd ways, count this as installed. 616*5c51f124SMoriah Waterland */ 617*5c51f124SMoriah Waterland if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg && 618*5c51f124SMoriah Waterland !el_ent->mstat.replace) 619*5c51f124SMoriah Waterland installed++; 620*5c51f124SMoriah Waterland return (changed); 621*5c51f124SMoriah Waterland } 622*5c51f124SMoriah Waterland 623*5c51f124SMoriah Waterland /* Insert an entirely new entry into the package database. */ 624*5c51f124SMoriah Waterland static int 625*5c51f124SMoriah Waterland do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl) 626*5c51f124SMoriah Waterland { 627*5c51f124SMoriah Waterland struct pinfo *pinfo; 628*5c51f124SMoriah Waterland char *tp; 629*5c51f124SMoriah Waterland int changed = 0; 630*5c51f124SMoriah Waterland 631*5c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == RM_RDY) { 632*5c51f124SMoriah Waterland return (0); 633*5c51f124SMoriah Waterland } 634*5c51f124SMoriah Waterland 635*5c51f124SMoriah Waterland tp = el_ent->server_path; 636*5c51f124SMoriah Waterland /* 637*5c51f124SMoriah Waterland * Check the file/dir existence only if any of the parent directory 638*5c51f124SMoriah Waterland * of the file/dir has not changed from symbolic link to directory. 639*5c51f124SMoriah Waterland * At this time we are only doing a dry run, the symlink is not yet 640*5c51f124SMoriah Waterland * replaced, so if this is done directly then access will result in 641*5c51f124SMoriah Waterland * incorrect information in case a file with the same attr and cont 642*5c51f124SMoriah Waterland * exists in the link target. 643*5c51f124SMoriah Waterland */ 644*5c51f124SMoriah Waterland if ((!el_ent->mstat.parentsyml2dir) && (access(tp, F_OK) == 0)) { 645*5c51f124SMoriah Waterland /* 646*5c51f124SMoriah Waterland * Path exists, and although its not referenced by any 647*5c51f124SMoriah Waterland * package we make it look like it is so it appears as a 648*5c51f124SMoriah Waterland * conflicting file in case the user doesn't want it 649*5c51f124SMoriah Waterland * installed. We set the rogue flag to distinguish this from 650*5c51f124SMoriah Waterland * package object conflicts if the administrator is queried 651*5c51f124SMoriah Waterland * about this later. Note that noconflict means NO conflict 652*5c51f124SMoriah Waterland * at the file level. Even rogue files count. 653*5c51f124SMoriah Waterland */ 654*5c51f124SMoriah Waterland el_ent->mstat.shared = 1; 655*5c51f124SMoriah Waterland el_ent->mstat.rogue = 1; 656*5c51f124SMoriah Waterland set_change(el_ent); 657*5c51f124SMoriah Waterland } else { 658*5c51f124SMoriah Waterland /* since path doesn't exist, we're changing everything */ 659*5c51f124SMoriah Waterland el_ent->mstat.rogue = 0; 660*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 661*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 662*5c51f124SMoriah Waterland } 663*5c51f124SMoriah Waterland 664*5c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.mode == WILDCARD) { 665*5c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == 'd') { 666*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = DEFAULT_MODE; 667*5c51f124SMoriah Waterland } else { 668*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = DEFAULT_MODE_FILE; 669*5c51f124SMoriah Waterland } 670*5c51f124SMoriah Waterland logerr(WRN_SET_DEF_MODE, el_ent->cf_ent.path, 671*5c51f124SMoriah Waterland (int)el_ent->cf_ent.ainfo.mode); 672*5c51f124SMoriah Waterland } 673*5c51f124SMoriah Waterland 674*5c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.owner, DB_UNDEFINED_ENTRY) == 0) 675*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.owner, 676*5c51f124SMoriah Waterland DEFAULT_OWNER); 677*5c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.group, DB_UNDEFINED_ENTRY) == 0) 678*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.group, 679*5c51f124SMoriah Waterland DEFAULT_GROUP); 680*5c51f124SMoriah Waterland 681*5c51f124SMoriah Waterland /* 682*5c51f124SMoriah Waterland * Do not allow installation if nocnflct is set and this pathname is 683*5c51f124SMoriah Waterland * already in place. Since this entry is new (not associated with a 684*5c51f124SMoriah Waterland * package), we don't issue anything to the database we're building. 685*5c51f124SMoriah Waterland */ 686*5c51f124SMoriah Waterland if (nocnflct && el_ent->mstat.shared) { 687*5c51f124SMoriah Waterland return (0); 688*5c51f124SMoriah Waterland } 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland if (!errflg) { 691*5c51f124SMoriah Waterland if (el_ent->mstat.preloaded) { 692*5c51f124SMoriah Waterland /* Add this package to the already established list. */ 693*5c51f124SMoriah Waterland pinfo = eptstat(&(el_ent->cf_ent), pkginst, DUP_ENTRY); 694*5c51f124SMoriah Waterland } else { 695*5c51f124SMoriah Waterland el_ent->cf_ent.npkgs = 1; 696*5c51f124SMoriah Waterland pinfo = (struct pinfo *)calloc(1, 697*5c51f124SMoriah Waterland sizeof (struct pinfo)); 698*5c51f124SMoriah Waterland if (!pinfo) { 699*5c51f124SMoriah Waterland progerr(gettext(ERR_MEMORY), errno); 700*5c51f124SMoriah Waterland quit(99); 701*5c51f124SMoriah Waterland } 702*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo = pinfo; 703*5c51f124SMoriah Waterland (void) strcpy(pinfo->pkg, pkginst); 704*5c51f124SMoriah Waterland } 705*5c51f124SMoriah Waterland 706*5c51f124SMoriah Waterland if (ctrl == 1) { /* quick verify assumes OK */ 707*5c51f124SMoriah Waterland pinfo->status = dbst ? dbst : ENTRY_OK; 708*5c51f124SMoriah Waterland /* 709*5c51f124SMoriah Waterland * The entry won't be verified, but the entry in the 710*5c51f124SMoriah Waterland * database isn't necessarily ENTRY_OK. If this is 711*5c51f124SMoriah Waterland * coming from a server, we need to note that 712*5c51f124SMoriah Waterland * instead. 713*5c51f124SMoriah Waterland */ 714*5c51f124SMoriah Waterland if (is_served(el_ent->server_path, 715*5c51f124SMoriah Waterland &(el_ent->fsys_value))) 716*5c51f124SMoriah Waterland pinfo->status = SERVED_FILE; 717*5c51f124SMoriah Waterland } else { 718*5c51f124SMoriah Waterland pinfo->status = dbst ? dbst : CONFIRM_CONT; 719*5c51f124SMoriah Waterland } 720*5c51f124SMoriah Waterland 721*5c51f124SMoriah Waterland output(vfpo, &(el_ent->cf_ent), pinfo); 722*5c51f124SMoriah Waterland changed++; 723*5c51f124SMoriah Waterland 724*5c51f124SMoriah Waterland free(pinfo); 725*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo = NULL; 726*5c51f124SMoriah Waterland } 727*5c51f124SMoriah Waterland if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg) { 728*5c51f124SMoriah Waterland installed++; 729*5c51f124SMoriah Waterland } 730*5c51f124SMoriah Waterland 731*5c51f124SMoriah Waterland return (changed); 732*5c51f124SMoriah Waterland } 733*5c51f124SMoriah Waterland 734*5c51f124SMoriah Waterland int 735*5c51f124SMoriah Waterland files_installed(void) 736*5c51f124SMoriah Waterland { 737*5c51f124SMoriah Waterland return (installed); 738*5c51f124SMoriah Waterland } 739*5c51f124SMoriah Waterland 740*5c51f124SMoriah Waterland /* 741*5c51f124SMoriah Waterland * This function determines if there is a difference between the file on 742*5c51f124SMoriah Waterland * the disk and the file to be laid down. It set's mstat flags attrchg 743*5c51f124SMoriah Waterland * and contchg accordingly. 744*5c51f124SMoriah Waterland */ 745*5c51f124SMoriah Waterland static void 746*5c51f124SMoriah Waterland set_change(struct cfextra *el_ent) 747*5c51f124SMoriah Waterland { 748*5c51f124SMoriah Waterland int n; 749*5c51f124SMoriah Waterland char *tp; 750*5c51f124SMoriah Waterland 751*5c51f124SMoriah Waterland tp = el_ent->server_path; 752*5c51f124SMoriah Waterland if ((el_ent->cf_ent.ftype == 'f') || (el_ent->cf_ent.ftype == 'e') || 753*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'v')) { 754*5c51f124SMoriah Waterland if (cverify(0, &(el_ent->cf_ent.ftype), tp, 755*5c51f124SMoriah Waterland &(el_ent->cf_ent.cinfo), 1)) { 756*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 757*5c51f124SMoriah Waterland } else if (!el_ent->mstat.contchg && !el_ent->mstat.attrchg) { 758*5c51f124SMoriah Waterland if (averify(0, &(el_ent->cf_ent.ftype), tp, 759*5c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo))) 760*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 761*5c51f124SMoriah Waterland } 762*5c51f124SMoriah Waterland } else if (!el_ent->mstat.attrchg && 763*5c51f124SMoriah Waterland ((el_ent->cf_ent.ftype == 'd') || 764*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'x') || 765*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'c') || 766*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'b') || 767*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'p'))) { 768*5c51f124SMoriah Waterland n = averify(0, &(el_ent->cf_ent.ftype), tp, 769*5c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo)); 770*5c51f124SMoriah Waterland if (n == VE_ATTR) 771*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 772*5c51f124SMoriah Waterland else if (n && (n != VE_EXIST)) { 773*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 774*5c51f124SMoriah Waterland } 775*5c51f124SMoriah Waterland } else if (!el_ent->mstat.attrchg && 776*5c51f124SMoriah Waterland ((el_ent->cf_ent.ftype == 's') || 777*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'l'))) { 778*5c51f124SMoriah Waterland n = averify(0, &(el_ent->cf_ent.ftype), tp, 779*5c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo)); 780*5c51f124SMoriah Waterland if (n == VE_ATTR) 781*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 782*5c51f124SMoriah Waterland else if (n && (n == VE_EXIST)) { 783*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 784*5c51f124SMoriah Waterland } 785*5c51f124SMoriah Waterland } 786*5c51f124SMoriah Waterland } 787*5c51f124SMoriah Waterland 788*5c51f124SMoriah Waterland static int 789*5c51f124SMoriah Waterland is_setuid(struct cfent *ent) 790*5c51f124SMoriah Waterland { 791*5c51f124SMoriah Waterland return (((ent->ftype == 'f') || (ent->ftype == 'v') || 792*5c51f124SMoriah Waterland (ent->ftype == 'e')) && 793*5c51f124SMoriah Waterland (ent->ainfo.mode != BADMODE) && 794*5c51f124SMoriah Waterland (ent->ainfo.mode != WILDCARD) && 795*5c51f124SMoriah Waterland (ent->ainfo.mode & S_ISUID)); 796*5c51f124SMoriah Waterland } 797*5c51f124SMoriah Waterland 798*5c51f124SMoriah Waterland static int 799*5c51f124SMoriah Waterland is_setgid(struct cfent *ent) 800*5c51f124SMoriah Waterland { 801*5c51f124SMoriah Waterland return (((ent->ftype == 'f') || (ent->ftype == 'v') || 802*5c51f124SMoriah Waterland (ent->ftype == 'e')) && (ent->ainfo.mode != BADMODE) && 803*5c51f124SMoriah Waterland (ent->ainfo.mode != WILDCARD) && 804*5c51f124SMoriah Waterland (ent->ainfo.mode & S_ISGID) && 805*5c51f124SMoriah Waterland (ent->ainfo.mode & (S_IEXEC|S_IXUSR|S_IXOTH))); 806*5c51f124SMoriah Waterland } 807*5c51f124SMoriah Waterland 808*5c51f124SMoriah Waterland char *types[] = { 809*5c51f124SMoriah Waterland "fev", /* type 1, regular files */ 810*5c51f124SMoriah Waterland "s", /* type 2, symbolic links */ 811*5c51f124SMoriah Waterland "l", /* type 3, linked files */ 812*5c51f124SMoriah Waterland "dx", /* type 4, directories */ 813*5c51f124SMoriah Waterland "c", /* type 5, character special devices */ 814*5c51f124SMoriah Waterland "b", /* type 6, block special devices */ 815*5c51f124SMoriah Waterland "p", /* type 7, named pipes */ 816*5c51f124SMoriah Waterland NULL 817*5c51f124SMoriah Waterland }; 818*5c51f124SMoriah Waterland 819*5c51f124SMoriah Waterland /* 820*5c51f124SMoriah Waterland * This determines if the ftype of the file on the disk and the file to be 821*5c51f124SMoriah Waterland * laid down are close enough. If they aren't, this either returns an error 822*5c51f124SMoriah Waterland * or displays a warning. This returns : 823*5c51f124SMoriah Waterland * TYPE_OK they're identical or close enough 824*5c51f124SMoriah Waterland * TYPE_WARNING they're pretty close (probably no problem) 825*5c51f124SMoriah Waterland * TYPE_IGNORED the type change was not allowed 826*5c51f124SMoriah Waterland * TYPE_REPLACE to be reviewed later - in endofclass() maybe 827*5c51f124SMoriah Waterland * TYPE_FATAL something awful happened 828*5c51f124SMoriah Waterland */ 829*5c51f124SMoriah Waterland static int 830*5c51f124SMoriah Waterland typechg(struct cfent *el_ent, struct cfent *cf_ent, struct mergstat *mstat) 831*5c51f124SMoriah Waterland { 832*5c51f124SMoriah Waterland int i, etype, itype, retcode; 833*5c51f124SMoriah Waterland 834*5c51f124SMoriah Waterland /* If they are identical, return OK */ 835*5c51f124SMoriah Waterland if (cf_ent->ftype == el_ent->ftype) 836*5c51f124SMoriah Waterland return (TYPE_OK); 837*5c51f124SMoriah Waterland 838*5c51f124SMoriah Waterland /* 839*5c51f124SMoriah Waterland * If package database entry is ambiguous, set it to the new entity's 840*5c51f124SMoriah Waterland * ftype 841*5c51f124SMoriah Waterland */ 842*5c51f124SMoriah Waterland if (cf_ent->ftype == BADFTYPE) { 843*5c51f124SMoriah Waterland cf_ent->ftype = el_ent->ftype; 844*5c51f124SMoriah Waterland return (TYPE_OK); /* do nothing; not really different */ 845*5c51f124SMoriah Waterland } 846*5c51f124SMoriah Waterland 847*5c51f124SMoriah Waterland /* If the new entity is ambiguous, wait for the verify */ 848*5c51f124SMoriah Waterland if (el_ent->ftype == BADFTYPE) 849*5c51f124SMoriah Waterland return (TYPE_OK); 850*5c51f124SMoriah Waterland 851*5c51f124SMoriah Waterland /* 852*5c51f124SMoriah Waterland * If we're trying to convert an existing regular directory to an 853*5c51f124SMoriah Waterland * exclusive directory, this is very dangerous. We will continue, but 854*5c51f124SMoriah Waterland * we will deny the conversion. 855*5c51f124SMoriah Waterland */ 856*5c51f124SMoriah Waterland if (el_ent->ftype == 'x' && cf_ent->ftype == 'd') { 857*5c51f124SMoriah Waterland logerr(gettext(WRN_TOEXCL), el_ent->path); 858*5c51f124SMoriah Waterland return (TYPE_IGNORED); 859*5c51f124SMoriah Waterland } 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland etype = itype = 0; 862*5c51f124SMoriah Waterland 863*5c51f124SMoriah Waterland /* Set etype to that of the new entity */ 864*5c51f124SMoriah Waterland for (i = 0; types[i]; ++i) { 865*5c51f124SMoriah Waterland if (strchr(types[i], el_ent->ftype)) { 866*5c51f124SMoriah Waterland etype = i+1; 867*5c51f124SMoriah Waterland break; 868*5c51f124SMoriah Waterland } 869*5c51f124SMoriah Waterland } 870*5c51f124SMoriah Waterland 871*5c51f124SMoriah Waterland /* Set itype to that in the package database. */ 872*5c51f124SMoriah Waterland for (i = 0; types[i]; ++i) { 873*5c51f124SMoriah Waterland if (strchr(types[i], cf_ent->ftype)) { 874*5c51f124SMoriah Waterland itype = i+1; 875*5c51f124SMoriah Waterland break; 876*5c51f124SMoriah Waterland } 877*5c51f124SMoriah Waterland } 878*5c51f124SMoriah Waterland 879*5c51f124SMoriah Waterland if (itype == etype) { 880*5c51f124SMoriah Waterland /* same basic object type */ 881*5c51f124SMoriah Waterland return (TYPE_OK); 882*5c51f124SMoriah Waterland } 883*5c51f124SMoriah Waterland 884*5c51f124SMoriah Waterland retcode = TYPE_WARNING; 885*5c51f124SMoriah Waterland 886*5c51f124SMoriah Waterland /* 887*5c51f124SMoriah Waterland * If a simple object (like a file) is overwriting a directory, mark 888*5c51f124SMoriah Waterland * it for full inspection during installation. 889*5c51f124SMoriah Waterland */ 890*5c51f124SMoriah Waterland if (etype != 4 && itype == 4) { 891*5c51f124SMoriah Waterland mstat->dir2nondir = 1; 892*5c51f124SMoriah Waterland retcode = TYPE_REPLACE; 893*5c51f124SMoriah Waterland } 894*5c51f124SMoriah Waterland 895*5c51f124SMoriah Waterland /* allow change, but warn user of possible problems */ 896*5c51f124SMoriah Waterland switch (itype) { 897*5c51f124SMoriah Waterland case 1: 898*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTFILE), el_ent->path); 899*5c51f124SMoriah Waterland break; 900*5c51f124SMoriah Waterland 901*5c51f124SMoriah Waterland case 2: 902*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTSYMLN), el_ent->path); 903*5c51f124SMoriah Waterland break; 904*5c51f124SMoriah Waterland 905*5c51f124SMoriah Waterland case 3: 906*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTLINK), el_ent->path); 907*5c51f124SMoriah Waterland break; 908*5c51f124SMoriah Waterland 909*5c51f124SMoriah Waterland case 4: 910*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTDIR), el_ent->path); 911*5c51f124SMoriah Waterland break; 912*5c51f124SMoriah Waterland 913*5c51f124SMoriah Waterland case 5: 914*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTCHAR), el_ent->path); 915*5c51f124SMoriah Waterland break; 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland case 6: 918*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTBLOCK), el_ent->path); 919*5c51f124SMoriah Waterland break; 920*5c51f124SMoriah Waterland 921*5c51f124SMoriah Waterland case 7: 922*5c51f124SMoriah Waterland logerr(gettext(WRN_NOTPIPE), el_ent->path); 923*5c51f124SMoriah Waterland break; 924*5c51f124SMoriah Waterland 925*5c51f124SMoriah Waterland default: 926*5c51f124SMoriah Waterland break; 927*5c51f124SMoriah Waterland } 928*5c51f124SMoriah Waterland return (retcode); 929*5c51f124SMoriah Waterland } 930*5c51f124SMoriah Waterland 931*5c51f124SMoriah Waterland /* 932*5c51f124SMoriah Waterland * This function takes el_ent (the entry from the pkgmap) and cf_ent (the 933*5c51f124SMoriah Waterland * entry from the package database) and merge them into el_ent. The rules 934*5c51f124SMoriah Waterland * are still being figured out, but the comments should make the approach 935*5c51f124SMoriah Waterland * pretty clear. 936*5c51f124SMoriah Waterland * 937*5c51f124SMoriah Waterland * RETURN CODES: 938*5c51f124SMoriah Waterland * MRG_DIFFERENT The two entries are different and el_ent now contains 939*5c51f124SMoriah Waterland * the intended new entry to be installed. 940*5c51f124SMoriah Waterland * MRG_SAME The two entries were identical and the old database 941*5c51f124SMoriah Waterland * entry will be replaced unchanged. 942*5c51f124SMoriah Waterland * MRG_REPLACE One or the other entry will be used but the decision 943*5c51f124SMoriah Waterland * has to be made at install time. 944*5c51f124SMoriah Waterland */ 945*5c51f124SMoriah Waterland static int 946*5c51f124SMoriah Waterland merg(struct cfextra *el_ent, struct cfent *cf_ent) 947*5c51f124SMoriah Waterland { 948*5c51f124SMoriah Waterland int n, changed = 0; 949*5c51f124SMoriah Waterland 950*5c51f124SMoriah Waterland /* 951*5c51f124SMoriah Waterland * We need to change the original entry to make it look like the new 952*5c51f124SMoriah Waterland * entry (the eptstat() routine has already added appropriate package 953*5c51f124SMoriah Waterland * information, but not about 'aclass' which may represent a change 954*5c51f124SMoriah Waterland * in class from the previous installation. 955*5c51f124SMoriah Waterland * 956*5c51f124SMoriah Waterland * NOTE: elent->cf_ent.pinfo (the list of associated packages) is NULL 957*5c51f124SMoriah Waterland * upon entry to this function. 958*5c51f124SMoriah Waterland */ 959*5c51f124SMoriah Waterland 960*5c51f124SMoriah Waterland el_ent->cf_ent.pinfo = cf_ent->pinfo; 961*5c51f124SMoriah Waterland 962*5c51f124SMoriah Waterland if (dbst == INST_RDY && el_ent->cf_ent.ftype == '?') { 963*5c51f124SMoriah Waterland el_ent->cf_ent.ftype = cf_ent->ftype; 964*5c51f124SMoriah Waterland } 965*5c51f124SMoriah Waterland 966*5c51f124SMoriah Waterland /* 967*5c51f124SMoriah Waterland * Evaluate the ftype change. Usually the ftype won't change. If it 968*5c51f124SMoriah Waterland * does it may be easy (s -> f), not allowed (d -> x), so complex we 969*5c51f124SMoriah Waterland * can't figure it 'til later (d -> s) or fatal (a hook for later). 970*5c51f124SMoriah Waterland */ 971*5c51f124SMoriah Waterland if (cf_ent->ftype != el_ent->cf_ent.ftype) { 972*5c51f124SMoriah Waterland n = typechg(&(el_ent->cf_ent), cf_ent, &(el_ent->mstat)); 973*5c51f124SMoriah Waterland 974*5c51f124SMoriah Waterland switch (n) { 975*5c51f124SMoriah Waterland case TYPE_OK: 976*5c51f124SMoriah Waterland break; 977*5c51f124SMoriah Waterland 978*5c51f124SMoriah Waterland /* This is an allowable change. */ 979*5c51f124SMoriah Waterland case TYPE_WARNING: 980*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 981*5c51f124SMoriah Waterland break; 982*5c51f124SMoriah Waterland 983*5c51f124SMoriah Waterland /* Not allowed, but leaving it as is is OK. */ 984*5c51f124SMoriah Waterland case TYPE_IGNORED: 985*5c51f124SMoriah Waterland logerr(gettext(MSG_TYPIGN)); 986*5c51f124SMoriah Waterland if (cp_cfent(cf_ent, el_ent) == 0) 987*5c51f124SMoriah Waterland quit(99); 988*5c51f124SMoriah Waterland return (MRG_SAME); 989*5c51f124SMoriah Waterland 990*5c51f124SMoriah Waterland /* Future analysis will reveal if this is OK. */ 991*5c51f124SMoriah Waterland case TYPE_REPLACE: 992*5c51f124SMoriah Waterland el_ent->mstat.replace = 1; 993*5c51f124SMoriah Waterland return (MRG_REPLACE); 994*5c51f124SMoriah Waterland 995*5c51f124SMoriah Waterland /* Kill it before it does any damage. */ 996*5c51f124SMoriah Waterland case TYPE_FATAL: 997*5c51f124SMoriah Waterland logerr(gettext(MSG_TYPE_ERR)); 998*5c51f124SMoriah Waterland quit(99); 999*5c51f124SMoriah Waterland 1000*5c51f124SMoriah Waterland default: 1001*5c51f124SMoriah Waterland break; 1002*5c51f124SMoriah Waterland } 1003*5c51f124SMoriah Waterland 1004*5c51f124SMoriah Waterland changed++; 1005*5c51f124SMoriah Waterland } 1006*5c51f124SMoriah Waterland 1007*5c51f124SMoriah Waterland /* Evaluate and merge the class. */ 1008*5c51f124SMoriah Waterland if (strcmp(cf_ent->pkg_class, el_ent->cf_ent.pkg_class)) { 1009*5c51f124SMoriah Waterland /* 1010*5c51f124SMoriah Waterland * we always allow a class change as long as we have 1011*5c51f124SMoriah Waterland * consistent ftypes, which at this point we must 1012*5c51f124SMoriah Waterland */ 1013*5c51f124SMoriah Waterland changed++; 1014*5c51f124SMoriah Waterland if (strcmp(cf_ent->pkg_class, "?")) { 1015*5c51f124SMoriah Waterland (void) strcpy(pkgpinfo->aclass, 1016*5c51f124SMoriah Waterland el_ent->cf_ent.pkg_class); 1017*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.pkg_class, 1018*5c51f124SMoriah Waterland cf_ent->pkg_class); 1019*5c51f124SMoriah Waterland chgclass(&(el_ent->cf_ent), pkgpinfo); 1020*5c51f124SMoriah Waterland } 1021*5c51f124SMoriah Waterland } 1022*5c51f124SMoriah Waterland 1023*5c51f124SMoriah Waterland /* 1024*5c51f124SMoriah Waterland * Evaluate and merge based upon the ftype of the intended package 1025*5c51f124SMoriah Waterland * database entry. 1026*5c51f124SMoriah Waterland */ 1027*5c51f124SMoriah Waterland if (((el_ent->cf_ent.ftype == 's') || (el_ent->cf_ent.ftype == 'l'))) { 1028*5c51f124SMoriah Waterland 1029*5c51f124SMoriah Waterland /* If both have link sources, then they need to be merged. */ 1030*5c51f124SMoriah Waterland if (cf_ent->ainfo.local && el_ent->cf_ent.ainfo.local) { 1031*5c51f124SMoriah Waterland /* 1032*5c51f124SMoriah Waterland * If both sources are identical, the merge is 1033*5c51f124SMoriah Waterland * already done. 1034*5c51f124SMoriah Waterland */ 1035*5c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.local, 1036*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.local) != NULL) { 1037*5c51f124SMoriah Waterland changed++; 1038*5c51f124SMoriah Waterland 1039*5c51f124SMoriah Waterland /* 1040*5c51f124SMoriah Waterland * Otherwise, if the pkgmap entry is 1041*5c51f124SMoriah Waterland * ambiguous, it will inherit the database 1042*5c51f124SMoriah Waterland * entry. 1043*5c51f124SMoriah Waterland */ 1044*5c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.local, 1045*5c51f124SMoriah Waterland "?") == NULL) { 1046*5c51f124SMoriah Waterland (void) strlcpy( 1047*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.local, 1048*5c51f124SMoriah Waterland cf_ent->ainfo.local, 1049*5c51f124SMoriah Waterland PATH_MAX); 1050*5c51f124SMoriah Waterland } else { 1051*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1052*5c51f124SMoriah Waterland } 1053*5c51f124SMoriah Waterland } 1054*5c51f124SMoriah Waterland } 1055*5c51f124SMoriah Waterland return (changed ? MRG_DIFFERENT : MRG_SAME); 1056*5c51f124SMoriah Waterland 1057*5c51f124SMoriah Waterland } else if (el_ent->cf_ent.ftype == 'e') { 1058*5c51f124SMoriah Waterland 1059*5c51f124SMoriah Waterland /* 1060*5c51f124SMoriah Waterland * The contents of edittable files are assumed to be changing 1061*5c51f124SMoriah Waterland * since some class action script will be doing the work and 1062*5c51f124SMoriah Waterland * we have no way of evaluating what it will actually do. 1063*5c51f124SMoriah Waterland */ 1064*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1065*5c51f124SMoriah Waterland changed++; 1066*5c51f124SMoriah Waterland } else if (((el_ent->cf_ent.ftype == 'f') || 1067*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'v'))) { 1068*5c51f124SMoriah Waterland /* 1069*5c51f124SMoriah Waterland * For regular files, Look at content information; a BADCONT 1070*5c51f124SMoriah Waterland * in any el_ent field indicates the contents are unknown -- 1071*5c51f124SMoriah Waterland * since cf_ent is guaranteed to have a valid entry here (bad 1072*5c51f124SMoriah Waterland * assumption?) this function will recognize this as a 1073*5c51f124SMoriah Waterland * change. The ambiguous el_ent values will be evaluated and 1074*5c51f124SMoriah Waterland * set later. 1075*5c51f124SMoriah Waterland */ 1076*5c51f124SMoriah Waterland 1077*5c51f124SMoriah Waterland /* 1078*5c51f124SMoriah Waterland * for type f/v files, if the file is in an area that is 1079*5c51f124SMoriah Waterland * inherited from the global zone, that area is read only 1080*5c51f124SMoriah Waterland * and the object cannot be changed - ignore any settings 1081*5c51f124SMoriah Waterland * in the current package database that may be present for 1082*5c51f124SMoriah Waterland * any existing object because they are irrelevant - since 1083*5c51f124SMoriah Waterland * the object is in a read-only area shared from the global 1084*5c51f124SMoriah Waterland * zone, accept that file's actual attributes as being correct. 1085*5c51f124SMoriah Waterland */ 1086*5c51f124SMoriah Waterland 1087*5c51f124SMoriah Waterland if (z_path_is_inherited(el_ent->cf_ent.path, 1088*5c51f124SMoriah Waterland el_ent->cf_ent.ftype, get_inst_root()) == B_TRUE) { 1089*5c51f124SMoriah Waterland echoDebug(DBG_PKGDBMRG_INHERITED, el_ent->cf_ent.path); 1090*5c51f124SMoriah Waterland } else if (cf_ent->cinfo.size != el_ent->cf_ent.cinfo.size) { 1091*5c51f124SMoriah Waterland changed++; 1092*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1093*5c51f124SMoriah Waterland } else if (cf_ent->cinfo.modtime != 1094*5c51f124SMoriah Waterland el_ent->cf_ent.cinfo.modtime) { 1095*5c51f124SMoriah Waterland changed++; 1096*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1097*5c51f124SMoriah Waterland } else if (cf_ent->cinfo.cksum != el_ent->cf_ent.cinfo.cksum) { 1098*5c51f124SMoriah Waterland changed++; 1099*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1100*5c51f124SMoriah Waterland } 1101*5c51f124SMoriah Waterland } else if (((el_ent->cf_ent.ftype == 'c') || 1102*5c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'b'))) { 1103*5c51f124SMoriah Waterland /* 1104*5c51f124SMoriah Waterland * For devices, if major or minor numbers are identical the 1105*5c51f124SMoriah Waterland * merge is trivial. If the el_ent value is ambiguous (BAD), 1106*5c51f124SMoriah Waterland * the cf_ent value is inherited. Otherwise, the el_ent value 1107*5c51f124SMoriah Waterland * is preserved. 1108*5c51f124SMoriah Waterland */ 1109*5c51f124SMoriah Waterland if (cf_ent->ainfo.major != el_ent->cf_ent.ainfo.major) { 1110*5c51f124SMoriah Waterland changed++; 1111*5c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.major == BADMAJOR) { 1112*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.major = 1113*5c51f124SMoriah Waterland cf_ent->ainfo.major; 1114*5c51f124SMoriah Waterland } else { 1115*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1116*5c51f124SMoriah Waterland } 1117*5c51f124SMoriah Waterland } 1118*5c51f124SMoriah Waterland if (cf_ent->ainfo.minor != el_ent->cf_ent.ainfo.minor) { 1119*5c51f124SMoriah Waterland changed++; 1120*5c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.minor == BADMINOR) 1121*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.minor = 1122*5c51f124SMoriah Waterland cf_ent->ainfo.minor; 1123*5c51f124SMoriah Waterland else 1124*5c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 1125*5c51f124SMoriah Waterland } 1126*5c51f124SMoriah Waterland } 1127*5c51f124SMoriah Waterland 1128*5c51f124SMoriah Waterland /* 1129*5c51f124SMoriah Waterland * For mode, owner and group follow the same rules as above - if 1130*5c51f124SMoriah Waterland * ambiguous, inherit, otherwise keep the new one. 1131*5c51f124SMoriah Waterland */ 1132*5c51f124SMoriah Waterland if (cf_ent->ainfo.mode != el_ent->cf_ent.ainfo.mode) { 1133*5c51f124SMoriah Waterland changed++; /* attribute info is changing */ 1134*5c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.mode == BADMODE) { 1135*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode; 1136*5c51f124SMoriah Waterland } else if (el_ent->cf_ent.ainfo.mode == WILDCARD) { 1137*5c51f124SMoriah Waterland /* 1138*5c51f124SMoriah Waterland * If pkgmap has a '?' set for mode, use the mode from 1139*5c51f124SMoriah Waterland * the pkg DB (contents file). 1140*5c51f124SMoriah Waterland */ 1141*5c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode; 1142*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 0; 1143*5c51f124SMoriah Waterland } else { 1144*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 1145*5c51f124SMoriah Waterland } 1146*5c51f124SMoriah Waterland } 1147*5c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.owner, el_ent->cf_ent.ainfo.owner) != 0) { 1148*5c51f124SMoriah Waterland changed++; /* attribute info is changing */ 1149*5c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.owner, BADOWNER) == 0) 1150*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.owner, 1151*5c51f124SMoriah Waterland cf_ent->ainfo.owner); 1152*5c51f124SMoriah Waterland else 1153*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 1154*5c51f124SMoriah Waterland } 1155*5c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.group, el_ent->cf_ent.ainfo.group) != 0) { 1156*5c51f124SMoriah Waterland changed++; /* attribute info is changing */ 1157*5c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.group, BADGROUP) == 0) 1158*5c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.group, 1159*5c51f124SMoriah Waterland cf_ent->ainfo.group); 1160*5c51f124SMoriah Waterland else 1161*5c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 1162*5c51f124SMoriah Waterland } 1163*5c51f124SMoriah Waterland return (changed ? MRG_DIFFERENT : MRG_SAME); 1164*5c51f124SMoriah Waterland } 1165*5c51f124SMoriah Waterland 1166*5c51f124SMoriah Waterland /* 1167*5c51f124SMoriah Waterland * This puts the current entry into the package database in the appropriate 1168*5c51f124SMoriah Waterland * intermediate format for this stage of the installation. This also assures 1169*5c51f124SMoriah Waterland * the correct format for the various package object ftypes, stripping the 1170*5c51f124SMoriah Waterland * link name before storing a regular file and stuff like that. 1171*5c51f124SMoriah Waterland */ 1172*5c51f124SMoriah Waterland 1173*5c51f124SMoriah Waterland static void 1174*5c51f124SMoriah Waterland output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo) 1175*5c51f124SMoriah Waterland { 1176*5c51f124SMoriah Waterland short svvolno; 1177*5c51f124SMoriah Waterland char *svpt; 1178*5c51f124SMoriah Waterland 1179*5c51f124SMoriah Waterland /* output without volume information */ 1180*5c51f124SMoriah Waterland svvolno = ent->volno; 1181*5c51f124SMoriah Waterland ent->volno = 0; 1182*5c51f124SMoriah Waterland 1183*5c51f124SMoriah Waterland pinfo->editflag = 0; 1184*5c51f124SMoriah Waterland if (((ent->ftype == 's') || (ent->ftype == 'l'))) { 1185*5c51f124SMoriah Waterland if (putcvfpfile(ent, vfpo)) { 1186*5c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 1187*5c51f124SMoriah Waterland quit(99); 1188*5c51f124SMoriah Waterland } 1189*5c51f124SMoriah Waterland } else { 1190*5c51f124SMoriah Waterland 1191*5c51f124SMoriah Waterland /* output without local pathname */ 1192*5c51f124SMoriah Waterland svpt = ent->ainfo.local; 1193*5c51f124SMoriah Waterland ent->ainfo.local = NULL; 1194*5c51f124SMoriah Waterland if (putcvfpfile(ent, vfpo)) { 1195*5c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 1196*5c51f124SMoriah Waterland quit(99); 1197*5c51f124SMoriah Waterland } 1198*5c51f124SMoriah Waterland 1199*5c51f124SMoriah Waterland ent->ainfo.local = svpt; 1200*5c51f124SMoriah Waterland /* 1201*5c51f124SMoriah Waterland * If this entry represents a file which is being edited, we 1202*5c51f124SMoriah Waterland * need to store in memory the fact that it is an edittable 1203*5c51f124SMoriah Waterland * file so that when we audit it after installation we do not 1204*5c51f124SMoriah Waterland * worry about its contents; we do this by resetting the ftype 1205*5c51f124SMoriah Waterland * to 'e' in the memory array which is later used to control 1206*5c51f124SMoriah Waterland * the audit 1207*5c51f124SMoriah Waterland */ 1208*5c51f124SMoriah Waterland if (pinfo->editflag) 1209*5c51f124SMoriah Waterland ent->ftype = 'e'; 1210*5c51f124SMoriah Waterland } 1211*5c51f124SMoriah Waterland /* restore volume information */ 1212*5c51f124SMoriah Waterland ent->volno = svvolno; 1213*5c51f124SMoriah Waterland } 1214*5c51f124SMoriah Waterland 1215*5c51f124SMoriah Waterland static void 1216*5c51f124SMoriah Waterland chgclass(struct cfent *cf_ent, struct pinfo *pinfo) 1217*5c51f124SMoriah Waterland { 1218*5c51f124SMoriah Waterland struct pinfo *pp; 1219*5c51f124SMoriah Waterland char *oldclass, newclass[CLSSIZ+1]; 1220*5c51f124SMoriah Waterland int newcnt, oldcnt; 1221*5c51f124SMoriah Waterland 1222*5c51f124SMoriah Waterland /* 1223*5c51f124SMoriah Waterland * we use this routine to minimize the use of the aclass element by 1224*5c51f124SMoriah Waterland * optimizing the use of the cf_ent->pkg_class element 1225*5c51f124SMoriah Waterland */ 1226*5c51f124SMoriah Waterland 1227*5c51f124SMoriah Waterland (void) strlcpy(newclass, pinfo->aclass, sizeof (newclass)); 1228*5c51f124SMoriah Waterland newcnt = 1; 1229*5c51f124SMoriah Waterland 1230*5c51f124SMoriah Waterland oldclass = cf_ent->pkg_class; 1231*5c51f124SMoriah Waterland oldcnt = 0; 1232*5c51f124SMoriah Waterland 1233*5c51f124SMoriah Waterland /* 1234*5c51f124SMoriah Waterland * count the number of times the newclass will be used and see if it 1235*5c51f124SMoriah Waterland * exceeds the number of times the oldclass is referenced 1236*5c51f124SMoriah Waterland */ 1237*5c51f124SMoriah Waterland pp = cf_ent->pinfo; 1238*5c51f124SMoriah Waterland while (pp) { 1239*5c51f124SMoriah Waterland if (pp->aclass[0] != '\0') { 1240*5c51f124SMoriah Waterland if (strcmp(pp->aclass, newclass) == 0) 1241*5c51f124SMoriah Waterland newcnt++; 1242*5c51f124SMoriah Waterland else if (strcmp(pp->aclass, oldclass) == 0) 1243*5c51f124SMoriah Waterland oldcnt++; 1244*5c51f124SMoriah Waterland } 1245*5c51f124SMoriah Waterland pp = pp->next; 1246*5c51f124SMoriah Waterland } 1247*5c51f124SMoriah Waterland if (newcnt > oldcnt) { 1248*5c51f124SMoriah Waterland pp = cf_ent->pinfo; 1249*5c51f124SMoriah Waterland while (pp) { 1250*5c51f124SMoriah Waterland if (pp->aclass[0] == '\0') { 1251*5c51f124SMoriah Waterland (void) strcpy(pp->aclass, oldclass); 1252*5c51f124SMoriah Waterland } else if (strcmp(pp->aclass, newclass) == 0) { 1253*5c51f124SMoriah Waterland pp->aclass[0] = '\0'; 1254*5c51f124SMoriah Waterland } 1255*5c51f124SMoriah Waterland pp = pp->next; 1256*5c51f124SMoriah Waterland } 1257*5c51f124SMoriah Waterland (void) strcpy(cf_ent->pkg_class, newclass); 1258*5c51f124SMoriah Waterland } 1259*5c51f124SMoriah Waterland } 1260