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
pkgdbmerg(PKGserver server,VFP_T * tmpvfp,struct cfextra ** extlist)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
do_like_ent(VFP_T * vfpo,struct cfextra * el_ent,struct cfent * cf_ent,int ctrl)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
do_new_ent(VFP_T * vfpo,struct cfextra * el_ent,int ctrl)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
files_installed(void)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
set_change(struct cfextra * el_ent)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
is_setuid(struct cfent * ent)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
is_setgid(struct cfent * ent)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
typechg(struct cfent * el_ent,struct cfent * cf_ent,struct mergstat * mstat)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
merg(struct cfextra * el_ent,struct cfent * cf_ent)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
output(VFP_T * vfpo,struct cfent * ent,struct pinfo * pinfo)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
chgclass(struct cfent * cf_ent,struct pinfo * pinfo)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