use fingerprinting for path lookups
CVS patchset: 2614 CVS date: 1998/12/26 17:13:34
This commit is contained in:
parent
a2c96ed1f5
commit
429557f9d6
72
lib/rpmdb.c
72
lib/rpmdb.c
|
@ -7,6 +7,7 @@
|
|||
#include "rpmlib.h"
|
||||
|
||||
#include "falloc.h"
|
||||
#include "fprint.h"
|
||||
#include "misc.h"
|
||||
#include "rpmdb.h"
|
||||
|
||||
|
@ -239,32 +240,13 @@ Header rpmdbGetRecord(rpmdb db, unsigned int offset) {
|
|||
|
||||
int rpmdbFindByFile(rpmdb db, char * filespec, dbiIndexSet * matches) {
|
||||
char * basename;
|
||||
fingerPrint fp1, fp2;
|
||||
dbiIndexSet allMatches;
|
||||
int rc;
|
||||
char * targPath, * possPath = NULL;
|
||||
int possPathAlloced = 0;
|
||||
int i, j;
|
||||
char ** fileList;
|
||||
int gotOne = 0;
|
||||
char * chptr1, * chptr2;
|
||||
int i, rc;
|
||||
Header h;
|
||||
struct stat sb1, sb2;
|
||||
char path[PATH_MAX];
|
||||
char ** fileList;
|
||||
|
||||
if (*filespec != '/') {
|
||||
/* Using realpath on the arg isn't correct if the arg is a symlink,
|
||||
* especially if the symlink is a dangling link. What we should
|
||||
* instead do is use realpath() on `.' and then append arg to
|
||||
* it.
|
||||
*/
|
||||
if (realpath(".", path) != NULL) {
|
||||
/* if the current directory doesn't exist, we might fail.
|
||||
oh well. likewise if it's too long. */
|
||||
chptr1 = alloca(strlen(path) + strlen(filespec) + 2);
|
||||
sprintf(chptr1, "%s/%s", path, filespec);
|
||||
filespec = chptr1;
|
||||
}
|
||||
}
|
||||
fp1 = fpLookup(filespec, 0);
|
||||
|
||||
basename = strrchr(filespec, '/');
|
||||
if (!basename)
|
||||
|
@ -275,46 +257,21 @@ int rpmdbFindByFile(rpmdb db, char * filespec, dbiIndexSet * matches) {
|
|||
rc = dbiSearchIndex(db->fileIndex, basename, &allMatches);
|
||||
if (rc) return rc;
|
||||
|
||||
/* This is pretty easy if both files are in the filesystem, as we can
|
||||
do a direct comparison of the dev/ino numbers of the "ideal" filespec.
|
||||
If that isn't the case, we need to walk through the paths, backwards,
|
||||
until we figure out whether or not these files would be the same
|
||||
or not <sigh>. Symbolic links are such a pain in the ass. */
|
||||
targPath = alloca(strlen(filespec) + 1);
|
||||
i = 0;
|
||||
*matches = dbiCreateIndexRecord();
|
||||
i = 0;
|
||||
while (i < allMatches.count) {
|
||||
if (!(h = rpmdbGetRecord(db, allMatches.recs[i].recOffset))) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
headerGetEntry(h, RPMTAG_FILENAMES, NULL, (void **) &fileList, NULL);
|
||||
|
||||
headerGetEntryMinMemory(h, RPMTAG_FILENAMES, NULL,
|
||||
(void **) &fileList, NULL);
|
||||
|
||||
do {
|
||||
strcpy(targPath, filespec);
|
||||
j = strlen(fileList[allMatches.recs[i].fileNumber]) + 1;
|
||||
if (j > possPathAlloced) {
|
||||
possPath = realloc(possPath, j);
|
||||
possPathAlloced = j;
|
||||
}
|
||||
strcpy(possPath, fileList[allMatches.recs[i].fileNumber]);
|
||||
|
||||
while (*targPath && *possPath) {
|
||||
if (!(chptr1 = strrchr(targPath, '/')) ||
|
||||
!(chptr2 = strrchr(possPath, '/')))
|
||||
break;
|
||||
|
||||
*chptr1 = *chptr2 = '\0';
|
||||
|
||||
/* as we're stating paths here, we want to follow symlinks */
|
||||
if (!stat(targPath, &sb1) && !stat(possPath, &sb2) &&
|
||||
sb1.st_ino == sb2.st_ino && sb1.st_dev == sb2.st_dev) {
|
||||
/* got a match */
|
||||
dbiAppendIndexRecord(matches, allMatches.recs[i]);
|
||||
gotOne = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fp2 = fpLookup(fileList[allMatches.recs[i].fileNumber], 1);
|
||||
if (FP_EQUAL(fp1, fp2))
|
||||
dbiAppendIndexRecord(matches, allMatches.recs[i]);
|
||||
|
||||
i++;
|
||||
} while ((i < allMatches.count) &&
|
||||
|
@ -322,13 +279,12 @@ int rpmdbFindByFile(rpmdb db, char * filespec, dbiIndexSet * matches) {
|
|||
allMatches.recs[i - 1].recOffset)));
|
||||
|
||||
free(fileList);
|
||||
|
||||
headerFree(h);
|
||||
}
|
||||
|
||||
if (possPath) free(possPath);
|
||||
dbiFreeIndexRecord(allMatches);
|
||||
|
||||
if (!gotOne) {
|
||||
if (!matches->count) {
|
||||
dbiFreeIndexRecord(*matches);
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue