added simple fingerprinting
CVS patchset: 2612 CVS date: 1998/12/26 17:12:50
This commit is contained in:
parent
29edbba1a8
commit
1319828529
|
@ -20,7 +20,7 @@ librpm_a_SOURCES = \
|
|||
messages.c misc.c oldheader.c package.c query.c \
|
||||
rebuilddb.c rpmdb.c rpmerr.c rpmio.c rpmlead.c \
|
||||
rpmrc.c signature.c stringbuf.c tagtable.c \
|
||||
tread.c uninstall.c verify.c transaction.c problems.c hash.c
|
||||
tread.c uninstall.c verify.c transaction.c problems.c hash.c fprint.c
|
||||
|
||||
include ../Makefile.inc
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include "system.h"
|
||||
|
||||
#include "rpmlib.h"
|
||||
|
||||
#include "fprint.h"
|
||||
|
||||
fingerPrint fpLookup(char * fullName, int scareMemory) {
|
||||
char dir[PATH_MAX];
|
||||
char * chptr1, * end;
|
||||
fingerPrint fp;
|
||||
struct stat sb;
|
||||
char * buf;
|
||||
|
||||
/* assert(*fullName == '/' || !scareMemory); */
|
||||
|
||||
/* FIXME: a directory stat cache could *really* speed things up. we'd
|
||||
have to be sure to flush it, but... */
|
||||
|
||||
if (*fullName != '/') {
|
||||
scareMemory = 0;
|
||||
|
||||
/* 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 the current directory doesn't exist, we might fail.
|
||||
oh well. likewise if it's too long. */
|
||||
if (realpath(".", dir) != NULL) {
|
||||
chptr1 = alloca(strlen(dir) + strlen(fullName) + 2);
|
||||
sprintf(chptr1, "%s/%s", dir, fullName);
|
||||
fullName = chptr1;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: perhaps we should collapse //, /./, and /../ stuff if
|
||||
!scareMemory?? */
|
||||
|
||||
buf = alloca(strlen(fullName) + 1);
|
||||
strcpy(buf, fullName);
|
||||
end = strrchr(buf, '/');
|
||||
while (*buf) {
|
||||
*end = '\0';
|
||||
|
||||
/* as we're stating paths here, we want to follow symlinks */
|
||||
if (!stat(buf, &sb)) {
|
||||
chptr1 = fullName + (end - buf) + 1;
|
||||
if (scareMemory)
|
||||
fp.basename = strdup(chptr1);
|
||||
else
|
||||
fp.basename = chptr1;
|
||||
fp.ino = sb.st_ino;
|
||||
fp.dev = sb.st_dev;
|
||||
return fp;
|
||||
}
|
||||
|
||||
buf--;
|
||||
while ((end > buf) && *end != '/') end--;
|
||||
}
|
||||
|
||||
/* this can't happen, or stat('/') just failed! */
|
||||
fp.basename = 0;
|
||||
fp.ino = fp.dev = 0;
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef H_FINGERPRINT
|
||||
#define H_FINGERPRINT
|
||||
|
||||
typedef struct fingerprint_s {
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
char * basename;
|
||||
} fingerPrint;
|
||||
|
||||
/* Be carefull with the memory... assert(*fullName == '/' || !scareMemory) */
|
||||
fingerPrint fpLookup(char * fullName, int scareMemory);
|
||||
|
||||
/* only if !scarceMemory */
|
||||
#define fpFree(a) free((a).basename)
|
||||
|
||||
#define FP_EQUAL(a, b) (((a).dev == (b).dev) && \
|
||||
((a).ino == (b).ino) && \
|
||||
!strcmp((a).basename, (b).basename))
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue