static void checkNotInstDeps(rpmts ts, depCache dcache, rpmte te, rpmTag depTag, const char *dep) { char *ndep = rmalloc(strlen(dep) + 2); ndep[0] = '!'; strcpy(ndep + 1, dep); checkInstDeps(ts, dcache, te, depTag, ndep); free(ndep); }
static void checkInstFileDeps(rpmts ts, depCache dcache, rpmte te, rpmTag depTag, rpmfi fi, int is_not, filedepHash cache, fingerPrintCache *fpcp) { fingerPrintCache fpc = *fpcp; fingerPrint * fp = NULL; const char *basename = rpmfiBN(fi); const char *dirname; const char **dirnames = 0; int ndirnames = 0; int i; filedepHashGetEntry(cache, basename, &dirnames, &ndirnames, NULL); if (!ndirnames) return; if (!fpc) *fpcp = fpc = fpCacheCreate(1001, NULL); dirname = rpmfiDN(fi); fpLookup(fpc, dirname, basename, &fp); for (i = 0; i < ndirnames; i++) { char *fpdep = 0; const char *dep; if (!strcmp(dirnames[i], dirname)) { dep = rpmfiFN(fi); } else if (fpLookupEquals(fpc, fp, dirnames[i], basename)) { fpdep = rmalloc(strlen(dirnames[i]) + strlen(basename) + 1); strcpy(fpdep, dirnames[i]); strcat(fpdep, basename); dep = fpdep; } else { continue; } if (!is_not) checkInstDeps(ts, dcache, te, depTag, dep); else checkNotInstDeps(ts, dcache, te, depTag, dep); _free(fpdep); } _free(fp); }
int rpmtsCheck(rpmts ts) { rpm_color_t tscolor = rpmtsColor(ts); rpmtsi pi = NULL; rpmte p; int closeatexit = 0; int rc = 0; depCache dcache = NULL; filedepHash confilehash = NULL; /* file conflicts of installed packages */ filedepHash connotfilehash = NULL; /* file conflicts of installed packages */ depexistsHash connothash = NULL; filedepHash reqfilehash = NULL; /* file requires of installed packages */ filedepHash reqnotfilehash = NULL; /* file requires of installed packages */ depexistsHash reqnothash = NULL; fingerPrintCache fpc = NULL; rpmdb rdb = NULL; (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0); /* Do lazy, readonly, open of rpm database. */ rdb = rpmtsGetRdb(ts); if (rdb == NULL && rpmtsGetDBMode(ts) != -1) { if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0) goto exit; rdb = rpmtsGetRdb(ts); closeatexit = 1; } if (rdb) rpmdbCtrl(rdb, RPMDB_CTRL_LOCK_RO); /* XXX FIXME: figure some kind of heuristic for the cache size */ dcache = depCacheCreate(5001, rstrhash, strcmp, (depCacheFreeKey)rfree, NULL); /* build hashes of all confilict sdependencies */ confilehash = filedepHashCreate(257, rstrhash, strcmp, (filedepHashFreeKey)rfree, (filedepHashFreeData)rfree); connothash = depexistsHashCreate(257, rstrhash, strcmp, (filedepHashFreeKey)rfree); connotfilehash = filedepHashCreate(257, rstrhash, strcmp, (filedepHashFreeKey)rfree, (filedepHashFreeData)rfree); addIndexToDepHashes(ts, RPMTAG_CONFLICTNAME, NULL, confilehash, connothash, connotfilehash); if (!filedepHashNumKeys(confilehash)) confilehash = filedepHashFree(confilehash); if (!depexistsHashNumKeys(connothash)) connothash= depexistsHashFree(connothash); if (!filedepHashNumKeys(connotfilehash)) connotfilehash = filedepHashFree(connotfilehash); /* build hashes of all requires dependencies */ reqfilehash = filedepHashCreate(8191, rstrhash, strcmp, (filedepHashFreeKey)rfree, (filedepHashFreeData)rfree); reqnothash = depexistsHashCreate(257, rstrhash, strcmp, (filedepHashFreeKey)rfree); reqnotfilehash = filedepHashCreate(257, rstrhash, strcmp, (filedepHashFreeKey)rfree, (filedepHashFreeData)rfree); addIndexToDepHashes(ts, RPMTAG_REQUIRENAME, NULL, reqfilehash, reqnothash, reqnotfilehash); if (!filedepHashNumKeys(reqfilehash)) reqfilehash = filedepHashFree(reqfilehash); if (!depexistsHashNumKeys(reqnothash)) reqnothash= depexistsHashFree(reqnothash); if (!filedepHashNumKeys(reqnotfilehash)) reqnotfilehash = filedepHashFree(reqnotfilehash); /* * Look at all of the added packages and make sure their dependencies * are satisfied. */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) { rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME)); rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n", rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p)); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME), tscolor); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME), tscolor); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME), tscolor); /* Check provides against conflicts in installed packages. */ while (rpmdsNext(provides) >= 0) { const char *dep = rpmdsN(provides); checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep); if (reqnothash && depexistsHashHasEntry(reqnothash, dep)) checkNotInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep); } /* Skip obsoletion checks for source packages (ie build) */ if (rpmteIsSource(p)) continue; /* Check package name (not provides!) against installed obsoletes */ checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p)); /* Check filenames against installed conflicts */ if (confilehash || reqnotfilehash) { rpmfiles files = rpmteFiles(p); rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD); while (rpmfiNext(fi) >= 0) { if (confilehash) checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 0, confilehash, &fpc); if (reqnotfilehash) checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 1, reqnotfilehash, &fpc); } rpmfiFree(fi); rpmfilesFree(files); } } rpmtsiFree(pi); /* * Look at the removed packages and make sure they aren't critical. */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) { rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME)); rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n", rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p)); /* Check provides and filenames against installed dependencies. */ while (rpmdsNext(provides) >= 0) { const char *dep = rpmdsN(provides); checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep); if (connothash && depexistsHashHasEntry(connothash, dep)) checkNotInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep); } if (reqfilehash || connotfilehash) { rpmfiles files = rpmteFiles(p); rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);; while (rpmfiNext(fi) >= 0) { if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) { if (reqfilehash) checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 0, reqfilehash, &fpc); if (connotfilehash) checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 1, connotfilehash, &fpc); } } rpmfiFree(fi); rpmfilesFree(files); } } rpmtsiFree(pi); if (rdb) rpmdbCtrl(rdb, RPMDB_CTRL_UNLOCK_RO); exit: depCacheFree(dcache); filedepHashFree(confilehash); filedepHashFree(connotfilehash); depexistsHashFree(connothash); filedepHashFree(reqfilehash); filedepHashFree(reqnotfilehash); depexistsHashFree(reqnothash); fpCacheFree(fpc); (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0); if (closeatexit) (void) rpmtsCloseDB(ts); return rc; }
int rpmtsCheck(rpmts ts) { rpm_color_t tscolor = rpmtsColor(ts); rpmtsi pi = NULL; rpmte p; int closeatexit = 0; int rc = 0; depCache dcache = NULL; conflictsCache confcache = NULL; (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0); /* Do lazy, readonly, open of rpm database. */ if (rpmtsGetRdb(ts) == NULL && rpmtsGetDBMode(ts) != -1) { if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0) goto exit; closeatexit = 1; } /* XXX FIXME: figure some kind of heuristic for the cache size */ dcache = depCacheCreate(5001, rstrhash, strcmp, (depCacheFreeKey)rfree, NULL); confcache = conflictsCacheCreate(257, rstrhash, strcmp, (depCacheFreeKey)rfree); if (confcache) { rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMTAG_CONFLICTNAME); if (ii) { char *key; size_t keylen; while ((rpmdbIndexIteratorNext(ii, (const void**)&key, &keylen)) == 0) { char *k; if (!key || keylen == 0 || key[0] != '/') continue; k = rmalloc(keylen + 1); memcpy(k, key, keylen); k[keylen] = 0; conflictsCacheAddEntry(confcache, k); } rpmdbIndexIteratorFree(ii); } } /* * Look at all of the added packages and make sure their dependencies * are satisfied. */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) { rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME)); rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n", rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p)); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME), NULL, tscolor); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME), NULL, tscolor); checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME), NULL, tscolor); /* Check provides against conflicts in installed packages. */ while (rpmdsNext(provides) >= 0) { checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, rpmdsN(provides)); } /* Skip obsoletion checks for source packages (ie build) */ if (rpmteIsSource(p)) continue; /* Check package name (not provides!) against installed obsoletes */ checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p)); /* Check filenames against installed conflicts */ if (conflictsCacheNumKeys(confcache)) { rpmfi fi = rpmfiInit(rpmteFI(p), 0); while (rpmfiNext(fi) >= 0) { const char *fn = rpmfiFN(fi); if (!conflictsCacheHasEntry(confcache, fn)) continue; checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fn); } } } rpmtsiFree(pi); /* * Look at the removed packages and make sure they aren't critical. */ pi = rpmtsiInit(ts); while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) { rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME)); rpmfi fi = rpmfiInit(rpmteFI(p), 0); rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n", rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p)); /* Check provides and filenames against installed dependencies. */ while (rpmdsNext(provides) >= 0) { checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmdsN(provides)); } while (rpmfiNext(fi) >= 0) { if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmfiFN(fi)); } } rpmtsiFree(pi); exit: depCacheFree(dcache); conflictsCacheFree(confcache); (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0); if (closeatexit) (void) rpmtsCloseDB(ts); return rc; }