fprint.c | fprint.c | |||
---|---|---|---|---|
skipping to change at line 25 | skipping to change at line 25 | |||
#include "fprint.h" | #include "fprint.h" | |||
#include "debug.h" | #include "debug.h" | |||
/*@access hashTable @*/ | /*@access hashTable @*/ | |||
fingerPrintCache fpCacheCreate(int sizeHint) | fingerPrintCache fpCacheCreate(int sizeHint) | |||
{ | { | |||
fingerPrintCache fpc; | fingerPrintCache fpc; | |||
fpc = xmalloc(sizeof(*fpc)); | fpc = (fingerPrintCache) xmalloc(sizeof(*fpc)); | |||
fpc->ht = htCreate(sizeHint * 2, 0, 1, NULL, NULL); | fpc->ht = htCreate(sizeHint * 2, 0, 1, NULL, NULL); | |||
assert(fpc->ht != NULL); | assert(fpc->ht != NULL); | |||
return fpc; | return fpc; | |||
} | } | |||
fingerPrintCache fpCacheFree(fingerPrintCache cache) | fingerPrintCache fpCacheFree(fingerPrintCache cache) | |||
{ | { | |||
cache->ht = htFree(cache->ht); | cache->ht = htFree(cache->ht); | |||
free(cache); | free(cache); | |||
return NULL; | return NULL; | |||
skipping to change at line 53 | skipping to change at line 53 | |||
*/ | */ | |||
static /*@null@*/ const struct fprintCacheEntry_s * cacheContainsDirectory( | static /*@null@*/ const struct fprintCacheEntry_s * cacheContainsDirectory( | |||
fingerPrintCache cache, | fingerPrintCache cache, | |||
const char * dirName) | const char * dirName) | |||
/*@*/ | /*@*/ | |||
{ | { | |||
const void ** data; | const void ** data; | |||
if (htGetEntry(cache->ht, dirName, &data, NULL, NULL)) | if (htGetEntry(cache->ht, dirName, &data, NULL, NULL)) | |||
return NULL; | return NULL; | |||
return data[0]; | return (const struct fprintCacheEntry_s *) data[0]; | |||
} | } | |||
/** | /** | |||
* Return finger print of a file path. | * Return finger print of a file path. | |||
* @param cache pointer to fingerprint cache | * @param cache pointer to fingerprint cache | |||
* @param dirName leading directory name of path | * @param dirName leading directory name of path | |||
* @param baseName file name of path | * @param baseName file name of path | |||
* @param scareMem | * @param scareMem | |||
* @return pointer to the finger print associated with a file path. | * @return pointer to the finger print associated with a file path. | |||
*/ | */ | |||
skipping to change at line 87 | skipping to change at line 87 | |||
/* assert(*dirName == '/' || !scareMem); */ | /* assert(*dirName == '/' || !scareMem); */ | |||
/* XXX WATCHOUT: fp.subDir is set below from relocated dirName arg */ | /* XXX WATCHOUT: fp.subDir is set below from relocated dirName arg */ | |||
cleanDirName = dirName; | cleanDirName = dirName; | |||
cdnl = strlen(cleanDirName); | cdnl = strlen(cleanDirName); | |||
if (*cleanDirName == '/') { | if (*cleanDirName == '/') { | |||
if (!scareMem) | if (!scareMem) | |||
cleanDirName = | cleanDirName = | |||
rpmCleanPath(strcpy(alloca(cdnl+1), dirName)); | rpmCleanPath(strcpy((char *)alloca(cdnl+1), dirName)); | |||
} else { | } else { | |||
scareMem = 0; /* XXX causes memory leak */ | scareMem = 0; /* XXX causes memory leak */ | |||
/* Using realpath on the arg isn't correct if the arg is a symlink, | /* Using realpath on the arg isn't correct if the arg is a symlink, | |||
* especially if the symlink is a dangling link. What we | * especially if the symlink is a dangling link. What we | |||
* do instead is use realpath() on `.' and then append arg to | * do instead is use realpath() on `.' and then append arg to | |||
* the result. | * the result. | |||
*/ | */ | |||
/* if the current directory doesn't exist, we might fail. | /* if the current directory doesn't exist, we might fail. | |||
skipping to change at line 120 | skipping to change at line 120 | |||
cdnl = end - dir; | cdnl = end - dir; | |||
} | } | |||
} | } | |||
fp.entry = NULL; | fp.entry = NULL; | |||
fp.subDir = NULL; | fp.subDir = NULL; | |||
fp.baseName = NULL; | fp.baseName = NULL; | |||
/*@-nullret@*/ | /*@-nullret@*/ | |||
if (cleanDirName == NULL) return fp; /* XXX can't happen */ | if (cleanDirName == NULL) return fp; /* XXX can't happen */ | |||
/*@=nullret@*/ | /*@=nullret@*/ | |||
buf = strcpy(alloca(cdnl + 1), cleanDirName); | buf = strcpy((char *)alloca(cdnl + 1), cleanDirName); | |||
end = buf + cdnl; | end = buf + cdnl; | |||
/* no need to pay attention to that extra little / at the end of dirNam e */ | /* no need to pay attention to that extra little / at the end of dirNam e */ | |||
if (buf[1] && end[-1] == '/') { | if (buf[1] && end[-1] == '/') { | |||
end--; | end--; | |||
*end = '\0'; | *end = '\0'; | |||
} | } | |||
while (1) { | while (1) { | |||
/* as we're stating paths here, we want to follow symlinks */ | /* as we're stating paths here, we want to follow symlinks */ | |||
cacheHit = cacheContainsDirectory(cache, (*buf != '\0' ? buf : "/")) ; | cacheHit = cacheContainsDirectory(cache, (*buf != '\0' ? buf : "/")) ; | |||
if (cacheHit != NULL) { | if (cacheHit != NULL) { | |||
fp.entry = cacheHit; | fp.entry = cacheHit; | |||
} else if (!stat((*buf != '\0' ? buf : "/"), &sb)) { | } else if (!stat((*buf != '\0' ? buf : "/"), &sb)) { | |||
size_t nb = sizeof(*fp.entry) + (*buf != '\0' ? (end-buf) : 1) + 1; | size_t nb = sizeof(*fp.entry) + (*buf != '\0' ? (end-buf) : 1) + 1; | |||
char * dn = xmalloc(nb); | char * dn = (char *) xmalloc(nb); | |||
struct fprintCacheEntry_s * newEntry = (void *)dn; | struct fprintCacheEntry_s * newEntry = (struct fprintCacheEntry_ | |||
s *)dn; | ||||
/*@-usereleased@*/ /* LCL: contiguous malloc confusion */ | /*@-usereleased@*/ /* LCL: contiguous malloc confusion */ | |||
dn += sizeof(*newEntry); | dn += sizeof(*newEntry); | |||
strcpy(dn, (*buf != '\0' ? buf : "/")); | strcpy(dn, (*buf != '\0' ? buf : "/")); | |||
newEntry->ino = (ino_t)sb.st_ino; | newEntry->ino = (ino_t)sb.st_ino; | |||
newEntry->dev = (dev_t)sb.st_dev; | newEntry->dev = (dev_t)sb.st_dev; | |||
newEntry->dirName = dn; | newEntry->dirName = dn; | |||
fp.entry = newEntry; | fp.entry = newEntry; | |||
/*@-kepttrans -dependenttrans @*/ | /*@-kepttrans -dependenttrans @*/ | |||
skipping to change at line 199 | skipping to change at line 199 | |||
fingerPrint fpLookup(fingerPrintCache cache, const char * dirName, | fingerPrint fpLookup(fingerPrintCache cache, const char * dirName, | |||
const char * baseName, int scareMem) | const char * baseName, int scareMem) | |||
{ | { | |||
return doLookup(cache, dirName, baseName, scareMem); | return doLookup(cache, dirName, baseName, scareMem); | |||
} | } | |||
rpmuint32_t fpHashFunction(rpmuint32_t h, const void * data, | rpmuint32_t fpHashFunction(rpmuint32_t h, const void * data, | |||
/*@unused@*/ size_t size) | /*@unused@*/ size_t size) | |||
{ | { | |||
const fingerPrint * fp = data; | const fingerPrint * fp = (fingerPrint *) data; | |||
const char * chptr = fp->baseName; | const char * chptr = fp->baseName; | |||
unsigned char ch = '\0'; | unsigned char ch = '\0'; | |||
while (*chptr != '\0') ch ^= *chptr++; | while (*chptr != '\0') ch ^= *chptr++; | |||
h |= ((unsigned)ch) << 24; | h |= ((unsigned)ch) << 24; | |||
h |= (((((unsigned)fp->entry->dev) >> 8) ^ fp->entry->dev) & 0xFF) << 1 6; | h |= (((((unsigned)fp->entry->dev) >> 8) ^ fp->entry->dev) & 0xFF) << 1 6; | |||
h |= fp->entry->ino & 0xFFFF; | h |= fp->entry->ino & 0xFFFF; | |||
return h; | return h; | |||
} | } | |||
int fpEqual(const void * key1, const void * key2) | int fpEqual(const void * key1, const void * key2) | |||
{ | { | |||
const fingerPrint *k1 = key1; | const fingerPrint *k1 = (fingerPrint *) key1; | |||
const fingerPrint *k2 = key2; | const fingerPrint *k2 = (fingerPrint *) key2; | |||
/* If the addresses are the same, so are the values. */ | /* If the addresses are the same, so are the values. */ | |||
if (k1 == k2) | if (k1 == k2) | |||
return 0; | return 0; | |||
/* Otherwise, compare fingerprints by value. */ | /* Otherwise, compare fingerprints by value. */ | |||
/*@-nullpass@*/ /* LCL: whines about (*k2).subdir */ | /*@-nullpass@*/ /* LCL: whines about (*k2).subdir */ | |||
if (FP_EQUAL(*k1, *k2)) | if (FP_EQUAL(*k1, *k2)) | |||
return 0; | return 0; | |||
/*@=nullpass@*/ | /*@=nullpass@*/ | |||
skipping to change at line 302 | skipping to change at line 302 | |||
/* XXX fpLookupSubdir should be moved to lib/rpmfi.c somewhen. */ | /* XXX fpLookupSubdir should be moved to lib/rpmfi.c somewhen. */ | |||
#define _RPMFI_INTERNAL | #define _RPMFI_INTERNAL | |||
#include "rpmfi.h" | #include "rpmfi.h" | |||
#define _RPMTE_INTERNAL | #define _RPMTE_INTERNAL | |||
#include "rpmte.h" | #include "rpmte.h" | |||
void fpLookupSubdir(hashTable symlinks, hashTable fphash, fingerPrintCache fpc, | void fpLookupSubdir(hashTable symlinks, hashTable fphash, fingerPrintCache fpc, | |||
void * _p, int filenr) | void * _p, int filenr) | |||
{ | { | |||
rpmte p = _p; | rpmte p = (rpmte) _p; | |||
rpmfi fi = p->fi; | rpmfi fi = p->fi; | |||
fingerPrint *const fps = fi->fps + filenr; | fingerPrint *const fps = fi->fps + filenr; | |||
struct fingerPrint_s current_fp; | struct fingerPrint_s current_fp; | |||
fingerPrint * cfp = ¤t_fp; | fingerPrint * cfp = ¤t_fp; | |||
int symlinkcount = 0; | int symlinkcount = 0; | |||
const char * s; | const char * s; | |||
const char * se; | const char * se; | |||
size_t ns; | size_t ns; | |||
char * t; | char * t; | |||
char * te; | char * te; | |||
struct rpmffi_s * ffi = xmalloc(sizeof(*ffi)); | struct rpmffi_s * ffi = (struct rpmffi_s *) xmalloc(sizeof(*ffi)); | |||
ffi->p = p; | ffi->p = p; | |||
ffi->fileno = filenr; | ffi->fileno = filenr; | |||
restart: | restart: | |||
*cfp = *fps; | *cfp = *fps; | |||
if (cfp->subDir == NULL) | if (cfp->subDir == NULL) | |||
goto exit; | goto exit; | |||
s = cfp->baseName = te = xstrdup(cfp->subDir); | s = cfp->baseName = te = xstrdup(cfp->subDir); | |||
ns = strlen(s); | ns = strlen(s); | |||
End of changes. 9 change blocks. | ||||
11 lines changed or deleted | 12 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |