Change file disposition code to access rpmfi's by index

- The final pre-requisite to handling file conflicts within a package:
  with this we're no longer tied to the single index per rpmfi. This
  is not supposed to change anything yet unless I screwed something up.
  Also goes to show that a semi-iterator interface for something
  that really needs random access only gets in the way rather than
  helping...
This commit is contained in:
Panu Matilainen 2012-04-12 17:50:54 +03:00
parent 87e7e88f90
commit 7633410733
2 changed files with 36 additions and 46 deletions

View File

@ -238,7 +238,7 @@ void fpLookupSubdir(rpmFpHash symlinks, rpmFpHash fphash, fingerPrintCache fpc,
struct rpmffi_s * recs; struct rpmffi_s * recs;
int numRecs; int numRecs;
int i, fiFX; int i;
fingerPrint *fp = rpmfiFpsIndex(fi, filenr); fingerPrint *fp = rpmfiFpsIndex(fi, filenr);
int symlinkcount = 0; int symlinkcount = 0;
struct rpmffi_s ffi = { p, filenr}; struct rpmffi_s ffi = { p, filenr};
@ -268,18 +268,10 @@ void fpLookupSubdir(rpmFpHash symlinks, rpmFpHash fphash, fingerPrintCache fpc,
&recs, &numRecs, NULL); &recs, &numRecs, NULL);
for (i=0; i<numRecs; i++) { for (i=0; i<numRecs; i++) {
rpmfi foundfi; rpmfi foundfi = rpmteFI(recs[i].p);
int filenr; char const *linktarget = rpmfiFLinkIndex(foundfi, recs[i].fileno);
char const *linktarget;
char *link; char *link;
foundfi = rpmteFI(recs[i].p);
fiFX = rpmfiFX(foundfi);
filenr = recs[i].fileno;
rpmfiSetFX(foundfi, filenr);
linktarget = rpmfiFLink(foundfi);
if (linktarget && *linktarget != '\0') { if (linktarget && *linktarget != '\0') {
/* this "directory" is a symlink */ /* this "directory" is a symlink */
link = NULL; link = NULL;
@ -322,7 +314,6 @@ void fpLookupSubdir(rpmFpHash symlinks, rpmFpHash fphash, fingerPrintCache fpc,
break; break;
} }
rpmfiSetFX(foundfi, fiFX);
} }
if (symlinkcount>50) { if (symlinkcount>50) {
// found too many symlinks in the path // found too many symlinks in the path

View File

@ -291,22 +291,21 @@ static uint64_t countFiles(rpmts ts)
* @param reportConflicts * @param reportConflicts
*/ */
/* XXX only ts->{probs,rpmdb} modified */ /* XXX only ts->{probs,rpmdb} modified */
static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi, int fx,
Header otherHeader, rpmfi otherFi, Header otherHeader, rpmfi otherFi, int ofx,
int beingRemoved) int beingRemoved)
{ {
unsigned int fx = rpmfiFX(fi);
rpmfs fs = rpmteGetFileStates(p); rpmfs fs = rpmteGetFileStates(p);
int isCfgFile = ((rpmfiFFlags(otherFi) | rpmfiFFlags(fi)) & RPMFILE_CONFIG); int isCfgFile = ((rpmfiFFlagsIndex(otherFi, ofx) | rpmfiFFlagsIndex(fi, fx)) & RPMFILE_CONFIG);
if (XFA_SKIPPING(rpmfsGetAction(fs, fx))) if (XFA_SKIPPING(rpmfsGetAction(fs, fx)))
return; return;
if (rpmfiCompare(otherFi, fi)) { if (rpmfiCompareIndex(otherFi, ofx, fi, fx)) {
rpm_color_t tscolor = rpmtsColor(ts); rpm_color_t tscolor = rpmtsColor(ts);
rpm_color_t prefcolor = rpmtsPrefColor(ts); rpm_color_t prefcolor = rpmtsPrefColor(ts);
rpm_color_t FColor = rpmfiFColor(fi) & tscolor; rpm_color_t FColor = rpmfiFColorIndex(fi, fx) & tscolor;
rpm_color_t oFColor = rpmfiFColor(otherFi) & tscolor; rpm_color_t oFColor = rpmfiFColorIndex(otherFi, ofx) & tscolor;
int rConflicts; int rConflicts;
char rState = RPMFILE_STATE_REPLACED; char rState = RPMFILE_STATE_REPLACED;
@ -325,27 +324,29 @@ static void handleInstInstalledFile(const rpmts ts, rpmte p, rpmfi fi,
if (rConflicts) { if (rConflicts) {
char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA); char *altNEVR = headerGetAsString(otherHeader, RPMTAG_NEVRA);
rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, rpmfiFN(fi), char *fn = rpmfiFNIndex(fi, fx);
rpmteAddProblem(p, RPMPROB_FILE_CONFLICT, altNEVR, fn,
headerGetInstance(otherHeader)); headerGetInstance(otherHeader));
free(fn);
free(altNEVR); free(altNEVR);
} }
/* Save file identifier to mark as state REPLACED. */ /* Save file identifier to mark as state REPLACED. */
if ( !(isCfgFile || XFA_SKIPPING(rpmfsGetAction(fs, fx))) ) { if ( !(isCfgFile || XFA_SKIPPING(rpmfsGetAction(fs, fx))) ) {
if (!beingRemoved) if (!beingRemoved)
rpmfsAddReplaced(rpmteGetFileStates(p), rpmfiFX(fi), rState, rpmfsAddReplaced(rpmteGetFileStates(p), fx, rState,
headerGetInstance(otherHeader), headerGetInstance(otherHeader), ofx);
rpmfiFX(otherFi));
} }
} }
/* Determine config file dispostion, skipping missing files (if any). */ /* Determine config file dispostion, skipping missing files (if any). */
if (isCfgFile) { if (isCfgFile) {
int skipMissing = ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1); int skipMissing = ((rpmtsFlags(ts) & RPMTRANS_FLAG_ALLFILES) ? 0 : 1);
rpmFileAction action = rpmfiDecideFate(otherFi, fi, skipMissing); rpmFileAction action;
action = rpmfiDecideFateIndex(otherFi, ofx, fi, fx, skipMissing);
rpmfsSetAction(fs, fx, action); rpmfsSetAction(fs, fx, action);
} }
rpmfiSetFReplacedSizeIndex(fi, fx, rpmfiFSize(otherFi)); rpmfiSetFReplacedSizeIndex(fi, fx, rpmfiFSizeIndex(otherFi, ofx));
} }
/** /**
@ -360,9 +361,9 @@ static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
rpm_color_t prefcolor = rpmtsPrefColor(ts); rpm_color_t prefcolor = rpmtsPrefColor(ts);
rpmfs fs = rpmteGetFileStates(p); rpmfs fs = rpmteGetFileStates(p);
rpmfs otherFs; rpmfs otherFs;
rpm_count_t fc = rpmfiFC(fi);
fi = rpmfiInit(fi, 0); for (i = 0; i < fc; i++) {
while ((i = rpmfiNext(fi)) >= 0) {
rpm_color_t oFColor, FColor; rpm_color_t oFColor, FColor;
struct fingerPrint_s * fiFps; struct fingerPrint_s * fiFps;
int otherPkgNum, otherFileNum; int otherPkgNum, otherFileNum;
@ -377,9 +378,9 @@ static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
continue; continue;
fiFps = rpmfiFpsIndex(fi, i); fiFps = rpmfiFpsIndex(fi, i);
FFlags = rpmfiFFlags(fi); FFlags = rpmfiFFlagsIndex(fi, i);
FMode = rpmfiFMode(fi); FMode = rpmfiFModeIndex(fi, i);
FColor = rpmfiFColor(fi); FColor = rpmfiFColorIndex(fi, i);
FColor &= tscolor; FColor &= tscolor;
fixupSize = 0; fixupSize = 0;
@ -433,14 +434,12 @@ static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
if (rpmteType(p) == TR_ADDED && rpmteType(otherTe) != TR_ADDED) if (rpmteType(p) == TR_ADDED && rpmteType(otherTe) != TR_ADDED)
continue; continue;
(void) rpmfiSetFX(otherFi, otherFileNum);
/* XXX Happens iff fingerprint for incomplete package install. */ /* XXX Happens iff fingerprint for incomplete package install. */
if (rpmfsGetAction(otherFs, otherFileNum) != FA_UNKNOWN) if (rpmfsGetAction(otherFs, otherFileNum) != FA_UNKNOWN)
break; break;
} }
oFColor = rpmfiFColor(otherFi); oFColor = rpmfiFColorIndex(otherFi, otherFileNum);
oFColor &= tscolor; oFColor &= tscolor;
switch (rpmteType(p)) { switch (rpmteType(p)) {
@ -455,7 +454,7 @@ static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
rpmFileAction action; rpmFileAction action;
if (rpmfsGetAction(fs, i) != FA_UNKNOWN) if (rpmfsGetAction(fs, i) != FA_UNKNOWN)
break; break;
if (rpmfiConfigConflict(fi)) { if (rpmfiConfigConflictIndex(fi, i)) {
/* Here is a non-overlapped pre-existing config file. */ /* Here is a non-overlapped pre-existing config file. */
action = (FFlags & RPMFILE_NOREPLACE) ? action = (FFlags & RPMFILE_NOREPLACE) ?
FA_ALTNAME : FA_BACKUP; FA_ALTNAME : FA_BACKUP;
@ -468,7 +467,7 @@ static void handleOverlappedFiles(rpmts ts, rpmFpHash ht, rpmte p, rpmfi fi)
assert(otherFi != NULL); assert(otherFi != NULL);
/* Mark added overlapped non-identical files as a conflict. */ /* Mark added overlapped non-identical files as a conflict. */
if (rpmfiCompare(otherFi, fi)) { if (rpmfiCompareIndex(otherFi, otherFileNum, fi, i)) {
int rConflicts; int rConflicts;
rConflicts = reportConflicts; rConflicts = reportConflicts;
@ -491,16 +490,17 @@ assert(otherFi != NULL);
done = 1; done = 1;
} }
if (rConflicts) { if (rConflicts) {
const char *fn = rpmfiFN(fi); char *fn = rpmfiFNIndex(fi, i);
rpmteAddProblem(p, RPMPROB_NEW_FILE_CONFLICT, rpmteAddProblem(p, RPMPROB_NEW_FILE_CONFLICT,
rpmteNEVRA(otherTe), fn, 0); rpmteNEVRA(otherTe), fn, 0);
free(fn);
} }
} }
/* Try to get the disk accounting correct even if a conflict. */ /* Try to get the disk accounting correct even if a conflict. */
fixupSize = rpmfiFSize(otherFi); fixupSize = rpmfiFSizeIndex(otherFi, otherFileNum);
if (rpmfiConfigConflict(fi)) { if (rpmfiConfigConflictIndex(fi, i)) {
/* Here is an overlapped pre-existing config file. */ /* Here is an overlapped pre-existing config file. */
rpmFileAction action; rpmFileAction action;
action = (FFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SKIP; action = (FFlags & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SKIP;
@ -525,7 +525,7 @@ assert(otherFi != NULL);
} }
if (XFA_SKIPPING(rpmfsGetAction(fs, i))) if (XFA_SKIPPING(rpmfsGetAction(fs, i)))
break; break;
if (rpmfiFState(fi) != RPMFILE_STATE_NORMAL) if (rpmfiFStateIndex(fi, i) != RPMFILE_STATE_NORMAL)
break; break;
/* Pre-existing modified config files need to be saved. */ /* Pre-existing modified config files need to be saved. */
@ -533,11 +533,12 @@ assert(otherFi != NULL);
int algo = 0; int algo = 0;
size_t diglen = 0; size_t diglen = 0;
const unsigned char *digest; const unsigned char *digest;
if ((digest = rpmfiFDigest(fi, &algo, &diglen))) { if ((digest = rpmfiFDigestIndex(fi, i, &algo, &diglen))) {
unsigned char fdigest[diglen]; unsigned char fdigest[diglen];
const char *fn = rpmfiFN(fi); char *fn = rpmfiFNIndex(fi, i);
int modified = (!rpmDoDigest(algo, fn, 0, fdigest, NULL) && int modified = (!rpmDoDigest(algo, fn, 0, fdigest, NULL) &&
memcmp(digest, fdigest, diglen)); memcmp(digest, fdigest, diglen));
free(fn);
if (modified) { if (modified) {
rpmfsSetAction(fs, i, FA_BACKUP); rpmfsSetAction(fs, i, FA_BACKUP);
break; break;
@ -552,7 +553,7 @@ assert(otherFi != NULL);
/* Update disk space info for a file. */ /* Update disk space info for a file. */
rpmtsUpdateDSI(ts, fiFps->entry->dev, fiFps->entry->dirName, rpmtsUpdateDSI(ts, fiFps->entry->dev, fiFps->entry->dirName,
rpmfiFSize(fi), rpmfiFReplacedSizeIndex(fi, i), rpmfiFSizeIndex(fi, i), rpmfiFReplacedSizeIndex(fi, i),
fixupSize, rpmfsGetAction(fs, i)); fixupSize, rpmfsGetAction(fs, i));
} }
@ -958,13 +959,11 @@ void checkInstalledFiles(rpmts ts, uint64_t fileCount, rpmFpHash ht, fingerPrint
/* XXX What to do if this fails? */ /* XXX What to do if this fails? */
otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER); otherFi = rpmfiNew(ts, h, RPMTAG_BASENAMES, RPMFI_KEEPHEADER);
} }
rpmfiSetFX(fi, recs[j].fileno); handleInstInstalledFile(ts, p, fi, recs[j].fileno,
rpmfiSetFX(otherFi, fileNum); h, otherFi, fileNum, beingRemoved);
handleInstInstalledFile(ts, p, fi, h, otherFi, beingRemoved);
break; break;
case TR_REMOVED: case TR_REMOVED:
if (!beingRemoved) { if (!beingRemoved) {
rpmfiSetFX(fi, recs[j].fileno);
if (*rpmtdGetChar(&ostates) == RPMFILE_STATE_NORMAL) if (*rpmtdGetChar(&ostates) == RPMFILE_STATE_NORMAL)
rpmfsSetAction(fs, recs[j].fileno, FA_SKIP); rpmfsSetAction(fs, recs[j].fileno, FA_SKIP);
} }