/* Check files in the transactions against the rpmdb
 * Lookup all files with the same basename in the rpmdb
 * and then check for matching finger prints
 * @param ts		transaction set
 * @param fpc		global finger print cache
 */
static
void checkInstalledFiles(rpmts ts, uint64_t fileCount, fingerPrintCache fpc)
{
    tsMembers tsmem = rpmtsMembers(ts);
    rpmte p;
    rpmfiles fi;
    rpmfs fs;
    int j;
    unsigned int fileNum;

    rpmdbMatchIterator mi;
    Header h, newheader;

    rpmlog(RPMLOG_DEBUG, "computing file dispositions\n");

    mi = rpmFindBaseNamesInDB(ts, fileCount);

    /* For all installed headers with matching basename's ... */
    if (mi == NULL)
	 return;

    if (rpmdbGetIteratorCount(mi) == 0) {
	mi = rpmdbFreeIterator(mi);
	return;
    }

    /* Loop over all packages from the rpmdb */
    h = newheader = rpmdbNextIterator(mi);
    while (h != NULL) {
	headerGetFlags hgflags = HEADERGET_MINMEM;
	struct rpmtd_s bnames, dnames, dindexes, ostates;
	fingerPrint *fpp = NULL;
	unsigned int installedPkg;
	int beingRemoved = 0;
	rpmfiles otherFi = NULL;
	rpmte *removedPkg = NULL;

	/* Is this package being removed? */
	installedPkg = rpmdbGetIteratorOffset(mi);
	if (packageHashGetEntry(tsmem->removedPackages, installedPkg,
				&removedPkg, NULL, NULL)) {
	    beingRemoved = 1;
	    otherFi = rpmteFiles(removedPkg[0]);
	}

	h = headerLink(h);
	/* For packages being removed we can use its rpmfi to avoid all this */
	if (!beingRemoved) {
	    headerGet(h, RPMTAG_BASENAMES, &bnames, hgflags);
	    headerGet(h, RPMTAG_DIRNAMES, &dnames, hgflags);
	    headerGet(h, RPMTAG_DIRINDEXES, &dindexes, hgflags);
	    headerGet(h, RPMTAG_FILESTATES, &ostates, hgflags);
	}

	/* loop over all interesting files in that package */
	do {
	    int fpIx;
	    struct rpmffi_s * recs;
	    int numRecs;
	    const char * dirName;
	    const char * baseName;

	    /* lookup finger print for this file */
	    fileNum = rpmdbGetIteratorFileNum(mi);
	    if (!beingRemoved) {
		rpmtdSetIndex(&bnames, fileNum);
		rpmtdSetIndex(&dindexes, fileNum);
		rpmtdSetIndex(&dnames, *rpmtdGetUint32(&dindexes));
		rpmtdSetIndex(&ostates, fileNum);

		dirName = rpmtdGetString(&dnames);
		baseName = rpmtdGetString(&bnames);

		fpLookup(fpc, dirName, baseName, &fpp);
		fpIx = 0;
	    } else {
		fpp = rpmfilesFps(otherFi);
		fpIx = fileNum;
	    }

	    /* search for files in the transaction with same finger print */
	    fpCacheGetByFp(fpc, fpp, fpIx, &recs, &numRecs);

	    for (j = 0; j < numRecs; j++) {
	        p = recs[j].p;
		fi = rpmteFiles(p);
		fs = rpmteGetFileStates(p);

		/* Determine the fate of each file. */
		switch (rpmteType(p)) {
		case TR_ADDED:
		    if (!otherFi) {
			/* XXX What to do if this fails? */
		        otherFi = rpmfilesNew(NULL, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
		    }
		    handleInstInstalledFile(ts, p, fi, recs[j].fileno,
					    h, otherFi, fileNum, beingRemoved);
		    break;
		case TR_REMOVED:
		    if (!beingRemoved) {
			if (*rpmtdGetChar(&ostates) == RPMFILE_STATE_NORMAL)
			    rpmfsSetAction(fs, recs[j].fileno, FA_SKIP);
		    }
		    break;
		}
		rpmfilesFree(fi);
	    }

	    newheader = rpmdbNextIterator(mi);

	} while (newheader==h);

	otherFi = rpmfilesFree(otherFi);
	if (!beingRemoved) {
	    rpmtdFreeData(&ostates);
	    rpmtdFreeData(&bnames);
	    rpmtdFreeData(&dnames);
	    rpmtdFreeData(&dindexes);
	    free(fpp);
	}
	headerFree(h);
	h = newheader;
    }

    rpmdbFreeIterator(mi);
}
Beispiel #2
0
/* Check files in the transactions against the rpmdb
 * Lookup all files with the same basename in the rpmdb
 * and then check for matching finger prints
 * @param ts		transaction set
 * @param fpc		global finger print cache
 */
static
void checkInstalledFiles(rpmts ts, fingerPrintCache fpc)
{
    rpmps ps;
    rpmte p;
    rpmfi fi;
    rpmfs fs;
    rpmfi otherFi=NULL;
    int j;
    int xx;
    unsigned int fileNum;
    const char * oldDir;

    rpmdbMatchIterator mi;
    Header h, newheader;

    int beingRemoved;

    rpmlog(RPMLOG_DEBUG, "computing file dispositions\n");

    mi = rpmFindBaseNamesInDB(ts);

    /* For all installed headers with matching basename's ... */
    if (mi == NULL)
	 return;

    if (rpmdbGetIteratorCount(mi) == 0) {
	mi = rpmdbFreeIterator(mi);
	return;
    }

    ps = rpmtsProblems(ts);

    /* Loop over all packages from the rpmdb */
    h = newheader = rpmdbNextIterator(mi);
    while (h != NULL) {
	headerGetFlags hgflags = HEADERGET_MINMEM;
	struct rpmtd_s bnames, dnames, dindexes, ostates;
	fingerPrint fp;
	unsigned int installedPkg;

	/* Is this package being removed? */
	installedPkg = rpmdbGetIteratorOffset(mi);
	beingRemoved = 0;
	if (ts->removedPackages != NULL)
	for (j = 0; j < ts->numRemovedPackages; j++) {
	    if (ts->removedPackages[j] != installedPkg)
	        continue;
	    beingRemoved = 1;
	    break;
	}

	h = headerLink(h);
	headerGet(h, RPMTAG_BASENAMES, &bnames, hgflags);
	headerGet(h, RPMTAG_DIRNAMES, &dnames, hgflags);
	headerGet(h, RPMTAG_DIRINDEXES, &dindexes, hgflags);
	headerGet(h, RPMTAG_FILESTATES, &ostates, hgflags);

	oldDir = NULL;
	/* loop over all interesting files in that package */
	do {
	    int gotRecs;
	    struct rpmffi_s * recs;
	    int numRecs;
	    const char * dirName;
	    const char * baseName;

	    fileNum = rpmdbGetIteratorFileNum(mi);
	    rpmtdSetIndex(&bnames, fileNum);
	    rpmtdSetIndex(&dindexes, fileNum);
	    rpmtdSetIndex(&dnames, *rpmtdGetUint32(&dindexes));
	    rpmtdSetIndex(&ostates, fileNum);

	    dirName = rpmtdGetString(&dnames);
	    baseName = rpmtdGetString(&bnames);

	    /* lookup finger print for this file */
	    if ( dirName == oldDir) {
	        /* directory is the same as last round */
	        fp.baseName = baseName;
	    } else {
	        fp = fpLookup(fpc, dirName, baseName, 1);
		oldDir = dirName;
	    }
	    /* search for files in the transaction with same finger print */
	    gotRecs = rpmFpHashGetEntry(ts->ht, &fp, &recs, &numRecs, NULL);

	    for (j=0; (j<numRecs)&&gotRecs; j++) {
	        p = recs[j].p;
		fi = rpmteFI(p);
		fs = rpmteGetFileStates(p);

		/* Determine the fate of each file. */
		switch (rpmteType(p)) {
		case TR_ADDED:
		    if (!otherFi) {
		        otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
		    }
		    rpmfiSetFX(fi, recs[j].fileno);
		    rpmfiSetFX(otherFi, fileNum);
		    xx = handleInstInstalledFile(ts, p, fi, h, otherFi, beingRemoved);
		    break;
		case TR_REMOVED:
		    if (!beingRemoved) {
		        rpmfiSetFX(fi, recs[j].fileno);
			if (*rpmtdGetChar(&ostates) == RPMFILE_STATE_NORMAL)
			    rpmfsSetAction(fs, recs[j].fileno, FA_SKIP);
		    }
		    break;
		}
	    }

	    newheader = rpmdbNextIterator(mi);

	} while (newheader==h);

	otherFi = rpmfiFree(otherFi);
	rpmtdFreeData(&ostates);
	rpmtdFreeData(&bnames);
	rpmtdFreeData(&dnames);
	rpmtdFreeData(&dindexes);
	headerFree(h);
	h = newheader;
    }

    mi = rpmdbFreeIterator(mi);
}