- rpm database has rpm.rpm g+w permissions to share db3 mutexes.
authorjbj <devnull@localhost>
Fri, 11 May 2001 04:01:04 +0000 (04:01 +0000)
committerjbj <devnull@localhost>
Fri, 11 May 2001 04:01:04 +0000 (04:01 +0000)
- expose more db3 macro configuration tokens.
- move fprint.[ch] and hash.[ch] to rpmdb directory.
- detect and fiddle incompatible mixtures of db3 env/open flags.
- add DBI_WRITECURSOR to map to db3 flags with CDB database model.
- add rpmdbSetIteratorRewrite to warn of pending lazy (re-)writes.

CVS patchset: 4765
CVS date: 2001/05/11 04:01:04

29 files changed:
CHANGES
Doxyfile.in
Makefile.am
db/os/os_map.c
db3/configure
lib/Makefile.am
lib/depends.c
lib/fprint.c [deleted file]
lib/fprint.h [deleted file]
lib/hash.c [deleted file]
lib/hash.h [deleted file]
lib/psm.c
lib/query.c
lib/rpmlib.h
lib/transaction.c
perl/Makefile.in
po/POTFILES.in
rpm.spec.in
rpmdb/Makefile.am
rpmdb/db1.c
rpmdb/db2.c
rpmdb/db3.c
rpmdb/dbconfig.c
rpmdb/falloc.c
rpmdb/falloc.h
rpmdb/rpmdb.c
rpmdb/rpmdb.h
rpmio/rpmerr.h
rpmio/rpmmacro.h

diff --git a/CHANGES b/CHANGES
index 37a09fe..9a4c034 100644 (file)
--- a/CHANGES
+++ b/CHANGES
        - use internal db-3.2.9 sources to build by default.
        - don't build db1 support by default.
        - create rpmdb.la so that linkage against rpm's db-3.2.9 is possible.
-       - rpm executables now setuid rpm to share write locks.
+       - rpm database has rpm.rpm g+w permissions to share db3 mutexes.
        - expose more db3 macro configuration tokens.
+       - move fprint.[ch] and hash.[ch] to rpmdb directory.
+       - detect and fiddle incompatible mixtures of db3 env/open flags.
+       - add DBI_WRITECURSOR to map to db3 flags with CDB database model.
+       - add rpmdbSetIteratorRewrite to warn of pending lazy (re-)writes.
 
 4.0 -> 4.0.[12]
        - add doxygen and lclint annotations most everywhere.
index 2e4cbf0..8240872 100644 (file)
@@ -356,13 +356,9 @@ INPUT                  = \
        ./lib/depends.c \
        ./lib/depends.h \
        ./lib/formats.c \
-       ./lib/fprint.c \
-       ./lib/fprint.h \
        ./lib/fs.c \
        ./lib/fsm.c \
        ./lib/fsm.h \
-       ./lib/hash.c \
-       ./lib/hash.h \
        ./lib/header.c \
        ./lib/header.h \
        ./lib/manifest.c \
@@ -400,6 +396,10 @@ INPUT                  = \
        ./rpmdb/dbconfig.c \
        ./rpmdb/falloc.c \
        ./rpmdb/falloc.h \
+       ./rpmdb/fprint.c \
+       ./rpmdb/fprint.h \
+       ./rpmdb/rpmhash.c \
+       ./rpmdb/rpmhash.h \
        ./rpmdb/rpmdb.c \
        ./rpmdb/rpmdb.h \
        ./rpmio/base64.c \
index 1a47937..8d3978c 100644 (file)
@@ -180,6 +180,19 @@ setperms:
        done
        @$(__CHOWN) ${RPMUSER}.${RPMGROUP} $(DESTDIR)$(pkglibdir)
        @$(__CHOWN) -R ${RPMUSER}.${RPMGROUP} $(DESTDIR)$(varprefix)/lib/rpm
+       -@$(__CHMOD) 0664 $(DESTDIR)$(varprefix)/lib/rpm/[A-Z]*
+       -@$(__CHMOD) 0775 $(DESTDIR)$(varprefix)/lib/rpm
+       -@$(__CHMOD) 0755 $(DESTDIR)$(varprefix)/lib/rpm/Desktop
+       -@$(__CHMOD) 0664 $(DESTDIR)$(varprefix)/lib/rpm/__db.*
+
+.PHONY:        unsetuid
+unsetuid:
+       @for f in $(rpmbin_PROGRAMS) ; do\
+           $(__CHMOD) u-s $(DESTDIR)$(rpmbindir)/$$f ;\
+       done
+       @for f in $(pkglib_PROGRAMS) ; do\
+           $(__CHMOD) u-s $(DESTDIR)$(pkglibdir)/$$f ;\
+       done
 
 .PHONY: tar
 tar:
index bb96a91..590ebc5 100644 (file)
@@ -110,7 +110,7 @@ __os_r_sysattach(dbenv, infop, rp)
                                }
                        }
                        if ((id =
-                           shmget(segid, rp->size, IPC_CREAT | 0600)) == -1) {
+                           shmget(segid, rp->size, IPC_CREAT | 0660)) == -1) {
                                ret = __os_get_errno();
                                __db_err(dbenv,
        "shmget: key: %ld: unable to create shared system memory region: %s",
index 16f8f8e..3128c6f 100755 (executable)
@@ -1,11 +1,13 @@
 #!/bin/sh
 #set -x 
 db_dist="../db/dist"
-CFLAGS="$CFLAGS" $db_dist/configure \
-       $(echo $* | sed -e "s% --srcdir=[^ ]*% --enable-shared --enable-static --srcdir=$db_dist%")
+
+rm -f config.cache
+CFALGS="-O2" $db_dist/configure \
+       $(echo $* | sed -e "s% --cache-file=.*$% --enable-shared --enable-static --enable-debug --enable-rpc --srcdir=$db_dist%")
 
 mv Makefile Makefile.orig
-cat Makefile.orig | sed -e '/^install:/c\
+cat Makefile.orig | sed -e 's/ -g$/ -g -O2/' -e '/^install:/c\
 .PHONY: listobjs\
 listobjs:\
        @echo $(OBJS)\
@@ -13,5 +15,3 @@ listobjs:\
 distdir install:\
 \
 db3_install: all install_setip \\' > Makefile
-
-make -s listobjs > db3lobjs
index a1b4974..7a112e6 100644 (file)
@@ -16,7 +16,7 @@ pkgincdir = $(pkgincludedir)
 pkginc_HEADERS = \
        header.h misc.h rpmlib.h stringbuf.h
 noinst_HEADERS = \
-       cpio.h depends.h fprint.h fsm.h hash.h \
+       cpio.h depends.h fsm.h \
        manifest.h md5.h psm.h \
        rpmlead.h signature.h
 
@@ -31,8 +31,8 @@ LIBS =
 
 lib_LTLIBRARIES = librpm.la
 librpm_la_SOURCES = \
-       cpio.c depends.c formats.c fprint.c fs.c fsm.c getdate.c \
-       hash.c header.c manifest.c md5.c md5sum.c misc.c package.c \
+       cpio.c depends.c formats.c fs.c fsm.c getdate.c \
+       header.c manifest.c md5.c md5sum.c misc.c package.c \
        problems.c poptBT.c poptQV.c psm.c query.c rpmchecksig.c \
        rpminstall.c rpmlead.c rpmlibprov.c rpmrc.c signature.c \
        stringbuf.c tagName.c tagtable.c transaction.c verify.c
index 437e784..477837e 100644 (file)
@@ -1191,7 +1191,7 @@ exit:
        } else {
            DBC * dbcursor = NULL;
            int xx;
-           xx = dbiCopen(dbi, &dbcursor, 0);
+           xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
            xx = dbiPut(dbi, dbcursor, keyDepend, strlen(keyDepend), &rc, sizeof(rc), 0);
            if (xx)
                _cacheDependsRC = 0;
@@ -1199,7 +1199,7 @@ exit:
            else
                rpmMessage(RPMMESS_DEBUG, _("%s: (%s, %s) added to Depends cache.\n"), keyType, keyDepend, (rc ? _("NO ") : _("YES")));
 #endif
-           xx = dbiCclose(dbi, dbcursor, 0);
+           xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
        }
     }
     return rc;
