added simple fingerprinting
authorewt <devnull@localhost>
Sat, 26 Dec 1998 17:12:50 +0000 (17:12 +0000)
committerewt <devnull@localhost>
Sat, 26 Dec 1998 17:12:50 +0000 (17:12 +0000)
CVS patchset: 2612
CVS date: 1998/12/26 17:12:50

lib/Makefile.am
lib/fprint.c [new file with mode: 0644]
lib/fprint.h [new file with mode: 0644]

index 1f805ab..5749c34 100644 (file)
@@ -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
 
diff --git a/lib/fprint.c b/lib/fprint.c
new file mode 100644 (file)
index 0000000..375e9dd
--- /dev/null
@@ -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;
+}
+
diff --git a/lib/fprint.h b/lib/fprint.h
new file mode 100644 (file)
index 0000000..f17ecc1
--- /dev/null
@@ -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