fix: more precise handling was needed for multiple overlapped removed files.
authorjbj <devnull@localhost>
Tue, 17 Aug 1999 23:05:24 +0000 (23:05 +0000)
committerjbj <devnull@localhost>
Tue, 17 Aug 1999 23:05:24 +0000 (23:05 +0000)
CVS patchset: 3234
CVS date: 1999/08/17 23:05:24

lib/hash.c
lib/hash.h
lib/transaction.c
po/rpm.pot

index 11d94fa..45eca47 100644 (file)
@@ -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;
 
index 90166e2..49e7aee 100644 (file)
@@ -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);
 
index 661315f..5ee6e99 100644 (file)
@@ -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;
        }
index 21ce65c..e727307 100644 (file)
@@ -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 <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"