diff --git a/lib/fprint.c b/lib/fprint.c
deleted file mode 100644 (file)
index 1a9e4c8..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * \file lib/fprint.c
- */
-
-#include "system.h"
-#include <rpmlib.h>
-#include <rpmmacro.h>  /* XXX for rpmCleanPath */
-
-#include "fprint.h"
-#include "debug.h"
-
-fingerPrintCache fpCacheCreate(int sizeHint)
-{
-    fingerPrintCache fpc;
-
-    fpc = xmalloc(sizeof(*fpc));
-    fpc->ht = htCreate(sizeHint * 2, 0, 1, hashFunctionString,
-                      hashEqualityString);
-    return fpc;
-}
-
-void fpCacheFree(fingerPrintCache cache)
-{
-    htFree(cache->ht);
-    free(cache);
-}
-
-/**
- * Find directory name entry in cache.
- * @param cache                pointer to fingerprint cache
- * @param dirName      string to locate in cache
- * @return pointer to directory name entry (or NULL if not found).
- */
-static const struct fprintCacheEntry_s * cacheContainsDirectory(
-                           fingerPrintCache cache,
-                           const char * dirName)
-{
-    const void ** data;
-
-    if (htGetEntry(cache->ht, dirName, &data, NULL, NULL))
-       return NULL;
-    return data[0];
-}
-
-/**
- * Return finger print of a file path.
- * @param cache                pointer to fingerprint cache
- * @param dirName      leading directory name of path
- * @param baseName     file name of path
- * @param scareMemory
- * @return pointer to the finger print associated with a file path.
- */
-static fingerPrint doLookup(fingerPrintCache cache,
-       const char * dirName, const char * baseName, int scareMemory)
-{
-    char dir[PATH_MAX];
-    const char * cleanDirName;
-    size_t cdnl;
-    char * end;                    /* points to the '\0' at the end of "buf" */
-    fingerPrint fp;
-    struct stat sb;
-    char * buf;
-    const struct fprintCacheEntry_s * cacheHit;
-
-    /* assert(*dirName == '/' || !scareMemory); */
-
-    /* XXX WATCHOUT: fp.subDir is set below from relocated dirName arg */
-    cleanDirName = dirName;
-    cdnl = strlen(cleanDirName);
-
-    if (*cleanDirName == '/') {
-       if (!scareMemory)
-           cleanDirName =
-               rpmCleanPath(strcpy(alloca(cdnl+1), dirName));
-    } else {
-       scareMemory = 0;        /* XXX causes memory leak */
-
-       /* Using realpath on the arg isn't correct if the arg is a symlink,
-        * especially if the symlink is a dangling link.  What we 
-        * do instead is use realpath() on `.' and then append arg to
-        * the result.
-        */
-
-       /* if the current directory doesn't exist, we might fail. 
-          oh well. likewise if it's too long.  */
-       dir[0] = '\0';
-       if ( /*@-unrecog@*/ realpath(".", dir) /*@=unrecog@*/ != NULL) {
-           end = dir + strlen(dir);
-           if (end[-1] != '/') *end++ = '/';
-           end = stpncpy(end, cleanDirName, sizeof(dir) - (end - dir));
-           *end = '\0';
-           (void)rpmCleanPath(dir); /* XXX possible /../ from concatenation */
-           end = dir + strlen(dir);
-           if (end[-1] != '/') *end++ = '/';
-           *end = '\0';
-           cleanDirName = dir;
-           cdnl = end - dir;
-       }
-    }
-    fp.entry = NULL;
-    fp.subDir = NULL;
-    fp.baseName = NULL;
-    if (cleanDirName == NULL) return fp;       /* XXX can't happen */
-
-    buf = strcpy(alloca(cdnl + 1), cleanDirName);
-    end = buf + cdnl;
-
-    /* no need to pay attention to that extra little / at the end of dirName */
-    if (buf[1] && end[-1] == '/') {
-       end--;
-       *end = '\0';
-    }
-
-    while (1) {
-
-       /* as we're stating paths here, we want to follow symlinks */
-
-       cacheHit = cacheContainsDirectory(cache, (*buf != '\0' ? buf : "/"));
-       if (cacheHit != NULL) {
-           fp.entry = cacheHit;
-       } else if (!stat((*buf != '\0' ? buf : "/"), &sb)) {
-           size_t nb = sizeof(*fp.entry) + (*buf != '\0' ? (end-buf) : 1) + 1;
-           char * dn = xmalloc(nb);
-           struct fprintCacheEntry_s * newEntry = (void *)dn;
-
-           dn += sizeof(*newEntry);
-           strcpy(dn, (*buf != '\0' ? buf : "/"));
-           newEntry->ino = sb.st_ino;
-           newEntry->dev = sb.st_dev;
-           newEntry->isFake = 0;
-           newEntry->dirName = dn;
-           fp.entry = newEntry;
-
-           /*@-kepttrans@*/
-           htAddEntry(cache->ht, dn, fp.entry);
-           /*@@kepttrans@*/
-       }
-
-        if (fp.entry) {
-           fp.subDir = cleanDirName + (end - buf);
-           if (fp.subDir[0] == '/' && fp.subDir[1] != '\0')
-               fp.subDir++;
-           if (fp.subDir[0] == '\0' ||
-           /* XXX don't bother saving '/' as subdir */
-              (fp.subDir[0] == '/' && fp.subDir[1] == '\0'))
-               fp.subDir = NULL;
-           fp.baseName = baseName;
-           if (!scareMemory && fp.subDir != NULL)
-               fp.subDir = xstrdup(fp.subDir);
-           return fp;
-       }
-
-        /* stat of '/' just failed! */
-       if (end == buf + 1)
-           abort();
-
-       end--;
-       while ((end > buf) && *end != '/') end--;
-       if (end == buf)     /* back to stat'ing just '/' */
-           end++;
-
-       *end = '\0';
-    }
-
-    /*@notreached@*/
-
-    /*@-nullret@*/ return fp; /*@=nullret@*/   /* LCL: can't happen. */
-}
-
-fingerPrint fpLookup(fingerPrintCache cache, const char * dirName, 
-                       const char * baseName, int scareMemory)
-{
-    return doLookup(cache, dirName, baseName, scareMemory);
-}
-
-unsigned int fpHashFunction(const void * key)
-{
-    const fingerPrint * fp = key;
-    unsigned int hash = 0;
-    char ch;
-    const char * chptr;
-
-    ch = 0;
-    chptr = fp->baseName;
-    while (*chptr != '\0') ch ^= *chptr++;
-
-    hash |= ((unsigned)ch) << 24;
-    hash |= (((((unsigned)fp->entry->dev) >> 8) ^ fp->entry->dev) & 0xFF) << 16;
-    hash |= fp->entry->ino & 0xFFFF;
-    
-    return hash;
-}
-
-int fpEqual(const void * key1, const void * key2)
-{
-    const fingerPrint *k1 = key1;
-    const fingerPrint *k2 = key2;
-
-    /* If the addresses are the same, so are the values. */
-    if (k1 == k2)
-       return 0;
-
-    /* Otherwise, compare fingerprints by value. */
-    /*@-nullpass@*/    /* LCL: whines about (*k2).subdir */
-    if (FP_EQUAL(*k1, *k2))
-       return 0;
-    /*@=nullpass@*/
-    return 1;
-
-}
-
-void fpLookupList(fingerPrintCache cache, const char ** dirNames, 
-                 const char ** baseNames, const int * dirIndexes, 
-                 int fileCount, fingerPrint * fpList)
-{
-    int i;
-
-    for (i = 0; i < fileCount; i++) {
-       /* If this is in the same directory as the last file, don't bother
-          redoing all of this work */
-       if (i > 0 && dirIndexes[i - 1] == dirIndexes[i]) {
-           fpList[i].entry = fpList[i - 1].entry;
-           fpList[i].subDir = fpList[i - 1].subDir;
-           fpList[i].baseName = baseNames[i];
-       } else {
-           fpList[i] = doLookup(cache, dirNames[dirIndexes[i]], baseNames[i],
-                                1);
-       }
-    }
-}
-
-void fpLookupHeader(fingerPrintCache cache, Header h, fingerPrint * fpList)
-{
-    HGE_t hge = (HGE_t)headerGetEntryMinMemory;
-    HFD_t hfd = headerFreeData;
-    const char ** baseNames, ** dirNames;
-    int bnt, dnt;
-    int_32 * dirIndexes;
-    int fileCount;
-
-    if (!hge(h, RPMTAG_BASENAMES, &bnt, (void **) &baseNames, &fileCount))
-       return;
-
-    (void) hge(h, RPMTAG_DIRNAMES, &dnt, (void **) &dirNames, NULL);
-    (void) hge(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
-    fpLookupList(cache, dirNames, baseNames, dirIndexes, fileCount, fpList);
-    dirNames = hfd(dirNames, dnt);
-    baseNames = hfd(baseNames, bnt);
-}
diff --git a/lib/fprint.h b/lib/fprint.h
deleted file mode 100644 (file)
index baa6e11..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-#ifndef H_FINGERPRINT
-#define H_FINGERPRINT
-
-/** \ingroup rpmtrans
- * \file lib/fprint.h
- * Identify a file name path by a unique "finger print".
- */
-
-#include "hash.h"
-#include "header.h"
-
-/**
- * Finger print cache entry.
- * This is really a directory and symlink cache. We don't differentiate between
- * the two. We can prepopulate it, which allows us to easily conduct "fake"
- * installs of a system w/o actually mounting filesystems.
- */
-struct fprintCacheEntry_s {
-    const char * dirName;              /*!< path to existing directory */
-    dev_t dev;                         /*!< stat(2) device number */
-    ino_t ino;                         /*!< stat(2) inode number */
-    int isFake;                                /*!< (currently unused) */
-};
-
-/**
- * Finger print cache.
- */
-typedef /*@abstract@*/ struct fprintCache_s {
-    hashTable ht;                      /*!< hashed by dirName */
-} * fingerPrintCache;
-
-/**
- * Associates a trailing sub-directory and final base name with an existing
- * directory finger print.
- */
-typedef struct fingerPrint_s {
-/*! directory finger print entry (the directory path is stat(2)-able */
-    const struct fprintCacheEntry_s * entry;
-/*! trailing sub-directory path (directories that are not stat(2)-able */
-/*@owned@*/ /*@null@*/ const char * subDir;
-/*@dependent@*/ const char * baseName; /*!< file base name */
-} fingerPrint;
-
-/* only if !scarceMemory */
-/** */
-#define fpFree(a) free((void *)(a).baseName)
-
-/** */
-#define        FP_ENTRY_EQUAL(a, b) (((a)->dev == (b)->dev) && ((a)->ino == (b)->ino))
-
-/** */
-#define FP_EQUAL(a, b) ( \
-       FP_ENTRY_EQUAL((a).entry, (b).entry) && \
-       !strcmp((a).baseName, (b).baseName) && ( \
-           ((a).subDir == (b).subDir) || \
-           ((a).subDir && (b).subDir && !strcmp((a).subDir, (b).subDir)) \
-       ) \
-    )
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Be carefull with the memory... assert(*fullName == '/' || !scareMemory) */
-
-/**
- * Create finger print cache.
- * @param sizeHint     number of elements expected
- * @return pointer to initialized fingerprint cache
- */
-/*@only@*/ fingerPrintCache fpCacheCreate(int sizeHint)        /*@*/;
-
-/**
- * Destroy finger print cache.
- * @param cache                pointer to fingerprint cache
- */
-void           fpCacheFree(/*@only@*/ fingerPrintCache cache);
-
-/**
- * Return finger print of a file path.
- * @param cache                pointer to fingerprint cache
- * @param dirName      leading directory name of file path
- * @param baseName     base name of file path
- * @param scareMemory
- * @return pointer to the finger print associated with a file path.
- */
-fingerPrint    fpLookup(fingerPrintCache cache, const char * dirName, 
-                       const char * baseName, int scareMemory) /*@*/;
-
-/**
- * Return hash value for a finger print.
- * Hash based on dev and inode only!
- * @param key          pointer to finger print entry
- * @return hash value
- */
-unsigned int fpHashFunction(const void * key)  /*@*/;
-
-/**
- * Compare two finger print entries.
- * exactly equivalent to FP_EQUAL macro.
- * @param key1         finger print 1
- * @param key2         finger print 2
- * @return result of comparing key1 and key2
- */
-int fpEqual(const void * key1, const void * key2)      /*@*/;
-
-/**
- * Return finger prints of an array of file paths.
- * @warning: scareMemory is assumed!
- * @param cache                pointer to fingerprint cache
- * @param dirNames     directory names
- * @param baseNames    file base names
- * @param dirIndexes   index into dirNames for each baseNames
- * @param fileCount    number of file entries
- * @retval fpList      pointer to array of finger prints
- */
-void fpLookupList(fingerPrintCache cache, const char ** dirNames, 
-                 const char ** baseNames, const int * dirIndexes, 
-                 int fileCount, fingerPrint * fpList)
-                       /*@modifies cache, *fpList @*/;
-
-/**
- * Return finger prints of all file names in header.
- * @warning: scareMemory is assumed!
- * @param cache                pointer to fingerprint cache
- * @param h            package header
- * @retval fpList      pointer to array of finger prints
- */
-void fpLookupHeader(fingerPrintCache cache, Header h, fingerPrint * fpList)
-       /*@modifies h, cache, *fpList @*/;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/hash.c b/lib/hash.c
deleted file mode 100644 (file)
index e333954..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * \file lib/hash.c
- * Hash table implemenation
- */
-
-#include "system.h"
-#include <rpmlib.h>
-#include "hash.h"
-#include "debug.h"
-
-typedef /*@owned@*/ const void * voidptr;
-
-/** */
-struct hashBucket {
-    voidptr key;                       /*!< hash key */
-/*@owned@*/ voidptr * data;            /*!< pointer to hashed data */
-    int dataCount;                     /*!< length of data (0 if unknown) */
-/*@dependent@*/struct hashBucket * next;/*!< pointer to next item in bucket */
-};
-
-/** */
-struct hashTable_s {
-    int numBuckets;                    /*!< number of hash buckets */
-    int keySize;                       /*!< size of key (0 if unknown) */
-    int freeData;      /*!< should data be freed when table is destroyed? */
-    struct hashBucket ** buckets;      /*!< hash bucket array */
-    hashFunctionType fn;               /*!< generate hash value for key */
-    hashEqualityType eq;               /*!< compare hash keys for equality */
-};
-
-/**
- * Find entry in hash table.
- * @param ht            pointer to hash table
- * @param key           pointer to key value
- * @return pointer to hash bucket of key (or NULL)
- */
-static /*@shared@*/ /*@null@*/
-struct hashBucket *findEntry(hashTable ht, const void * key)
-{
-    unsigned int hash;
-    struct hashBucket * b;
-
-    hash = ht->fn(key) % ht->numBuckets;
-    b = ht->buckets[hash];
-
-    while (b && b->key && ht->eq(b->key, key))
-       b = b->next;
-
-    return b;
-}
-
-int hashEqualityString(const void * key1, const void * key2)
-{
-    const char *k1 = (const char *)key1;
-    const char *k2 = (const char *)key2;
-    return strcmp(k1, k2);
-}
-
-unsigned int hashFunctionString(const void * string)
-{
-    char xorValue = 0;
-    char sum = 0;
-    short len;
-    int i;
-    const char * chp = string;
-
-    len = strlen(string);
-    for (i = 0; i < len; i++, chp++) {
-       xorValue ^= *chp;
-       sum += *chp;
-    }
-
-    return ((((unsigned)len) << 16) + (((unsigned)sum) << 8) + xorValue);
-}
-
-hashTable htCreate(int numBuckets, int keySize, int freeData, hashFunctionType fn,
-                  hashEqualityType eq)
-{
-    hashTable ht;
-
-    ht = xmalloc(sizeof(*ht));
-    ht->numBuckets = numBuckets;
-    ht->buckets = xcalloc(numBuckets, sizeof(*ht->buckets));
-    ht->keySize = keySize;
-    ht->freeData = freeData;
-    ht->fn = fn;
-    ht->eq = eq;
-
-    return ht;
-}
-
-void htAddEntry(hashTable ht, const void * key, const void * data)
-{
-    unsigned int hash;
-    struct hashBucket * b;
-
-    hash = ht->fn(key) % ht->numBuckets;
-    b = ht->buckets[hash];
-
-    while (b && b->key && ht->eq(b->key, key))
-       b = b->next;
-
-    if (b == NULL) {
-       b = xmalloc(sizeof(*b));
-       if (ht->keySize) {
-           char *k = xmalloc(ht->keySize);
-           memcpy(k, key, ht->keySize);
-           b->key = k;
-       } else {
-           b->key = key;
-       }
-       b->dataCount = 0;
-       b->next = ht->buckets[hash];
-       b->data = NULL;
-       ht->buckets[hash] = b;
-    }
-
-    b->data = xrealloc(b->data, sizeof(*b->data) * (b->dataCount + 1));
-    b->data[b->dataCount++] = data;
-}
-
-void htFree(hashTable ht)
-{
-    struct hashBucket * b, * n;
-    int i;
-
-    for (i = 0; i < ht->numBuckets; i++) {
-       b = ht->buckets[i];
-       if (ht->keySize && b) free((void *)b->key);
-       while (b) {
-           n = b->next;
-           if (b->data) {
-               if (ht->freeData)
-                   *b->data = _free(*b->data);
-               b->data = _free(b->data);
-           }
-           b = _free(b);
-           b = n;
-       }
-    }
-
-    ht->buckets = _free(ht->buckets);
-    ht = _free(ht);
-}
-
-int htHasEntry(hashTable ht, const void * key)
-{
-    struct hashBucket * b;
-
-    if (!(b = findEntry(ht, key))) return 0; else return 1;
-}
-
-int htGetEntry(hashTable ht, const void * key, const void *** data,
-              int * dataCount, const void ** tableKey)
-{
-    struct hashBucket * b;
-
-    if ((b = findEntry(ht, key)) == NULL)
-       return 1;
-
-    if (data)
-       *data = (const void **) b->data;
-    if (dataCount)
-       *dataCount = b->dataCount;
-    if (tableKey)
-       *tableKey = b->key;
-
-    return 0;
-}
diff --git a/lib/hash.h b/lib/hash.h
deleted file mode 100644 (file)
index 402cd29..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#ifndef H_HASH
-#define H_HASH
-
-/**
- * \file lib/hash.h
- * Hash table implemenation.
- */
-
-typedef struct hashTable_s * hashTable;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** */
-typedef unsigned int (*hashFunctionType) (const void * string) /*@*/;
-/** */
-typedef int (*hashEqualityType) (const void * key1, const void * key2) /*@*/;
-
-/**
- * Return hash value of a string
- * @param string  string on which to calculate hash value
- * @return hash value
- */
-unsigned int hashFunctionString(const void * string) /*@*/;
-
-/**
- * Compare two hash table entries for equality.
- * @param key1          entry 1
- * @param key2          entry 2
- * @return 0 if entries are equal
- */
-int hashEqualityString(const void * key1, const void * key2) /*@*/;
-
-/**
- * Create hash table.
- * If keySize > 0, the key is duplicated within the table (which costs
- * memory, but may be useful anyway.
- * @param numBuckets    number of hash buckets
- * @param keySize       size of key (0 if unknown)
- * @param freeData      should data be freed when table is destroyed?
- * @param fn            function to generate hash value for key
- * @param eq            function to compare hash keys for equality
- * @return pointer to initialized hash table
- */
-hashTable htCreate(int numBuckets, int keySize, int freeData,
-               hashFunctionType fn, hashEqualityType eq) /*@*/; 
-
-/**
- * Destroy hash table.
- * @param ht            pointer to hash table
- */
-void htFree( /*@only@*/ hashTable ht);
-
-/**
- * Add item to hash table.
- * @param ht            pointer to hash table
- * @param key           pointer to key
- * @param data          pointer to data value
- */
-void htAddEntry(hashTable ht, /*@owned@*/ const void * key,
-               /*@owned@*/ const void * data) /*@modifies ht */;
-
-/**
- * Retrieve item from hash table.
- * @param ht            pointer to hash table
- * @param key           pointer to key value
- * @retval data         address to store data value from bucket
- * @retval dataCount    address to store data value size from bucket
- * @retval tableKey     address to store key value from bucket (may be NULL)
- * @return 0 on success, 1 if the item is not found.
- */
-int htGetEntry(hashTable ht, const void * key,
-               /*@null@*/ /*@out@*/ const void *** data,
-               /*@null@*/ /*@out@*/ int * dataCount,
-               /*@null@*/ /*@out@*/ const void ** tableKey)
-       /*@modifies *data, *dataCount, *tableKey @*/;
-
-/**
- * Check for key in hash table.
- * @param ht            pointer to hash table
- * @param key           pointer to key value
- * @return 1 if the key is present, 0 otherwise
- */
-int htHasEntry(hashTable ht, const void * key) /*@*/;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index 022651d..778a8e4 100644 (file)
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -499,6 +499,7 @@ static int markReplacedFiles(PSM_t psm)
 
     mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES, NULL, 0);
     (void) rpmdbAppendIterator(mi, offsets, num);
+    (void) rpmdbSetIteratorRewrite(mi, 1);
 
     sfi = replaced;
     while ((h = rpmdbNextIterator(mi)) != NULL) {
index b8f6c78..c74b69d 100644 (file)
@@ -460,8 +460,10 @@ int showMatches(QVA_t qva, rpmdbMatchIterator mi, QVF_t showPackage)
 
     while ((h = rpmdbNextIterator(mi)) != NULL) {
        int rc;
+       /*@-nullpass@*/
        if ((rc = showPackage(qva, rpmdbGetIteratorRpmDB(mi), h)) != 0)
            ec = rc;
+       /*@=nullpass@*/
     }
     mi = rpmdbFreeIterator(mi);
     return ec;
index e32f58e..2f733d2 100644 (file)
@@ -650,7 +650,9 @@ typedef /*@abstract@*/ struct _rpmdbMatchIterator * rpmdbMatchIterator;
  * @param mi           rpm database iterator
  * @return             rpm database handle
  */
-/*@kept@*/ rpmdb rpmdbGetIteratorRpmDB(/*@null@*/ rpmdbMatchIterator mi) /*@*/;
+/*@kept@*/ /*@null@*/ rpmdb rpmdbGetIteratorRpmDB(
+               /*@null@*/ rpmdbMatchIterator mi)
+       /*@*/;
 
 /** \ingroup rpmdb
  * Return join key for current position of rpm database iterator.
@@ -710,6 +712,16 @@ void rpmdbSetIteratorRelease(/*@null@*/ rpmdbMatchIterator mi,
                /*@modifies mi @*/;
 
 /** \ingroup rpmdb
+ * Prepare iterator for lazy writes.
+ * @note: must be called before rpmdbNextIterator() in CDB model database.
+ * @param mi           rpm database iterator
+ * @param rewrite      new value of rewrite
+ * @return             previous value
+ */
+int rpmdbSetIteratorRewrite(/*@null@*/ rpmdbMatchIterator mi, int rewrite)
+               /*@modifies mi @*/;
+
+/** \ingroup rpmdb
  * Modify iterator to mark header for lazy write.
  * @param mi           rpm database iterator
  * @param modified     new value of modified
index b1dd2f4..c61ec3d 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "psm.h"
 #include "fprint.h"
-#include "hash.h"
+#include "rpmhash.h"
 #include "md5.h"
 #include "misc.h"
 #include "rpmdb.h"
index 547b2bb..a46fcc9 100644 (file)
@@ -123,6 +123,10 @@ RPMCANONARCH = @RPMCANONARCH@
 RPMCANONOS = @RPMCANONOS@
 RPMCANONVENDOR = @RPMCANONVENDOR@
 RPMCONFIGDIR = @RPMCONFIGDIR@
+RPMGID = @RPMGID@
+RPMGROUP = @RPMGROUP@
+RPMUID = @RPMUID@
+RPMUSER = @RPMUSER@
 SYSCONFIGDIR = @SYSCONFIGDIR@
 U = @U@
 UNZIPBIN = @UNZIPBIN@
index 1d51241..9708164 100644 (file)
@@ -27,10 +27,8 @@ build/spec.c
 lib/cpio.c
 lib/depends.c
 lib/formats.c
-lib/fprint.c
 lib/fs.c
 lib/fsm.c
-lib/hash.c
 lib/header.c
 lib/manifest.c
 lib/md5.c
@@ -55,6 +53,8 @@ rpmdb/db2.c
 rpmdb/db3.c
 rpmdb/dbconfig.c
 rpmdb/falloc.c
+rpmdb/fprint.c
+rpmdb/rpmhash.c
 rpmdb/rpmdb.c
 rpmio/base64.c
 rpmio/digest.c
index f3da260..de9137b 100644 (file)
@@ -207,7 +207,7 @@ fi
 %files
 %defattr(-,root,root)
 %doc RPM-PGP-KEY RPM-GPG-KEY CHANGES GROUPS doc/manual/[a-z]*
-%attr(4755, @@RPMUSER@@, @@RPMGROUP@@) /bin/rpm
+%attr(0755, @@RPMUSER@@, @@RPMGROUP@@) /bin/rpm
 %dir                   /etc/rpm
 %config(missingok)     /etc/rpm/macros.db1
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/bin/rpm2cpio
@@ -228,7 +228,7 @@ fi
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/convertrpmrc.sh
 %attr(0644, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/macros
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/mkinstalldirs
-%attr(4755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpm[deiukqv]
+%attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpm[deiukqv]
 %attr(0644, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpmpopt*
 %attr(0644, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpmrc
 
@@ -322,7 +322,7 @@ fi
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/magic.req
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/perl.prov
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/perl.req
-%attr(4755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpm[bt]
+%attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpm[bt]
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpmdiff
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/rpmdiff.cgi
 %attr(0755, @@RPMUSER@@, @@RPMGROUP@@) %{__prefix}/lib/rpm/u_pkg.sh
index 8de1f01..c3a8df3 100644 (file)
@@ -14,7 +14,7 @@ EXTRA_DIST = db3.c db2.c db1.c falloc.c
 
 pkgincdir = $(pkgincludedir)
 pkginc_HEADERS = rpmdb.h
-noinst_HEADERS = falloc.h
+noinst_HEADERS = falloc.h fprint.h rpmhash.h
 
 mylibpaths = \
        -L$(top_builddir)/lib/.libs \
@@ -27,7 +27,7 @@ LIBS =
 DB3LOBJS = $(shell cat $(top_builddir)/$(WITH_DB_SUBDIR)/db3lobjs)
 
 lib_LTLIBRARIES = librpmdb.la
-librpmdb_la_SOURCES = $(DBLIBSRCS) dbconfig.c rpmdb.c
+librpmdb_la_SOURCES = $(DBLIBSRCS) dbconfig.c fprint.c rpmhash.c rpmdb.c
 librpmdb_la_LDFLAGS = @libdb3@ @libdb2@ @libdb1@
 librpmdb_la_LIBADD = $(DBLIBOBJS) $(DB3LOBJS)
 librpmdb_la_DEPENDENCIES = $(DBLIBOBJS) createlinks
index 4162afb..cb88f37 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup db1
- * \file lib/db1.c
+ * \file rpmdb/db1.c
  */
 
 #include "system.h"
index e70f409..7a59e87 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup db2
- * \file lib/db2.c
+ * \file rpmdb/db2.c
  */
 
 static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */
index 7f6eb53..3a0e585 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup db3
- * \file lib/db3.c
+ * \file rpmdb/db3.c
  */
 
 static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */
@@ -184,6 +184,7 @@ static int db_init(dbiIndex dbi, const char *dbhome,
        rpmdb->db_errfile = stderr;
 
     eflags = (dbi->dbi_oeflags | dbi->dbi_eflags);
+    if (eflags & DB_JOINENV) eflags &= DB_JOINENV;
 
     if (dbfile)
        rpmMessage(RPMMESS_DEBUG, _("opening db environment %s/%s %s\n"),
@@ -381,7 +382,7 @@ static inline int db3c_close(dbiIndex dbi, /*@only@*/ /*@null@*/ DBC * dbcursor)
     return rc;
 }
 
-static inline int db3c_open(dbiIndex dbi, /*@out@*/ DBC ** dbcp)
+static inline int db3c_open(dbiIndex dbi, /*@out@*/ DBC ** dbcp, int dbiflags)
 {
     DB * db = dbi->dbi_db;
     DB_TXN * txnid = NULL;
@@ -390,7 +391,10 @@ static inline int db3c_open(dbiIndex dbi, /*@out@*/ DBC ** dbcp)
 
     if (db == NULL) return -2;
 #if defined(__USE_DB3)
-    if ((dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY)) {
+    if ((dbiflags & DBI_WRITECURSOR) &&
+       (dbi->dbi_eflags & DB_INIT_CDB) && !(dbi->dbi_oflags & DB_RDONLY))
+    {
+fprintf(stderr, "D: *** WRITECURSOR\n");
        flags = DB_WRITECURSOR;
     } else
        flags = 0;
@@ -409,7 +413,7 @@ static int db3cclose(dbiIndex dbi, /*@only@*/ /*@null@*/ DBC * dbcursor,
     int rc = 0;
 
     /* XXX per-iterator cursors */
-    if (flags == 1)
+    if (flags & DBI_ITERATOR)
        return db3c_close(dbi, dbcursor);
 
     if (!dbi->dbi_use_cursors)
@@ -431,8 +435,8 @@ static int db3copen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags)
     int rc = 0;
 
     /* XXX per-iterator cursors */
-    if (flags == 1)
-       return db3c_open(dbi, dbcp);
+    if (flags & DBI_ITERATOR)
+       return db3c_open(dbi, dbcp, flags);
 
     if (!dbi->dbi_use_cursors) {
        if (dbcp) *dbcp = NULL;
@@ -440,7 +444,7 @@ static int db3copen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags)
     }
 
     if ((dbcursor = dbi->dbi_rmw) == NULL) {
-       if ((rc = db3c_open(dbi, &dbcursor)) == 0)
+       if ((rc = db3c_open(dbi, &dbcursor, flags)) == 0)
            dbi->dbi_rmw = dbcursor;
     }
 
@@ -719,26 +723,40 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
      * Avoid incompatible DB_CREATE/DB_RDONLY flags on DBENV->open.
      */
     if (dbi->dbi_use_dbenv) {
-       if (access(dbhome, W_OK|F_OK) == -1) {
+       if (access(dbhome, W_OK) == -1) {
 
            /* dbhome is unwritable, don't attempt DB_CREATE on DB->open ... */
            oflags &= ~DB_CREATE;
 
            /* ... but DBENV->open might still need DB_CREATE ... */
-           if (!(dbi->dbi_eflags & DB_PRIVATE)) {
+           if (dbi->dbi_eflags & DB_PRIVATE) {
+               dbi->dbi_eflags &= ~DB_JOINENV;
+           } else {
+               dbi->dbi_eflags |= DB_JOINENV;
                dbi->dbi_oeflags &= ~DB_CREATE;
                dbi->dbi_oeflags &= ~DB_THREAD;
-               dbi->dbi_eflags = 0;
-               dbi->dbi_eflags |= DB_JOINENV;
+               /* ... but, unless DB_PRIVATE is used, skip DBENV. */
+               dbi->dbi_use_dbenv = 0;
            }
 
-           /* ... DB_RDONLY seems OK ...  */
+           /* ... DB_RDONLY maps dphome perms across files ...  */
            oflags |= DB_RDONLY;
 
-           /* ... so DB_WRITECURSOR won't be needed ...  */
+           /* ... and DB_WRITECURSOR won't be needed ...  */
            dbi->dbi_oflags |= DB_RDONLY;
-       } else {
-           dbi->dbi_eflags &= ~DB_JOINENV;
+       } else {        /* dbhome is writable, check for persistent dbenv. */
+           const char * dbf = rpmGetPath(dbhome, "/__db.001", NULL);
+
+           if (access(dbf, F_OK) == -1) {
+               /* ... non-existent (or unwritable) DBENV, will create ... */
+               dbi->dbi_oeflags |= DB_CREATE;
+               dbi->dbi_eflags &= ~DB_JOINENV;
+           } else {
+               /* ... pre-existent (or bogus) DBENV, will join ... */
+               dbi->dbi_oeflags &= ~DB_CREATE;
+               dbi->dbi_eflags |= DB_JOINENV;
+           }
+           dbf = _free(dbf);
        }
     }
 
@@ -746,31 +764,25 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
      * Avoid incompatible DB_CREATE/DB_RDONLY flags on DB->open.
      */
     if ((oflags & DB_CREATE) && (oflags & DB_RDONLY)) {
-       /* Otherwise dbhome is writable, and DB->open flags may conflict. */
-       const char * dbfullpath;
-       const char * sdn = (dbfile ? dbfile : tagName(dbi->dbi_rpmtag));
-       char * t;
-       int nb;
-
-       nb = strlen(dbhome) + 1 + strlen(sdn);
-       dbfullpath = t = alloca(nb + 1);
-       t = stpcpy( stpcpy( stpcpy( t, dbhome), "/"), sdn);
-
-       if (access(dbfullpath, F_OK) == -1) {
-           /* If file does not exist, DB->open might create ... */
+       /* dbhome is writable, and DB->open flags may conflict. */
+       const char * dbfn = (dbfile ? dbfile : tagName(dbi->dbi_rpmtag));
+       const char * dbf = rpmGetPath(dbhome, "/", dbfn, NULL);
+
+       if (access(dbf, F_OK) == -1) {
+           /* File does not exist, DB->open might create ... */
            oflags &= ~DB_RDONLY;
        } else {
-           /* If file exists, DB->open need not create ... */
+           /* File exists, DB->open need not create ... */
            oflags &= ~DB_CREATE;
        }
 
        /* Only writers need DB_WRITECURSOR ... */
-       if (!(oflags & DB_RDONLY) && access(dbfullpath, W_OK) == 0) {
+       if (!(oflags & DB_RDONLY) && access(dbf, W_OK) == 0) {
            dbi->dbi_oflags &= ~DB_RDONLY;
        } else {
            dbi->dbi_oflags |= DB_RDONLY;
        }
-
+       dbf = _free(dbf);
     }
 
     dbi->dbi_dbinfo = NULL;
@@ -784,6 +796,8 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
 
     if (rc == 0) {
 #if defined(__USE_DB3)
+       static int _lockdbfd = 0;
+
        rc = db_create(&db, dbenv, dbi->dbi_cflags);
        rc = cvtdberr(dbi, "db_create", rc, _debug);
        if (rc == 0 && db != NULL) {
@@ -900,8 +914,9 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
            _printit = (rc > 0 ? 0 : _debug);
            xx = cvtdberr(dbi, "db->open", rc, _printit);
 
-           if (rc == 0 && dbi->dbi_get_rmw_cursor) {
+           if (rc == 0 && dbi->dbi_use_dbenv && (dbi->dbi_eflags & DB_INIT_CDB) && dbi->dbi_get_rmw_cursor) {
                DBC * dbcursor = NULL;
+fprintf(stderr, "D: *** rmw WRITECURSOR\n");
                xx = db->cursor(db, txnid, &dbcursor,
                        ((oflags & DB_RDONLY) ? 0 : DB_WRITECURSOR));
                xx = cvtdberr(dbi, "db->cursor", xx, _debug);
@@ -909,13 +924,31 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
            } else
                dbi->dbi_rmw = NULL;
 
-           if (rc == 0 && dbi->dbi_lockdbfd) {
+           /*
+            * Lock a file using fcntl(2). Traditionally this is Packages,
+            * the file used * to store metadata of installed header(s),
+            * as Packages is always opened, and should be opened first,
+            * for any rpmdb access.
+            *
+            * If no DBENV is used, then access is protected with a
+            * shared/exclusive locking scheme, as always.
+            *
+            * With a DBENV, the fcntl(2) lock is necessary only to keep
+            * the riff-raff from playing where they don't belong, as
+            * the DBENV should provide it's own locking scheme. So try to
+            * acquire a lock, but permit failures, as some other
+            * DBENV player may already have acquired the lock.
+            */
+           if (rc == 0 && dbi->dbi_lockdbfd &&
+               (!dbi->dbi_use_dbenv || _lockdbfd++ == 0))
+           {
                int fdno = -1;
 
                if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
                    rc = 1;
                } else {
                    struct flock l;
+                   memset(&l, 0, sizeof(l));
                    l.l_whence = 0;
                    l.l_start = 0;
                    l.l_len = 0;
@@ -923,13 +956,15 @@ static int db3open(/*@keep@*/ rpmdb rpmdb, int rpmtag, dbiIndex * dbip)
                                ? F_WRLCK : F_RDLCK;
                    l.l_pid = 0;
 
-                   if (fcntl(fdno, F_SETLK, (void *) &l)) {
-                       rpmError(RPMERR_FLOCK,
+                   rc = fcntl(fdno, F_SETLK, (void *) &l);
+                   if (rc) {
+                       rpmError(
+                           (!dbi->dbi_use_dbenv ? RPMERR_FLOCK : RPMWARN_FLOCK),
                                _("cannot get %s lock on %s/%s\n"),
                                ((dbi->dbi_mode & (O_RDWR|O_WRONLY))
                                        ? _("exclusive") : _("shared")),
                                dbhome, (dbfile ? dbfile : ""));
-                       rc = 1;
+                       rc = (!dbi->dbi_use_dbenv ? 1 : 0);
                    } else if (dbfile) {
                        rpmMessage(RPMMESS_DEBUG,
                                _("locked  db index       %s/%s\n"),
index 5042324..061956c 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup rpmdb
- * \file lib/dbconfig.c
+ * \file rpmdb/dbconfig.c
  */
 
 #include "system.h"
index c882079..f1d0af2 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup rpmio db1
- * \file lib/falloc.c
+ * \file rpmdb/falloc.c
  * 
  * The entire file space is thus divided into blocks with a "struct fablock"
  * at the header of each. The size fields doubly link this block list.
index 8468681..621f98c 100644 (file)
@@ -2,7 +2,7 @@
 #define H_FALLOC
 
 /** \ingroup db1
- * \file lib/falloc.h
+ * \file rpmdb/falloc.h
  * File space allocation routines.
  *
  * Best fit allocation is used, free blocks are compacted. Minimal
index c94ae5d..b3a4ff0 100644 (file)
@@ -1,5 +1,5 @@
 /** \ingroup rpmdb dbi
- * \file lib/rpmdb.c
+ * \file rpmdb/rpmdb.c
  */
 
 #include "system.h"
@@ -70,11 +70,11 @@ static void dbiTagsInit(void)
 
     /*@-nullpass@*/
     dbiTagStr = rpmExpand("%{_dbi_tags}", NULL);
-    /*@=nullpass@*/
     if (!(dbiTagStr && *dbiTagStr && *dbiTagStr != '%')) {
        dbiTagStr = _free(dbiTagStr);
        dbiTagStr = xstrdup(_dbiTagStr_default);
     }
+    /*@=nullpass@*/
 
     if (dbiTagsMax || dbiTags) {
        dbiTags = _free(dbiTags);
@@ -155,7 +155,7 @@ INLINE int XdbiCopen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags,
        const char * f, unsigned int l)
 {
 if (_debug < 0 || dbi->dbi_debug)
-fprintf(stderr, "+++ RMW %s (%s:%u)\n", tagName(dbi->dbi_rpmtag), f, l);
+fprintf(stderr, "+++ RMW %s %s (%s:%u)\n", tagName(dbi->dbi_rpmtag), ((flags & DBI_WRITECURSOR) ? "WRITECURSOR" : ""), f, l);
     return (*dbi->dbi_vec->copen) (dbi, dbcp, flags);
 }
 
@@ -167,6 +167,8 @@ fprintf(stderr, "--- RMW %s (%s:%u)\n", tagName(dbi->dbi_rpmtag), f, l);
     return (*dbi->dbi_vec->cclose) (dbi, dbcursor, flags);
 }
 
+#define        printable(_c)   (((_c) >= ' ') && ((_c) <= '\177'))
+
 INLINE int dbiDel(dbiIndex dbi, DBC * dbcursor, const void * keyp, size_t keylen, unsigned int flags)
 {
     int NULkey;
@@ -198,22 +200,33 @@ INLINE int dbiGet(dbiIndex dbi, DBC * dbcursor, void ** keypp, size_t * keylenp,
     if (NULkey && keylenp) (*keylenp)--;
     /*@=nullderef =nullpass@*/
 
+/*@-nullderef -nullpass@*/
 if (_debug < 0 || dbi->dbi_debug) {
-char keyval[32];
-int dataval = 0xdeadbeef;
-if (dbi->dbi_rpmtag == RPMDBI_PACKAGES && keypp && *keypp && keylenp && *keylenp <= sizeof(int)) {
+ int dataval = 0xdeadbeef;
+ const char * kvp;
+ char keyval[64];
+ keyval[0] = '\0';
+ if (keypp && *keypp && keylenp) {
+  if (*keylenp <= sizeof(int) &&
+       !(  printable( ((unsigned char *)(*keypp))[0] ) && printable( ((unsigned char *)(*keypp))[1] ) &&
+           printable( ((unsigned char *)(*keypp))[2] ) && printable( ((unsigned char *)(*keypp))[3] ))) {
     int keyint = 0;
     memcpy(&keyint, *keypp, sizeof(keyint));
     sprintf(keyval, "#%d", keyint);
-} else keyval[0] = '\0';
-if (rc == 0 && datapp && *datapp && datalenp && *datalenp >= sizeof(dataval)) {
+    kvp = keyval;
+  } else {
+    kvp = *keypp;
+  }
+ } else
+   kvp = keyval;
+ if (rc == 0 && datapp && *datapp && datalenp && *datalenp >= sizeof(dataval)) {
     memcpy(&dataval, *datapp, sizeof(dataval));
-    dataval = ntohl(dataval);
-}
-fprintf(stderr, "    Get %s key (%p,%ld) data (%p,%ld) \"%s\" %x rc %d\n",
+ }
+ fprintf(stderr, "    Get %s key (%p,%ld) data (%p,%ld) \"%s\" %x rc %d\n",
     tagName(dbi->dbi_rpmtag), *keypp, (long)*keylenp, *datapp, (long)*datalenp,
-    (dbi->dbi_rpmtag != RPMDBI_PACKAGES ? (char *)*keypp : keyval), (unsigned)dataval, rc);
+    kvp, (unsigned)dataval, rc);
 }
+/*@=nullderef =nullpass@*/
     return rc;
 }
 
@@ -229,18 +242,38 @@ INLINE int dbiPut(dbiIndex dbi, DBC * dbcursor, const void * keyp, size_t keylen
     rc = (*dbi->dbi_vec->cput) (dbi, dbcursor, keyp, keylen, datap, datalen, flags);
     if (NULkey) keylen--;
 
+/*@-nullderef -nullpass@*/
 if (_debug < 0 || dbi->dbi_debug) {
-int dataval = 0xdeadbeef;
-if (datap) memcpy(&dataval, datap, sizeof(dataval));
-fprintf(stderr, "    Put %s key (%p,%ld) data (%p,%ld) \"%s\" %x rc %d\n", tagName(dbi->dbi_rpmtag), keyp, (long)keylen, (datap ? datap : NULL), (long)datalen, (dbi->dbi_rpmtag != RPMDBI_PACKAGES ? (char *)keyp : ""), (unsigned)dataval, rc);
+ int dataval = 0xdeadbeef;
+ const char * kvp;
+ char keyval[64];
+ keyval[0] = '\0';
+ if (keyp) {
+  if (keylen == sizeof(int) &&
+       !(  printable( ((unsigned char *)keyp)[0] ) && printable( ((unsigned char *)keyp)[1] ) &&
+           printable( ((unsigned char *)keyp)[2] ) && printable( ((unsigned char *)keyp)[3] ))){
+    int keyint = 0;
+    memcpy(&keyint, keyp, sizeof(keyint));
+    sprintf(keyval, "#%d", keyint);
+    kvp = keyval;
+  } else {
+    kvp = keyp;
+  }
+ } else
+   kvp = keyval;
+ if (rc == 0 && datap && datalen >= sizeof(dataval)) {
+    memcpy(&dataval, datap, sizeof(dataval));
+ }
+ fprintf(stderr, "    Put %s key (%p,%ld) data (%p,%ld) \"%s\" %x rc %d\n", tagName(dbi->dbi_rpmtag), keyp, (long)keylen, (datap ? datap : NULL), (long)datalen, kvp, (unsigned)dataval, rc);
 }
+/*@=nullderef =nullpass@*/
 
     return rc;
 }
 
 INLINE int dbiClose(dbiIndex dbi, unsigned int flags) {
 if (_debug < 0 || dbi->dbi_debug)
-fprintf(stderr, "    %s Close\n", tagName(dbi->dbi_rpmtag));
+fprintf(stderr, "    Close %s\n", tagName(dbi->dbi_rpmtag));
     return (*dbi->dbi_vec->close) (dbi, flags);
 }
 
@@ -1051,7 +1084,9 @@ int rpmdbCountPackages(rpmdb rpmdb, const char * name)
     }
 
     if (rc == 0)       /* success */
+       /*@-nullpass@*/
        rc = dbiIndexSetCount(matches);
+       /*@=nullpass@*/
     else if (rc > 0)   /* error */
        rpmError(RPMERR_DBCORRUPT, _("error(%d) counting packages\n"), rc);
     else               /* not found */
@@ -1068,8 +1103,10 @@ int rpmdbCountPackages(rpmdb rpmdb, const char * name)
 /* 1 no matches */
 /* 2 error */
 static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
-       const char * name, const char * version, const char * release,
-       /*@out@*/ dbiIndexSet * matches)
+               const char * name,
+               /*@null@*/ const char * version,
+               /*@null@*/ const char * release,
+               /*@out@*/ dbiIndexSet * matches)
 {
     int gotMatches;
     int rc;
@@ -1082,7 +1119,7 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
        goto exit;
     }
 
-    if (!version && !release) {
+    if (version == NULL && release == NULL) {
        rc = 0;
        goto exit;
     }
@@ -1115,7 +1152,9 @@ static int dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
            goto exit;
        }
 
+       /*@-nullpass@*/
        (void) headerNVR(h, NULL, &pkgVersion, &pkgRelease);
+       /*@=nullpass@*/
            
        goodRelease = goodVersion = 1;
 
@@ -1177,6 +1216,7 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
 
     chptr = (localarg + strlen(localarg)) - 1;
     while (chptr > localarg && *chptr != '-') chptr--;
+    /*@-nullstate@*/   /* FIX: *matches may be NULL. */
     if (chptr == localarg) return 1;
 
     *chptr = '\0';
@@ -1195,6 +1235,7 @@ static int dbiFindByLabel(dbiIndex dbi, DBC * dbcursor,
 
     *chptr = '\0';
     return dbiFindMatches(dbi, dbcursor, localarg, chptr + 1, release, matches);
+    /*@=nullstate@*/
 }
 
 /**
@@ -1239,6 +1280,7 @@ struct _rpmdbMatchIterator {
     int                        mi_setx;
 /*@null@*/ Header      mi_h;
     int                        mi_sorted;
+    int                        mi_cflags;
     int                        mi_modified;
     unsigned int       mi_prevoffset;
     unsigned int       mi_offset;
@@ -1259,12 +1301,8 @@ rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi)
 
     dbi = dbiOpen(mi->mi_rpmdb, RPMDBI_PACKAGES, 0);
     if (mi->mi_h) {
-       if (dbi && mi->mi_modified && mi->mi_prevoffset) {
-           DBC * dbcursor = NULL;
-           xx = dbiCopen(dbi, &dbcursor, 0);
-           (void) dbiUpdateRecord(dbi, dbcursor, mi->mi_prevoffset, mi->mi_h);
-           xx = dbiCclose(dbi, dbcursor, 0);
-           dbcursor = NULL;
+       if (dbi && mi->mi_dbc && mi->mi_modified && mi->mi_prevoffset) {
+           xx = dbiUpdateRecord(dbi, mi->mi_dbc, mi->mi_prevoffset, mi->mi_h);
        }
        headerFree(mi->mi_h);
        mi->mi_h = NULL;
@@ -1278,7 +1316,7 @@ rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi)
     mi->mi_release = _free(mi->mi_release);
     mi->mi_version = _free(mi->mi_version);
     if (dbi && mi->mi_dbc)
-       xx = dbiCclose(dbi, mi->mi_dbc, 1);
+       xx = dbiCclose(dbi, mi->mi_dbc, DBI_ITERATOR);
     mi->mi_dbc = NULL;
     if (mi->mi_set)
        dbiFreeIndexSet(mi->mi_set);
@@ -1326,6 +1364,18 @@ void rpmdbSetIteratorVersion(rpmdbMatchIterator mi, const char * version) {
     mi->mi_version = (version ? xstrdup(version) : NULL);
 }
 
+int rpmdbSetIteratorRewrite(rpmdbMatchIterator mi, int rewrite) {
+    int rc;
+    if (mi == NULL)
+       return 0;
+    rc = (mi->mi_cflags & DBI_WRITECURSOR) ? 1 : 0;
+    if (rewrite)
+       mi->mi_cflags |= DBI_WRITECURSOR;
+    else
+       mi->mi_cflags &= ~DBI_WRITECURSOR;
+    return rc;
+}
+
 int rpmdbSetIteratorModified(rpmdbMatchIterator mi, int modified) {
     int rc;
     if (mi == NULL)
@@ -1351,10 +1401,15 @@ Header XrpmdbNextIterator(rpmdbMatchIterator mi, const char * f, unsigned l)
     dbi = dbiOpen(mi->mi_rpmdb, RPMDBI_PACKAGES, 0);
     if (dbi == NULL)
        return NULL;
-    /* XXX cursors need to be per-iterator, not per-dbi. Get a cursor now. */
-    if (mi->mi_dbc == NULL) {
-       xx = XdbiCopen(dbi, &mi->mi_dbc, 1, f, l);
-    }
+
+    /*
+     * Cursors are per-iterator, not per-dbi, so get a cursor for the
+     * iterator on 1st call. If the iteration is to rewrite headers, and the
+     * CDB model is used for the database, then the cursor needs to
+     * marked with DB_WRITECURSOR as well.
+     */
+    if (mi->mi_dbc == NULL)
+       xx = XdbiCopen(dbi, &mi->mi_dbc, (mi->mi_cflags | DBI_ITERATOR), f, l);
     dbi->dbi_lastoffset = mi->mi_prevoffset;
 
 top:
@@ -1410,7 +1465,7 @@ if (dbi->dbi_api == 1 && dbi->dbi_rpmtag == RPMDBI_PACKAGES && rc == EFAULT) {
     /* Free current header */
     if (mi->mi_h) {
        if (mi->mi_modified && mi->mi_prevoffset)
-           (void) dbiUpdateRecord(dbi, mi->mi_dbc, mi->mi_prevoffset, mi->mi_h);
+           (void)dbiUpdateRecord(dbi, mi->mi_dbc, mi->mi_prevoffset, mi->mi_h);
        headerFree(mi->mi_h);
        mi->mi_h = NULL;
     }
@@ -1420,15 +1475,19 @@ if (dbi->dbi_api == 1 && dbi->dbi_rpmtag == RPMDBI_PACKAGES && rc == EFAULT) {
     if (dbi->dbi_api <= 1) uh = _free(uh);
 
     if (mi->mi_h && mi->mi_release) {
-       const char *release;
+       const char * release;
+       /*@-nullpass@*/
        (void) headerNVR(mi->mi_h, NULL, NULL, &release);
+       /*@=nullpass@*/
        if (mi->mi_release && strcmp(mi->mi_release, release))
            goto top;
     }
 
     if (mi->mi_h && mi->mi_version) {
-       const char *version;
+       const char * version;
+       /*@-nullpass@*/
        (void) headerNVR(mi->mi_h, NULL, &version, NULL);
+       /*@=nullpass@*/
        if (mi->mi_version && strcmp(mi->mi_version, version))
            goto top;
     }
@@ -1440,7 +1499,9 @@ exit:
 #ifdef NOTNOW
     if (mi->mi_h) {
        const char *n, *v, *r;
+       /*@-nullpass@*/
        headerNVR(mi->mi_h, &n, &v, &r);
+       /*@=nullpass@*/
        rpmMessage(RPMMESS_DEBUG, "%s-%s-%s at 0x%x, h %p\n", n, v, r,
                mi->mi_offset, mi->mi_h);
     }
@@ -1608,6 +1669,7 @@ fprintf(stderr, "*** RMW %s %p\n", tagName(rpmtag), dbi->dbi_rmw);
     mi->mi_setx = 0;
     mi->mi_h = NULL;
     mi->mi_sorted = 0;
+    mi->mi_cflags = 0;
     mi->mi_modified = 0;
     mi->mi_prevoffset = 0;
     mi->mi_offset = 0;
@@ -1616,7 +1678,9 @@ fprintf(stderr, "*** RMW %s %p\n", tagName(rpmtag), dbi->dbi_rmw);
     mi->mi_dbnum = 0;
     mi->mi_version = NULL;
     mi->mi_release = NULL;
+    /*@-nullret@*/
     return mi;
+    /*@=nullret@*/
 }
 
 /**
@@ -1718,9 +1782,9 @@ int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
            case RPMDBI_PACKAGES:
              dbi = dbiOpen(rpmdb, rpmtag, 0);
              if (dbi != NULL) {
-               xx = dbiCopen(dbi, &dbcursor, 0);
+               xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
                xx = dbiDel(dbi, dbcursor, &hdrNum, sizeof(hdrNum), 0);
-               xx = dbiCclose(dbi, dbcursor, 0);
+               xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
                dbcursor = NULL;
                if (!dbi->dbi_no_dbsync)
                    xx = dbiSync(dbi, 0);
@@ -1734,7 +1798,7 @@ int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
 
          dbi = dbiOpen(rpmdb, rpmtag, 0);
          if (dbi != NULL) {
-           xx = dbiCopen(dbi, &dbcursor, 0);
+           xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
 
            if (rpmtype == RPM_STRING_TYPE) {
 
@@ -1796,7 +1860,7 @@ int rpmdbRemove(rpmdb rpmdb, int rid, unsigned int hdrNum)
                xx = removeIndexEntry(dbi, dbcursor, valp, vallen, rec);
            }
 
-           xx = dbiCclose(dbi, dbcursor, 0);
+           xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
            dbcursor = NULL;
 
            if (!dbi->dbi_no_dbsync)
@@ -1907,7 +1971,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
        datap = h;
        datalen = headerSizeof(h, HEADER_MAGIC_NO);
 
-       xx = dbiCopen(dbi, &dbcursor, 0);
+       xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
 
        /* Retrieve join key for next header instance. */
 
@@ -1929,7 +1993,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
        rc = dbiPut(dbi, dbcursor, keyp, keylen, datap, datalen, 0);
        xx = dbiSync(dbi, 0);
 
-       xx = dbiCclose(dbi, dbcursor, 0);
+       xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
        dbcursor = NULL;
       }
 
@@ -1972,9 +2036,9 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
            case RPMDBI_PACKAGES:
              dbi = dbiOpen(rpmdb, rpmtag, 0);
              if (dbi != NULL) {
-               xx = dbiCopen(dbi, &dbcursor, 0);
+               xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
                xx = dbiUpdateRecord(dbi, dbcursor, hdrNum, h);
-               xx = dbiCclose(dbi, dbcursor, 0);
+               xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
                dbcursor = NULL;
                if (!dbi->dbi_no_dbsync)
                    xx = dbiSync(dbi, 0);
@@ -2013,7 +2077,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
          dbi = dbiOpen(rpmdb, rpmtag, 0);
          if (dbi != NULL) {
 
-           xx = dbiCopen(dbi, &dbcursor, 0);
+           xx = dbiCopen(dbi, &dbcursor, DBI_WRITECURSOR);
            if (rpmtype == RPM_STRING_TYPE) {
                rpmMessage(RPMMESS_DEBUG, _("adding \"%s\" to %s index.\n"), 
                        (const char *)rpmvals, tagName(dbi->dbi_rpmtag));
@@ -2095,7 +2159,7 @@ int rpmdbAdd(rpmdb rpmdb, int iid, Header h)
 
                rc += addIndexEntry(dbi, dbcursor, valp, vallen, rec);
            }
-           xx = dbiCclose(dbi, dbcursor, 0);
+           xx = dbiCclose(dbi, dbcursor, DBI_WRITECURSOR);
            dbcursor = NULL;
 
            if (!dbi->dbi_no_dbsync)
@@ -2434,7 +2498,9 @@ int rpmdbRebuild(const char * rootdir)
     _dbapi = rpmExpandNumeric("%{_dbapi}");
     _dbapi_rebuild = rpmExpandNumeric("%{_dbapi_rebuild}");
 
+    /*@-nullpass@*/
     tfn = rpmGetPath("%{_dbpath}", NULL);
+    /*@=nullpass@*/
     if (!(tfn && tfn[0] != '%')) {
        rpmMessage(RPMMESS_DEBUG, _("no dbpath has been set"));
        rc = 1;
@@ -2445,7 +2511,9 @@ int rpmdbRebuild(const char * rootdir)
        dbpath += strlen(rootdir);
     tfn = _free(tfn);
 
+    /*@-nullpass@*/
     tfn = rpmGetPath("%{_dbpath_rebuild}", NULL);
+    /*@=nullpass@*/
     if (!(tfn && tfn[0] != '%' && strcmp(tfn, dbpath))) {
        char pidbuf[20];
        char *t;
index b3889d6..c7130dd 100644 (file)
@@ -2,7 +2,7 @@
 #define H_RPMDB
 
 /** \ingroup rpmdb dbi db1 db3
- * \file lib/rpmdb.h
+ * \file rpmdb/rpmdb.h
  * Access RPM indices using Berkeley DB interface(s).
  */
 
@@ -319,13 +319,16 @@ void db3Free( /*@only@*/ /*@null@*/ dbiIndex dbi);
 
 /** \ingroup dbi
  * @param dbi          index database handle
- * @param flags                (unused)
+ * @param dbiflags     DBI_WRITECURSOR or DBI_ITERATOR
  */
-int dbiCopen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags);
-int XdbiCopen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int flags, const char *f, unsigned int l);
+int dbiCopen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int dbiflags);
+int XdbiCopen(dbiIndex dbi, /*@out@*/ DBC ** dbcp, unsigned int dbiflags, const char *f, unsigned int l);
 #define        dbiCopen(_a,_b,_c) \
        XdbiCopen(_a, _b, _c, __FILE__, __LINE__)
 
+#define        DBI_WRITECURSOR         (1 << 0)
+#define        DBI_ITERATOR            (1 << 1)
+
 /** \ingroup dbi
  * @param dbi          index database handle
  * @param flags                (unused)
index acbb311..a19934e 100644 (file)
@@ -102,7 +102,8 @@ typedef enum rpmerrCode_e {
     RPMERR_SIGVFY      = _nm(202), /*!< */
 
     RPMWARN_UNLINK     = _wm(512u+16),  /*!< unlink(2) failed */
-    RPMWARN_RMDIR      = _wm(512u+17)   /*!< rmdir(2) failed */
+    RPMWARN_RMDIR      = _wm(512u+17),  /*!< rmdir(2) failed */
+    RPMWARN_FLOCK      = _wm(512u+27)   /*!< locking the database failed */
 } rpmerrCode;
 
 /**
index 252aea0..c14dfa7 100644 (file)
@@ -157,7 +157,7 @@ char *      rpmExpand       (/*@null@*/ const char * arg, ...)
  * @param path         macro(s) to expand (NULL terminates list)
  * @return             canonicalized path (malloc'ed)
  */
-const char *rpmGetPath (/*@null@*/ const char * path, ...)
+const char * rpmGetPath        (/*@null@*/ const char * path, ...)
        /*@*/;
 
 /**
@@ -170,7 +170,7 @@ const char *rpmGetPath      (/*@null@*/ const char * path, ...)
  * @param file         file URL (often a file, or NULL)
  * @return             expanded, merged, canonicalized path (malloc'ed)
  */
-const char *rpmGenPath (/*@null@*/ const char * root,
+const char * rpmGenPath        (/*@null@*/ const char * root,
                        /*@null@*/ const char * mdir,
                        /*@null@*/ const char * file)
        /*@*/;