removes for upgrades should happen inthe middle of transactions, not

clustered at the end

CVS patchset: 2943
CVS date: 1999/04/04 21:26:36
This commit is contained in:
ewt 1999-04-04 21:26:36 +00:00
parent 3e38468d2d
commit 81bb570437
3 changed files with 262 additions and 175 deletions

View File

@ -5,13 +5,19 @@
#include "depends.h" #include "depends.h"
#include "misc.h" #include "misc.h"
struct orderListIndex {
int alIndex;
int orIndex;
};
static int orderListIndexCmp(const void * one, const void * two);
static void alMakeIndex(struct availableList * al); static void alMakeIndex(struct availableList * al);
static void alCreate(struct availableList * al); static void alCreate(struct availableList * al);
static void alFreeIndex(struct availableList * al); static void alFreeIndex(struct availableList * al);
static void alFree(struct availableList * al); static void alFree(struct availableList * al);
static void alAddPackage(struct availableList * al, Header h, const void * key, static struct availablePackage * alAddPackage(struct availableList * al,
FD_t fd, rpmRelocation * relocs); Header h, const void * key,
FD_t fd, rpmRelocation * relocs);
static int intcmp(const void * a, const void *b); static int intcmp(const void * a, const void *b);
static int indexcmp(const void * a, const void *b); static int indexcmp(const void * a, const void *b);
static int unsatisfiedDepend(rpmTransactionSet rpmdep, char * reqName, static int unsatisfiedDepend(rpmTransactionSet rpmdep, char * reqName,
@ -32,9 +38,10 @@ static int checkPackageSet(rpmTransactionSet rpmdep, struct problemsSet * psp,
char * package, dbiIndexSet * matches); char * package, dbiIndexSet * matches);
static int addOrderedPack(rpmTransactionSet rpmdep, static int addOrderedPack(rpmTransactionSet rpmdep,
struct availablePackage * package, struct availablePackage * package,
struct availablePackage * ordering, int * orderNumPtr, int * ordering, int * orderNumPtr,
int * selected, int selectionClass, int * selected, int selectionClass,
int satisfyDepends, char ** errorStack); int satisfyDepends, char ** errorStack);
static void removePackage(rpmTransactionSet rpmdep, int dboffset, int depends);
static void alCreate(struct availableList * al) { static void alCreate(struct availableList * al) {
al->list = malloc(sizeof(*al->list) * 5); al->list = malloc(sizeof(*al->list) * 5);
@ -69,8 +76,9 @@ static void alFree(struct availableList * al) {
alFreeIndex(al); alFreeIndex(al);
} }
static void alAddPackage(struct availableList * al, Header h, const void * key, static struct availablePackage * alAddPackage(struct availableList * al,
FD_t fd, rpmRelocation * relocs) { Header h, const void * key,
FD_t fd, rpmRelocation * relocs) {
struct availablePackage * p; struct availablePackage * p;
if (al->size == al->alloced) { if (al->size == al->alloced) {
@ -112,6 +120,8 @@ static void alAddPackage(struct availableList * al, Header h, const void * key,
p->fd = fd; p->fd = fd;
alFreeIndex(al); alFreeIndex(al);
return p;
} }
static void alMakeIndex(struct availableList * al) { static void alMakeIndex(struct availableList * al) {
@ -226,6 +236,10 @@ rpmTransactionSet rpmtransCreateSet(rpmdb db, const char * root) {
alCreate(&rpmdep->addedPackages); alCreate(&rpmdep->addedPackages);
alCreate(&rpmdep->availablePackages); alCreate(&rpmdep->availablePackages);
rpmdep->orderAlloced = 5;
rpmdep->orderCount = 0;
rpmdep->order = malloc(sizeof(*rpmdep->order) * rpmdep->orderAlloced);
return rpmdep; return rpmdep;
} }
@ -236,6 +250,7 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
char * name; char * name;
int count, i, j; int count, i, j;
char ** obsoletes; char ** obsoletes;
int alNum;
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */ /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE)) if (headerIsEntry(h, RPMTAG_SOURCEPACKAGE))
@ -246,7 +261,15 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
makes it difficult to generate a return code based on the number of makes it difficult to generate a return code based on the number of
packages which failed. */ packages which failed. */
alAddPackage(&rpmdep->addedPackages, h, key, fd, relocs); if (rpmdep->orderCount == rpmdep->orderAlloced) {
rpmdep->orderAlloced += 5;
rpmdep->order = realloc(rpmdep->order,
sizeof(*rpmdep->order) * rpmdep->orderAlloced);
}
rpmdep->order[rpmdep->orderCount].type = TR_ADDED;
alNum = alAddPackage(&rpmdep->addedPackages, h, key, fd, relocs) -
rpmdep->addedPackages.list;
rpmdep->order[rpmdep->orderCount++].u.addedIndex = alNum;
if (!upgrade || rpmdep->db == NULL) return 0; if (!upgrade || rpmdep->db == NULL) return 0;
@ -254,7 +277,7 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
if (!rpmdbFindPackage(rpmdep->db, name, &matches)) { if (!rpmdbFindPackage(rpmdep->db, name, &matches)) {
for (i = 0; i < dbiIndexSetCount(matches); i++) { for (i = 0; i < dbiIndexSetCount(matches); i++) {
rpmtransRemovePackage(rpmdep, dbiIndexRecordOffset(matches, i)); removePackage(rpmdep, dbiIndexRecordOffset(matches, i), alNum);
} }
dbiFreeIndexRecord(matches); dbiFreeIndexRecord(matches);
@ -265,7 +288,8 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
if (!rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches)) { if (!rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches)) {
for (i = 0; i < dbiIndexSetCount(matches); i++) { for (i = 0; i < dbiIndexSetCount(matches); i++) {
rpmtransRemovePackage(rpmdep, dbiIndexRecordOffset(matches, i)); removePackage(rpmdep, dbiIndexRecordOffset(matches, i),
alNum);
} }
dbiFreeIndexRecord(matches); dbiFreeIndexRecord(matches);
@ -275,14 +299,14 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
free(obsoletes); free(obsoletes);
} }
return 0; return 0;
} }
void rpmtransAvailablePackage(rpmTransactionSet rpmdep, Header h, void * key) { void rpmtransAvailablePackage(rpmTransactionSet rpmdep, Header h, void * key) {
alAddPackage(&rpmdep->availablePackages, h, key, NULL, NULL); alAddPackage(&rpmdep->availablePackages, h, key, NULL, NULL);
} }
void rpmtransRemovePackage(rpmTransactionSet rpmdep, int dboffset) { static void removePackage(rpmTransactionSet rpmdep, int dboffset, int depends) {
if (rpmdep->numRemovedPackages == rpmdep->allocedRemovedPackages) { if (rpmdep->numRemovedPackages == rpmdep->allocedRemovedPackages) {
rpmdep->allocedRemovedPackages += 5; rpmdep->allocedRemovedPackages += 5;
rpmdep->removedPackages = realloc(rpmdep->removedPackages, rpmdep->removedPackages = realloc(rpmdep->removedPackages,
@ -290,6 +314,20 @@ void rpmtransRemovePackage(rpmTransactionSet rpmdep, int dboffset) {
} }
rpmdep->removedPackages[rpmdep->numRemovedPackages++] = dboffset; rpmdep->removedPackages[rpmdep->numRemovedPackages++] = dboffset;
if (rpmdep->orderCount == rpmdep->orderAlloced) {
rpmdep->orderAlloced += 5;
rpmdep->order = realloc(rpmdep->order,
sizeof(*rpmdep->order) * rpmdep->orderAlloced);
}
rpmdep->order[rpmdep->orderCount].type = TR_REMOVED;
rpmdep->order[rpmdep->orderCount].u.removed.dboffset = dboffset;
rpmdep->order[rpmdep->orderCount++].u.removed.dependsOnIndex = depends;
}
void rpmtransRemovePackage(rpmTransactionSet rpmdep, int dboffset) {
removePackage(rpmdep, dboffset, -1);
} }
void rpmtransFree(rpmTransactionSet rpmdep) { void rpmtransFree(rpmTransactionSet rpmdep) {
@ -789,7 +827,7 @@ static int dbrecMatchesDepFlags(rpmTransactionSet rpmdep, int recOffset,
static int addOrderedPack(rpmTransactionSet rpmdep, static int addOrderedPack(rpmTransactionSet rpmdep,
struct availablePackage * package, struct availablePackage * package,
struct availablePackage * ordering, int * orderNumPtr, int * ordering, int * orderNumPtr,
int * selected, int selectionClass, int * selected, int selectionClass,
int satisfyDepends, char ** errorStack) { int satisfyDepends, char ** errorStack) {
char ** requires, ** requiresVersion; char ** requires, ** requiresVersion;
@ -870,18 +908,21 @@ static int addOrderedPack(rpmTransactionSet rpmdep,
} }
/* whew -- add this package */ /* whew -- add this package */
ordering[(*orderNumPtr)++] = *package; ordering[(*orderNumPtr)++] = packageNum;
selected[packageNum] = -1; selected[packageNum] = -1;
return 0; return 0;
} }
int rpmdepOrder(rpmTransactionSet rpmdep) { int rpmdepOrder(rpmTransactionSet rpmdep) {
int i; int i, j;
int * selected; int * selected;
struct availablePackage * order; int * ordering;
int orderNum; int orderingCount;
char ** errorStack; char ** errorStack;
struct transactionElement * newOrder;
int newOrderCount = 0;
struct orderListIndex * orderList, * needle, key;
alMakeIndex(&rpmdep->addedPackages); alMakeIndex(&rpmdep->addedPackages);
alMakeIndex(&rpmdep->availablePackages); alMakeIndex(&rpmdep->availablePackages);
@ -892,21 +933,76 @@ int rpmdepOrder(rpmTransactionSet rpmdep) {
errorStack = alloca(sizeof(*errorStack) * (rpmdep->addedPackages.size + 1)); errorStack = alloca(sizeof(*errorStack) * (rpmdep->addedPackages.size + 1));
*errorStack++ = NULL; *errorStack++ = NULL;
order = malloc(sizeof(*order) * (rpmdep->addedPackages.size + 1)); ordering = alloca(sizeof(*ordering) * (rpmdep->addedPackages.size + 1));
orderNum = 0; orderingCount = 0;
for (i = 0; i < rpmdep->addedPackages.size; i++) { for (i = 0; i < rpmdep->addedPackages.size; i++) {
if (!selected[i]) { if (!selected[i]) {
if (addOrderedPack(rpmdep, rpmdep->addedPackages.list + i, if (addOrderedPack(rpmdep, rpmdep->addedPackages.list + i,
order, &orderNum, selected, 1, 0, errorStack)) { ordering, &orderingCount, selected, 1, 0,
free(order); errorStack)) {
free(ordering);
return 1; return 1;
} }
} }
} }
free(rpmdep->addedPackages.list); /* The order ends up as installed packages followed by removed packages,
rpmdep->addedPackages.list = order; with removes for upgrades immediately follwing the installation of
the new package. This would be easier if we could sort the
addedPackages array, but we store indexes into it in various places. */
orderList = malloc(sizeof(*orderList) * rpmdep->addedPackages.size);
for (i = 0, j = 0; i < rpmdep->orderCount; i++) {
if (rpmdep->order[i].type == TR_ADDED) {
orderList[j].alIndex = rpmdep->order[i].u.addedIndex;
orderList[j].orIndex = i;
j++;
}
}
qsort(orderList, rpmdep->addedPackages.size, sizeof(*orderList),
orderListIndexCmp);
newOrder = malloc(sizeof(*newOrder) * rpmdep->orderCount);
for (i = 0, newOrderCount = 0; i < orderingCount; i++) {
key.alIndex = ordering[i];
needle = bsearch(&key, orderList, rpmdep->addedPackages.size,
sizeof(key), orderListIndexCmp);
/* bsearch should never, ever fail */
newOrder[newOrderCount++] = rpmdep->order[needle->orIndex];
for (j = needle->orIndex + 1; j < rpmdep->orderCount; j++) {
if (rpmdep->order[j].type == TR_REMOVED &&
rpmdep->order[j].u.removed.dependsOnIndex == needle->alIndex) {
newOrder[newOrderCount++] = rpmdep->order[j];
} else {
break;
}
}
}
for (i = 0; i < rpmdep->orderCount; i++) {
if (rpmdep->order[i].type == TR_REMOVED &&
rpmdep->order[i].u.removed.dependsOnIndex == -1) {
newOrder[newOrderCount++] = rpmdep->order[i];
}
}
free(rpmdep->order);
rpmdep->order = newOrder;
rpmdep->orderAlloced = rpmdep->orderCount;
free(orderList);
return 0;
}
static int orderListIndexCmp(const void * one, const void * two) {
const struct orderListIndex * a = one;
const struct orderListIndex * b = two;
if (a->alIndex < b->alIndex)
return -1;
if (a->alIndex > b->alIndex)
return 1;
return 0; return 0;
} }

View File

@ -35,11 +35,24 @@ struct availableList {
int size, alloced; int size, alloced;
}; };
struct transactionElement {
enum rpmTransactionType { TR_ADDED, TR_REMOVED } type;
union {
int addedIndex;
struct {
int dboffset;
int dependsOnIndex;
} removed;
} u;
};
struct rpmTransactionSet_s { struct rpmTransactionSet_s {
rpmdb db; /* may be NULL */ rpmdb db; /* may be NULL */
int * removedPackages; int * removedPackages;
int numRemovedPackages, allocedRemovedPackages; int numRemovedPackages, allocedRemovedPackages;
struct availableList addedPackages, availablePackages; struct availableList addedPackages, availablePackages;
struct transactionElement * order;
int orderCount, orderAlloced;
char * root; char * root;
FD_t scriptFd; FD_t scriptFd;
}; };

View File

@ -28,7 +28,7 @@
struct fileInfo { struct fileInfo {
/* for all packages */ /* for all packages */
enum fileInfo_e { ADDED, REMOVED } type; enum rpmTransactionType type;
enum fileActions * actions; enum fileActions * actions;
fingerPrint * fps; fingerPrint * fps;
uint_32 * fflags, * fsizes; uint_32 * fflags, * fsizes;
@ -37,14 +37,14 @@ struct fileInfo {
uint_16 * fmodes; uint_16 * fmodes;
Header h; Header h;
int fc; int fc;
/* these are for ADDED packages */ char * fstates;
/* these are for TR_ADDED packages */
char ** flinks; char ** flinks;
struct availablePackage * ap; struct availablePackage * ap;
struct sharedFileInfo * replaced; struct sharedFileInfo * replaced;
uint_32 * replacedSizes; uint_32 * replacedSizes;
/* for REMOVED packages */ /* for TR_REMOVED packages */
unsigned int record; unsigned int record;
char * fstates;
}; };
struct diskspaceInfo { struct diskspaceInfo {
@ -114,7 +114,7 @@ static void freeFi(struct fileInfo *fi)
free(fi->fmd5s); fi->fmd5s = NULL; free(fi->fmd5s); fi->fmd5s = NULL;
} }
if (fi->type == REMOVED) { if (fi->type == TR_REMOVED) {
if (fi->fsizes) { if (fi->fsizes) {
free(fi->fsizes); fi->fsizes = NULL; free(fi->fsizes); fi->fsizes = NULL;
} }
@ -132,17 +132,10 @@ static void freeFi(struct fileInfo *fi)
static void freeFl(rpmTransactionSet ts, struct fileInfo *flList) static void freeFl(rpmTransactionSet ts, struct fileInfo *flList)
{ {
struct availableList * al = &ts->addedPackages;
struct availablePackage * alp;
struct fileInfo *fi; struct fileInfo *fi;
int i; int oc;
for (alp = al->list, fi = flList; (alp - al->list) < al->size; for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
alp++, fi++) {
freeFi(fi);
}
for (i = 0; i < ts->numRemovedPackages; i++, fi++) {
freeFi(fi); freeFi(fi);
} }
} }
@ -155,10 +148,8 @@ static void freeFl(rpmTransactionSet ts, struct fileInfo *flList)
happened */ happened */
int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify, int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
void * notifyData, rpmProblemSet okProbs, void * notifyData, rpmProblemSet okProbs,
rpmProblemSet * newProbs, int flags, int ignoreSet) rpmProblemSet * newProbs, int flags, int ignoreSet) {
{
int i, j; int i, j;
struct availableList * al = &ts->addedPackages;
int rc, ourrc = 0; int rc, ourrc = 0;
struct availablePackage * alp; struct availablePackage * alp;
rpmProblemSet probs; rpmProblemSet probs;
@ -172,12 +163,14 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
int numShared; int numShared;
int flEntries; int flEntries;
int last; int last;
int lastFailed;
int beingRemoved; int beingRemoved;
char * currDir, * chptr; char * currDir, * chptr;
FD_t fd; FD_t fd;
const char ** filesystems; const char ** filesystems;
int filesystemCount; int filesystemCount;
struct diskspaceInfo * di = NULL; struct diskspaceInfo * di = NULL;
int oc;
/* FIXME: what if the same package is included in ts twice? */ /* FIXME: what if the same package is included in ts twice? */
@ -206,9 +199,11 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
probs = psCreate(); probs = psCreate();
*newProbs = probs; *newProbs = probs;
hdrs = alloca(sizeof(*hdrs) * al->size); hdrs = alloca(sizeof(*hdrs) * ts->addedPackages.size);
for (alp = al->list; (alp - al->list) < al->size; alp++) { /* The ordering doesn't matter here */
for (alp = ts->addedPackages.list; (alp - ts->addedPackages.list) <
ts->addedPackages.size; alp++) {
if (!archOkay(alp->h) && !(ignoreSet & RPMPROB_FILTER_IGNOREARCH)) if (!archOkay(alp->h) && !(ignoreSet & RPMPROB_FILTER_IGNOREARCH))
psAppend(probs, RPMPROB_BADARCH, alp->key, alp->h, NULL, NULL, 0); psAppend(probs, RPMPROB_BADARCH, alp->key, alp->h, NULL, NULL, 0);
@ -244,6 +239,7 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
} }
/* FIXME: it seems a bit silly to read in all of these headers twice */ /* FIXME: it seems a bit silly to read in all of these headers twice */
/* The ordering doesn't matter here */
for (i = 0; i < ts->numRemovedPackages; i++) { for (i = 0; i < ts->numRemovedPackages; i++) {
Header h; Header h;
@ -255,7 +251,7 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
} }
} }
flEntries = al->size + ts->numRemovedPackages; flEntries = ts->addedPackages.size + ts->numRemovedPackages;
flList = alloca(sizeof(*flList) * (flEntries)); flList = alloca(sizeof(*flList) * (flEntries));
ht = htCreate(totalFileCount * 2, 0, fpHashFunction, fpEqual); ht = htCreate(totalFileCount * 2, 0, fpHashFunction, fpEqual);
@ -263,24 +259,46 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
/* FIXME?: we'd be better off assembling one very large file list and /* FIXME?: we'd be better off assembling one very large file list and
calling fpLookupList only once. I'm not sure that the speedup is calling fpLookupList only once. I'm not sure that the speedup is
worth the trouble though. */ worth the trouble though. */
for (fi = flList, alp = al->list; (alp - al->list) < al->size; for (fi = flList, oc = 0; oc < ts->orderCount; fi++, oc++) {
fi++, alp++) {
memset(fi, 0, sizeof(*fi)); memset(fi, 0, sizeof(*fi));
if (!headerGetEntryMinMemory(alp->h, RPMTAG_FILENAMES, NULL, if (ts->order[oc].type == TR_ADDED) {
(void *) NULL, &fi->fc)) { i = ts->order[oc].u.addedIndex;
fi->h = headerLink(alp->h); alp = ts->addedPackages.list + ts->order[oc].u.addedIndex;
hdrs[alp - al->list] = headerLink(fi->h);
if (!headerGetEntryMinMemory(alp->h, RPMTAG_FILENAMES, NULL,
(void *) NULL, &fi->fc)) {
fi->h = headerLink(alp->h);
hdrs[i] = headerLink(fi->h);
continue;
}
fi->actions = calloc(sizeof(*fi->actions), fi->fc);
hdrs[i] = relocateFileList(alp, probs, alp->h, fi->actions,
ignoreSet & RPMPROB_FILTER_FORCERELOCATE);
fi->h = headerLink(hdrs[i]);
fi->type = TR_ADDED;
fi->ap = alp;
} else {
fi->record = ts->order[oc].u.removed.dboffset;
fi->h = rpmdbGetRecord(ts->db, fi->record);
if (!fi->h) {
/* ACK! */
continue;
}
fi->type = TR_REMOVED;
}
if (!headerGetEntry(fi->h, RPMTAG_FILENAMES, NULL,
(void *) &fi->fl, &fi->fc)) {
/* This catches removed packages w/ no file lists */
fi->fc = 0;
continue; continue;
} }
fi->actions = calloc(sizeof(*fi->actions), fi->fc); /* actions is initialized earlier for added packages */
hdrs[alp - al->list] = relocateFileList(alp, probs, alp->h, if (!fi->actions)
fi->actions, ignoreSet & RPMPROB_FILTER_FORCERELOCATE); fi->actions = calloc(sizeof(*fi->actions), fi->fc);
fi->h = headerLink(hdrs[alp - al->list]);
headerGetEntryMinMemory(fi->h, RPMTAG_FILENAMES, NULL,
(void *) &fi->fl, &fi->fc);
headerGetEntryMinMemory(fi->h, RPMTAG_FILEMD5S, NULL, headerGetEntryMinMemory(fi->h, RPMTAG_FILEMD5S, NULL,
(void *) &fi->fmd5s, NULL); (void *) &fi->fmd5s, NULL);
@ -292,59 +310,29 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
(void *) &fi->fflags, NULL); (void *) &fi->fflags, NULL);
headerGetEntryMinMemory(fi->h, RPMTAG_FILESIZES, NULL, headerGetEntryMinMemory(fi->h, RPMTAG_FILESIZES, NULL,
(void *) &fi->fsizes, NULL); (void *) &fi->fsizes, NULL);
headerGetEntryMinMemory(fi->h, RPMTAG_FILESTATES, NULL,
/* 0 makes for noops */
fi->replacedSizes = calloc(fi->fc, sizeof(*fi->replacedSizes));
skipFiles(fi, flags & RPMTRANS_FLAG_NODOCS);
fi->type = ADDED;
fi->fps = malloc(fi->fc * sizeof(*fi->fps));
fi->ap = alp;
}
for (i = 0; i < ts->numRemovedPackages; i++, fi++) {
memset(fi, 0, sizeof(*fi));
fi->type = REMOVED;
fi->record = ts->removedPackages[i];
fi->h = rpmdbGetRecord(ts->db, fi->record);
if (!fi->h) {
/* ACK! */
continue;
}
if (!headerGetEntry(fi->h, RPMTAG_FILENAMES, NULL,
(void *) &fi->fl, &fi->fc)) {
fi->fc = 0;
continue;
}
headerGetEntry(fi->h, RPMTAG_FILESIZES, NULL,
(void *) &fi->fsizes, NULL);
fi->fsizes = memcpy(malloc(fi->fc * sizeof(*fi->fsizes)),
fi->fsizes, fi->fc * sizeof(*fi->fsizes));
headerGetEntry(fi->h, RPMTAG_FILEFLAGS, NULL,
(void *) &fi->fflags, NULL);
fi->fflags = memcpy(malloc(fi->fc * sizeof(*fi->fflags)),
fi->fflags, fi->fc * sizeof(*fi->fflags));
headerGetEntry(fi->h, RPMTAG_FILEMD5S, NULL,
(void *) &fi->fmd5s, NULL);
headerGetEntry(fi->h, RPMTAG_FILEMODES, NULL,
(void *) &fi->fmodes, NULL);
fi->fmodes = memcpy(malloc(fi->fc * sizeof(*fi->fmodes)),
fi->fmodes, fi->fc * sizeof(*fi->fmodes));
headerGetEntry(fi->h, RPMTAG_FILESTATES, NULL,
(void *) &fi->fstates, NULL); (void *) &fi->fstates, NULL);
fi->fstates = memcpy(malloc(fi->fc * sizeof(*fi->fstates)),
fi->fstates, fi->fc * sizeof(*fi->fstates));
/* Note that as FA_UNKNOWN = 0, this does the right thing */ if (ts->order[oc].type == TR_REMOVED) {
fi->actions = calloc(sizeof(*fi->actions), fi->fc); fi->fsizes = memcpy(malloc(fi->fc * sizeof(*fi->fsizes)),
fi->fsizes, fi->fc * sizeof(*fi->fsizes));
fi->fflags = memcpy(malloc(fi->fc * sizeof(*fi->fflags)),
fi->fflags, fi->fc * sizeof(*fi->fflags));
fi->fmodes = memcpy(malloc(fi->fc * sizeof(*fi->fmodes)),
fi->fmodes, fi->fc * sizeof(*fi->fmodes));
fi->fstates = memcpy(malloc(fi->fc * sizeof(*fi->fstates)),
fi->fstates, fi->fc * sizeof(*fi->fstates));
headerFree(fi->h);
fi->h = NULL;
} else {
/* ADDED package */
/* 0 makes for noops */
fi->replacedSizes = calloc(fi->fc, sizeof(*fi->replacedSizes));
skipFiles(fi, flags & RPMTRANS_FLAG_NODOCS);
}
fi->fps = malloc(fi->fc * sizeof(*fi->fps)); fi->fps = malloc(fi->fc * sizeof(*fi->fps));
headerFree(fi->h);
fi->h = NULL;
} }
chptr = currentDirectory(); chptr = currentDirectory();
@ -404,13 +392,13 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
} }
beingRemoved = (j < ts->numRemovedPackages); beingRemoved = (j < ts->numRemovedPackages);
if (fi->type == ADDED) if (fi->type == TR_ADDED)
handleInstInstalledFiles(fi, ts->db, sharedList + i, handleInstInstalledFiles(fi, ts->db, sharedList + i,
last - i + 1, last - i + 1,
!(beingRemoved || !(beingRemoved ||
(ignoreSet & RPMPROB_FILTER_REPLACEOLDFILES)), (ignoreSet & RPMPROB_FILTER_REPLACEOLDFILES)),
probs); probs);
else if (fi->type == REMOVED && !beingRemoved) else if (fi->type == TR_REMOVED && !beingRemoved)
handleRmvdInstalledFiles(fi, ts->db, sharedList + i, handleRmvdInstalledFiles(fi, ts->db, sharedList + i,
last - i + 1); last - i + 1);
@ -422,7 +410,7 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
handleOverlappedFiles(fi, ht, handleOverlappedFiles(fi, ht,
(ignoreSet & RPMPROB_FILTER_REPLACENEWFILES) ? NULL : probs, di); (ignoreSet & RPMPROB_FILTER_REPLACENEWFILES) ? NULL : probs, di);
if (di && fi->type == ADDED) { if (di && fi->type == TR_ADDED) {
for (i = 0; i < filesystemCount; i++) { for (i = 0; i < filesystemCount; i++) {
if (di[i].needed > di[i].avail) { if (di[i].needed > di[i].avail) {
psAppend(probs, RPMPROB_DISKSPACE, fi->ap->key, fi->ap->h, psAppend(probs, RPMPROB_DISKSPACE, fi->ap->key, fi->ap->h,
@ -440,11 +428,10 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
htFree(ht); htFree(ht);
for (alp = al->list, fi = flList; (alp - al->list) < al->size; for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
alp++, fi++) {
if (fi->fc) { if (fi->fc) {
free(fi->fl); fi->fl = NULL; free(fi->fl); fi->fl = NULL;
if (fi->type == ADDED) { if (fi->type == TR_ADDED) {
free(fi->fmd5s); fi->fmd5s = NULL; free(fi->fmd5s); fi->fmd5s = NULL;
free(fi->flinks); fi->flinks = NULL; free(fi->flinks); fi->flinks = NULL;
free(fi->fps); fi->fps = NULL; free(fi->fps); fi->fps = NULL;
@ -456,81 +443,72 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
(probs->numProblems && (!okProbs || psTrim(okProbs, probs)))) { (probs->numProblems && (!okProbs || psTrim(okProbs, probs)))) {
*newProbs = probs; *newProbs = probs;
for (alp = al->list, fi = flList; (alp - al->list) < al->size; for (alp = ts->addedPackages.list, fi = flList;
alp++, fi++) { (alp - ts->addedPackages.list) < ts->addedPackages.size;
headerFree(hdrs[alp - al->list]); alp++, fi++) {
freeFi(fi); /* XXX ==> LEAK */ headerFree(hdrs[alp - ts->addedPackages.list]);
} }
freeFl(ts, flList); /* XXX ==> LEAK */ freeFl(ts, flList);
return al->size + ts->numRemovedPackages; return ts->orderCount;
} }
NOTIFY((NULL, RPMCALLBACK_TRANS_START, 9, al->size, NULL, notifyData)); lastFailed = -2;
for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
if (ts->order[oc].type == TR_ADDED) {
alp = ts->addedPackages.list + ts->order[oc].u.addedIndex;
i = ts->order[oc].u.addedIndex;
for (alp = al->list, fi = flList; (alp - al->list) < al->size; if (alp->fd) {
alp++, fi++) { fd = alp->fd;
if (alp->fd) { } else {
fd = alp->fd; fd = notify(fi->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0,
} else { alp->key, notifyData);
fd = notify(fi->h, RPMCALLBACK_INST_OPEN_FILE, 0, 0, if (fd) {
alp->key, notifyData); Header h;
if (fd) {
Header h;
headerFree(hdrs[alp - al->list]); headerFree(hdrs[i]);
rc = rpmReadPackageHeader(fd, &h, NULL, NULL, NULL); rc = rpmReadPackageHeader(fd, &h, NULL, NULL, NULL);
if (rc) { if (rc) {
notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0, notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0,
alp->key, notifyData); alp->key, notifyData);
ourrc++; ourrc++;
fd = NULL; fd = NULL;
} else { } else {
hdrs[alp - al->list] = hdrs[i] = relocateFileList(alp, probs, h, NULL, 1);
relocateFileList(alp, probs, h, NULL, 1); headerFree(h);
headerFree(h); }
} }
} }
}
if (fd) { if (fd) {
if (installBinaryPackage(ts->root, ts->db, fd, if (installBinaryPackage(ts->root, ts->db, fd,
hdrs[alp - al->list], flags, notify, hdrs[i], flags, notify,
notifyData, alp->key, fi->actions, notifyData, alp->key, fi->actions,
fi->fc ? fi->replaced : NULL, fi->fc ? fi->replaced : NULL,
ts->scriptFd)) ts->scriptFd)) {
ourrc++;
lastFailed = i;
}
} else {
ourrc++; ourrc++;
} else { lastFailed = i;
ourrc++; }
}
headerFree(hdrs[alp - al->list]); headerFree(hdrs[i]);
if (!alp->fd && fd) if (!alp->fd && fd)
notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0, alp->key, notify(fi->h, RPMCALLBACK_INST_CLOSE_FILE, 0, 0, alp->key,
notifyData); notifyData);
} } else if (ts->order[oc].u.removed.dependsOnIndex != lastFailed) {
NOTIFY((NULL, RPMCALLBACK_TRANS_STOP, 9, al->size, NULL, notifyData)); if (removeBinaryPackage(ts->root, ts->db, fi->record,
flags, fi->actions, ts->scriptFd))
NOTIFY((NULL, RPMCALLBACK_UNINST_START, 0, ts->numRemovedPackages, ourrc++;
NULL, notifyData)); }
/* fi is left at the first package which is to be removed */
for (i = 0; i < ts->numRemovedPackages; i++, fi++) {
NOTIFY((fi->h, RPMCALLBACK_UNINST_PROGRESS, i, ts->numRemovedPackages,
NULL, notifyData));
if (removeBinaryPackage(ts->root, ts->db, ts->removedPackages[i],
flags, fi->actions, ts->scriptFd))
ourrc++;
} }
NOTIFY((NULL, RPMCALLBACK_UNINST_STOP, 0, ts->numRemovedPackages, freeFl(ts, flList);
NULL, notifyData));
freeFl(ts, flList); /* XXX ==> LEAK */
if (ourrc) if (ourrc)
return -1; return -1;
@ -1096,7 +1074,7 @@ void handleOverlappedFiles(struct fileInfo * fi, hashTable ht,
otherPkgNum = j - 1; otherPkgNum = j - 1;
otherFileNum = -1; /* keep gcc quiet */ otherFileNum = -1; /* keep gcc quiet */
while (otherPkgNum >= 0) { while (otherPkgNum >= 0) {
if (recs[otherPkgNum]->type == ADDED) { if (recs[otherPkgNum]->type == TR_ADDED) {
/* TESTME: there are more efficient searches in the world... */ /* TESTME: there are more efficient searches in the world... */
for (otherFileNum = 0; otherFileNum < recs[otherPkgNum]->fc; for (otherFileNum = 0; otherFileNum < recs[otherPkgNum]->fc;
otherFileNum++) otherFileNum++)
@ -1110,7 +1088,7 @@ void handleOverlappedFiles(struct fileInfo * fi, hashTable ht,
otherPkgNum--; otherPkgNum--;
} }
if (fi->type == ADDED && otherPkgNum < 0) { if (fi->type == TR_ADDED && otherPkgNum < 0) {
if (fi->actions[i] == FA_UNKNOWN) { if (fi->actions[i] == FA_UNKNOWN) {
if ((fi->fflags[i] & RPMFILE_CONFIG) && if ((fi->fflags[i] & RPMFILE_CONFIG) &&
!lstat(fi->fl[i], &sb)) !lstat(fi->fl[i], &sb))
@ -1118,7 +1096,7 @@ void handleOverlappedFiles(struct fileInfo * fi, hashTable ht,
else else
fi->actions[i] = FA_CREATE; fi->actions[i] = FA_CREATE;
} }
} else if (fi->type == ADDED) { } else if (fi->type == TR_ADDED) {
if (probs && filecmp(recs[otherPkgNum]->fmodes[otherFileNum], if (probs && filecmp(recs[otherPkgNum]->fmodes[otherFileNum],
recs[otherPkgNum]->fmd5s[otherFileNum], recs[otherPkgNum]->fmd5s[otherFileNum],
recs[otherPkgNum]->flinks[otherFileNum], recs[otherPkgNum]->flinks[otherFileNum],
@ -1135,9 +1113,9 @@ void handleOverlappedFiles(struct fileInfo * fi, hashTable ht,
file handling choice we already made, which may very file handling choice we already made, which may very
well be exactly right. What about noreplace files?? */ well be exactly right. What about noreplace files?? */
fi->actions[i] = FA_CREATE; fi->actions[i] = FA_CREATE;
} else if (fi->type == REMOVED && otherPkgNum >= 0) { } else if (fi->type == TR_REMOVED && otherPkgNum >= 0) {
fi->actions[i] = FA_SKIP; fi->actions[i] = FA_SKIP;
} else if (fi->type == REMOVED) { } else if (fi->type == TR_REMOVED) {
if (fi->actions[i] != FA_SKIP && fi->actions[i] != FA_SKIPNSTATE && if (fi->actions[i] != FA_SKIP && fi->actions[i] != FA_SKIPNSTATE &&
fi->fstates[i] == RPMFILE_STATE_NORMAL ) { fi->fstates[i] == RPMFILE_STATE_NORMAL ) {
if (S_ISREG(fi->fmodes[i]) && if (S_ISREG(fi->fmodes[i]) &&