15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 285c51f124SMoriah Waterland /* All Rights Reserved */ 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland 315c51f124SMoriah Waterland #include <stdio.h> 325c51f124SMoriah Waterland #include <signal.h> 335c51f124SMoriah Waterland #include <string.h> 345c51f124SMoriah Waterland #include <errno.h> 355c51f124SMoriah Waterland #include <unistd.h> 365c51f124SMoriah Waterland #include <stdlib.h> 375c51f124SMoriah Waterland #include <assert.h> 385c51f124SMoriah Waterland #include <pkgstrct.h> 395c51f124SMoriah Waterland #include <sys/stat.h> 405c51f124SMoriah Waterland #include <locale.h> 415c51f124SMoriah Waterland #include <libintl.h> 425c51f124SMoriah Waterland #include <pkginfo.h> 435c51f124SMoriah Waterland #include <instzones_api.h> 445c51f124SMoriah Waterland #include <pkglib.h> 455c51f124SMoriah Waterland #include <libinst.h> 465c51f124SMoriah Waterland #include <messages.h> 475c51f124SMoriah Waterland 485c51f124SMoriah Waterland /* merg() return codes */ 495c51f124SMoriah Waterland #define MRG_SAME 0 505c51f124SMoriah Waterland #define MRG_DIFFERENT 1 515c51f124SMoriah Waterland #define MRG_REPLACE 2 525c51f124SMoriah Waterland 535c51f124SMoriah Waterland /* typechg() return codes */ 545c51f124SMoriah Waterland #define TYPE_OK 0 555c51f124SMoriah Waterland #define TYPE_WARNING 1 565c51f124SMoriah Waterland #define TYPE_IGNORED 2 575c51f124SMoriah Waterland #define TYPE_REPLACE 3 585c51f124SMoriah Waterland #define TYPE_FATAL 4 595c51f124SMoriah Waterland 605c51f124SMoriah Waterland /* message pool */ 615c51f124SMoriah Waterland #define ERR_OUTPUT "unable to update package database" 625c51f124SMoriah Waterland #define ERR_PINFO "missing pinfo structure for <%s>" 635c51f124SMoriah Waterland #define INFO_PROCESS " %2ld%% of information processed; continuing ..." 645c51f124SMoriah Waterland 655c51f124SMoriah Waterland #define WRN_NOTFILE "WARNING: %s <no longer a regular file>" 665c51f124SMoriah Waterland #define WRN_NOTSYMLN "WARNING: %s <no longer a symbolic link>" 675c51f124SMoriah Waterland #define WRN_NOTLINK "WARNING: %s <no longer a linked file>" 685c51f124SMoriah Waterland #define WRN_NOTDIR "WARNING: %s <no longer a directory>" 695c51f124SMoriah Waterland #define WRN_NOTCHAR "WARNING: %s <no longer a character special device>" 705c51f124SMoriah Waterland #define WRN_NOTBLOCK "WARNING: %s <no longer a block special device>" 715c51f124SMoriah Waterland #define WRN_NOTPIPE "WARNING: %s <no longer a named pipe>" 725c51f124SMoriah Waterland #define WRN_TOEXCL "WARNING: cannot convert %s to an exclusive directory." 735c51f124SMoriah Waterland #define WRN_ODDVERIFY "WARNING: quick verify disabled for class %s." 745c51f124SMoriah Waterland 755c51f124SMoriah Waterland #define MSG_TYPIGN "Object type change ignored." 765c51f124SMoriah Waterland #define MSG_TYPE_ERR "Package attempts fatal object type change." 775c51f124SMoriah Waterland 785c51f124SMoriah Waterland extern char *pkginst; 795c51f124SMoriah Waterland extern int nosetuid, nocnflct, otherstoo; 805c51f124SMoriah Waterland 815c51f124SMoriah Waterland /* pkgobjmap.c */ 825c51f124SMoriah Waterland extern int cp_cfent(struct cfent *cf_ent, struct cfextra *el_ent); 835c51f124SMoriah Waterland 845c51f124SMoriah Waterland /* setlist.c */ 855c51f124SMoriah Waterland extern void cl_def_dverify(int idx); 865c51f124SMoriah Waterland 875c51f124SMoriah Waterland char dbst = '\0'; /* usually set by installf() or removef() */ 885c51f124SMoriah Waterland 895c51f124SMoriah Waterland int files_installed(void); /* return number of files installed. */ 905c51f124SMoriah Waterland 915c51f124SMoriah Waterland static int errflg = 0; 925c51f124SMoriah Waterland static int eptnum; 935c51f124SMoriah Waterland static int installed; /* # of files, already properly installed. */ 945c51f124SMoriah Waterland static struct pinfo *pkgpinfo = (struct pinfo *)0; 955c51f124SMoriah Waterland 965c51f124SMoriah Waterland static int is_setuid(struct cfent *ent); 975c51f124SMoriah Waterland static int is_setgid(struct cfent *ent); 985c51f124SMoriah Waterland static int merg(struct cfextra *el_ent, struct cfent *cf_ent); 995c51f124SMoriah Waterland static int do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, 1005c51f124SMoriah Waterland struct cfent *cf_ent, int ctrl); 1015c51f124SMoriah Waterland static int do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl); 102*b46ec01aSok199659 static int typechg(struct cfent *el_ent, struct cfent *cf_ent, 1035c51f124SMoriah Waterland struct mergstat *mstat); 1045c51f124SMoriah Waterland 1055c51f124SMoriah Waterland static void set_change(struct cfextra *el_ent); 1065c51f124SMoriah Waterland static void chgclass(struct cfent *cf_ent, struct pinfo *pinfo); 1075c51f124SMoriah Waterland static void output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo); 1085c51f124SMoriah Waterland 1095c51f124SMoriah Waterland /* 11062224350SCasper H.S. Dik * This scans the extlist (pkgmap) and matches them to the database, copying 11162224350SCasper H.S. Dik * out the modified contents to the file at tmpfp. It updates the mergstat 1125c51f124SMoriah Waterland * structures and deals with administrative defaults regarding setuid and 1135c51f124SMoriah Waterland * conflict. 1145c51f124SMoriah Waterland */ 1155c51f124SMoriah Waterland 1165c51f124SMoriah Waterland int 11762224350SCasper H.S. Dik pkgdbmerg(PKGserver server, VFP_T *tmpvfp, struct cfextra **extlist) 1185c51f124SMoriah Waterland { 1195c51f124SMoriah Waterland static struct cfent cf_ent; /* scratch area */ 1205c51f124SMoriah Waterland struct cfextra *el_ent; /* extlist entry under review */ 1215c51f124SMoriah Waterland int n; 1225c51f124SMoriah Waterland int changed; 1235c51f124SMoriah Waterland int assume_ok = 0; 1245c51f124SMoriah Waterland 1255c51f124SMoriah Waterland cf_ent.pinfo = (NULL); 1265c51f124SMoriah Waterland errflg = 0; 1275c51f124SMoriah Waterland installed = changed = 0; 1285c51f124SMoriah Waterland 1295c51f124SMoriah Waterland vfpRewind(tmpvfp); 1305c51f124SMoriah Waterland 13162224350SCasper H.S. Dik for (eptnum = 0; (el_ent = extlist[eptnum]) != NULL; eptnum++) { 1325c51f124SMoriah Waterland /* 1335c51f124SMoriah Waterland * If there's an entry in the extlist at this position, 1345c51f124SMoriah Waterland * process that entry. 1355c51f124SMoriah Waterland */ 1365c51f124SMoriah Waterland /* Metafiles don't get merged. */ 1375c51f124SMoriah Waterland if ((el_ent->cf_ent.ftype == 'i') || 1385c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'n')) { 1395c51f124SMoriah Waterland continue; 1405c51f124SMoriah Waterland } 1415c51f124SMoriah Waterland 1425c51f124SMoriah Waterland /* 1435c51f124SMoriah Waterland * Copy cfextra structure for duplicated paths. 1445c51f124SMoriah Waterland * This is not just an optimization, it is 1455c51f124SMoriah Waterland * necessary for correct operation of algorithm. 1465c51f124SMoriah Waterland */ 1475c51f124SMoriah Waterland if ((eptnum > 0) && (strncmp(el_ent->cf_ent.path, 1485c51f124SMoriah Waterland extlist[eptnum-1]->cf_ent.path, PATH_MAX) == 0)) { 1495c51f124SMoriah Waterland memcpy(extlist[eptnum], extlist[eptnum-1], 1505c51f124SMoriah Waterland sizeof (struct cfextra)); 1515c51f124SMoriah Waterland continue; 1525c51f124SMoriah Waterland } 1535c51f124SMoriah Waterland 1545c51f124SMoriah Waterland /* 1555c51f124SMoriah Waterland * Normally dbst comes to us from installf() or 1565c51f124SMoriah Waterland * removef() in order to specify their special 1575c51f124SMoriah Waterland * database status codes. They cannot implement a 1585c51f124SMoriah Waterland * quick verify (it just doesn't make sense). For 1595c51f124SMoriah Waterland * that reason, we can test to see if we already have 1605c51f124SMoriah Waterland * a special database status. If we don't (it's from 1615c51f124SMoriah Waterland * pkgadd) then we can test to see if this is calling 1625c51f124SMoriah Waterland * for a quick verify wherein we assume the install 1635c51f124SMoriah Waterland * will work and fix it if it doesn't. In that case 1645c51f124SMoriah Waterland * we set our own dbst to be ENTRY_OK. 1655c51f124SMoriah Waterland */ 1665c51f124SMoriah Waterland if (dbst == '\0') { 1675c51f124SMoriah Waterland if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) == 1685c51f124SMoriah Waterland QKVERIFY) { 1695c51f124SMoriah Waterland assume_ok = 1; 1705c51f124SMoriah Waterland } 1715c51f124SMoriah Waterland } else { 1725c51f124SMoriah Waterland /* 1735c51f124SMoriah Waterland * If we DO end up with an installf/quick 1745c51f124SMoriah Waterland * verify combination, we fix that by simply 1755c51f124SMoriah Waterland * denying the quick verify for this class. 1765c51f124SMoriah Waterland * This forces everything to come out alright 1775c51f124SMoriah Waterland * by forcing the standard assumptions as 1785c51f124SMoriah Waterland * regards package database for the rest of 1795c51f124SMoriah Waterland * the load. 1805c51f124SMoriah Waterland */ 1815c51f124SMoriah Waterland if (cl_dvfy(el_ent->cf_ent.pkg_class_idx) == 1825c51f124SMoriah Waterland QKVERIFY) { 1835c51f124SMoriah Waterland logerr(gettext(WRN_ODDVERIFY), 18462224350SCasper H.S. Dik cl_nam(el_ent->cf_ent.pkg_class_idx)); 1855c51f124SMoriah Waterland /* 1865c51f124SMoriah Waterland * Set destination verification to 1875c51f124SMoriah Waterland * default. 1885c51f124SMoriah Waterland */ 18962224350SCasper H.S. Dik cl_def_dverify(el_ent->cf_ent.pkg_class_idx); 1905c51f124SMoriah Waterland } 1915c51f124SMoriah Waterland } 1925c51f124SMoriah Waterland 1935c51f124SMoriah Waterland /* 1945c51f124SMoriah Waterland * Comply with administrative requirements regarding 1955c51f124SMoriah Waterland * setuid/setgid processes. 1965c51f124SMoriah Waterland */ 1975c51f124SMoriah Waterland if (is_setuid(&(el_ent->cf_ent))) { 1985c51f124SMoriah Waterland el_ent->mstat.setuid = 1; 1995c51f124SMoriah Waterland } 2005c51f124SMoriah Waterland if (is_setgid(&(el_ent->cf_ent))) { 2015c51f124SMoriah Waterland el_ent->mstat.setgid = 1; 2025c51f124SMoriah Waterland } 2035c51f124SMoriah Waterland 2045c51f124SMoriah Waterland /* 2055c51f124SMoriah Waterland * If setuid/setgid processes are not allowed, reset 2065c51f124SMoriah Waterland * those bits. 2075c51f124SMoriah Waterland */ 2085c51f124SMoriah Waterland if (nosetuid && (el_ent->mstat.setgid || 2095c51f124SMoriah Waterland el_ent->mstat.setuid)) { 21062224350SCasper H.S. Dik el_ent->cf_ent.ainfo.mode &= ~(S_ISUID | S_ISGID); 2115c51f124SMoriah Waterland } 2125c51f124SMoriah Waterland 2135c51f124SMoriah Waterland /* Search package database for this entry. */ 21462224350SCasper H.S. Dik n = srchcfile(&cf_ent, el_ent->cf_ent.path, server); 2155c51f124SMoriah Waterland 2165c51f124SMoriah Waterland /* 2175c51f124SMoriah Waterland * If there was an error, note it and return an error 2185c51f124SMoriah Waterland * flag. 2195c51f124SMoriah Waterland */ 2205c51f124SMoriah Waterland if (n < 0) { 2215c51f124SMoriah Waterland char *errstr = getErrstr(); 22262224350SCasper H.S. Dik progerr(ERR_CFBAD); 22362224350SCasper H.S. Dik logerr(gettext("pathname: %s"), 2245c51f124SMoriah Waterland (cf_ent.path && *cf_ent.path) ? 2255c51f124SMoriah Waterland cf_ent.path : "Unknown"); 22662224350SCasper H.S. Dik logerr(gettext("problem: %s"), 2275c51f124SMoriah Waterland (errstr && *errstr) ? errstr : "Unknown"); 2285c51f124SMoriah Waterland return (-1); 2295c51f124SMoriah Waterland /* 2305c51f124SMoriah Waterland * If there was a match, then merge them into a 2315c51f124SMoriah Waterland * single entry. 2325c51f124SMoriah Waterland */ 2335c51f124SMoriah Waterland } else if (n == 1) { 2345c51f124SMoriah Waterland /* 2355c51f124SMoriah Waterland * If this package is overwriting a setuid or 2365c51f124SMoriah Waterland * setgid process, set the status bits so we 2375c51f124SMoriah Waterland * can inform the administrator. 2385c51f124SMoriah Waterland */ 2395c51f124SMoriah Waterland if (is_setuid(&cf_ent)) { 2405c51f124SMoriah Waterland el_ent->mstat.osetuid = 1; 2415c51f124SMoriah Waterland } 2425c51f124SMoriah Waterland 2435c51f124SMoriah Waterland if (is_setgid(&cf_ent)) { 2445c51f124SMoriah Waterland el_ent->mstat.osetgid = 1; 2455c51f124SMoriah Waterland } 2465c51f124SMoriah Waterland /* 2475c51f124SMoriah Waterland * Detect if a symlink has changed to directory 2485c51f124SMoriah Waterland * If so mark all the files/dir supposed to be 2495c51f124SMoriah Waterland * iniside this dir, so that they are not miss 2505c51f124SMoriah Waterland * understood by do_new_ent later as already 2515c51f124SMoriah Waterland * installed. 2525c51f124SMoriah Waterland */ 25362224350SCasper H.S. Dik if ((cf_ent.ftype == 's') && 2545c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'd')) { 2555c51f124SMoriah Waterland int i; 2565c51f124SMoriah Waterland int plen = strlen(el_ent->cf_ent.path); 2575c51f124SMoriah Waterland for (i = eptnum + 1; extlist[i]; i++) { 2585c51f124SMoriah Waterland if (strncmp(el_ent->cf_ent.path, 2595c51f124SMoriah Waterland extlist[i]->cf_ent.path, 2605c51f124SMoriah Waterland plen) != 0) 2615c51f124SMoriah Waterland break; 2625c51f124SMoriah Waterland extlist[i]->mstat.parentsyml2dir 2635c51f124SMoriah Waterland = 1; 2645c51f124SMoriah Waterland } 2655c51f124SMoriah Waterland } 2665c51f124SMoriah Waterland 26762224350SCasper H.S. Dik if (do_like_ent(tmpvfp, el_ent, &cf_ent, assume_ok)) { 2685c51f124SMoriah Waterland changed++; 2695c51f124SMoriah Waterland } 2705c51f124SMoriah Waterland 2715c51f124SMoriah Waterland } else { 2725c51f124SMoriah Waterland /* 27362224350SCasper H.S. Dik * The file doesn't exist in the database. 2745c51f124SMoriah Waterland */ 2755c51f124SMoriah Waterland if (do_new_ent(tmpvfp, el_ent, assume_ok)) { 2765c51f124SMoriah Waterland changed++; 2775c51f124SMoriah Waterland } 2785c51f124SMoriah Waterland } 2795c51f124SMoriah Waterland } 2805c51f124SMoriah Waterland 2815c51f124SMoriah Waterland return (errflg ? -1 : changed); 2825c51f124SMoriah Waterland } 2835c51f124SMoriah Waterland 2845c51f124SMoriah Waterland /* 2855c51f124SMoriah Waterland * Merge a new entry with an installed package object of the same name and 2865c51f124SMoriah Waterland * insert that object into the package database. Obey administrative defaults 2875c51f124SMoriah Waterland * as regards conflicting files. 2885c51f124SMoriah Waterland */ 2895c51f124SMoriah Waterland 2905c51f124SMoriah Waterland static int 2915c51f124SMoriah Waterland do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, struct cfent *cf_ent, int ctrl) 2925c51f124SMoriah Waterland { 2935c51f124SMoriah Waterland int stflag, ignore, changed, mrg_result; 2945c51f124SMoriah Waterland 2955c51f124SMoriah Waterland ignore = changed = 0; 2965c51f124SMoriah Waterland 2975c51f124SMoriah Waterland /* 2985c51f124SMoriah Waterland * Construct the record defining the current package. If there are 2995c51f124SMoriah Waterland * other packages involved, this will be appended to the existing 3005c51f124SMoriah Waterland * list. If this is an update of the same package, it will get merged 3015c51f124SMoriah Waterland * with the existing record. If this is a preloaded record (like from 3025c51f124SMoriah Waterland * a dryrun file), it will keep it's current pinfo pointer and will 3035c51f124SMoriah Waterland * pass it on to the record from the contents file - because on the 3045c51f124SMoriah Waterland * final continuation, the contents file will be wrong. 3055c51f124SMoriah Waterland */ 3065c51f124SMoriah Waterland if (el_ent->mstat.preloaded) { 3075c51f124SMoriah Waterland struct pinfo *pkginfo; 3085c51f124SMoriah Waterland 3095c51f124SMoriah Waterland /* Contents file is not to be trusted for this list. */ 3105c51f124SMoriah Waterland pkginfo = cf_ent->pinfo; 3115c51f124SMoriah Waterland 3125c51f124SMoriah Waterland /* Free the potentially bogus list. */ 3135c51f124SMoriah Waterland while (pkginfo) { 3145c51f124SMoriah Waterland struct pinfo *next; 3155c51f124SMoriah Waterland next = pkginfo->next; 3165c51f124SMoriah Waterland free(pkginfo); 3175c51f124SMoriah Waterland pkginfo = next; 3185c51f124SMoriah Waterland } 3195c51f124SMoriah Waterland 3205c51f124SMoriah Waterland cf_ent->pinfo = el_ent->cf_ent.pinfo; 3215c51f124SMoriah Waterland } 3225c51f124SMoriah Waterland 3235c51f124SMoriah Waterland pkgpinfo = eptstat(cf_ent, pkginst, DUP_ENTRY); 3245c51f124SMoriah Waterland 3255c51f124SMoriah Waterland stflag = pkgpinfo->status; 3265c51f124SMoriah Waterland 3275c51f124SMoriah Waterland if (otherstoo) 3285c51f124SMoriah Waterland el_ent->mstat.shared = 1; 3295c51f124SMoriah Waterland 3305c51f124SMoriah Waterland /* If it's marked for erasure, make it official */ 3315c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == RM_RDY) { 3325c51f124SMoriah Waterland if (!errflg) { 3335c51f124SMoriah Waterland pkgpinfo = eptstat(cf_ent, pkginst, RM_RDY); 3345c51f124SMoriah Waterland 3355c51f124SMoriah Waterland /* 3365c51f124SMoriah Waterland * Get copy of status character in case the object is 3375c51f124SMoriah Waterland * "shared" by a server, in which case we need to 3385c51f124SMoriah Waterland * maintain the shared status after the entry is 3395c51f124SMoriah Waterland * written to the package database with RM_RDY 3405c51f124SMoriah Waterland * status. This is needed to support the `removef' 3415c51f124SMoriah Waterland * command. 3425c51f124SMoriah Waterland */ 3435c51f124SMoriah Waterland stflag = pkgpinfo->status; 3445c51f124SMoriah Waterland pkgpinfo->status = RM_RDY; 3455c51f124SMoriah Waterland 3465c51f124SMoriah Waterland if (putcvfpfile(cf_ent, vfpo)) { 3475c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 3485c51f124SMoriah Waterland quit(99); 3495c51f124SMoriah Waterland } 3505c51f124SMoriah Waterland 3515c51f124SMoriah Waterland /* 3525c51f124SMoriah Waterland * If object is provided by a server, allocate an 3535c51f124SMoriah Waterland * info block and set the status to indicate this. 3545c51f124SMoriah Waterland * This is needed to support the `removef' command. 3555c51f124SMoriah Waterland */ 3565c51f124SMoriah Waterland if (stflag == SERVED_FILE) { 3575c51f124SMoriah Waterland el_ent->cf_ent.pinfo = 3585c51f124SMoriah Waterland (struct pinfo *)calloc(1, 3595c51f124SMoriah Waterland sizeof (struct pinfo)); 3605c51f124SMoriah Waterland el_ent->cf_ent.pinfo->next = NULL; 3615c51f124SMoriah Waterland el_ent->cf_ent.pinfo->status = SERVED_FILE; 3625c51f124SMoriah Waterland } 3635c51f124SMoriah Waterland } 3645c51f124SMoriah Waterland return (1); 3655c51f124SMoriah Waterland } 3665c51f124SMoriah Waterland 3675c51f124SMoriah Waterland /* 3685c51f124SMoriah Waterland * If there is no package associated with it, there's something 3695c51f124SMoriah Waterland * very wrong. 3705c51f124SMoriah Waterland */ 3715c51f124SMoriah Waterland if (!pkgpinfo) { 3725c51f124SMoriah Waterland progerr(gettext(ERR_PINFO), cf_ent->path); 3735c51f124SMoriah Waterland quit(99); 3745c51f124SMoriah Waterland } 3755c51f124SMoriah Waterland 3765c51f124SMoriah Waterland /* 3775c51f124SMoriah Waterland * Do not allow installation if nocnflct is set and other packages 3785c51f124SMoriah Waterland * reference this pathname. The cp_cfent() function below writes the 3795c51f124SMoriah Waterland * information from the installed file over the new entry, so the 3805c51f124SMoriah Waterland * package database will be unchanged. 3815c51f124SMoriah Waterland * 3825c51f124SMoriah Waterland * By the way, ftype "e" is often shared and that's OK, so ftype 3835c51f124SMoriah Waterland * "e" doesn't count here. 3845c51f124SMoriah Waterland */ 3855c51f124SMoriah Waterland if ((nocnflct && el_ent->mstat.shared && el_ent->cf_ent.ftype != 'e')) { 3865c51f124SMoriah Waterland /* 3875c51f124SMoriah Waterland * First set the attrchg and contchg entries for proper 3885c51f124SMoriah Waterland * messaging in the install phase. 3895c51f124SMoriah Waterland */ 3905c51f124SMoriah Waterland set_change(el_ent); 3915c51f124SMoriah Waterland 3925c51f124SMoriah Waterland /* 3935c51f124SMoriah Waterland * Now overwrite the new entry with the entry for the 3945c51f124SMoriah Waterland * currently installed object. 3955c51f124SMoriah Waterland */ 3965c51f124SMoriah Waterland if (cp_cfent(cf_ent, el_ent) == 0) 3975c51f124SMoriah Waterland quit(99); 3985c51f124SMoriah Waterland 3995c51f124SMoriah Waterland ignore++; 4005c51f124SMoriah Waterland } else { 4015c51f124SMoriah Waterland mrg_result = merg(el_ent, cf_ent); 4025c51f124SMoriah Waterland 4035c51f124SMoriah Waterland switch (mrg_result) { 4045c51f124SMoriah Waterland case MRG_SAME: 4055c51f124SMoriah Waterland break; 4065c51f124SMoriah Waterland 4075c51f124SMoriah Waterland case MRG_DIFFERENT: 4085c51f124SMoriah Waterland changed++; 4095c51f124SMoriah Waterland break; 4105c51f124SMoriah Waterland 4115c51f124SMoriah Waterland case MRG_REPLACE: 4125c51f124SMoriah Waterland /* 4135c51f124SMoriah Waterland * We'll pick one or the other later. For now, cf_ent 4145c51f124SMoriah Waterland * will have the fault value and el_ent will retain 4155c51f124SMoriah Waterland * the other value. This is the only state that allows 4165c51f124SMoriah Waterland * the database and the pkgmap to differ. 4175c51f124SMoriah Waterland */ 4185c51f124SMoriah Waterland 4195c51f124SMoriah Waterland el_ent->mstat.contchg = 1; /* subject to change */ 4205c51f124SMoriah Waterland ignore++; 4215c51f124SMoriah Waterland break; 4225c51f124SMoriah Waterland 4235c51f124SMoriah Waterland default: 4245c51f124SMoriah Waterland break; 4255c51f124SMoriah Waterland } 4265c51f124SMoriah Waterland } 4275c51f124SMoriah Waterland 4285c51f124SMoriah Waterland /* el_ent structure now contains updated entry */ 4295c51f124SMoriah Waterland if (!el_ent->mstat.contchg && !ignore) { 4305c51f124SMoriah Waterland /* 4315c51f124SMoriah Waterland * We know the DB entry matches the pkgmap, so now we need to 4325c51f124SMoriah Waterland * see if the actual object matches the pkgmap. 4335c51f124SMoriah Waterland */ 4345c51f124SMoriah Waterland set_change(el_ent); 4355c51f124SMoriah Waterland } 4365c51f124SMoriah Waterland 4375c51f124SMoriah Waterland if (!errflg) { 4385c51f124SMoriah Waterland if (ctrl == 1) { /* quick verify assumes OK */ 4395c51f124SMoriah Waterland /* 4405c51f124SMoriah Waterland * The pkgpinfo entry is already correctly 4415c51f124SMoriah Waterland * constructed. Look into dropping this soon. 4425c51f124SMoriah Waterland */ 4435c51f124SMoriah Waterland pkgpinfo = eptstat(&(el_ent->cf_ent), pkginst, 4445c51f124SMoriah Waterland ENTRY_OK); 4455c51f124SMoriah Waterland 4465c51f124SMoriah Waterland if (stflag != DUP_ENTRY) { 4475c51f124SMoriah Waterland changed++; 4485c51f124SMoriah Waterland } 4495c51f124SMoriah Waterland 4505c51f124SMoriah Waterland /* 4515c51f124SMoriah Waterland * We could trust the prior pkginfo entry, but things 4525c51f124SMoriah Waterland * could have changed and we need to update the 4535c51f124SMoriah Waterland * fs_tab[] anyway. We check for a server object 4545c51f124SMoriah Waterland * here. 4555c51f124SMoriah Waterland */ 4565c51f124SMoriah Waterland if (is_served(el_ent->server_path, 4575c51f124SMoriah Waterland &(el_ent->fsys_value))) 4585c51f124SMoriah Waterland pkgpinfo->status = SERVED_FILE; 4595c51f124SMoriah Waterland } else { 4605c51f124SMoriah Waterland if (!ignore && el_ent->mstat.contchg) { 4615c51f124SMoriah Waterland pkgpinfo = 4625c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 4635c51f124SMoriah Waterland (dbst ? dbst : CONFIRM_CONT)); 4645c51f124SMoriah Waterland } else if (!ignore && el_ent->mstat.attrchg) { 4655c51f124SMoriah Waterland pkgpinfo = 4665c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 4675c51f124SMoriah Waterland (dbst ? dbst : CONFIRM_ATTR)); 4685c51f124SMoriah Waterland } else if (!ignore && el_ent->mstat.shared) { 4695c51f124SMoriah Waterland pkgpinfo = 4705c51f124SMoriah Waterland eptstat(&(el_ent->cf_ent), pkginst, 4715c51f124SMoriah Waterland dbst); 4725c51f124SMoriah Waterland changed++; 4735c51f124SMoriah Waterland } else if (stflag != DUP_ENTRY) { 4745c51f124SMoriah Waterland pkgpinfo = eptstat(&(el_ent->cf_ent), 4755c51f124SMoriah Waterland pkginst, '\0'); 4765c51f124SMoriah Waterland if (stflag != ENTRY_OK) { 4775c51f124SMoriah Waterland changed++; 4785c51f124SMoriah Waterland } 4795c51f124SMoriah Waterland } 4805c51f124SMoriah Waterland } 4815c51f124SMoriah Waterland 4825c51f124SMoriah Waterland if (mrg_result == MRG_REPLACE) { 4835c51f124SMoriah Waterland /* 4845c51f124SMoriah Waterland * Put the original package database entry back into 4855c51f124SMoriah Waterland * the package database for now. 4865c51f124SMoriah Waterland */ 4875c51f124SMoriah Waterland output(vfpo, cf_ent, pkgpinfo); 4885c51f124SMoriah Waterland } else { 4895c51f124SMoriah Waterland /* Put the merged entry into the package database. */ 4905c51f124SMoriah Waterland output(vfpo, &(el_ent->cf_ent), pkgpinfo); 4915c51f124SMoriah Waterland } 4925c51f124SMoriah Waterland } 4935c51f124SMoriah Waterland 4945c51f124SMoriah Waterland if (pkgpinfo->aclass[0] != '\0') { 4955c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.pkg_class, pkgpinfo->aclass); 4965c51f124SMoriah Waterland } 4975c51f124SMoriah Waterland 4985c51f124SMoriah Waterland /* 4995c51f124SMoriah Waterland * If a sym link entry exists in the contents file and 5005c51f124SMoriah Waterland * and the destination of the link does not exist on the the system 5015c51f124SMoriah Waterland * then the contents file needs to be updated appropriately so a 5025c51f124SMoriah Waterland * subsequent invocation of "installf -f" will create the destination. 5035c51f124SMoriah Waterland */ 5045c51f124SMoriah Waterland if (el_ent->mstat.contchg && pkgpinfo->status == INST_RDY) { 5055c51f124SMoriah Waterland changed++; 5065c51f124SMoriah Waterland } 5075c51f124SMoriah Waterland 5085c51f124SMoriah Waterland if (!(el_ent->mstat.preloaded)) 5095c51f124SMoriah Waterland el_ent->cf_ent.pinfo = NULL; 5105c51f124SMoriah Waterland 5115c51f124SMoriah Waterland /* 5125c51f124SMoriah Waterland * If no change during the merg and we don't have a case where types 5135c51f124SMoriah Waterland * were different in odd ways, count this as installed. 5145c51f124SMoriah Waterland */ 5155c51f124SMoriah Waterland if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg && 5165c51f124SMoriah Waterland !el_ent->mstat.replace) 5175c51f124SMoriah Waterland installed++; 5185c51f124SMoriah Waterland return (changed); 5195c51f124SMoriah Waterland } 5205c51f124SMoriah Waterland 5215c51f124SMoriah Waterland /* Insert an entirely new entry into the package database. */ 5225c51f124SMoriah Waterland static int 5235c51f124SMoriah Waterland do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl) 5245c51f124SMoriah Waterland { 5255c51f124SMoriah Waterland struct pinfo *pinfo; 5265c51f124SMoriah Waterland char *tp; 5275c51f124SMoriah Waterland int changed = 0; 5285c51f124SMoriah Waterland 5295c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == RM_RDY) { 5305c51f124SMoriah Waterland return (0); 5315c51f124SMoriah Waterland } 5325c51f124SMoriah Waterland 5335c51f124SMoriah Waterland tp = el_ent->server_path; 5345c51f124SMoriah Waterland /* 5355c51f124SMoriah Waterland * Check the file/dir existence only if any of the parent directory 5365c51f124SMoriah Waterland * of the file/dir has not changed from symbolic link to directory. 5375c51f124SMoriah Waterland * At this time we are only doing a dry run, the symlink is not yet 5385c51f124SMoriah Waterland * replaced, so if this is done directly then access will result in 5395c51f124SMoriah Waterland * incorrect information in case a file with the same attr and cont 5405c51f124SMoriah Waterland * exists in the link target. 5415c51f124SMoriah Waterland */ 5425c51f124SMoriah Waterland if ((!el_ent->mstat.parentsyml2dir) && (access(tp, F_OK) == 0)) { 5435c51f124SMoriah Waterland /* 5445c51f124SMoriah Waterland * Path exists, and although its not referenced by any 5455c51f124SMoriah Waterland * package we make it look like it is so it appears as a 5465c51f124SMoriah Waterland * conflicting file in case the user doesn't want it 5475c51f124SMoriah Waterland * installed. We set the rogue flag to distinguish this from 5485c51f124SMoriah Waterland * package object conflicts if the administrator is queried 5495c51f124SMoriah Waterland * about this later. Note that noconflict means NO conflict 5505c51f124SMoriah Waterland * at the file level. Even rogue files count. 5515c51f124SMoriah Waterland */ 5525c51f124SMoriah Waterland el_ent->mstat.shared = 1; 5535c51f124SMoriah Waterland el_ent->mstat.rogue = 1; 5545c51f124SMoriah Waterland set_change(el_ent); 5555c51f124SMoriah Waterland } else { 5565c51f124SMoriah Waterland /* since path doesn't exist, we're changing everything */ 5575c51f124SMoriah Waterland el_ent->mstat.rogue = 0; 5585c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 5595c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 5605c51f124SMoriah Waterland } 5615c51f124SMoriah Waterland 5625c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.mode == WILDCARD) { 5635c51f124SMoriah Waterland if (el_ent->cf_ent.ftype == 'd') { 5645c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = DEFAULT_MODE; 5655c51f124SMoriah Waterland } else { 5665c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = DEFAULT_MODE_FILE; 5675c51f124SMoriah Waterland } 5685c51f124SMoriah Waterland logerr(WRN_SET_DEF_MODE, el_ent->cf_ent.path, 5695c51f124SMoriah Waterland (int)el_ent->cf_ent.ainfo.mode); 5705c51f124SMoriah Waterland } 5715c51f124SMoriah Waterland 5725c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.owner, DB_UNDEFINED_ENTRY) == 0) 5735c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.owner, 5745c51f124SMoriah Waterland DEFAULT_OWNER); 5755c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.group, DB_UNDEFINED_ENTRY) == 0) 5765c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.group, 5775c51f124SMoriah Waterland DEFAULT_GROUP); 5785c51f124SMoriah Waterland 5795c51f124SMoriah Waterland /* 5805c51f124SMoriah Waterland * Do not allow installation if nocnflct is set and this pathname is 5815c51f124SMoriah Waterland * already in place. Since this entry is new (not associated with a 5825c51f124SMoriah Waterland * package), we don't issue anything to the database we're building. 5835c51f124SMoriah Waterland */ 5845c51f124SMoriah Waterland if (nocnflct && el_ent->mstat.shared) { 5855c51f124SMoriah Waterland return (0); 5865c51f124SMoriah Waterland } 5875c51f124SMoriah Waterland 5885c51f124SMoriah Waterland if (!errflg) { 5895c51f124SMoriah Waterland if (el_ent->mstat.preloaded) { 5905c51f124SMoriah Waterland /* Add this package to the already established list. */ 5915c51f124SMoriah Waterland pinfo = eptstat(&(el_ent->cf_ent), pkginst, DUP_ENTRY); 5925c51f124SMoriah Waterland } else { 5935c51f124SMoriah Waterland el_ent->cf_ent.npkgs = 1; 5945c51f124SMoriah Waterland pinfo = (struct pinfo *)calloc(1, 5955c51f124SMoriah Waterland sizeof (struct pinfo)); 5965c51f124SMoriah Waterland if (!pinfo) { 5975c51f124SMoriah Waterland progerr(gettext(ERR_MEMORY), errno); 5985c51f124SMoriah Waterland quit(99); 5995c51f124SMoriah Waterland } 6005c51f124SMoriah Waterland el_ent->cf_ent.pinfo = pinfo; 6015c51f124SMoriah Waterland (void) strcpy(pinfo->pkg, pkginst); 6025c51f124SMoriah Waterland } 6035c51f124SMoriah Waterland 6045c51f124SMoriah Waterland if (ctrl == 1) { /* quick verify assumes OK */ 6055c51f124SMoriah Waterland pinfo->status = dbst ? dbst : ENTRY_OK; 6065c51f124SMoriah Waterland /* 6075c51f124SMoriah Waterland * The entry won't be verified, but the entry in the 6085c51f124SMoriah Waterland * database isn't necessarily ENTRY_OK. If this is 6095c51f124SMoriah Waterland * coming from a server, we need to note that 6105c51f124SMoriah Waterland * instead. 6115c51f124SMoriah Waterland */ 6125c51f124SMoriah Waterland if (is_served(el_ent->server_path, 6135c51f124SMoriah Waterland &(el_ent->fsys_value))) 6145c51f124SMoriah Waterland pinfo->status = SERVED_FILE; 6155c51f124SMoriah Waterland } else { 6165c51f124SMoriah Waterland pinfo->status = dbst ? dbst : CONFIRM_CONT; 6175c51f124SMoriah Waterland } 6185c51f124SMoriah Waterland 6195c51f124SMoriah Waterland output(vfpo, &(el_ent->cf_ent), pinfo); 6205c51f124SMoriah Waterland changed++; 6215c51f124SMoriah Waterland 6225c51f124SMoriah Waterland free(pinfo); 6235c51f124SMoriah Waterland el_ent->cf_ent.pinfo = NULL; 6245c51f124SMoriah Waterland } 6255c51f124SMoriah Waterland if (!el_ent->mstat.attrchg && !el_ent->mstat.contchg) { 6265c51f124SMoriah Waterland installed++; 6275c51f124SMoriah Waterland } 6285c51f124SMoriah Waterland 6295c51f124SMoriah Waterland return (changed); 6305c51f124SMoriah Waterland } 6315c51f124SMoriah Waterland 6325c51f124SMoriah Waterland int 6335c51f124SMoriah Waterland files_installed(void) 6345c51f124SMoriah Waterland { 6355c51f124SMoriah Waterland return (installed); 6365c51f124SMoriah Waterland } 6375c51f124SMoriah Waterland 6385c51f124SMoriah Waterland /* 6395c51f124SMoriah Waterland * This function determines if there is a difference between the file on 6405c51f124SMoriah Waterland * the disk and the file to be laid down. It set's mstat flags attrchg 6415c51f124SMoriah Waterland * and contchg accordingly. 6425c51f124SMoriah Waterland */ 6435c51f124SMoriah Waterland static void 6445c51f124SMoriah Waterland set_change(struct cfextra *el_ent) 6455c51f124SMoriah Waterland { 6465c51f124SMoriah Waterland int n; 6475c51f124SMoriah Waterland char *tp; 6485c51f124SMoriah Waterland 6495c51f124SMoriah Waterland tp = el_ent->server_path; 6505c51f124SMoriah Waterland if ((el_ent->cf_ent.ftype == 'f') || (el_ent->cf_ent.ftype == 'e') || 6515c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'v')) { 6525c51f124SMoriah Waterland if (cverify(0, &(el_ent->cf_ent.ftype), tp, 6535c51f124SMoriah Waterland &(el_ent->cf_ent.cinfo), 1)) { 6545c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 6555c51f124SMoriah Waterland } else if (!el_ent->mstat.contchg && !el_ent->mstat.attrchg) { 6565c51f124SMoriah Waterland if (averify(0, &(el_ent->cf_ent.ftype), tp, 6575c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo))) 6585c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 6595c51f124SMoriah Waterland } 6605c51f124SMoriah Waterland } else if (!el_ent->mstat.attrchg && 6615c51f124SMoriah Waterland ((el_ent->cf_ent.ftype == 'd') || 6625c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'x') || 6635c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'c') || 6645c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'b') || 6655c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'p'))) { 6665c51f124SMoriah Waterland n = averify(0, &(el_ent->cf_ent.ftype), tp, 6675c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo)); 6685c51f124SMoriah Waterland if (n == VE_ATTR) 6695c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 6705c51f124SMoriah Waterland else if (n && (n != VE_EXIST)) { 6715c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 6725c51f124SMoriah Waterland } 6735c51f124SMoriah Waterland } else if (!el_ent->mstat.attrchg && 6745c51f124SMoriah Waterland ((el_ent->cf_ent.ftype == 's') || 6755c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'l'))) { 6765c51f124SMoriah Waterland n = averify(0, &(el_ent->cf_ent.ftype), tp, 6775c51f124SMoriah Waterland &(el_ent->cf_ent.ainfo)); 6785c51f124SMoriah Waterland if (n == VE_ATTR) 6795c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 6805c51f124SMoriah Waterland else if (n && (n == VE_EXIST)) { 6815c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 6825c51f124SMoriah Waterland } 6835c51f124SMoriah Waterland } 6845c51f124SMoriah Waterland } 6855c51f124SMoriah Waterland 6865c51f124SMoriah Waterland static int 6875c51f124SMoriah Waterland is_setuid(struct cfent *ent) 6885c51f124SMoriah Waterland { 6895c51f124SMoriah Waterland return (((ent->ftype == 'f') || (ent->ftype == 'v') || 6905c51f124SMoriah Waterland (ent->ftype == 'e')) && 6915c51f124SMoriah Waterland (ent->ainfo.mode != BADMODE) && 6925c51f124SMoriah Waterland (ent->ainfo.mode != WILDCARD) && 6935c51f124SMoriah Waterland (ent->ainfo.mode & S_ISUID)); 6945c51f124SMoriah Waterland } 6955c51f124SMoriah Waterland 6965c51f124SMoriah Waterland static int 6975c51f124SMoriah Waterland is_setgid(struct cfent *ent) 6985c51f124SMoriah Waterland { 6995c51f124SMoriah Waterland return (((ent->ftype == 'f') || (ent->ftype == 'v') || 7005c51f124SMoriah Waterland (ent->ftype == 'e')) && (ent->ainfo.mode != BADMODE) && 7015c51f124SMoriah Waterland (ent->ainfo.mode != WILDCARD) && 7025c51f124SMoriah Waterland (ent->ainfo.mode & S_ISGID) && 7035c51f124SMoriah Waterland (ent->ainfo.mode & (S_IEXEC|S_IXUSR|S_IXOTH))); 7045c51f124SMoriah Waterland } 7055c51f124SMoriah Waterland 7065c51f124SMoriah Waterland char *types[] = { 7075c51f124SMoriah Waterland "fev", /* type 1, regular files */ 7085c51f124SMoriah Waterland "s", /* type 2, symbolic links */ 7095c51f124SMoriah Waterland "l", /* type 3, linked files */ 7105c51f124SMoriah Waterland "dx", /* type 4, directories */ 7115c51f124SMoriah Waterland "c", /* type 5, character special devices */ 7125c51f124SMoriah Waterland "b", /* type 6, block special devices */ 7135c51f124SMoriah Waterland "p", /* type 7, named pipes */ 7145c51f124SMoriah Waterland NULL 7155c51f124SMoriah Waterland }; 7165c51f124SMoriah Waterland 7175c51f124SMoriah Waterland /* 7185c51f124SMoriah Waterland * This determines if the ftype of the file on the disk and the file to be 7195c51f124SMoriah Waterland * laid down are close enough. If they aren't, this either returns an error 7205c51f124SMoriah Waterland * or displays a warning. This returns : 7215c51f124SMoriah Waterland * TYPE_OK they're identical or close enough 7225c51f124SMoriah Waterland * TYPE_WARNING they're pretty close (probably no problem) 7235c51f124SMoriah Waterland * TYPE_IGNORED the type change was not allowed 7245c51f124SMoriah Waterland * TYPE_REPLACE to be reviewed later - in endofclass() maybe 7255c51f124SMoriah Waterland * TYPE_FATAL something awful happened 7265c51f124SMoriah Waterland */ 7275c51f124SMoriah Waterland static int 728*b46ec01aSok199659 typechg(struct cfent *el_ent, struct cfent *cf_ent, struct mergstat *mstat) 7295c51f124SMoriah Waterland { 7305c51f124SMoriah Waterland int i, etype, itype, retcode; 7315c51f124SMoriah Waterland 7325c51f124SMoriah Waterland /* If they are identical, return OK */ 733*b46ec01aSok199659 if (cf_ent->ftype == el_ent->ftype) 7345c51f124SMoriah Waterland return (TYPE_OK); 7355c51f124SMoriah Waterland 7365c51f124SMoriah Waterland /* 7375c51f124SMoriah Waterland * If package database entry is ambiguous, set it to the new entity's 7385c51f124SMoriah Waterland * ftype 7395c51f124SMoriah Waterland */ 740*b46ec01aSok199659 if (cf_ent->ftype == BADFTYPE) { 741*b46ec01aSok199659 cf_ent->ftype = el_ent->ftype; 7425c51f124SMoriah Waterland return (TYPE_OK); /* do nothing; not really different */ 7435c51f124SMoriah Waterland } 7445c51f124SMoriah Waterland 7455c51f124SMoriah Waterland /* If the new entity is ambiguous, wait for the verify */ 7465c51f124SMoriah Waterland if (el_ent->ftype == BADFTYPE) 7475c51f124SMoriah Waterland return (TYPE_OK); 7485c51f124SMoriah Waterland 7495c51f124SMoriah Waterland /* 7505c51f124SMoriah Waterland * If we're trying to convert an existing regular directory to an 7515c51f124SMoriah Waterland * exclusive directory, this is very dangerous. We will continue, but 7525c51f124SMoriah Waterland * we will deny the conversion. 7535c51f124SMoriah Waterland */ 754*b46ec01aSok199659 if (el_ent->ftype == 'x' && cf_ent->ftype == 'd') { 7555c51f124SMoriah Waterland logerr(gettext(WRN_TOEXCL), el_ent->path); 7565c51f124SMoriah Waterland return (TYPE_IGNORED); 7575c51f124SMoriah Waterland } 7585c51f124SMoriah Waterland 7595c51f124SMoriah Waterland etype = itype = 0; 7605c51f124SMoriah Waterland 7615c51f124SMoriah Waterland /* Set etype to that of the new entity */ 7625c51f124SMoriah Waterland for (i = 0; types[i]; ++i) { 7635c51f124SMoriah Waterland if (strchr(types[i], el_ent->ftype)) { 7645c51f124SMoriah Waterland etype = i+1; 7655c51f124SMoriah Waterland break; 7665c51f124SMoriah Waterland } 7675c51f124SMoriah Waterland } 7685c51f124SMoriah Waterland 7695c51f124SMoriah Waterland /* Set itype to that in the package database. */ 7705c51f124SMoriah Waterland for (i = 0; types[i]; ++i) { 771*b46ec01aSok199659 if (strchr(types[i], cf_ent->ftype)) { 7725c51f124SMoriah Waterland itype = i+1; 7735c51f124SMoriah Waterland break; 7745c51f124SMoriah Waterland } 7755c51f124SMoriah Waterland } 7765c51f124SMoriah Waterland 7775c51f124SMoriah Waterland if (itype == etype) { 7785c51f124SMoriah Waterland /* same basic object type */ 7795c51f124SMoriah Waterland return (TYPE_OK); 7805c51f124SMoriah Waterland } 7815c51f124SMoriah Waterland 7825c51f124SMoriah Waterland retcode = TYPE_WARNING; 7835c51f124SMoriah Waterland 7845c51f124SMoriah Waterland /* 7855c51f124SMoriah Waterland * If a simple object (like a file) is overwriting a directory, mark 7865c51f124SMoriah Waterland * it for full inspection during installation. 7875c51f124SMoriah Waterland */ 7885c51f124SMoriah Waterland if (etype != 4 && itype == 4) { 7895c51f124SMoriah Waterland mstat->dir2nondir = 1; 7905c51f124SMoriah Waterland retcode = TYPE_REPLACE; 7915c51f124SMoriah Waterland } 7925c51f124SMoriah Waterland 7935c51f124SMoriah Waterland /* allow change, but warn user of possible problems */ 7945c51f124SMoriah Waterland switch (itype) { 7955c51f124SMoriah Waterland case 1: 7965c51f124SMoriah Waterland logerr(gettext(WRN_NOTFILE), el_ent->path); 7975c51f124SMoriah Waterland break; 7985c51f124SMoriah Waterland 7995c51f124SMoriah Waterland case 2: 8005c51f124SMoriah Waterland logerr(gettext(WRN_NOTSYMLN), el_ent->path); 8015c51f124SMoriah Waterland break; 8025c51f124SMoriah Waterland 8035c51f124SMoriah Waterland case 3: 8045c51f124SMoriah Waterland logerr(gettext(WRN_NOTLINK), el_ent->path); 8055c51f124SMoriah Waterland break; 8065c51f124SMoriah Waterland 8075c51f124SMoriah Waterland case 4: 8085c51f124SMoriah Waterland logerr(gettext(WRN_NOTDIR), el_ent->path); 8095c51f124SMoriah Waterland break; 8105c51f124SMoriah Waterland 8115c51f124SMoriah Waterland case 5: 8125c51f124SMoriah Waterland logerr(gettext(WRN_NOTCHAR), el_ent->path); 8135c51f124SMoriah Waterland break; 8145c51f124SMoriah Waterland 8155c51f124SMoriah Waterland case 6: 8165c51f124SMoriah Waterland logerr(gettext(WRN_NOTBLOCK), el_ent->path); 8175c51f124SMoriah Waterland break; 8185c51f124SMoriah Waterland 8195c51f124SMoriah Waterland case 7: 8205c51f124SMoriah Waterland logerr(gettext(WRN_NOTPIPE), el_ent->path); 8215c51f124SMoriah Waterland break; 8225c51f124SMoriah Waterland 8235c51f124SMoriah Waterland default: 8245c51f124SMoriah Waterland break; 8255c51f124SMoriah Waterland } 8265c51f124SMoriah Waterland return (retcode); 8275c51f124SMoriah Waterland } 8285c51f124SMoriah Waterland 8295c51f124SMoriah Waterland /* 8305c51f124SMoriah Waterland * This function takes el_ent (the entry from the pkgmap) and cf_ent (the 8315c51f124SMoriah Waterland * entry from the package database) and merge them into el_ent. The rules 8325c51f124SMoriah Waterland * are still being figured out, but the comments should make the approach 8335c51f124SMoriah Waterland * pretty clear. 8345c51f124SMoriah Waterland * 8355c51f124SMoriah Waterland * RETURN CODES: 8365c51f124SMoriah Waterland * MRG_DIFFERENT The two entries are different and el_ent now contains 8375c51f124SMoriah Waterland * the intended new entry to be installed. 8385c51f124SMoriah Waterland * MRG_SAME The two entries were identical and the old database 8395c51f124SMoriah Waterland * entry will be replaced unchanged. 8405c51f124SMoriah Waterland * MRG_REPLACE One or the other entry will be used but the decision 8415c51f124SMoriah Waterland * has to be made at install time. 8425c51f124SMoriah Waterland */ 8435c51f124SMoriah Waterland static int 8445c51f124SMoriah Waterland merg(struct cfextra *el_ent, struct cfent *cf_ent) 8455c51f124SMoriah Waterland { 8465c51f124SMoriah Waterland int n, changed = 0; 8475c51f124SMoriah Waterland 8485c51f124SMoriah Waterland /* 8495c51f124SMoriah Waterland * We need to change the original entry to make it look like the new 8505c51f124SMoriah Waterland * entry (the eptstat() routine has already added appropriate package 8515c51f124SMoriah Waterland * information, but not about 'aclass' which may represent a change 8525c51f124SMoriah Waterland * in class from the previous installation. 8535c51f124SMoriah Waterland * 8545c51f124SMoriah Waterland * NOTE: elent->cf_ent.pinfo (the list of associated packages) is NULL 8555c51f124SMoriah Waterland * upon entry to this function. 8565c51f124SMoriah Waterland */ 8575c51f124SMoriah Waterland 8585c51f124SMoriah Waterland el_ent->cf_ent.pinfo = cf_ent->pinfo; 8595c51f124SMoriah Waterland 8605c51f124SMoriah Waterland if (dbst == INST_RDY && el_ent->cf_ent.ftype == '?') { 8615c51f124SMoriah Waterland el_ent->cf_ent.ftype = cf_ent->ftype; 8625c51f124SMoriah Waterland } 8635c51f124SMoriah Waterland 8645c51f124SMoriah Waterland /* 8655c51f124SMoriah Waterland * Evaluate the ftype change. Usually the ftype won't change. If it 8665c51f124SMoriah Waterland * does it may be easy (s -> f), not allowed (d -> x), so complex we 8675c51f124SMoriah Waterland * can't figure it 'til later (d -> s) or fatal (a hook for later). 8685c51f124SMoriah Waterland */ 8695c51f124SMoriah Waterland if (cf_ent->ftype != el_ent->cf_ent.ftype) { 870*b46ec01aSok199659 n = typechg(&(el_ent->cf_ent), cf_ent, &(el_ent->mstat)); 8715c51f124SMoriah Waterland 8725c51f124SMoriah Waterland switch (n) { 8735c51f124SMoriah Waterland case TYPE_OK: 8745c51f124SMoriah Waterland break; 8755c51f124SMoriah Waterland 8765c51f124SMoriah Waterland /* This is an allowable change. */ 8775c51f124SMoriah Waterland case TYPE_WARNING: 8785c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 8795c51f124SMoriah Waterland break; 8805c51f124SMoriah Waterland 8815c51f124SMoriah Waterland /* Not allowed, but leaving it as is is OK. */ 8825c51f124SMoriah Waterland case TYPE_IGNORED: 8835c51f124SMoriah Waterland logerr(gettext(MSG_TYPIGN)); 8845c51f124SMoriah Waterland if (cp_cfent(cf_ent, el_ent) == 0) 8855c51f124SMoriah Waterland quit(99); 8865c51f124SMoriah Waterland return (MRG_SAME); 8875c51f124SMoriah Waterland 8885c51f124SMoriah Waterland /* Future analysis will reveal if this is OK. */ 8895c51f124SMoriah Waterland case TYPE_REPLACE: 8905c51f124SMoriah Waterland el_ent->mstat.replace = 1; 8915c51f124SMoriah Waterland return (MRG_REPLACE); 8925c51f124SMoriah Waterland 8935c51f124SMoriah Waterland /* Kill it before it does any damage. */ 8945c51f124SMoriah Waterland case TYPE_FATAL: 8955c51f124SMoriah Waterland logerr(gettext(MSG_TYPE_ERR)); 8965c51f124SMoriah Waterland quit(99); 8975c51f124SMoriah Waterland 8985c51f124SMoriah Waterland default: 8995c51f124SMoriah Waterland break; 9005c51f124SMoriah Waterland } 9015c51f124SMoriah Waterland 9025c51f124SMoriah Waterland changed++; 9035c51f124SMoriah Waterland } 9045c51f124SMoriah Waterland 9055c51f124SMoriah Waterland /* Evaluate and merge the class. */ 9065c51f124SMoriah Waterland if (strcmp(cf_ent->pkg_class, el_ent->cf_ent.pkg_class)) { 9075c51f124SMoriah Waterland /* 9085c51f124SMoriah Waterland * we always allow a class change as long as we have 9095c51f124SMoriah Waterland * consistent ftypes, which at this point we must 9105c51f124SMoriah Waterland */ 9115c51f124SMoriah Waterland changed++; 9125c51f124SMoriah Waterland if (strcmp(cf_ent->pkg_class, "?")) { 9135c51f124SMoriah Waterland (void) strcpy(pkgpinfo->aclass, 9145c51f124SMoriah Waterland el_ent->cf_ent.pkg_class); 9155c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.pkg_class, 9165c51f124SMoriah Waterland cf_ent->pkg_class); 9175c51f124SMoriah Waterland chgclass(&(el_ent->cf_ent), pkgpinfo); 9185c51f124SMoriah Waterland } 9195c51f124SMoriah Waterland } 9205c51f124SMoriah Waterland 9215c51f124SMoriah Waterland /* 9225c51f124SMoriah Waterland * Evaluate and merge based upon the ftype of the intended package 9235c51f124SMoriah Waterland * database entry. 9245c51f124SMoriah Waterland */ 9255c51f124SMoriah Waterland if (((el_ent->cf_ent.ftype == 's') || (el_ent->cf_ent.ftype == 'l'))) { 9265c51f124SMoriah Waterland 9275c51f124SMoriah Waterland /* If both have link sources, then they need to be merged. */ 9285c51f124SMoriah Waterland if (cf_ent->ainfo.local && el_ent->cf_ent.ainfo.local) { 9295c51f124SMoriah Waterland /* 9305c51f124SMoriah Waterland * If both sources are identical, the merge is 9315c51f124SMoriah Waterland * already done. 9325c51f124SMoriah Waterland */ 9335c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.local, 9345c51f124SMoriah Waterland el_ent->cf_ent.ainfo.local) != NULL) { 9355c51f124SMoriah Waterland changed++; 9365c51f124SMoriah Waterland 9375c51f124SMoriah Waterland /* 9385c51f124SMoriah Waterland * Otherwise, if the pkgmap entry is 9395c51f124SMoriah Waterland * ambiguous, it will inherit the database 9405c51f124SMoriah Waterland * entry. 9415c51f124SMoriah Waterland */ 9425c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.local, 9435c51f124SMoriah Waterland "?") == NULL) { 9445c51f124SMoriah Waterland (void) strlcpy( 9455c51f124SMoriah Waterland el_ent->cf_ent.ainfo.local, 9465c51f124SMoriah Waterland cf_ent->ainfo.local, 9475c51f124SMoriah Waterland PATH_MAX); 9485c51f124SMoriah Waterland } else { 9495c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 9505c51f124SMoriah Waterland } 9515c51f124SMoriah Waterland } 9525c51f124SMoriah Waterland } 9535c51f124SMoriah Waterland return (changed ? MRG_DIFFERENT : MRG_SAME); 9545c51f124SMoriah Waterland 9555c51f124SMoriah Waterland } else if (el_ent->cf_ent.ftype == 'e') { 9565c51f124SMoriah Waterland 9575c51f124SMoriah Waterland /* 9585c51f124SMoriah Waterland * The contents of edittable files are assumed to be changing 9595c51f124SMoriah Waterland * since some class action script will be doing the work and 9605c51f124SMoriah Waterland * we have no way of evaluating what it will actually do. 9615c51f124SMoriah Waterland */ 9625c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 9635c51f124SMoriah Waterland changed++; 9645c51f124SMoriah Waterland } else if (((el_ent->cf_ent.ftype == 'f') || 9655c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'v'))) { 9665c51f124SMoriah Waterland /* 9675c51f124SMoriah Waterland * For regular files, Look at content information; a BADCONT 9685c51f124SMoriah Waterland * in any el_ent field indicates the contents are unknown -- 9695c51f124SMoriah Waterland * since cf_ent is guaranteed to have a valid entry here (bad 9705c51f124SMoriah Waterland * assumption?) this function will recognize this as a 9715c51f124SMoriah Waterland * change. The ambiguous el_ent values will be evaluated and 9725c51f124SMoriah Waterland * set later. 9735c51f124SMoriah Waterland */ 9745c51f124SMoriah Waterland 9755c51f124SMoriah Waterland /* 9765c51f124SMoriah Waterland * for type f/v files, if the file is in an area that is 9775c51f124SMoriah Waterland * inherited from the global zone, that area is read only 9785c51f124SMoriah Waterland * and the object cannot be changed - ignore any settings 9795c51f124SMoriah Waterland * in the current package database that may be present for 9805c51f124SMoriah Waterland * any existing object because they are irrelevant - since 9815c51f124SMoriah Waterland * the object is in a read-only area shared from the global 9825c51f124SMoriah Waterland * zone, accept that file's actual attributes as being correct. 9835c51f124SMoriah Waterland */ 9845c51f124SMoriah Waterland 9855c51f124SMoriah Waterland if (z_path_is_inherited(el_ent->cf_ent.path, 9865c51f124SMoriah Waterland el_ent->cf_ent.ftype, get_inst_root()) == B_TRUE) { 9875c51f124SMoriah Waterland echoDebug(DBG_PKGDBMRG_INHERITED, el_ent->cf_ent.path); 9885c51f124SMoriah Waterland } else if (cf_ent->cinfo.size != el_ent->cf_ent.cinfo.size) { 9895c51f124SMoriah Waterland changed++; 9905c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 9915c51f124SMoriah Waterland } else if (cf_ent->cinfo.modtime != 9925c51f124SMoriah Waterland el_ent->cf_ent.cinfo.modtime) { 9935c51f124SMoriah Waterland changed++; 9945c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 9955c51f124SMoriah Waterland } else if (cf_ent->cinfo.cksum != el_ent->cf_ent.cinfo.cksum) { 9965c51f124SMoriah Waterland changed++; 9975c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 9985c51f124SMoriah Waterland } 9995c51f124SMoriah Waterland } else if (((el_ent->cf_ent.ftype == 'c') || 10005c51f124SMoriah Waterland (el_ent->cf_ent.ftype == 'b'))) { 10015c51f124SMoriah Waterland /* 10025c51f124SMoriah Waterland * For devices, if major or minor numbers are identical the 10035c51f124SMoriah Waterland * merge is trivial. If the el_ent value is ambiguous (BAD), 10045c51f124SMoriah Waterland * the cf_ent value is inherited. Otherwise, the el_ent value 10055c51f124SMoriah Waterland * is preserved. 10065c51f124SMoriah Waterland */ 10075c51f124SMoriah Waterland if (cf_ent->ainfo.major != el_ent->cf_ent.ainfo.major) { 10085c51f124SMoriah Waterland changed++; 10095c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.major == BADMAJOR) { 10105c51f124SMoriah Waterland el_ent->cf_ent.ainfo.major = 10115c51f124SMoriah Waterland cf_ent->ainfo.major; 10125c51f124SMoriah Waterland } else { 10135c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 10145c51f124SMoriah Waterland } 10155c51f124SMoriah Waterland } 10165c51f124SMoriah Waterland if (cf_ent->ainfo.minor != el_ent->cf_ent.ainfo.minor) { 10175c51f124SMoriah Waterland changed++; 10185c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.minor == BADMINOR) 10195c51f124SMoriah Waterland el_ent->cf_ent.ainfo.minor = 10205c51f124SMoriah Waterland cf_ent->ainfo.minor; 10215c51f124SMoriah Waterland else 10225c51f124SMoriah Waterland el_ent->mstat.contchg = 1; 10235c51f124SMoriah Waterland } 10245c51f124SMoriah Waterland } 10255c51f124SMoriah Waterland 10265c51f124SMoriah Waterland /* 10275c51f124SMoriah Waterland * For mode, owner and group follow the same rules as above - if 10285c51f124SMoriah Waterland * ambiguous, inherit, otherwise keep the new one. 10295c51f124SMoriah Waterland */ 10305c51f124SMoriah Waterland if (cf_ent->ainfo.mode != el_ent->cf_ent.ainfo.mode) { 10315c51f124SMoriah Waterland changed++; /* attribute info is changing */ 10325c51f124SMoriah Waterland if (el_ent->cf_ent.ainfo.mode == BADMODE) { 10335c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode; 10345c51f124SMoriah Waterland } else if (el_ent->cf_ent.ainfo.mode == WILDCARD) { 10355c51f124SMoriah Waterland /* 10365c51f124SMoriah Waterland * If pkgmap has a '?' set for mode, use the mode from 10375c51f124SMoriah Waterland * the pkg DB (contents file). 10385c51f124SMoriah Waterland */ 10395c51f124SMoriah Waterland el_ent->cf_ent.ainfo.mode = cf_ent->ainfo.mode; 10405c51f124SMoriah Waterland el_ent->mstat.attrchg = 0; 10415c51f124SMoriah Waterland } else { 10425c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 10435c51f124SMoriah Waterland } 10445c51f124SMoriah Waterland } 10455c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.owner, el_ent->cf_ent.ainfo.owner) != 0) { 10465c51f124SMoriah Waterland changed++; /* attribute info is changing */ 10475c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.owner, BADOWNER) == 0) 10485c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.owner, 10495c51f124SMoriah Waterland cf_ent->ainfo.owner); 10505c51f124SMoriah Waterland else 10515c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 10525c51f124SMoriah Waterland } 10535c51f124SMoriah Waterland if (strcmp(cf_ent->ainfo.group, el_ent->cf_ent.ainfo.group) != 0) { 10545c51f124SMoriah Waterland changed++; /* attribute info is changing */ 10555c51f124SMoriah Waterland if (strcmp(el_ent->cf_ent.ainfo.group, BADGROUP) == 0) 10565c51f124SMoriah Waterland (void) strcpy(el_ent->cf_ent.ainfo.group, 10575c51f124SMoriah Waterland cf_ent->ainfo.group); 10585c51f124SMoriah Waterland else 10595c51f124SMoriah Waterland el_ent->mstat.attrchg = 1; 10605c51f124SMoriah Waterland } 10615c51f124SMoriah Waterland return (changed ? MRG_DIFFERENT : MRG_SAME); 10625c51f124SMoriah Waterland } 10635c51f124SMoriah Waterland 10645c51f124SMoriah Waterland /* 10655c51f124SMoriah Waterland * This puts the current entry into the package database in the appropriate 10665c51f124SMoriah Waterland * intermediate format for this stage of the installation. This also assures 10675c51f124SMoriah Waterland * the correct format for the various package object ftypes, stripping the 10685c51f124SMoriah Waterland * link name before storing a regular file and stuff like that. 10695c51f124SMoriah Waterland */ 10705c51f124SMoriah Waterland 10715c51f124SMoriah Waterland static void 10725c51f124SMoriah Waterland output(VFP_T *vfpo, struct cfent *ent, struct pinfo *pinfo) 10735c51f124SMoriah Waterland { 10745c51f124SMoriah Waterland short svvolno; 10755c51f124SMoriah Waterland char *svpt; 10765c51f124SMoriah Waterland 10775c51f124SMoriah Waterland /* output without volume information */ 10785c51f124SMoriah Waterland svvolno = ent->volno; 10795c51f124SMoriah Waterland ent->volno = 0; 10805c51f124SMoriah Waterland 10815c51f124SMoriah Waterland pinfo->editflag = 0; 10825c51f124SMoriah Waterland if (((ent->ftype == 's') || (ent->ftype == 'l'))) { 10835c51f124SMoriah Waterland if (putcvfpfile(ent, vfpo)) { 10845c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 10855c51f124SMoriah Waterland quit(99); 10865c51f124SMoriah Waterland } 10875c51f124SMoriah Waterland } else { 10885c51f124SMoriah Waterland 10895c51f124SMoriah Waterland /* output without local pathname */ 10905c51f124SMoriah Waterland svpt = ent->ainfo.local; 10915c51f124SMoriah Waterland ent->ainfo.local = NULL; 10925c51f124SMoriah Waterland if (putcvfpfile(ent, vfpo)) { 10935c51f124SMoriah Waterland progerr(gettext(ERR_OUTPUT)); 10945c51f124SMoriah Waterland quit(99); 10955c51f124SMoriah Waterland } 10965c51f124SMoriah Waterland 10975c51f124SMoriah Waterland ent->ainfo.local = svpt; 10985c51f124SMoriah Waterland /* 10995c51f124SMoriah Waterland * If this entry represents a file which is being edited, we 11005c51f124SMoriah Waterland * need to store in memory the fact that it is an edittable 11015c51f124SMoriah Waterland * file so that when we audit it after installation we do not 11025c51f124SMoriah Waterland * worry about its contents; we do this by resetting the ftype 11035c51f124SMoriah Waterland * to 'e' in the memory array which is later used to control 11045c51f124SMoriah Waterland * the audit 11055c51f124SMoriah Waterland */ 11065c51f124SMoriah Waterland if (pinfo->editflag) 11075c51f124SMoriah Waterland ent->ftype = 'e'; 11085c51f124SMoriah Waterland } 11095c51f124SMoriah Waterland /* restore volume information */ 11105c51f124SMoriah Waterland ent->volno = svvolno; 11115c51f124SMoriah Waterland } 11125c51f124SMoriah Waterland 11135c51f124SMoriah Waterland static void 11145c51f124SMoriah Waterland chgclass(struct cfent *cf_ent, struct pinfo *pinfo) 11155c51f124SMoriah Waterland { 11165c51f124SMoriah Waterland struct pinfo *pp; 11175c51f124SMoriah Waterland char *oldclass, newclass[CLSSIZ+1]; 11185c51f124SMoriah Waterland int newcnt, oldcnt; 11195c51f124SMoriah Waterland 11205c51f124SMoriah Waterland /* 11215c51f124SMoriah Waterland * we use this routine to minimize the use of the aclass element by 11225c51f124SMoriah Waterland * optimizing the use of the cf_ent->pkg_class element 11235c51f124SMoriah Waterland */ 11245c51f124SMoriah Waterland 11255c51f124SMoriah Waterland (void) strlcpy(newclass, pinfo->aclass, sizeof (newclass)); 11265c51f124SMoriah Waterland newcnt = 1; 11275c51f124SMoriah Waterland 11285c51f124SMoriah Waterland oldclass = cf_ent->pkg_class; 11295c51f124SMoriah Waterland oldcnt = 0; 11305c51f124SMoriah Waterland 11315c51f124SMoriah Waterland /* 11325c51f124SMoriah Waterland * count the number of times the newclass will be used and see if it 11335c51f124SMoriah Waterland * exceeds the number of times the oldclass is referenced 11345c51f124SMoriah Waterland */ 11355c51f124SMoriah Waterland pp = cf_ent->pinfo; 11365c51f124SMoriah Waterland while (pp) { 11375c51f124SMoriah Waterland if (pp->aclass[0] != '\0') { 11385c51f124SMoriah Waterland if (strcmp(pp->aclass, newclass) == 0) 11395c51f124SMoriah Waterland newcnt++; 11405c51f124SMoriah Waterland else if (strcmp(pp->aclass, oldclass) == 0) 11415c51f124SMoriah Waterland oldcnt++; 11425c51f124SMoriah Waterland } 11435c51f124SMoriah Waterland pp = pp->next; 11445c51f124SMoriah Waterland } 11455c51f124SMoriah Waterland if (newcnt > oldcnt) { 11465c51f124SMoriah Waterland pp = cf_ent->pinfo; 11475c51f124SMoriah Waterland while (pp) { 11485c51f124SMoriah Waterland if (pp->aclass[0] == '\0') { 11495c51f124SMoriah Waterland (void) strcpy(pp->aclass, oldclass); 11505c51f124SMoriah Waterland } else if (strcmp(pp->aclass, newclass) == 0) { 11515c51f124SMoriah Waterland pp->aclass[0] = '\0'; 11525c51f124SMoriah Waterland } 11535c51f124SMoriah Waterland pp = pp->next; 11545c51f124SMoriah Waterland } 11555c51f124SMoriah Waterland (void) strcpy(cf_ent->pkg_class, newclass); 11565c51f124SMoriah Waterland } 11575c51f124SMoriah Waterland } 1158