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