From 210d76a5cd8dad3eb22fbf8f8b02ac2d00829924 Mon Sep 17 00:00:00 2001 From: jbj Date: Tue, 17 Aug 1999 23:05:24 +0000 Subject: [PATCH] fix: more precise handling was needed for multiple overlapped removed files. CVS patchset: 3234 CVS date: 1999/08/17 23:05:24 --- lib/hash.c | 23 ++++++++++++----------- lib/hash.h | 6 +++--- lib/transaction.c | 54 +++++++++++++++++++++++++++++++++++++++++------------- po/rpm.pot | 2 +- 4 files changed, 57 insertions(+), 28 deletions(-) diff --git a/lib/hash.c b/lib/hash.c index 11d94fa..45eca47 100644 --- a/lib/hash.c +++ b/lib/hash.c @@ -4,8 +4,8 @@ #include "hash.h" struct hashBucket { - void * key; - void ** data; + const void * key; + const void ** data; int dataCount; struct hashBucket * next; }; @@ -34,8 +34,8 @@ static struct hashBucket * findEntry(hashTable ht, const void * key) int hashEqualityString(const void * key1, const void * key2) { - char *k1 = (char *)key1; - char *k2 = (char *)key2; + const char *k1 = (const char *)key1; + const char *k2 = (const char *)key2; return strcmp(k1, k2); } @@ -71,7 +71,7 @@ hashTable htCreate(int numBuckets, int keySize, hashFunctionType fn, return ht; } -void htAddEntry(hashTable ht, const void * key, void * data) +void htAddEntry(hashTable ht, const void * key, const void * data) { unsigned int hash; struct hashBucket * b, * ob; @@ -85,8 +85,9 @@ void htAddEntry(hashTable ht, const void * key, void * data) if (!b) { b = malloc(sizeof(*b)); if (ht->keySize) { - b->key = malloc(ht->keySize); - memcpy(b->key, key, ht->keySize); + char *k = malloc(ht->keySize); + memcpy(k, key, ht->keySize); + b->key = k; } else { b->key = (void *) key; } @@ -107,10 +108,10 @@ void htFree(hashTable ht) for (i = 0; i < ht->numBuckets; i++) { b = ht->buckets[i]; - if (ht->keySize && b) free(b->key); + if (ht->keySize && b) xfree(b->key); while (b) { n = b->next; - if (b->data) free(b->data); /* XXX ==> LEAK */ + if (b->data) xfree(b->data); free(b); b = n; } @@ -127,8 +128,8 @@ int htHasEntry(hashTable ht, const void * key) if (!(b = findEntry(ht, key))) return 0; else return 1; } -int htGetEntry(hashTable ht, const void * key, void *** data, - int * dataCount, void ** tableKey) +int htGetEntry(hashTable ht, const void * key, const void *** data, + int * dataCount, const void ** tableKey) { struct hashBucket * b; diff --git a/lib/hash.h b/lib/hash.h index 90166e2..49e7aee 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -17,11 +17,11 @@ int hashEqualityString(const void * key1, const void * key2); memory, but may be usefull anyway */ hashTable htCreate(int numBuckets, int keySize, hashFunctionType fn, hashEqualityType eq); -void htAddEntry(hashTable ht, const void * key, void * data); +void htAddEntry(hashTable ht, const void * key, const void * data); void htFree(hashTable ht); /* returns 0 on success, 1 if the item is not found. tableKey may be NULL */ -int htGetEntry(hashTable ht, const void * key, void *** data, int * dataCount, - void ** tableKey); +int htGetEntry(hashTable ht, const void * key, const void *** data, int * dataCount, + const void ** tableKey); /* returns 1 if the item is present, 0 otherwise */ int htHasEntry(hashTable ht, const void * key); diff --git a/lib/transaction.c b/lib/transaction.c index 661315f..5ee6e99 100644 --- a/lib/transaction.c +++ b/lib/transaction.c @@ -686,7 +686,7 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, for (i = 0; i < fi->fc; i++) { int otherPkgNum, otherFileNum; - struct fileInfo ** recs; + const struct fileInfo ** recs; int numRecs; if (XFA_SKIPPING(fi->actions[i])) @@ -699,20 +699,44 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, fixupSize = 0; } - htGetEntry(ht, &fi->fps[i], (void ***) &recs, &numRecs, NULL); + /* + * Retrieve all records that apply to this file. Note that the + * file info records were built in the same order as the packages + * will be installed and removed so the records for an overlapped + * files will be sorted in exactly the same order. + */ + htGetEntry(ht, &fi->fps[i], (const void ***) &recs, &numRecs, NULL); - /* We need to figure out the current fate of this file. So, - work backwards from this file and look for a final action - we can work against. */ + /* + * If this package is being added, look only at other packages + * being added -- removed packages dance to a different tune. + * If both this and the other package are being added, overlapped + * files must be identical (or marked as a conflict). The + * disposition of already installed config files leads to + * a small amount of extra complexity. + * + * If this package is being removed, then there are two cases that + * need to be worried about: + * If the other package is being added, then skip any overlapped files + * so that this package removal doesn't nuke the overlapped files + * that were just installed. + * If both this and the other package are being removed, then each + * file removal from preceding packages needs to be skipped so that + * the file removal occurs only on the last occurence of an overlapped + * file in the transaction set. + * + */ + + /* Locate this overlapped file in the set of added/removed packages. */ for (j = 0; recs[j] != fi; j++) ; + /* Find what the previous disposition of this file was. */ otherFileNum = -1; /* keep gcc quiet */ for (otherPkgNum = j - 1; otherPkgNum >= 0; otherPkgNum--) { -#if XXX_ERASED_PACKAGES_LAST - if (recs[otherPkgNum]->type != TR_ADDED) + /* Added packages need only look at other added packages. */ + if (fi->type == TR_ADDED && recs[otherPkgNum]->type != TR_ADDED) continue; -#endif /* TESTME: there are more efficient searches in the world... */ for (otherFileNum = 0; otherFileNum < recs[otherPkgNum]->fc; @@ -720,6 +744,7 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, if (FP_EQUAL(fi->fps[i], recs[otherPkgNum]->fps[otherFileNum])) break; } + /* XXX is this test still necessary? */ if (recs[otherPkgNum]->actions[otherFileNum] != FA_UNKNOWN) break; } @@ -728,9 +753,11 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, struct stat sb; case TR_ADDED: if (otherPkgNum < 0) { + /* XXX is this test still necessary? */ if (fi->actions[i] != FA_UNKNOWN) break; if ((fi->fflags[i] & RPMFILE_CONFIG) && !lstat(fi->fl[i], &sb)) { + /* Here is a non-overlapped pre-existing config file. */ fi->actions[i] = (fi->fflags[i] & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_BACKUP; } else { @@ -739,6 +766,7 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, break; } + /* Mark added overlapped nnon-identical files as a conflict. */ if (probs && filecmp(recs[otherPkgNum]->fmodes[otherFileNum], recs[otherPkgNum]->fmd5s[otherFileNum], recs[otherPkgNum]->flinks[otherFileNum], @@ -749,12 +777,11 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, fi->ap->h, fi->fl[i], recs[otherPkgNum]->ap->h, 0); } + /* Try to get the disk accounting correct even if a conflict. */ fixupSize = recs[otherPkgNum]->fsizes[otherFileNum]; - /* FIXME: is this right??? it locks us into the config - file handling choice we already made, which may very - well be exactly right. What about noreplace files?? */ if ((fi->fflags[i] & RPMFILE_CONFIG) && !lstat(fi->fl[i], &sb)) { + /* Here is an overlapped pre-existing config file. */ fi->actions[i] = (fi->fflags[i] & RPMFILE_NOREPLACE) ? FA_ALTNAME : FA_SKIP; } else { @@ -767,12 +794,13 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, fi->actions[i] = FA_SKIP; break; #else + /* Here is an overlapped added file we don't want to nuke */ if (recs[otherPkgNum]->actions[otherFileNum] != FA_REMOVE) { /* On updates, don't remove files. */ fi->actions[i] = FA_SKIP; break; } - /* Remove file on last occurrence. Other package should skip. */ + /* Here is an overlapped removed file: skip in previous. */ recs[otherPkgNum]->actions[otherFileNum] = FA_SKIP; #endif } @@ -785,13 +813,13 @@ static void handleOverlappedFiles(struct fileInfo * fi, hashTable ht, break; } + /* Here is a pre-existing modified config file that needs saving. */ { char mdsum[50]; if (!mdfile(fi->fl[i], mdsum) && strcmp(fi->fmd5s[i], mdsum)) { fi->actions[i] = FA_BACKUP; break; } } - /* FIXME: config files may need to be saved */ fi->actions[i] = FA_REMOVE; break; } diff --git a/po/rpm.pot b/po/rpm.pot index 21ce65c..e727307 100644 --- a/po/rpm.pot +++ b/po/rpm.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-08-16 18:09-0400\n" +"POT-Creation-Date: 1999-08-17 18:52-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" -- 2.7.4