summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorewt <devnull@localhost>1999-10-06 22:52:12 +0000
committerewt <devnull@localhost>1999-10-06 22:52:12 +0000
commitc0f5d38f862c428849bf73e9242d475a33f08c31 (patch)
tree1c61f243c03b533dffedc73dfc3b00930fab29e5 /lib
parent360c32cb66543a85d9b3a2befc1e97f6af9e8ea1 (diff)
downloadrpm-c0f5d38f862c428849bf73e9242d475a33f08c31.tar.gz
rpm-c0f5d38f862c428849bf73e9242d475a33f08c31.tar.bz2
rpm-c0f5d38f862c428849bf73e9242d475a33f08c31.zip
updated for compressed file lists -- dep check should stay much smaller
now CVS patchset: 3375 CVS date: 1999/10/06 22:52:12
Diffstat (limited to 'lib')
-rw-r--r--lib/depends.c164
-rw-r--r--lib/depends.h18
2 files changed, 147 insertions, 35 deletions
diff --git a/lib/depends.c b/lib/depends.c
index a07dd1694..3cb5a6181 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -91,7 +91,9 @@ static void alCreate( /*@out@*/ struct availableList * al)
al->index.index = NULL;
al->index.size = 0;
- alFreeIndex(al);
+
+ al->numDirs = 0;
+ al->dirs = NULL;
}
static void alFree( /*@only@*/ struct availableList * al)
@@ -104,8 +106,8 @@ static void alFree( /*@only@*/ struct availableList * al)
free(al->list[i].provides);
if (al->list[i].providesEVR)
free(al->list[i].providesEVR);
- if (al->list[i].files)
- free(al->list[i].files);
+ if (al->list[i].baseFileNames)
+ free(al->list[i].baseFileNames);
headerFree(al->list[i].h);
if (al->list[i].relocs) {
@@ -117,12 +119,28 @@ static void alFree( /*@only@*/ struct availableList * al)
}
}
+ for (i = 0; i < al->numDirs; i++) {
+ free(al->dirs[i].dirName);
+ free(al->dirs[i].files);
+ }
+
+ if (al->numDirs)
+ free(al->dirs);
+ al->dirs = NULL;
+
if (al->alloced && al->list)
free(al->list);
al->list = NULL;
alFreeIndex(al);
}
+static int dirInfoCompare(const void * one, const void * two) {
+ const struct dirInfo * a = one;
+ const struct dirInfo * b = two;
+
+ return strcmp(a->dirName, b->dirName);
+}
+
static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList * al,
Header h, const void * key,
FD_t fd, rpmRelocation * relocs)
@@ -130,6 +148,14 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList
struct availablePackage * p;
rpmRelocation * r;
int i;
+ int_32 * fileDirIndex;
+ char ** dirList;
+ int numDirs, dirNum;
+ int * dirMapping;
+ struct dirInfo dirNeedle;
+ struct dirInfo * dirMatch;
+ int first, last, fileNum;
+ int origNumDirs;
if (al->size == al->alloced) {
al->alloced += 5;
@@ -159,19 +185,69 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList
p->provideFlags = NULL;
}
- if (!headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL, (void **) &p->files,
- &p->filesCount)) {
+ if (!headerGetEntryMinMemory(h, RPMTAG_COMPFILELIST, NULL, (void **)
+ &p->baseFileNames, &p->filesCount)) {
p->filesCount = 0;
- p->files = NULL;
- }
+ p->baseFileNames = NULL;
+ } else {
+ headerGetEntryMinMemory(h, RPMTAG_COMPDIRLIST, NULL, (void **)
+ &dirList, &numDirs);
+ headerGetEntryMinMemory(h, RPMTAG_COMPFILEDIRS, NULL, (void **)
+ &fileDirIndex, NULL);
+
+ /* XXX FIXME: We ought to relocate the directory list here */
+
+ dirMapping = alloca(sizeof(*dirMapping) * numDirs);
+
+ /* allocated enough space for all the directories we could possible
+ need to add */
+ al->dirs = xrealloc(al->dirs,
+ sizeof(*al->dirs) * (al->numDirs + numDirs));
+ origNumDirs = al->numDirs;
+
+ for (dirNum = 0; dirNum < numDirs; dirNum++) {
+ dirNeedle.dirName = dirList[dirNum];
+ dirMatch = bsearch(&dirNeedle, al->dirs, origNumDirs,
+ sizeof(dirNeedle), dirInfoCompare);
+ if (dirMatch) {
+ dirMapping[dirNum] = dirMatch - al->dirs;
+ } else {
+ al->dirs[al->numDirs].dirName = strdup(dirList[dirNum]);
+ al->dirs[al->numDirs].files = NULL;
+ al->dirs[al->numDirs].numFiles = 0;
+ al->dirs[al->numDirs].dirNum = al->numDirs;
+ dirMapping[dirNum] = al->numDirs;
+ al->numDirs++;
+ }
+ }
+
+ if (origNumDirs + al->numDirs)
+ qsort(al->dirs, al->numDirs, sizeof(dirNeedle), dirInfoCompare);
+
+ free(dirList);
+
+ first = 0;
+ while (first < p->filesCount) {
+ last = first;
+ while ((last + 1) < p->filesCount) {
+ if (fileDirIndex[first] != fileDirIndex[last + 1]) break;
+ last++;
+ }
+
+ dirMatch = al->dirs + dirMapping[fileDirIndex[first]];
+ dirMatch->files = xrealloc(dirMatch->files,
+ sizeof(*dirMatch->files) *
+ (dirMatch->numFiles + last - first + 1));
+ for (fileNum = first; fileNum <= last; fileNum++) {
+ dirMatch->files[dirMatch->numFiles].basename =
+ p->baseFileNames[fileNum];
+ dirMatch->files[dirMatch->numFiles].package = p;
+ dirMatch->numFiles++;
+ }
- /* We don't use these entries (and rpm >= 2 never have) and they are
- pretty misleading. Let's just get rid of them so they don't confuse
- anyone. */
- if (headerIsEntry(h, RPMTAG_FILEUSERNAME))
- headerRemoveEntry(h, RPMTAG_FILEUIDS);
- if (headerIsEntry(h, RPMTAG_FILEGROUPNAME))
- headerRemoveEntry(h, RPMTAG_FILEGIDS);
+ first = last + 1;
+ }
+ }
p->key = key;
p->fd = fd;
@@ -211,12 +287,8 @@ static void alMakeIndex(struct availableList * al)
if (ai->size) return;
ai->size = al->size;
- for (i = 0; i < al->size; i++) {
+ for (i = 0; i < al->size; i++)
ai->size += al->list[i].providesCount;
- }
- for (i = 0; i < al->size; i++) {
- ai->size += al->list[i].filesCount;
- }
if (ai->size) {
ai->index = xcalloc(ai->size, sizeof(*ai->index));
@@ -234,13 +306,6 @@ static void alMakeIndex(struct availableList * al)
ai->index[k].type = IET_PROVIDES;
k++;
}
-
- for (j = 0; j < al->list[i].filesCount; j++) {
- ai->index[k].package = al->list + i;
- ai->index[k].entry = al->list[i].files[j];
- ai->index[k].type = IET_FILE;
- k++;
- }
}
qsort(ai->index, ai->size, sizeof(*ai->index), indexcmp);
@@ -666,7 +731,41 @@ void rpmdepFreeConflicts(struct rpmDependencyConflict * conflicts, int
free(conflicts);
}
-static /*@exposed@*/ struct availablePackage * alSatisfiesDepend(struct availableList * al,
+static struct availablePackage * alFileSatisfiesDepend(
+ struct availableList * al, const char * keyType, const char *fileName) {
+ int i;
+ char * file = strdup(fileName);
+ char * chptr = strrchr(file, '/');
+ char * base;
+ struct dirInfo dirNeedle;
+ struct dirInfo * dirMatch;
+
+ chptr++;
+ *chptr = '\0';
+
+ dirNeedle.dirName = file;
+ dirMatch = bsearch(&dirNeedle, al->dirs, al->numDirs,
+ sizeof(dirNeedle), dirInfoCompare);
+ free(file);
+ if (!dirMatch) return NULL;
+
+ base = strrchr(fileName, '/') + 1;
+
+ /* XXX FIXME: these file lists should be sorted and bsearched */
+ for (i = 0; i < dirMatch->numFiles; i++) {
+ if (!strcmp(dirMatch->files[i].basename, base)) {
+ if (keyType)
+ rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by added file "
+ "list.\n"), keyType, file);
+ return dirMatch->files[i].package;
+ }
+ }
+
+ return NULL;
+}
+
+static /*@exposed@*/ struct availablePackage * alSatisfiesDepend(
+ struct availableList * al,
const char *keyType, const char *keyDepend,
const char * keyName, const char * keyEVR, int keyFlags)
{
@@ -674,6 +773,9 @@ static /*@exposed@*/ struct availablePackage * alSatisfiesDepend(struct availabl
struct availablePackage *p;
int i, rc;
+ if (*keyName == '/')
+ return alFileSatisfiesDepend(al, keyType, keyName);
+
if (!al->index.size) return NULL;
needle.entry = keyName;
@@ -709,13 +811,9 @@ static /*@exposed@*/ struct availablePackage * alSatisfiesDepend(struct availabl
if (rc) break;
}
if (keyType && keyDepend && rc)
- rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by added provide.\n"), keyType, keyDepend);
+ rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by added "
+ "provide.\n"), keyType, keyDepend);
break;
- case IET_FILE:
- rc = 1;
- if (keyType && keyDepend && rc)
- rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by added file list.\n"), keyType, keyDepend);
- break;
}
if (rc)
diff --git a/lib/depends.h b/lib/depends.h
index 786f4f915..347707b31 100644
--- a/lib/depends.h
+++ b/lib/depends.h
@@ -8,7 +8,7 @@ struct availablePackage {
const char ** provides;
const char ** providesEVR;
/*@dependent@*/ int * provideFlags;
- const char ** files;
+ const char ** baseFileNames;
/*@dependent@*/ const char * name;
/*@dependent@*/ const char * version;
/*@dependent@*/ const char * release;
@@ -19,7 +19,7 @@ struct availablePackage {
/*@dependent@*/ FD_t fd;
} ;
-enum indexEntryType { IET_NAME, IET_PROVIDES, IET_FILE };
+enum indexEntryType { IET_NAME, IET_PROVIDES };
struct availableIndexEntry {
/*@dependent@*/ struct availablePackage * package;
@@ -27,6 +27,18 @@ struct availableIndexEntry {
enum indexEntryType type;
} ;
+struct fileIndexEntry {
+ struct availablePackage * package;
+ const char * basename;
+} ;
+
+struct dirInfo {
+ char * dirName; /* strdup'd */
+ int dirNum;
+ struct fileIndexEntry * files; /* malloc'd */
+ int numFiles;
+} ;
+
struct availableIndex {
/*@null@*/ struct availableIndexEntry * index ;
int size;
@@ -36,6 +48,8 @@ struct availableList {
/*@owned@*/ /*@null@*/ struct availablePackage * list;
struct availableIndex index;
int size, alloced;
+ int numDirs;
+ struct dirInfo * dirs; /* malloc'd */
};
struct transactionElement {