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 \
|
messages.c misc.c oldheader.c package.c query.c \
|
||||||
rebuilddb.c rpmdb.c rpmerr.c rpmio.c rpmlead.c \
|
rebuilddb.c rpmdb.c rpmerr.c rpmio.c rpmlead.c \
|
||||||
rpmrc.c signature.c stringbuf.c tagtable.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
|
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