diff options
author | ewt <devnull@localhost> | 2000-01-31 16:42:12 +0000 |
---|---|---|
committer | ewt <devnull@localhost> | 2000-01-31 16:42:12 +0000 |
commit | 128700d1d69d74bc8ce760e503d398cd5f1c7087 (patch) | |
tree | 83e6533080fb6799b8b4c123b2de212cb8ef3780 /python | |
parent | 6a63a1472b653b85843b10809a1218edd5bd30fa (diff) | |
download | rpm-128700d1d69d74bc8ce760e503d398cd5f1c7087.tar.gz rpm-128700d1d69d74bc8ce760e503d398cd5f1c7087.tar.bz2 rpm-128700d1d69d74bc8ce760e503d398cd5f1c7087.zip |
updated upgrade code to handle new format file lists
CVS patchset: 3540
CVS date: 2000/01/31 16:42:12
Diffstat (limited to 'python')
-rw-r--r-- | python/hash.c | 88 | ||||
-rw-r--r-- | python/hash.h | 9 | ||||
-rw-r--r-- | python/upgrade.c | 162 |
3 files changed, 167 insertions, 92 deletions
diff --git a/python/hash.c b/python/hash.c index c3fad331d..2bc6e0bf2 100644 --- a/python/hash.c +++ b/python/hash.c @@ -5,10 +5,15 @@ #include "hash.h" -#define CHUNK 4 +#define CHUNK 1 + +struct filePath { + char * dir; + char * base; +} ; struct bucket { - char **data; + struct filePath * data; int allocated; int firstFree; /* as in data[firstFree] */ }; @@ -16,7 +21,6 @@ struct bucket { struct hash_table { int size; int entries; - int totalData; int overHead; struct bucket *bucket; }; @@ -29,12 +33,11 @@ struct hash_table *htNewTable(int size) res = malloc(sizeof(struct hash_table)); res->bucket = malloc(sizeof(struct bucket) * size); res->size = size; - res->totalData = 0; res->entries = 0; res->overHead = sizeof(struct bucket) * size + CHUNK * sizeof(char *); while (i < size) { - res->bucket[i].data = malloc(CHUNK * sizeof(char *)); + res->bucket[i].data = malloc(CHUNK * sizeof(*res->bucket[i].data)); res->bucket[i].allocated = CHUNK; res->bucket[i].firstFree = 0; i++; @@ -46,14 +49,14 @@ struct hash_table *htNewTable(int size) void htFreeHashTable(struct hash_table *ht) { struct bucket * b; + int item; b = ht->bucket; while (ht->size--) { - while (b->firstFree) { - b->firstFree--; - free(b->data[b->firstFree]); + for (item = 0; item < b->firstFree; item++) { + free(b->data[item].dir); + free(b->data[item].base); } - free(b->data); b++; } @@ -78,70 +81,94 @@ void htHashStats(struct hash_table *t) printf("Total Buckets : %d\n", t->size); printf("Empty Buckets : %d\n", empty); printf("Total Entries : %d\n", t->entries); - printf("Total Data : %d\n", t->totalData); printf("Total Overhead: %d\n", t->overHead); printf("Avergage Depth: %f\n", (double)t->entries / (double)t->size); } -static unsigned int htHashString(char *s) +static unsigned int htHashStrings(const char *s, const char *t) { unsigned int res = 0; while (*s) res = ((res<<1) + (int)(*(s++))); + while (*t) + res = ((res<<1) + (int)(*(t++))); return res; } -static char *in_table_aux(struct hash_table *t, int hash, char *s) +/* returns bucket # containing item, or -1 */ +static int in_table_aux(struct hash_table *t, int hash, const char * dir, + const char * base) { int x; x = 0; while (x < t->bucket[hash].firstFree) { - if (! strcmp(t->bucket[hash].data[x], s)) { - return t->bucket[hash].data[x]; + if (! strcmp(t->bucket[hash].data[x].dir, dir) && + ! strcmp(t->bucket[hash].data[x].base, base)) { + return x; } x++; } - return NULL; + return -1; } -char *htInTable(struct hash_table *t, char *s) +int htInTable(struct hash_table *t, const char * dir, const char * base) { int hash; - hash = htHashString(s) % t->size; - return in_table_aux(t, hash, s); + hash = htHashStrings(dir, base) % t->size; + + if (in_table_aux(t, hash, dir, base) == -1) + return 0; + return 1; } -void htAddToTable(struct hash_table *t, char *s) +void htAddToTable(struct hash_table *t, const char * dir, const char * base) { - int hash; + static int hash = 1; - if (s == NULL) + if (!dir || !base) return; - hash = htHashString(s) % t->size; - if (in_table_aux(t, hash, s)) { + hash = htHashStrings(dir, base) % t->size; + if (in_table_aux(t, hash, dir, base) != -1) return; - } if (t->bucket[hash].firstFree == t->bucket[hash].allocated) { t->bucket[hash].allocated += CHUNK; t->bucket[hash].data = realloc(t->bucket[hash].data, - t->bucket[hash].allocated * sizeof(char *)); + t->bucket[hash].allocated * sizeof(*(t->bucket->data))); /*printf("Bucket %d grew to %d\n", hash, t->bucket[hash].allocated);*/ t->overHead += sizeof(char *) * CHUNK; } /*printf("In bucket %d, item %d\n", hash, t->bucket[hash].firstFree);*/ - t->bucket[hash].data[t->bucket[hash].firstFree++] = strdup(s); - t->totalData += strlen(s) + 1; + t->bucket[hash].data[t->bucket[hash].firstFree].dir = strdup(dir); + t->bucket[hash].data[t->bucket[hash].firstFree++].base = strdup(base); t->entries++; } +void htRemoveFromTable(struct hash_table *t, const char * dir, + const char * base) { + int hash; + int item; + int last; + + hash = htHashStrings(dir, base) % t->size; + if ((item = in_table_aux(t, hash, dir, base)) == -1) { + return; + } + + free(t->bucket[hash].data[item].dir); + free(t->bucket[hash].data[item].base); + + last = --t->bucket[hash].firstFree; + t->bucket[hash].data[item] = t->bucket[hash].data[last]; +} + int htNumEntries(struct hash_table *t) { return t->entries; } @@ -151,12 +178,15 @@ void htIterStart(htIterator * iter) { iter->item = -1; } -int htIterGetNext(struct hash_table * t, htIterator * iter, char ** s) { +int htIterGetNext(struct hash_table * t, htIterator * iter, + const char ** dir, const char ** base) { iter->item++; while (iter->bucket < t->size) { if (iter->item < t->bucket[iter->bucket].firstFree) { - *s = t->bucket[iter->bucket].data[iter->item]; + *dir = t->bucket[iter->bucket].data[iter->item].dir; + *base = t->bucket[iter->bucket].data[iter->item].base; + return 1; } diff --git a/python/hash.h b/python/hash.h index 26b638787..954ad3bf4 100644 --- a/python/hash.h +++ b/python/hash.h @@ -13,13 +13,16 @@ typedef struct ht_iterator htIterator; struct hash_table *htNewTable(int size); void htFreeHashTable(struct hash_table *ht); -char *htInTable(struct hash_table *t, char *s); -void htAddToTable(struct hash_table *t, char *s); +int htInTable(struct hash_table *t, const char * dir, const char * base); +void htAddToTable(struct hash_table *t, const char * dir, const char * base); void htPrintHashStats(struct hash_table *t); int htNumEntries(struct hash_table *t); +void htRemoveFromTable(struct hash_table *t, const char * dir, + const char * base); /* these use static storage */ void htIterStart(htIterator * iter); -int htIterGetNext(struct hash_table * t, htIterator * iter, char ** s); +int htIterGetNext(struct hash_table * t, htIterator * iter, + const char ** dir, const char ** base); #endif diff --git a/python/upgrade.c b/python/upgrade.c index 63cc9e6a1..51e5e8378 100644 --- a/python/upgrade.c +++ b/python/upgrade.c @@ -1,4 +1,3 @@ -#ifdef DYING #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -7,9 +6,6 @@ #include <glob.h> /* XXX rpmio.h */ #include <dirent.h> /* XXX rpmio.h */ -#else -#include "system.h" -#endif #include <rpmlib.h> @@ -47,28 +43,44 @@ int pkgCompare(void * first, void * second) { } -static void compareFileList(int availFileCount, char **availFiles, - int installedFileCount, char **installedFiles, +/* Adds all files in the second file list which are not in the first + file list to the hash table. */ +static void compareFileList(int availFileCount, char **availBaseNames, + char ** availDirNames, int * availDirIndexes, + int instFileCount, char **instBaseNames, + char ** instDirNames, int * instDirIndexes, struct hash_table *ht) { int installedX, availX, rc; + char * availDir, * availBase; + char * instDir, * instBase; + static int i = 0; availX = 0; installedX = 0; - while (installedX < installedFileCount) { + while (installedX < instFileCount) { + instBase = instBaseNames[installedX]; + instDir = instDirNames[instDirIndexes[installedX]]; + if (availX == availFileCount) { /* All the rest have moved */ - DEBUG(("=> %s\n", installedFiles[installedX])); - if (strncmp(installedFiles[installedX], "/etc/rc.d/", 10)) - htAddToTable(ht, installedFiles[installedX]); + DEBUG(("=> %d: %s%s\n", i++, instDir, instBase)) + if (strncmp(instDir, "/etc/rc.d/", 10)) + htAddToTable(ht, instDir, instBase); installedX++; } else { - rc = strcmp(availFiles[availX], installedFiles[installedX]); + availBase = availBaseNames[availX]; + availDir = availDirNames[availDirIndexes[availX]]; + + rc = strcmp(availDir, instDir); + if (!rc) + rc = strcmp(availBase, instBase); + if (rc > 0) { /* Avail > Installed -- file has moved */ - DEBUG (("=> %s\n", installedFiles[installedX])); - if (strncmp(installedFiles[installedX], "/etc/rc.d/", 10)) - htAddToTable(ht, installedFiles[installedX]); + DEBUG(("=> %d: %s%s\n", i++, instDir, instBase)) + if (strncmp(instDir, "/etc/rc.d/", 10)) + htAddToTable(ht, instDir, instBase); installedX++; } else if (rc < 0) { /* Avail < Installed -- avail has some new files */ @@ -91,6 +103,8 @@ static void addLostFiles(rpmdb db, struct pkgSet *psp, struct hash_table *ht) struct packageInfo key; struct packageInfo *keyaddr = &key; char **installedFiles; + char **installedDirs; + int_32 * installedDirIndexes; int installedFileCount; num = rpmdbFirstRecNum(db); @@ -109,11 +123,19 @@ static void addLostFiles(rpmdb db, struct pkgSet *psp, struct hash_table *ht) pack = bsearch(&keyaddr, psp->packages, psp->numPackages, sizeof(*psp->packages), (void *)pkgCompare); if (!pack) { - if (headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL, + if (headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL, (void **) &installedFiles, &installedFileCount)) { - compareFileList(0, NULL, installedFileCount, - installedFiles, ht); + headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, + (void **) &installedDirIndexes, NULL); + headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, + (void **) &installedDirs, NULL); + + compareFileList(0, NULL, NULL, NULL, installedFileCount, + installedFiles, installedDirs, + installedDirIndexes, ht); + free(installedFiles); + free(installedDirs); } } @@ -137,7 +159,7 @@ static int findPackagesWithObsoletes(rpmdb db, struct pkgSet *psp) continue; } - if (headerGetEntry((*pip)->h, RPMTAG_OBSOLETES, NULL, + if (headerGetEntryMinMemory((*pip)->h, RPMTAG_OBSOLETES, NULL, (void **) &obsoletes, &obsoletesCount)) { while (obsoletesCount--) { rc = rpmdbFindPackage(db, obsoletes[obsoletesCount], &matches); @@ -170,10 +192,12 @@ static int findUpgradePackages(rpmdb db, struct pkgSet *psp, { int skipThis; Header h, installedHeader; - char *name, *version, *release; + char *name; dbiIndexSet matches; int rc, i, count; char **installedFiles, **availFiles; + char **installedDirs, ** availDirs; + int_32 * installedDirIndexes, * availDirIndexes; int installedFileCount, availFileCount; struct packageInfo **pip; @@ -181,17 +205,15 @@ static int findUpgradePackages(rpmdb db, struct pkgSet *psp, pip = psp->packages; while (count--) { h = (*pip)->h; - name = version = release = NULL; + name = NULL; headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL); - headerGetEntry(h, RPMTAG_VERSION, NULL, (void **) &version, NULL); - headerGetEntry(h, RPMTAG_RELEASE, NULL, (void **) &release, NULL); - if (! (name && version && release)) { + if (!name) { /* bum header */ /*logMessage("Failed with bad header");*/ return(-1); } - DEBUG (("Avail: %s-%s-%s\n", name, version, release)); + DEBUG (("Avail: %s\n", name)); rc = rpmdbFindPackage(db, name, &matches); if (rc == 0) { @@ -224,34 +246,44 @@ static int findUpgradePackages(rpmdb db, struct pkgSet *psp, DEBUG (("UPGRADE\n")) (*pip)->selected = 1; - if (!headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL, + if (!headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL, (void **) &availFiles, &availFileCount)) { availFiles = NULL; availFileCount = 0; + } else { + headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, + (void **) &availDirs, NULL); + headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, + (void **) &availDirIndexes, NULL); } for (i = 0; i < matches.count; i++) { /* Compare the file lists */ installedHeader = rpmdbGetRecord(db, matches.recs[i].recOffset); - if (!headerGetEntry(installedHeader, RPMTAG_OLDFILENAMES, NULL, - (void **) &installedFiles, + if (headerGetEntryMinMemory(installedHeader, RPMTAG_BASENAMES, + NULL, (void **) &installedFiles, &installedFileCount)) { - installedFiles = NULL; - installedFileCount = 0; - } + headerGetEntryMinMemory(installedHeader, RPMTAG_DIRNAMES, + NULL, (void **) &installedDirs, NULL); + headerGetEntryMinMemory(installedHeader, RPMTAG_DIRINDEXES, + NULL, (void **) &installedDirIndexes, NULL); - compareFileList(availFileCount, availFiles, - installedFileCount, installedFiles, ht); + compareFileList(availFileCount, availFiles, + availDirs, availDirIndexes, + installedFileCount, installedFiles, + installedDirs, installedDirIndexes, + ht); - if (installedFiles) { free(installedFiles); + free(installedDirs); } headerFree(installedHeader); } if (availFiles) { free(availFiles); + free(availDirs); } } @@ -273,9 +305,9 @@ static int removeMovedFilesAlreadyHandled(struct pkgSet *psp, char *name; int i, count; Header h; - char **availFiles; + char **availFiles, ** availDirs; + int_32 * availDirIndexes; int availFileCount; - char *file; struct packageInfo **pip; count = psp->numPackages; @@ -286,21 +318,27 @@ static int removeMovedFilesAlreadyHandled(struct pkgSet *psp, name = NULL; headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL); - if (!headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL, + if (headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL, (void **) &availFiles, &availFileCount)) { - availFiles = NULL; - availFileCount = 0; - } - for (i = 0; i < availFileCount; i++) { - if ((file = htInTable(ht, availFiles[i]))) { - *file = '\0'; - DEBUG (("File already in %s: %s\n", name, availFiles[i])) - break; + headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, + (void **) &availDirs, NULL); + headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, + (void **) &availDirIndexes, NULL); + + for (i = 0; i < availFileCount; i++) { + if (htInTable(ht, availDirs[availDirIndexes[i]], + availFiles[i])) { + htRemoveFromTable(ht, availDirs[availDirIndexes[i]], + availFiles[i]); + DEBUG (("File already in %s: %s%s\n", name, + availDirs[availDirIndexes[i]], availFiles[i])) + break; + } } - } - if (availFiles) { + free(availFiles); + free(availDirs); } } @@ -316,9 +354,9 @@ static int findPackagesWithRelocatedFiles(struct pkgSet *psp, char *name; int i, count; Header h; - char **availFiles; + char **availFiles, **availDirs; + int_32 * availDirIndexes; int availFileCount; - char *file; struct packageInfo **pip; count = psp->numPackages; @@ -329,20 +367,26 @@ static int findPackagesWithRelocatedFiles(struct pkgSet *psp, name = NULL; headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL); - availFiles = NULL; - availFileCount = 0; - if (headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL, + if (headerGetEntry(h, RPMTAG_BASENAMES, NULL, (void **) &availFiles, &availFileCount)) { + headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, + (void **) &availDirs, NULL); + headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, + (void **) &availDirIndexes, NULL); + for (i = 0; i < availFileCount; i++) { - if ((file = htInTable(ht, availFiles[i]))) { - *file = '\0'; - DEBUG (("Found file in %s: %s\n", name, - availFiles[i])) + if (htInTable(ht, availDirs[availDirIndexes[i]], + availFiles[i])) { + htRemoveFromTable(ht, availDirs[availDirIndexes[i]], + availFiles[i]); + DEBUG (("Found file in %s: %s%s\n", name, + availDirs[availDirIndexes[i]], availFiles[i])) (*pip)->selected = 1; break; } } free(availFiles); + free(availDirs); } } @@ -375,7 +419,7 @@ static int unmarkPackagesAlreadyInstalled(rpmdb db, struct pkgSet *psp) { dbiIndexSet matches; Header h, installedHeader; - char *name, *version, *release; + char *name; struct packageInfo **pip; int count, rc, i; @@ -385,11 +429,9 @@ static int unmarkPackagesAlreadyInstalled(rpmdb db, struct pkgSet *psp) if ((*pip)->selected) { h = (*pip)->h; /* If this package is already installed, don't bother */ - name = version = release = NULL; + name = NULL; headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &name, NULL); - headerGetEntry(h, RPMTAG_VERSION, NULL, (void **) &version, NULL); - headerGetEntry(h, RPMTAG_RELEASE, NULL, (void **) &release, NULL); - if (! (name && version && release)) { + if (!name) { /* bum header */ /*logMessage("Failed with bad header");*/ return(-1); |