14 #define _FPRINT_INTERNAL 26 fpc->ht =
htCreate(sizeHint * 2, 0, 1, NULL, NULL);
27 assert(fpc->ht != NULL);
33 cache->ht =
htFree(cache->ht);
51 if (
htGetEntry(cache->ht, dirName, &data, NULL, NULL))
53 return (
const struct fprintCacheEntry_s *) data[0];
65 const char *
dirName,
const char * baseName,
int scareMem)
70 const char * cleanDirName;
76 const struct fprintCacheEntry_s * cacheHit;
82 cdnl = strlen(cleanDirName);
84 if (*cleanDirName ==
'/') {
101 end = dir + strlen(dir);
102 if (end[-1] !=
'/') *end++ =
'/';
103 end =
stpncpy(end, cleanDirName,
sizeof(dir) - (end - dir));
106 end = dir + strlen(dir);
107 if (end[-1] !=
'/') *end++ =
'/';
117 if (cleanDirName == NULL)
return fp;
120 buf = strcpy((
char *)
alloca(cdnl + 1), cleanDirName);
124 if (buf[1] && end[-1] ==
'/') {
134 if (cacheHit != NULL) {
136 }
else if (!stat((*buf !=
'\0' ? buf :
"/"), &sb)) {
137 size_t nb =
sizeof(*fp.
entry) + (*buf !=
'\0' ? (end-buf) : 1) + 1;
138 char * dn = (
char *)
xmalloc(nb);
139 struct fprintCacheEntry_s * newEntry = (
struct fprintCacheEntry_s *)dn;
142 dn +=
sizeof(*newEntry);
143 strcpy(dn, (*buf !=
'\0' ? buf :
"/"));
144 newEntry->ino = (ino_t)sb.st_ino;
145 newEntry->dev = (dev_t)sb.st_dev;
146 newEntry->dirName = dn;
156 fp.
subDir = cleanDirName + (end - buf);
159 if (fp.
subDir[0] ==
'\0' ||
164 if (!scareMem && fp.
subDir != NULL)
176 while ((end > buf) && *end !=
'/') end--;
191 const char * baseName,
int scareMem)
193 return doLookup(cache, dirName, baseName, scareMem);
201 unsigned char ch =
'\0';
203 while (*chptr !=
'\0') ch ^= *chptr++;
205 h |= ((unsigned)ch) << 24;
206 h |= (((((unsigned)fp->
entry->dev) >> 8) ^ fp->
entry->dev) & 0xFF) << 16;
207 h |= fp->
entry->ino & 0xFFFF;
212 int fpEqual(
const void * key1,
const void * key2)
231 const char ** baseNames,
const rpmuint32_t * dirIndexes,
236 for (i = 0; i < (unsigned) fileCount; i++) {
239 if (i > 0 && dirIndexes[i - 1] == dirIndexes[i]) {
244 fpList[i] =
doLookup(cache, dirNames[dirIndexes[i]], baseNames[i],
263 HE_s he_s = { .
tag = 0, .t = 0, .p = &he_p, .c = 0, .freeData = 0 };
265 const char ** baseNames;
266 const char ** dirNames;
273 baseNames = he_p.
argv;
280 dirNames = he_p.
argv;
283 dirIndexes = he_p.
ui32p;
285 fpLookupList(cache, dirNames, baseNames, dirIndexes, fileCount, fpList);
287 dirIndexes =
_free(dirIndexes);
288 dirNames =
_free(dirNames);
289 baseNames =
_free(baseNames);
294 #define _RPMFI_INTERNAL 296 #define _RPMTE_INTERNAL 300 void * _p,
int filenr)
308 int symlinkcount = 0;
316 struct rpmffi_s * ffi = (
struct rpmffi_s *)
xmalloc(
sizeof(*ffi));
318 ffi->fileno = filenr;
322 if (cfp->subDir == NULL)
328 cfp->subDir = t = NULL;
331 while (*te !=
'/' && te < se)
336 struct rpmffi_s **
recs;
342 (void)
htGetEntry(symlinks, cfp, &recs, &numRecs, NULL);
344 for (i = 0; i < numRecs; i++) {
349 fx = recs[i]->fileno;
351 flink = fi->flinks[fx];
352 if (!(flink && *flink !=
'\0'))
358 link =
rpmGetPath(flink,
"/", te+1,
"/", NULL);
359 else if (cfp->subDir == NULL)
361 flink,
"/", te+1,
"/", NULL);
363 link =
rpmGetPath(cfp->entry->dirName,
"/", cfp->subDir,
"/",
364 flink,
"/", te+1,
"/", NULL);
367 assert(link[strlen(link)-1] ==
'/');
375 if (++symlinkcount > 50)
380 if (cfp->subDir == NULL)
385 cfp->baseName = t + 1;
389 while (*te !=
'\0' && *te !=
'/')
fingerPrint fpLookup(fingerPrintCache cache, const char *dirName, const char *baseName, int scareMem)
Return finger print of a file path.
static fingerPrint doLookup(fingerPrintCache cache, const char *dirName, const char *baseName, int scareMem)
Return finger print of a file path.
Structures used for an "rpmte" transaction element.
char * xstrdup(const char *str)
char * rpmCleanPath(char *path)
Canonicalize file path.
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
Structure(s) used for file info tag sets.
rpmuint32_t fpHashFunction(rpmuint32_t h, const void *data, size_t size)
fingerPrintCache fpCacheFree(fingerPrintCache cache)
Destroy finger print cache.
struct rpmte_s * rpmte
An element of a transaction set, i.e.
int htGetEntry(hashTable ht, const void *key, const void *data, int *dataCount, const void *tableKey)
Retrieve item from hash table.
static const struct fprintCacheEntry_s * cacheContainsDirectory(fingerPrintCache cache, const char *dirName)
Find directory name entry in cache.
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
char * stpncpy(char *dest, const char *src, size_t n)
hashTable htFree(hashTable ht)
Destroy hash table.
void fpLookupList(fingerPrintCache cache, const char **dirNames, const char **baseNames, const rpmuint32_t *dirIndexes, rpmuint32_t fileCount, fingerPrint *fpList)
Return finger prints of an array of file paths.
int fpEqual(const void *key1, const void *key2)
Compare two finger print entries.
Identify a file name path by a unique "finger print".
Associates a trailing sub-directory and final base name with an existing directory finger print...
static const char * dirName
void htAddEntry(hashTable ht, const void *key, const void *data)
Add item to hash table.
const struct fprintCacheEntry_s * entry
struct fprintCache_s * fingerPrintCache
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
void fpLookupSubdir(hashTable symlinks, hashTable fphash, fingerPrintCache fpc, void *_p, int filenr)
Check file for to be installed symlinks in their path, correct their fingerprint and add it to newht...
Access RPM indices using Berkeley DB interface(s).
hashTable htCreate(int numBuckets, size_t keySize, int freeData, hashFunctionType fn, hashEqualityType eq)
Create hash table.
char * Realpath(const char *path, char *resolved_path)
realpath(3) clone.
fingerPrintCache fpCacheCreate(int sizeHint)
Create finger print cache.