- API: change dbi to pass by reference, not value.
authorjbj <devnull@localhost>
Thu, 23 Mar 2000 15:49:50 +0000 (15:49 +0000)
committerjbj <devnull@localhost>
Thu, 23 Mar 2000 15:49:50 +0000 (15:49 +0000)
- cram all of db1, db_185, and db2 interfaces into rpmlib.

CVS patchset: 3636
CVS date: 2000/03/23 15:49:50

43 files changed:
CHANGES
build/parsePreamble.c
build/spec.c
configure.in
lib/.lclintrc
lib/Makefile.am
lib/cpio.c
lib/cpio.h
lib/db0.c [new file with mode: 0644]
lib/db0.h [new file with mode: 0644]
lib/db1.c [new file with mode: 0644]
lib/db1.h [new file with mode: 0644]
lib/db2.c [new file with mode: 0644]
lib/db2.h [new file with mode: 0644]
lib/dbindex.c
lib/dbindex.h
lib/depends.c
lib/fprint.c
lib/hash.c
lib/hash.h
lib/install.c
lib/lookup.c
lib/lookup.h
lib/md5.c
lib/misc.c
lib/misc.h
lib/query.c
lib/rebuilddb.c
lib/rpmdb.c
lib/rpmdb.h
lib/rpminstall.c
lib/rpmio.h
lib/rpmlib.h
lib/rpmrc.c
lib/transaction.c
lib/uninstall.c
lib/verify.c
perl/Makefile.PL
perl/Makefile.in
po/rpm.pot
python/Makefile.in
rpm.spec
scripts/Makefile.in

diff --git a/CHANGES b/CHANGES
index fb76296..7b5af42 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
 3.0.4 -> 3.1
        - use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
        - configure.in fiddles for BSD systems (Patrick Schoo).
+       - API: change dbi to pass by reference, not value.
+       - cram all of db1, db_185, and db2 interfaces into rpmlib.
 
 3.0.3 -> 3.0.4
        - use compressed filenames on install side.
index 98bd790..acb1433 100644 (file)
@@ -47,9 +47,8 @@ static void addOrAppendListEntry(Header h, int_32 tag, char *line)
     const char **argv;
 
     poptParseArgvString(line, &argc, &argv);
-    if (argc) {
+    if (argc)
        headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, argv, argc);
-    }
     FREE(argv);
 }
 
@@ -168,7 +167,7 @@ static int checkForValidArchitectures(Spec spec)
     return 0;
 }
 
-static int checkForRequired(Header h, char *name)
+static int checkForRequired(Header h, const char *name)
 {
     int res = 0;
     int *p;
@@ -184,7 +183,7 @@ static int checkForRequired(Header h, char *name)
     return res;
 }
 
-static int checkForDuplicates(Header h, char *name)
+static int checkForDuplicates(Header h, const char *name)
 {
     int res = 0;
     int lastTag, tag;
index 113809f..feb0b4e 100644 (file)
@@ -174,9 +174,8 @@ void freePackages(Spec spec)
 {
     Package p;
 
-    while (spec->packages) {
-       p = spec->packages;
-       spec->packages = spec->packages->next;
+    while ((p = spec->packages) != NULL) {
+       spec->packages = p->next;
        p->next = NULL;
        freePackage(p);
     }
index 31e543f..d6eea27 100644 (file)
@@ -308,11 +308,23 @@ dnl for this macro (not LIBS=...), otherwise the check for dbopen
 dnl will fail.
 AC_CHECK_LIB(port, writev)
 
-AC_CHECK_FUNC(dbopen, [],
-  AC_CHECK_LIB(db1, dbopen, [LIBS="$LIBS -ldb1"],
-    AC_CHECK_LIB(db, dbopen, [LIBS="$LIBS -ldb"],
-       AC_MSG_ERROR([sorry rpm requires a db-1.85 API])))
-           )
+DBLIBOBJS=""
+dnl Check for Berkeley db2 API.
+AC_CHECK_FUNC(db_open, [DBLIBOBJS="$DBLIBOBJS db2.c"],
+  AC_CHECK_LIB(db, db_open, [LIBS="$LIBS -ldb"; DBLIBOBJS="$DBLIBOBJS db2.c"])
+)
+dnl Check for Berkeley db1 API retrofit to db2 database.
+AC_CHECK_FUNC(dbopen, [DBLIBOBJS="$DBLIBOBJS db1.c"],
+    AC_CHECK_LIB(db, dbopen, [DBLIBOBJS="$DBLIBOBJS db1.c"])
+)
+dnl Check for Berkeley db1 API in glibc.
+AC_CHECK_LIB(db1, dbopen, [DBLIBOBJS="$DBLIBOBJS db0.c"])
+
+if test X"$DBLIBOBJS" = X; then
+    AC_MSG_ERROR([sorry rpm requires libdb.a or libdb1.a (from the Berkeley db package)]) 
+fi
+dnl AC_DEFINE_UNQUOTED(DBLIBOBJS, "$DBLIBOBJS")
+AC_SUBST(DBLIBOBJS)
 
 AC_CHECK_FUNC(fork, [], [echo "using vfork() instead of fork()";
        LIBOBJS=fakefork.o])
index 5ff453c..d4ad2d0 100644 (file)
@@ -7,6 +7,9 @@
 
 +unixlib
 
+# XXX ignore doxygen markings
+-unrecogcomments
+
 # don't-bother-me-yet parameters
 -branchstate
 #-immediatetrans
index e6abb9c..ee21c3e 100644 (file)
@@ -4,6 +4,8 @@ AUTOMAKE_OPTIONS = 1.4 foreign
 
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/build -I$(top_srcdir)/popt @INCPATH@
 
+EXTRA_DIST = db0.[ch] db1.[ch] db2.[ch]
+
 pkgincdir = $(pkgincludedir)
 pkginc_HEADERS = \
        dbindex.h header.h misc.h rpmio.h rpmlib.h rpmmacro.h rpmurl.h stringbuf.h
@@ -17,15 +19,53 @@ mylibs=     -lrpm -lpopt @INTLLIBS@ @LIBMISC@
 
 lib_LTLIBRARIES = librpm.la
 librpm_la_SOURCES = \
-       cpio.c dbindex.c depends.c falloc.c \
+       cpio.c $(DBLIBOBJS) dbindex.c depends.c falloc.c \
        formats.c fprint.c fs.c hash.c header.c install.c \
        lookup.c macro.c md5.c md5sum.c \
        messages.c misc.c oldheader.c package.c problems.c query.c \
        rebuilddb.c rpmchecksig.c rpmdb.c rpmerr.c rpminstall.c \
        rpmio.c rpmlead.c rpmmalloc.c rpmrc.c signature.c stringbuf.c stubs.c \
        tagName.c tagtable.c transaction.c uninstall.c url.c verify.c
+librpm_la_LIBADD = $(subst .c,.lo,$(DBLIBOBJS))
 #librpm_la_LIBADD = -lpopt
 
+Xdb0.o:        db0.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+       @__LD@ -r -o $@.o $@ -L/usr/lib -ldb1
+       @__OBJCOPY@ `\
+           @__NM@ -g --defined-only $@.o | \
+           sed -e '/ [TWD] /!d' -e 's/.* [TWD] /-L /' | \
+           grep -v '^-L $*'` $@.o $@
+       rm -f $@.o
+
+db0.lo: db0.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+       @__LD@ -r -o $*.o.o $*.o -L/usr/lib -ldb1
+       @__OBJCOPY@ `\
+           @__NM@ -g --defined-only $*.o.o | \
+           sed -e '/ [TWD] /!d' -e 's/.* [TWD] /-L /' | \
+           grep -v '^-L $*'` $*.o.o $*.o
+       rm -f $*.o.o
+       @__LD@ -r -o $@.o $@ -L/usr/lib -ldb1
+       @__OBJCOPY@ `\
+           @__NM@ -g --defined-only $@.o | \
+           sed -e '/ [TWD] /!d' -e 's/.* [TWD] /-L /' | \
+           grep -v '^-L $*'` $@.o $@
+       rm -f $@.o
+
 tagtable.c: rpmlib.h 
        @echo '#include "system.h"' > tagtable.c
        @echo '#include "rpmlib.h"' >> tagtable.c
index 93c4972..5babb39 100644 (file)
@@ -1,16 +1,22 @@
+/** \file lib/cpio.c
+ *  Handle cpio payloads within rpm packages.
+ *
+ * @warning FIXME: We don't translate between cpio and system mode bits! These
+ * should both be the same, but really odd things are going to happen if
+ * that's not true!
+ */
+
 #include "system.h"
 
 #include <rpmio.h>
 #include "cpio.h"
 
+#define        xfree(_p)       free((void *)_p)
+
 #define CPIO_NEWC_MAGIC        "070701"
 #define CPIO_CRC_MAGIC "070702"
 #define TRAILER                "TRAILER!!!"
 
-/* FIXME: We don't translate between cpio and system mode bits! These
-   should both be the same, but really odd things are going to happen if
-   that's not true! */
-
 /** */
 struct hardLink {
     struct hardLink * next;
@@ -18,12 +24,14 @@ struct hardLink {
     int * fileMaps;            /* used by build */
     dev_t dev;
     ino_t inode;
-    int nlink;                 
+    int nlink;
     int linksLeft;
     int createdPath;
     struct stat sb;
 };
 
+enum hardLinkType { HARDLINK_INSTALL=1, HARDLINK_BUILD };
+
 /** */
 struct cpioCrcPhysicalHeader {
     char magic[6];
@@ -46,15 +54,8 @@ struct cpioCrcPhysicalHeader {
 
 /** */
 struct cpioHeader {
-    ino_t inode;
-    mode_t mode;
-    uid_t uid;
-    gid_t gid;
-    int nlink;
-    time_t mtime;
-    long size;
-    dev_t dev, rdev;
-    /*@owned@*/char * path;
+    /*@owned@*/ const char * path;
+    struct stat sb;
 };
 
 /** */
@@ -92,7 +93,7 @@ static inline void padinfd(FD_t cfd, int modulo)
 {
     int buf[10];
     int amount;
-    
+
     amount = (modulo - fdGetCpioPos(cfd) % modulo) % modulo;
     (void)ourread(cfd, buf, amount);
 }
@@ -116,7 +117,7 @@ static inline off_t safewrite(FD_t cfd, const void * vbuf, size_t amount)
        amount -= nb;
     }
 
-    return rc; 
+    return rc;
 }
 
 /** */
@@ -124,11 +125,11 @@ static inline int padoutfd(FD_t cfd, size_t * where, int modulo)
 {
     static int buf[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     int amount;
-    
+
     amount = (modulo - *where % modulo) % modulo;
     *where += amount;
 
-    if (safewrite(cfd, buf, amount) != amount) 
+    if (safewrite(cfd, buf, amount) != amount)
        return CPIOERR_WRITE_FAILED;
     return 0;
 }
@@ -160,46 +161,49 @@ static int strntoul(const char *str, /*@out@*/char **endptr, int base, int num)
        memcpy(phys, space, 8);
 
 /** */
-static int getNextHeader(FD_t cfd, /*@out@*/ struct cpioHeader * chPtr)
+static int getNextHeader(FD_t cfd, struct cpioHeader * hdr)
 {
     struct cpioCrcPhysicalHeader physHeader;
+    struct stat * st = &hdr->sb;
     int nameSize;
     char * end;
     int major, minor;
 
-    if (ourread(cfd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) 
+    if (ourread(cfd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE)
        return CPIOERR_READ_FAILED;
 
     if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, sizeof(CPIO_CRC_MAGIC)-1) &&
        strncmp(CPIO_NEWC_MAGIC, physHeader.magic, sizeof(CPIO_NEWC_MAGIC)-1))
        return CPIOERR_BAD_MAGIC;
 
-    GET_NUM_FIELD(physHeader.inode, chPtr->inode);
-    GET_NUM_FIELD(physHeader.mode, chPtr->mode);
-    GET_NUM_FIELD(physHeader.uid, chPtr->uid);
-    GET_NUM_FIELD(physHeader.gid, chPtr->gid);
-    GET_NUM_FIELD(physHeader.nlink, chPtr->nlink);
-    GET_NUM_FIELD(physHeader.mtime, chPtr->mtime);
-    GET_NUM_FIELD(physHeader.filesize, chPtr->size);
+    GET_NUM_FIELD(physHeader.inode, st->st_ino);
+    GET_NUM_FIELD(physHeader.mode, st->st_mode);
+    GET_NUM_FIELD(physHeader.uid, st->st_uid);
+    GET_NUM_FIELD(physHeader.gid, st->st_gid);
+    GET_NUM_FIELD(physHeader.nlink, st->st_nlink);
+    GET_NUM_FIELD(physHeader.mtime, st->st_mtime);
+    GET_NUM_FIELD(physHeader.filesize, st->st_size);
 
     GET_NUM_FIELD(physHeader.devMajor, major);
     GET_NUM_FIELD(physHeader.devMinor, minor);
-    chPtr->dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
+    st->st_dev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
 
     GET_NUM_FIELD(physHeader.rdevMajor, major);
     GET_NUM_FIELD(physHeader.rdevMinor, minor);
-    chPtr->rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
+    st->st_rdev = /*@-shiftsigned@*/ makedev(major, minor) /*@=shiftsigned@*/ ;
 
     GET_NUM_FIELD(physHeader.namesize, nameSize);
 
-    chPtr->path = xmalloc(nameSize + 1);
-    if (ourread(cfd, chPtr->path, nameSize) != nameSize) {
-       free(chPtr->path);
-       chPtr->path = NULL;
-       return CPIOERR_BAD_HEADER;
+    {  char * t = xmalloc(nameSize + 1);
+       if (ourread(cfd, t, nameSize) != nameSize) {
+           free(t);
+           hdr->path = NULL;
+           return CPIOERR_BAD_HEADER;
+       }
+       hdr->path = t;
     }
 
-    /* this is unecessary chPtr->path[nameSize] = '\0'; */
+    /* this is unecessary hdr->path[nameSize] = '\0'; */
 
     padinfd(cfd, 4);
 
@@ -217,7 +221,7 @@ int cpioFileMapCmp(const void * a, const void * b)
 
 /* This could trash files in the path! I'm not sure that's a good thing */
 /** */
-static int createDirectory(char * path, mode_t perms)
+static int createDirectory(const char * path, mode_t perms)
 {
     struct stat sb;
 
@@ -227,7 +231,7 @@ static int createDirectory(char * path, mode_t perms)
            return 0;
        } else if (S_ISLNK(sb.st_mode)) {
            if (stat(path, &sb)) {
-               if (errno != ENOENT) 
+               if (errno != ENOENT)
                    return CPIOERR_STAT_FAILED;
                dounlink = 1;
            } else {
@@ -258,20 +262,21 @@ static int setInfo(struct cpioHeader * hdr)
 {
     int rc = 0;
     struct utimbuf stamp;
+    struct stat * st = &hdr->sb;
 
-    stamp.actime = hdr->mtime; 
-    stamp.modtime = hdr->mtime;
+    stamp.actime = st->st_mtime;
+    stamp.modtime = st->st_mtime;
 
-    if (!S_ISLNK(hdr->mode)) {
-       if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid))
+    if (!S_ISLNK(st->st_mode)) {
+       if (!getuid() && chown(hdr->path, st->st_uid, st->st_gid))
            rc = CPIOERR_CHOWN_FAILED;
-       if (!rc && chmod(hdr->path, hdr->mode & 07777))
+       if (!rc && chmod(hdr->path, st->st_mode & 07777))
            rc = CPIOERR_CHMOD_FAILED;
        if (!rc && utime(hdr->path, &stamp))
            rc = CPIOERR_UTIME_FAILED;
     } else {
 #       if ! CHOWN_FOLLOWS_SYMLINK
-           if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid))
+           if (!getuid() && !rc && lchown(hdr->path, st->st_uid, st->st_gid))
                rc = CPIOERR_CHOWN_FAILED;
 #       endif
     }
@@ -332,7 +337,8 @@ static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
     FD_t ofd;
     char buf[BUFSIZ];
     int bytesRead;
-    int left = hdr->size;
+    struct stat * st = &hdr->sb;
+    int left = st->st_size;
     int rc = 0;
     struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
     struct stat sb;
@@ -361,7 +367,7 @@ static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
        return CPIOERR_OPEN_FAILED;
 
     cbInfo.file = hdr->path;
-    cbInfo.fileSize = hdr->size;
+    cbInfo.fileSize = st->st_size;
 
     while (left) {
        bytesRead = ourread(cfd, buf, left < sizeof(buf) ? left : sizeof(buf));
@@ -379,14 +385,14 @@ static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
 
        /* don't call this with fileSize == fileComplete */
        if (!rc && cb && left) {
-           cbInfo.fileComplete = hdr->size - left;
+           cbInfo.fileComplete = st->st_size - left;
            cbInfo.bytesProcessed = fdGetCpioPos(cfd);
            cb(&cbInfo, cbData);
        }
     }
 
     Fclose(ofd);
-    
+
     return rc;
 }
 
@@ -395,15 +401,16 @@ static int expandSymlink(FD_t cfd, struct cpioHeader * hdr)
 {
     char buf[2048], buf2[2048];
     struct stat sb;
+    struct stat * st = &hdr->sb;
     int len;
 
-    if ((hdr->size + 1)> sizeof(buf))
+    if ((st->st_size + 1)> sizeof(buf))
        return CPIOERR_HDR_SIZE;
 
-    if (ourread(cfd, buf, hdr->size) != hdr->size)
+    if (ourread(cfd, buf, st->st_size) != st->st_size)
        return CPIOERR_READ_FAILED;
 
-    buf[hdr->size] = '\0';
+    buf[st->st_size] = '\0';
 
     if (!lstat(hdr->path, &sb)) {
        if (S_ISLNK(sb.st_mode)) {
@@ -439,50 +446,87 @@ static int expandFifo( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
     if (mkfifo(hdr->path, 0))
        return CPIOERR_MKFIFO_FAILED;
 
-    return 0; 
+    return 0;
 }
 
 /** */
 static int expandDevice( /*@unused@*/ FD_t cfd, struct cpioHeader * hdr)
 {
+    struct stat * st = &hdr->sb;
     struct stat sb;
 
     if (!lstat(hdr->path, &sb)) {
-       if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && 
-               (sb.st_rdev == hdr->rdev))
+       if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) &&
+               (sb.st_rdev == st->st_rdev))
            return 0;
        if (unlink(hdr->path))
            return CPIOERR_UNLINK_FAILED;
     }
 
-    if ( /*@-unrecog@*/ mknod(hdr->path, hdr->mode & (~0777), hdr->rdev) /*@=unrecog@*/ )
+    if ( /*@-unrecog@*/ mknod(hdr->path, st->st_mode & (~0777), st->st_rdev) /*@=unrecog@*/ )
        return CPIOERR_MKNOD_FAILED;
-    
+
     return 0;
 }
 
 /** */
-static void freeLink( /*@only@*/ struct hardLink * li)
+static /*@only@*/ struct hardLink * newHardLink(const struct stat * st,
+                               enum hardLinkType hltype)
 {
-    int i;
+    struct hardLink * li = xmalloc(sizeof(*li));
+
+    li->next = NULL;
+    li->nlink = st->st_nlink;
+    li->dev = st->st_dev;
+    li->inode = st->st_ino;
+    li->createdPath = -1;
+
+    switch (hltype) {
+    case HARDLINK_INSTALL:
+       li->linksLeft = st->st_nlink;
+       li->fileMaps = xmalloc(sizeof(li->fileMaps[0]) * st->st_nlink);
+       li->files = NULL;
+       break;
+    case HARDLINK_BUILD:
+       li->linksLeft = 0;
+       li->fileMaps = NULL;
+       li->files = xcalloc(st->st_nlink, sizeof(*li->files));
+       break;
+    }
+    li->sb = *st;      /* structure assignment */
+    return li;
+}
 
-    for (i = 0; i < li->nlink; i++) {
-       if (li->files[i] == NULL) continue;
-       /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
-       li->files[i] = NULL;
+/** */
+static void freeHardLink( /*@only@*/ struct hardLink * li)
+{
+
+    if (li->files) {
+       int i;
+       for (i = 0; i < li->nlink; i++) {
+           if (li->files[i] == NULL) continue;
+           /*@-unqualifiedtrans@*/ free((void *)li->files[i]) /*@=unqualifiedtrans@*/ ;
+           li->files[i] = NULL;
+       }
+       free(li->files);
+       li->files = NULL;
+    }
+    if (li->fileMaps) {
+       free(li->fileMaps);
+       li->fileMaps = NULL;
     }
-    free(li->files);
+    free(li);
 }
 
 /** */
-static int createLinks(struct hardLink * li, /*@out@*/const char ** failedFile)
+static int createLinks(struct hardLink * li, /*@out@*/ const char ** failedFile)
 {
     int i;
     struct stat sb;
 
     for (i = 0; i < li->nlink; i++) {
        if (i == li->createdPath) continue;
-       if (!li->files[i]) continue;
+       if (li->files[i] == NULL) continue;
 
        if (!lstat(li->files[i], &sb)) {
            if (unlink(li->files[i])) {
@@ -511,7 +555,7 @@ static int eatBytes(FD_t cfd, int amount)
 {
     char buf[4096];
     int bite;
-   
+
     while (amount) {
        bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
        if (ourread(cfd, buf, bite) != bite)
@@ -523,16 +567,14 @@ static int eatBytes(FD_t cfd, int amount)
 }
 
 /** */
-int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings, 
+int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
                       int numMappings, cpioCallback cb, void * cbData,
                       const char ** failedFile)
 {
-    struct cpioHeader ch;
+    struct cpioHeader ch, *hdr = &ch;
     int rc = 0;
-    int linkNum = 0;
     struct cpioFileMapping * map = NULL;
     struct cpioFileMapping needle;
-    mode_t cpioMode;
     int olderr;
     struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
     struct hardLink * links = NULL;
@@ -542,74 +584,71 @@ int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
     if (failedFile)
        *failedFile = NULL;
 
-    ch.path = NULL;
-    do {
-       if ((rc = getNextHeader(cfd, &ch))) {
+    memset(hdr, 0, sizeof(*hdr));
+    hdr->path = NULL;
+    rc = 0;
+    while (rc == 0) {
+       struct stat * st;
+
+       if (hdr->path) {
+           xfree(hdr->path);
+           hdr->path = NULL;
+       }
+       if ((rc = getNextHeader(cfd, hdr))) {
 #if 0  /* XXX this is the failure point for an unreadable rpm */
            fprintf(stderr, _("getNextHeader: %s\n"), cpioStrerror(rc));
 #endif
            return rc;
        }
+       st = &hdr->sb;
 
-       if (!strcmp(ch.path, TRAILER)) {
-           if (ch.path) free(ch.path);
+       if (!strcmp(hdr->path, TRAILER))
            break;
-       }
 
        if (mappings) {
-           needle.archivePath = ch.path;
+           needle.archivePath = hdr->path;
            map = bsearch(&needle, mappings, numMappings, sizeof(needle),
                          cpioFileMapCmp);
        }
 
        if (mappings && !map) {
-           eatBytes(cfd, ch.size);
+           eatBytes(cfd, st->st_size);
        } else {
-           cpioMode = ch.mode;
-
            if (map) {
                if (map->mapFlags & CPIO_MAP_PATH) {
-                   if (ch.path) free(ch.path);
-                   ch.path = xstrdup(map->fsPath);
-               } 
+                   if (hdr->path) xfree(hdr->path);
+                   hdr->path = xstrdup(map->fsPath);
+               }
 
                if (map->mapFlags & CPIO_MAP_MODE)
-                   ch.mode = map->finalMode;
+                   st->st_mode = map->finalMode;
                if (map->mapFlags & CPIO_MAP_UID)
-                   ch.uid = map->finalUid;
+                   st->st_uid = map->finalUid;
                if (map->mapFlags & CPIO_MAP_GID)
-                   ch.gid = map->finalGid;
+                   st->st_gid = map->finalGid;
            }
 
-           /* This won't get hard linked symlinks right, but I can't seem 
+           /* This won't get hard linked symlinks right, but I can't seem
               to create those anyway */
 
-           if (S_ISREG(ch.mode) && ch.nlink > 1) {
+           if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
                for (li = links; li; li = li->next) {
-                   if (li->inode == ch.inode && li->dev == ch.dev) break;
+                   if (li->inode == st->st_ino && li->dev == st->st_dev) break;
                }
 
                if (li == NULL) {
-                   li = xmalloc(sizeof(*li));
-                   li->inode = ch.inode;
-                   li->dev = ch.dev;
-                   li->nlink = ch.nlink;
-                   li->linksLeft = ch.nlink;
-                   li->createdPath = -1;
-                   li->files = xcalloc(li->nlink,(sizeof(*li->files)));
+                   li = newHardLink(st, HARDLINK_BUILD);
                    li->next = links;
                    links = li;
                }
 
-               for (linkNum = 0; linkNum < li->nlink; linkNum++)
-                   if (!li->files[linkNum]) break;
-               li->files[linkNum] = xstrdup(ch.path);
+               li->files[li->linksLeft++] = xstrdup(hdr->path);
            }
-               
-           if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
+
+           if ((st->st_nlink > 1) && S_ISREG(st->st_mode) && !st->st_size &&
                li->createdPath == -1) {
                /* defer file creation */
-           } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && 
+           } else if ((st->st_nlink > 1) && S_ISREG(st->st_mode) &&
                       (li->createdPath != -1)) {
                createLinks(li, failedFile);
 
@@ -618,44 +657,43 @@ int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
                   listed (intead of the data being given just once. This
                   shouldn't happen, but I've made it happen w/ buggy
                   code, so what the heck? GNU cpio handles this well fwiw */
-               if (ch.size) eatBytes(cfd, ch.size);
+               if (st->st_size) eatBytes(cfd, st->st_size);
            } else {
-               rc = checkDirectory(ch.path);
+               rc = checkDirectory(hdr->path);
 
                if (!rc) {
-                   if (S_ISREG(ch.mode))
-                       rc = expandRegular(cfd, &ch, cb, cbData);
-                   else if (S_ISDIR(ch.mode))
-                       rc = createDirectory(ch.path, 000);
-                   else if (S_ISLNK(ch.mode))
-                       rc = expandSymlink(cfd, &ch);
-                   else if (S_ISFIFO(ch.mode))
-                       rc = expandFifo(cfd, &ch);
-                   else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
-                       rc = expandDevice(cfd, &ch);
-                   else if (S_ISSOCK(ch.mode)) {
+                   if (S_ISREG(st->st_mode))
+                       rc = expandRegular(cfd, hdr, cb, cbData);
+                   else if (S_ISDIR(st->st_mode))
+                       rc = createDirectory(hdr->path, 000);
+                   else if (S_ISLNK(st->st_mode))
+                       rc = expandSymlink(cfd, hdr);
+                   else if (S_ISFIFO(st->st_mode))
+                       rc = expandFifo(cfd, hdr);
+                   else if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
+                       rc = expandDevice(cfd, hdr);
+                   else if (S_ISSOCK(st->st_mode)) {
                        /* this mimicks cpio but probably isnt' right */
-                       rc = expandFifo(cfd, &ch);
+                       rc = expandFifo(cfd, hdr);
                    } else {
                        rc = CPIOERR_UNKNOWN_FILETYPE;
                    }
                }
 
                if (!rc)
-                   rc = setInfo(&ch);
+                   rc = setInfo(hdr);
 
-               if (S_ISREG(ch.mode) && ch.nlink > 1) {
-                   li->createdPath = linkNum;
-                   li->linksLeft--;
+               if (S_ISREG(st->st_mode) && st->st_nlink > 1) {
+                   li->createdPath = li->linksLeft--;
                    rc = createLinks(li, failedFile);
                }
            }
 
            if (rc && failedFile && *failedFile == NULL) {
-               *failedFile = xstrdup(ch.path);
+               *failedFile = xstrdup(hdr->path);
 
                olderr = errno;
-               unlink(ch.path);
+               unlink(hdr->path);
                errno = olderr;
            }
        }
@@ -663,49 +701,41 @@ int cpioInstallArchive(FD_t cfd, struct cpioFileMapping * mappings,
        padinfd(cfd, 4);
 
        if (!rc && cb) {
-           cbInfo.file = ch.path;
-           cbInfo.fileSize = ch.size;
-           cbInfo.fileComplete = ch.size;
+           cbInfo.file = hdr->path;
+           cbInfo.fileSize = st->st_size;
+           cbInfo.fileComplete = st->st_size;
            cbInfo.bytesProcessed = fdGetCpioPos(cfd);
            cb(&cbInfo, cbData);
        }
 
-       if (ch.path) free(ch.path);
-       ch.path = NULL;
-    } while (1 && !rc);
+    }
+
+    if (hdr->path) {
+       xfree(hdr->path);
+       hdr->path = NULL;
+    }
+
+    /* Create any remaining links (if no error), and clean up. */
+    while ((li = links) != NULL) {
+       links = li->next;
+       li->next = NULL;
 
-    li = links;
-    while (li && !rc) {
-       if (li->linksLeft) {
+       if (rc == 0 && li->linksLeft) {
            if (li->createdPath == -1)
                rc = CPIOERR_MISSING_HARDLINK;
-           else 
+           else
                rc = createLinks(li, failedFile);
        }
 
-       freeLink(li);
-
-       links = li;
-       li = li->next;
-       free(links);
-       links = li;
-    }
-
-    li = links;
-    /* if an error got us here links will still be eating some memory */
-    while (li) {
-       freeLink(li);
-       links = li;
-       li = li->next;
-       free(links);
+       freeHardLink(li);
     }
 
     return rc;
 }
 
 /** */
-static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map, 
-                    /*@out@*/size_t * sizep, int writeData)
+static int writeFile(FD_t cfd, struct stat * st,
+       struct cpioFileMapping * map, /*@out@*/ size_t * sizep, int writeData)
 {
     struct cpioCrcPhysicalHeader hdr;
     char buf[8192], symbuf[2048];
@@ -717,15 +747,15 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
     if (!(map->mapFlags & CPIO_MAP_PATH))
        map->archivePath = map->fsPath;
     if (map->mapFlags & CPIO_MAP_MODE)
-       sb.st_mode = (sb.st_mode & S_IFMT) | map->finalMode;
+       st->st_mode = (st->st_mode & S_IFMT) | map->finalMode;
     if (map->mapFlags & CPIO_MAP_UID)
-       sb.st_uid = map->finalUid;
+       st->st_uid = map->finalUid;
     if (map->mapFlags & CPIO_MAP_GID)
-       sb.st_gid = map->finalGid;
+       st->st_gid = map->finalGid;
 
-    if (!writeData || S_ISDIR(sb.st_mode)) {
-       sb.st_size = 0;
-    } else if (S_ISLNK(sb.st_mode)) {
+    if (!writeData || S_ISDIR(st->st_mode)) {
+       st->st_size = 0;
+    } else if (S_ISLNK(st->st_mode)) {
        /* While linux puts the size of a symlink in the st_size field,
           I don't think that's a specified standard */
 
@@ -734,22 +764,22 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
            return CPIOERR_READLINK_FAILED;
        }
 
-       sb.st_size = amount;
+       st->st_size = amount;
     }
 
     memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
-    SET_NUM_FIELD(hdr.inode, sb.st_ino, buf);
-    SET_NUM_FIELD(hdr.mode, sb.st_mode, buf);
-    SET_NUM_FIELD(hdr.uid, sb.st_uid, buf);
-    SET_NUM_FIELD(hdr.gid, sb.st_gid, buf);
-    SET_NUM_FIELD(hdr.nlink, sb.st_nlink, buf);
-    SET_NUM_FIELD(hdr.mtime, sb.st_mtime, buf);
-    SET_NUM_FIELD(hdr.filesize, sb.st_size, buf);
-
-    num = major((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMajor, num, buf);
-    num = minor((unsigned)sb.st_dev); SET_NUM_FIELD(hdr.devMinor, num, buf);
-    num = major((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMajor, num, buf);
-    num = minor((unsigned)sb.st_rdev); SET_NUM_FIELD(hdr.rdevMinor, num, buf);
+    SET_NUM_FIELD(hdr.inode, st->st_ino, buf);
+    SET_NUM_FIELD(hdr.mode, st->st_mode, buf);
+    SET_NUM_FIELD(hdr.uid, st->st_uid, buf);
+    SET_NUM_FIELD(hdr.gid, st->st_gid, buf);
+    SET_NUM_FIELD(hdr.nlink, st->st_nlink, buf);
+    SET_NUM_FIELD(hdr.mtime, st->st_mtime, buf);
+    SET_NUM_FIELD(hdr.filesize, st->st_size, buf);
+
+    num = major((unsigned)st->st_dev); SET_NUM_FIELD(hdr.devMajor, num, buf);
+    num = minor((unsigned)st->st_dev); SET_NUM_FIELD(hdr.devMinor, num, buf);
+    num = major((unsigned)st->st_rdev); SET_NUM_FIELD(hdr.rdevMajor, num, buf);
+    num = minor((unsigned)st->st_rdev); SET_NUM_FIELD(hdr.rdevMinor, num, buf);
 
     num = strlen(map->archivePath) + 1; SET_NUM_FIELD(hdr.namesize, num, buf);
     memcpy(hdr.checksum, "00000000", 8);
@@ -761,8 +791,8 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
     size = PHYS_HDR_SIZE + num;
     if ((rc = padoutfd(cfd, &size, 4)))
        return rc;
-       
-    if (writeData && S_ISREG(sb.st_mode)) {
+
+    if (writeData && S_ISREG(st->st_mode)) {
        char *b;
 #if HAVE_MMAP
        void *mapped;
@@ -776,19 +806,19 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
 
 #if HAVE_MMAP
        nmapped = 0;
-       mapped = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, Fileno(datafd), 0);
+       mapped = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, Fileno(datafd), 0);
        if (mapped != (void *)-1) {
            b = (char *)mapped;
-           nmapped = sb.st_size;
+           nmapped = st->st_size;
        } else
 #endif
        {
            b = buf;
        }
 
-       size += sb.st_size;
+       size += st->st_size;
 
-       while (sb.st_size) {
+       while (st->st_size) {
 #if HAVE_MMAP
          if (mapped != (void *)-1) {
            amount = nmapped;
@@ -796,7 +826,7 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
 #endif
          {
            amount = Fread(b, sizeof(buf[0]),
-                       (sb.st_size > sizeof(buf) ? sizeof(buf) : sb.st_size),
+                       (st->st_size > sizeof(buf) ? sizeof(buf) : st->st_size),
                        datafd);
            if (amount <= 0) {
                olderrno = errno;
@@ -813,17 +843,17 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
                return rc;
            }
 
-           sb.st_size -= amount;
+           st->st_size -= amount;
        }
 
 #if HAVE_MMAP
        if (mapped != (void *)-1) {
-           munmap(mapped, nmapped);
+           /*@-noeffect@*/ munmap(mapped, nmapped) /*@=noeffect@*/;
        }
 #endif
 
        Fclose(datafd);
-    } else if (writeData && S_ISLNK(sb.st_mode)) {
+    } else if (writeData && S_ISLNK(st->st_mode)) {
        if ((rc = safewrite(cfd, symbuf, amount)) != amount)
            return rc;
        size += amount;
@@ -840,7 +870,7 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
 }
 
 /** */
-static int writeLinkedFile(FD_t cfd, struct hardLink * hlink, 
+static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
                           struct cpioFileMapping * mappings,
                           cpioCallback cb, void * cbData,
                           /*@out@*/size_t * sizep,
@@ -853,7 +883,7 @@ static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
     total = 0;
 
     for (i = hlink->nlink - 1; i > hlink->linksLeft; i--) {
-       if ((rc = writeFile(cfd, hlink->sb, mappings + hlink->fileMaps[i], 
+       if ((rc = writeFile(cfd, &hlink->sb, mappings + hlink->fileMaps[i],
                            &size, 0))) {
            if (failedFile)
                *failedFile = xstrdup(mappings[hlink->fileMaps[i]].fsPath);
@@ -868,12 +898,12 @@ static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
        }
     }
 
-    if ((rc = writeFile(cfd, hlink->sb, 
-                       mappings + hlink->fileMaps[hlink->linksLeft], 
+    if ((rc = writeFile(cfd, &hlink->sb,
+                       mappings + hlink->fileMaps[hlink->linksLeft],
                        &size, 1))) {
        if (sizep)
            *sizep = total;
-       if (failedFile) 
+       if (failedFile)
            *failedFile = xstrdup(mappings[hlink->fileMaps[hlink->linksLeft]].fsPath);
        return rc;
     }
@@ -891,7 +921,7 @@ static int writeLinkedFile(FD_t cfd, struct hardLink * hlink,
 }
 
 /** */
-int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings, 
+int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
                     int numMappings, cpioCallback cb, void * cbData,
                     unsigned int * archiveSize, const char ** failedFile)
 {
@@ -900,19 +930,19 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
     int i;
     struct cpioCallbackInfo cbInfo = { NULL, 0, 0, 0 };
     struct cpioCrcPhysicalHeader hdr;
-    struct stat sb;
 /*@-fullinitblock@*/
     struct hardLink hlinkList = { NULL };
 /*@=fullinitblock@*/
-    struct hardLink * hlink, * parent;
+    struct stat * st = &hlinkList.sb;
+    struct hardLink * hlink;
 
     hlinkList.next = NULL;
 
     for (i = 0; i < numMappings; i++) {
        if (mappings[i].mapFlags & CPIO_FOLLOW_SYMLINKS)
-           rc = Stat(mappings[i].fsPath, &sb);
+           rc = Stat(mappings[i].fsPath, st);
        else
-           rc = Lstat(mappings[i].fsPath, &sb);
+           rc = Lstat(mappings[i].fsPath, st);
 
        if (rc) {
            if (failedFile)
@@ -920,42 +950,40 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
            return CPIOERR_STAT_FAILED;
        }
 
-       if (!S_ISDIR(sb.st_mode) && sb.st_nlink > 1) {
+       if (!S_ISDIR(st->st_mode) && st->st_nlink > 1) {
            hlink = hlinkList.next;
-           while (hlink && 
-                  (hlink->dev != sb.st_dev || hlink->inode != sb.st_ino))
-               hlink = hlink->next;
-           if (!hlink) {
-               hlink = xmalloc(sizeof(*hlink));
+           while (hlink &&
+                 (hlink->dev != st->st_dev || hlink->inode != st->st_ino))
+                       hlink = hlink->next;
+           if (hlink == NULL) {
+               hlink = newHardLink(st, HARDLINK_INSTALL);
                hlink->next = hlinkList.next;
                hlinkList.next = hlink;
-               hlink->sb = sb;         /* structure assignment */
-               hlink->dev = sb.st_dev;
-               hlink->inode = sb.st_ino;
-               hlink->nlink = sb.st_nlink;
-               hlink->linksLeft = sb.st_nlink;
-               hlink->fileMaps = xmalloc(sizeof(*hlink->fileMaps) * 
-                                               sb.st_nlink);
            }
 
            hlink->fileMaps[--hlink->linksLeft] = i;
 
-           if (!hlink->linksLeft) {
+           if (hlink->linksLeft == 0) {
+               struct hardLink * prev;
                if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
                                          &size, failedFile)))
                    return rc;
 
                totalsize += size;
 
-               free(hlink->fileMaps);
-
-               parent = &hlinkList;
-               while (parent->next != hlink) parent = parent->next;
-               parent->next = parent->next->next;
-               free(hlink);
+               prev = &hlinkList;
+               do {
+                   if (prev->next != hlink)
+                       continue;
+                   prev->next = hlink->next;
+                   hlink->next = NULL;
+                   freeHardLink(hlink);
+                   hlink = NULL;
+                   break;
+               } while ((prev = prev->next) != NULL);
            }
        } else {
-           if ((rc = writeFile(cfd, sb, mappings + i, &size, 1))) {
+           if ((rc = writeFile(cfd, st, mappings + i, &size, 1))) {
                if (failedFile)
                    *failedFile = xstrdup(mappings[i].fsPath);
                return rc;
@@ -968,20 +996,22 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
 
            totalsize += size;
        }
-    }    
+    }
 
-    hlink = hlinkList.next;
-    while (hlink) {
-       if ((rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
-                                 &size, failedFile)))
-           return rc;
-       free(hlink->fileMaps);
-       parent = hlink;
-       hlink = hlink->next;
-       free(parent);
+    rc = 0;
+    while ((hlink = hlinkList.next) != NULL) {
+       hlinkList.next = hlink->next;
+       hlink->next = NULL;
 
-       totalsize += size;
+       if (rc == 0) {
+           rc = writeLinkedFile(cfd, hlink, mappings, cb, cbData,
+                                 &size, failedFile);
+           totalsize += size;
+       }
+       freeHardLink(hlink);
     }
+    if (rc)
+       return rc;
 
     memset(&hdr, '0', PHYS_HDR_SIZE);
     memcpy(hdr.magic, CPIO_NEWC_MAGIC, sizeof(hdr.magic));
@@ -995,7 +1025,7 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
 
     /* GNU cpio pads to 512 bytes here, but we don't. I'm not sure if
        it matters or not */
-    
+
     if ((rc = padoutfd(cfd, &totalsize, 4)))
        return rc;
 
index ed19f89..fb95c72 100644 (file)
@@ -8,7 +8,7 @@
  *  standard cpio.
  *  The implementation is pretty close, but it has some behaviors which are
  *  more to RPM's liking. I tried to document the differing behavior in cpio.c,
- *  but I may have missed some.
+ *  but I may have missed some (ewt).
  *
  */
 
 #define CPIO_MAP_GID           (1 << 3)
 #define CPIO_FOLLOW_SYMLINKS   (1 << 4)  /* only for building */
 
-/** The structure used to define a cpio payload file. */
+/**
+ * Defines a single file to be included in a cpio payload.
+ */
 struct cpioFileMapping {
-/*@{*/
-    /*@owned@*/ const char * archivePath; /*!< Path to store in cpio archive. */
-    /*@owned@*/ const char * fsPath;   /*!< Location of payload file. */
+/*@dependent@*/ const char * archivePath; /*!< Path to store in cpio archive. */
+/*@dependent@*/ const char * fsPath;      /*!< Location of payload file. */
     mode_t finalMode;          /*!< Mode of payload file (from header). */
     uid_t finalUid;            /*!< Uid of payload file (from header). */
     gid_t finalGid;            /*!< Gid of payload file (from header). */
     int mapFlags;
-/*@}*/
 };
 
-/** The structure passed as first argument during a cpio progress callback.
+/**
+ * The first argument passed in a cpio progress callback.
  *
  * Note: When building the cpio payload, only "file" is filled in.
  */
 struct cpioCallbackInfo {
-/*@{*/
-    /*@dependent@*/ const char * file; /*!< File name being installed. */
+/*@dependent@*/ const char * file;     /*!< File name being installed. */
     long fileSize;                     /*!< Total file size. */
     long fileComplete;                 /*!< Amount of file unpacked. */
     long bytesProcessed;               /*!< No. bytes in archive read. */
-/*@}*/
 };
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ */
 typedef void (*cpioCallback) (struct cpioCallbackInfo * filespec, void * data);
 
 /**
@@ -103,10 +104,14 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
                     int numMappings, cpioCallback cb, void * cbData,
                     unsigned int * archiveSize, /*@out@*/const char ** failedFile);
 
-/** This is designed to be qsort/bsearch compatible */
+/**
+ * Compare two cpio file map entries.
+ * This is designed to be qsort/bsearch compatible.
+ */
 int cpioFileMapCmp(const void * a, const void * b);
 
-/** */
+/**
+ */
 /*@observer@*/ const char *cpioStrerror(int rc);
 
 #ifdef __cplusplus
diff --git a/lib/db0.c b/lib/db0.c
new file mode 100644 (file)
index 0000000..008967a
--- /dev/null
+++ b/lib/db0.c
@@ -0,0 +1,327 @@
+#include "system.h"
+
+#include <db1/db.h>
+
+#define        DB_VERSION_MAJOR        0
+#define        DB_VERSION_MINOR        0
+#define        DB_VERSION_PATCH        0
+
+#define        _mymemset(_a, _b, _c)
+
+#include <rpmlib.h>
+
+#include "dbindex.h"
+/*@access dbiIndex@*/
+/*@access dbiIndexSet@*/
+
+#include "db0.h"
+
+static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype)
+{
+    switch(dbitype) {
+    case DBI_BTREE:    return DB_BTREE;
+    case DBI_HASH:     return DB_HASH;
+    case DBI_RECNO:    return DB_RECNO;
+    }
+    /*@notreached@*/ return DB_HASH;
+}
+
+static inline /*@observer@*/ /*@null@*/ DB * GetDB(dbiIndex dbi) {
+    return ((DB *)dbi->dbi_db);
+}
+
+#if defined(__USE_DB2)
+static int db_init(const char *home, int dbflags,
+                       DB_ENV **dbenvp, DB_INFO **dbinfop)
+{
+    DB_ENV *dbenv = xcalloc(1, sizeof(*dbenv));
+    DB_INFO *dbinfo = xcalloc(1, sizeof(*dbinfo));
+    int rc;
+
+    if (dbenvp) *dbenvp = NULL;
+    if (dbinfop) *dbinfop = NULL;
+
+    dbenv->db_errfile = stderr;
+    dbenv->db_errpfx = "rpmdb";
+    dbenv->mp_size = 1024 * 1024;
+
+    rc = db_appinit(home, NULL, dbenv, dbflags);
+    if (rc)
+       goto errxit;
+
+    dbinfo->db_pagesize = 1024;
+
+    if (dbenvp)
+       *dbenvp = dbenv;
+    else
+       free(dbenv);
+
+    if (dbinfop)
+       *dbinfop = dbinfo;
+    else
+       free(dbinfo);
+
+    return 0;
+
+errxit:
+    if (dbenv) free(dbenv);
+    if (dbinfo)        free(dbinfo);
+    return rc;
+}
+#endif
+
+int db0open(dbiIndex dbi)
+{
+    int rc;
+
+#if defined(__USE_DB2)
+    char * dbhome = NULL;
+    DB_ENV * dbenv = NULL;
+    DB_INFO * dbinfo = NULL;
+    u_int32_t dbflags;
+
+    dbflags = (        !(dbi->dbi_flags & O_RDWR) ? DB_RDONLY :
+               ((dbi->dbi_flags & O_CREAT) ? DB_CREATE : 0));
+
+    rc = db_init(dbhome, dbflags, &dbenv, &dbinfo);
+    dbi->dbi_dbenv = dbenv;
+    dbi->dbi_dbinfo = dbinfo;
+
+    if (rc == 0)
+       rc = db_open(dbi->dbi_file, dbi_to_dbtype(dbi->dbi_type), dbflags,
+                       dbi->dbi_perms, dbenv, dbinfo, &dbi->dbi_db);
+
+    if (rc)
+       dbi->dbi_db = NULL;
+#else
+    dbi->dbi_db = dbopen(dbi->dbi_file, dbi->dbi_flags, dbi->dbi_perms,
+               dbi_to_dbtype(dbi->dbi_type), dbi->dbi_openinfo);
+#endif
+
+    if (dbi->dbi_db) {
+       rc = 0;
+       dbi->dbi_major = DB_VERSION_MAJOR;
+       dbi->dbi_minor = DB_VERSION_MINOR;
+       dbi->dbi_patch = DB_VERSION_PATCH;
+    } else
+       rc = 1;
+
+    return rc;
+}
+
+int db0close(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    DB_ENV * dbenv = (DB_ENV *)dbi->dbi_dbenv;
+    DB_INFO * dbinfo = (DB_INFO *)dbi->dbi_dbinfo;
+    DBC * dbcursor = (DBC *)dbi->dbi_cursor;
+
+    if (dbcursor) {
+       dbcursor->c_close(dbcursor)
+       dbi->dbi_cursor = NULL;
+    }
+
+    rc = db->close(db, 0);
+    dbi->dbi_db = NULL;
+
+    if (dbinfo) {
+       free(dbinfo);
+       dbi->dbi_dbinfo = NULL;
+    }
+    if (dbenv) {
+       (void) db_appexit(dbenv);
+       free(dbenv);
+       dbi->dbi_dbenv = NULL;
+    }
+#else
+    rc = db->close(db);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db0sync(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    rc = db->sync(db, flags);
+#else
+    rc = db->sync(db, flags);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db0GetFirstKey(dbiIndex dbi, const char ** keyp) {
+    DBT key, data;
+    DB * db;
+    int rc;
+
+    if (dbi == NULL || dbi->dbi_db == NULL)
+       return 1;
+
+    db = GetDB(dbi);
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = NULL;
+    key.size = 0;
+
+#if defined(__USE_DB2)
+    {  DBC * dbcursor = NULL;
+       rc = dbp->cursor(dbp, NULL, &dbcursor, 0);
+       if (rc == 0)
+           rc = dbc->c_get(dbcp, &key, &data, DB_FIRST)
+       if (dbcursor)
+           dbcp->c_close(dbcursor)
+    }
+#else
+    rc = db->seq(db, &key, &data, R_FIRST);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (keyp) {
+           char *k = xmalloc(key.size + 1);
+           memcpy(k, key.data, key.size);
+           k[key.size] = '\0';
+           *keyp = k;
+       }
+       break;
+    }
+
+    return rc;
+}
+
+int db0SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) {
+    DBT key, data;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    if (set) *set = NULL;
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = (void *)str;
+    key.size = strlen(str);
+    data.data = NULL;
+    data.size = 0;
+
+#if defined(__USE_DB2)
+    rc = db->get(db, NULL, &key, &data, 0);
+#else
+    rc = db->get(db, &key, &data, 0);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (set) {
+           *set = dbiCreateIndexSet();
+           (*set)->recs = xmalloc(data.size);
+           memcpy((*set)->recs, data.data, data.size);
+           (*set)->count = data.size / sizeof(*(*set)->recs);
+       }
+       break;
+    }
+    return rc;
+}
+
+/*@-compmempass@*/
+int db0UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) {
+    DBT key;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    _mymemset(&key, 0, sizeof(key));
+    key.data = (void *)str;
+    key.size = strlen(str);
+
+    if (set->count) {
+       DBT data;
+
+       _mymemset(&data, 0, sizeof(data));
+       data.data = set->recs;
+       data.size = set->count * sizeof(*(set->recs));
+
+#if defined(__USE_DB2)
+       rc = db->put(db, NULL, &key, &data, 0);
+#else
+       rc = db->put(db, &key, &data, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    } else {
+
+#if defined(__USE_DB2)
+       rc = db->del(db, NULL, &key, 0);
+#else
+       rc = db->del(db, &key, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    }
+
+    return rc;
+}
+/*@=compmempass@*/
diff --git a/lib/db0.h b/lib/db0.h
new file mode 100644 (file)
index 0000000..08f038d
--- /dev/null
+++ b/lib/db0.h
@@ -0,0 +1,64 @@
+#ifndef H_DB1
+#define H_DB1
+
+/** \file lib/db0.h
+ * Access RPM indices using Berkeley db-1.85 format and API.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return handle for an index database.
+ * @param dbi  index database handle
+ * @return     0 success 1 fail
+ */
+int db0open(dbiIndex dbi);
+
+/**
+ * Close index database.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db0close(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Flush pending operations to disk.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db0sync(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Return first index database key.
+ * @param dbi  index database handle
+ * @param key  address of first key
+ * @return     0 success - fails if rec is not found
+ */
+int db0GetFirstKey(dbiIndex dbi, const char ** keyp);
+
+/**
+ * Return items that match criteria.
+ * @param dbi  index database handle
+ * @param str  search key
+ * @param set  items retrieved from index database
+ * @return     -1 error, 0 success, 1 not found
+ */
+int db0SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set);
+
+/**
+ * Change/delete items that match criteria.
+ * @param dbi  index database handle
+ * @param str  update key
+ * @param set  items to update in index database
+ * @return     0 success, 1 not found
+ */
+int db0UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_DB1 */
+
diff --git a/lib/db1.c b/lib/db1.c
new file mode 100644 (file)
index 0000000..e57b9ec
--- /dev/null
+++ b/lib/db1.c
@@ -0,0 +1,326 @@
+#include "system.h"
+
+#ifdef HAVE_DB_185_H
+#include <db_185.h>
+
+#define        _mymemset(_a, _b, _c)
+
+#include <rpmlib.h>
+
+#include "dbindex.h"
+/*@access dbiIndex@*/
+/*@access dbiIndexSet@*/
+
+#include "db1.h"
+
+static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype)
+{
+    switch(dbitype) {
+    case DBI_BTREE:    return DB_BTREE;
+    case DBI_HASH:     return DB_HASH;
+    case DBI_RECNO:    return DB_RECNO;
+    }
+    /*@notreached@*/ return DB_HASH;
+}
+
+static inline /*@observer@*/ /*@null@*/ DB * GetDB(dbiIndex dbi) {
+    return ((DB *)dbi->dbi_db);
+}
+
+#if defined(__USE_DB2)
+static int db_init(const char *home, int dbflags,
+                       DB_ENV **dbenvp, DB_INFO **dbinfop)
+{
+    DB_ENV *dbenv = xcalloc(1, sizeof(*dbenv));
+    DB_INFO *dbinfo = xcalloc(1, sizeof(*dbinfo));
+    int rc;
+
+    if (dbenvp) *dbenvp = NULL;
+    if (dbinfop) *dbinfop = NULL;
+
+    dbenv->db_errfile = stderr;
+    dbenv->db_errpfx = "rpmdb";
+    dbenv->mp_size = 1024 * 1024;
+
+    rc = db_appinit(home, NULL, dbenv, dbflags);
+    if (rc)
+       goto errxit;
+
+    dbinfo->db_pagesize = 1024;
+
+    if (dbenvp)
+       *dbenvp = dbenv;
+    else
+       free(dbenv);
+
+    if (dbinfop)
+       *dbinfop = dbinfo;
+    else
+       free(dbinfo);
+
+    return 0;
+
+errxit:
+    if (dbenv) free(dbenv);
+    if (dbinfo)        free(dbinfo);
+    return rc;
+}
+#endif
+
+int db1open(dbiIndex dbi)
+{
+    int rc;
+
+#if defined(__USE_DB2)
+    char * dbhome = NULL;
+    DB_ENV * dbenv = NULL;
+    DB_INFO * dbinfo = NULL;
+    u_int32_t dbflags;
+
+    dbflags = (        !(dbi->dbi_flags & O_RDWR) ? DB_RDONLY :
+               ((dbi->dbi_flags & O_CREAT) ? DB_CREATE : 0));
+
+    rc = db_init(dbhome, dbflags, &dbenv, &dbinfo);
+    dbi->dbi_dbenv = dbenv;
+    dbi->dbi_dbinfo = dbinfo;
+
+    if (rc == 0)
+       rc = db_open(dbi->dbi_file, dbi_to_dbtype(dbi->dbi_type), dbflags,
+                       dbi->dbi_perms, dbenv, dbinfo, &dbi->dbi_db);
+
+    if (rc)
+       dbi->dbi_db = NULL;
+#else
+    dbi->dbi_db = dbopen(dbi->dbi_file, dbi->dbi_flags, dbi->dbi_perms,
+               dbi_to_dbtype(dbi->dbi_type), dbi->dbi_openinfo);
+#endif
+
+    if (dbi->dbi_db) {
+       rc = 0;
+       dbi->dbi_major = DB_VERSION_MAJOR;
+       dbi->dbi_minor = DB_VERSION_MINOR;
+       dbi->dbi_patch = DB_VERSION_PATCH;
+    } else
+       rc = 1;
+
+    return rc;
+}
+
+int db1close(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    DB_ENV * dbenv = (DB_ENV *)dbi->dbi_dbenv;
+    DB_INFO * dbinfo = (DB_INFO *)dbi->dbi_dbinfo;
+    DBC * dbcursor = (DBC *)dbi->dbi_cursor;
+
+    if (dbcursor) {
+       dbcursor->c_close(dbcursor)
+       dbi->dbi_cursor = NULL;
+    }
+
+    rc = db->close(db, 0);
+    dbi->dbi_db = NULL;
+
+    if (dbinfo) {
+       free(dbinfo);
+       dbi->dbi_dbinfo = NULL;
+    }
+    if (dbenv) {
+       (void) db_appexit(dbenv);
+       free(dbenv);
+       dbi->dbi_dbenv = NULL;
+    }
+#else
+    rc = db->close(db);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db1sync(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    rc = db->sync(db, flags);
+#else
+    rc = db->sync(db, flags);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db1GetFirstKey(dbiIndex dbi, const char ** keyp) {
+    DBT key, data;
+    DB * db;
+    int rc;
+
+    if (dbi == NULL || dbi->dbi_db == NULL)
+       return 1;
+
+    db = GetDB(dbi);
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = NULL;
+    key.size = 0;
+
+#if defined(__USE_DB2)
+    {  DBC * dbcursor = NULL;
+       rc = dbp->cursor(dbp, NULL, &dbcursor, 0);
+       if (rc == 0)
+           rc = dbc->c_get(dbcp, &key, &data, DB_FIRST)
+       if (dbcursor)
+           dbcp->c_close(dbcursor)
+    }
+#else
+    rc = db->seq(db, &key, &data, R_FIRST);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (keyp) {
+           char *k = xmalloc(key.size + 1);
+           memcpy(k, key.data, key.size);
+           k[key.size] = '\0';
+           *keyp = k;
+       }
+       break;
+    }
+
+    return rc;
+}
+
+int db1SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) {
+    DBT key, data;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    if (set) *set = NULL;
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = (void *)str;
+    key.size = strlen(str);
+    data.data = NULL;
+    data.size = 0;
+
+#if defined(__USE_DB2)
+    rc = db->get(db, NULL, &key, &data, 0);
+#else
+    rc = db->get(db, &key, &data, 0);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (set) {
+           *set = dbiCreateIndexSet();
+           (*set)->recs = xmalloc(data.size);
+           memcpy((*set)->recs, data.data, data.size);
+           (*set)->count = data.size / sizeof(*(*set)->recs);
+       }
+       break;
+    }
+    return rc;
+}
+
+/*@-compmempass@*/
+int db1UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) {
+    DBT key;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    _mymemset(&key, 0, sizeof(key));
+    key.data = (void *)str;
+    key.size = strlen(str);
+
+    if (set->count) {
+       DBT data;
+
+       _mymemset(&data, 0, sizeof(data));
+       data.data = set->recs;
+       data.size = set->count * sizeof(*(set->recs));
+
+#if defined(__USE_DB2)
+       rc = db->put(db, NULL, &key, &data, 0);
+#else
+       rc = db->put(db, &key, &data, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    } else {
+
+#if defined(__USE_DB2)
+       rc = db->del(db, NULL, &key, 0);
+#else
+       rc = db->del(db, &key, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    }
+
+    return rc;
+}
+/*@=compmempass@*/
+
+#endif /* HABE_DB_185_H */
diff --git a/lib/db1.h b/lib/db1.h
new file mode 100644 (file)
index 0000000..35d9aa7
--- /dev/null
+++ b/lib/db1.h
@@ -0,0 +1,68 @@
+#ifndef H_DB185
+#define H_DB185
+
+/** \file lib/db1.h
+ * Access RPM indices using Berkeley db2 with db-1.85 API.
+ */
+
+#define        DB_VERSION_MAJOR        1
+#define        DB_VERSION_MINOR        85
+#define        DB_VERSION_PATCH        0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return handle for an index database.
+ * @param dbi  index database handle
+ * @return     0 success 1 fail
+ */
+int db1open(dbiIndex dbi);
+
+/**
+ * Close index database.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db1close(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Flush pending operations to disk.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db1sync(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Return first index database key.
+ * @param dbi  index database handle
+ * @param key  address of first key
+ * @return     0 success - fails if rec is not found
+ */
+int db1GetFirstKey(dbiIndex dbi, const char ** keyp);
+
+/**
+ * Return items that match criteria.
+ * @param dbi  index database handle
+ * @param str  search key
+ * @param set  items retrieved from index database
+ * @return     -1 error, 0 success, 1 not found
+ */
+int db1SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set);
+
+/**
+ * Change/delete items that match criteria.
+ * @param dbi  index database handle
+ * @param str  update key
+ * @param set  items to update in index database
+ * @return     0 success, 1 not found
+ */
+int db1UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_DB185 */
+
diff --git a/lib/db2.c b/lib/db2.c
new file mode 100644 (file)
index 0000000..fa5e01f
--- /dev/null
+++ b/lib/db2.c
@@ -0,0 +1,329 @@
+#include "system.h"
+
+#include <db.h>
+
+
+#include <rpmlib.h>
+
+#include "dbindex.h"
+/*@access dbiIndex@*/
+/*@access dbiIndexSet@*/
+
+#include "db2.h"
+
+#if DB_VERSION_MAJOR == 2
+#define        __USE_DB2       1
+#define        _mymemset(_a, _b, _c)   memset((_a), (_b), (_c))
+
+static inline DBTYPE dbi_to_dbtype(DBI_TYPE dbitype)
+{
+    switch(dbitype) {
+    case DBI_BTREE:    return DB_BTREE;
+    case DBI_HASH:     return DB_HASH;
+    case DBI_RECNO:    return DB_RECNO;
+    }
+    /*@notreached@*/ return DB_HASH;
+}
+
+static inline /*@observer@*/ /*@null@*/ DB * GetDB(dbiIndex dbi) {
+    return ((DB *)dbi->dbi_db);
+}
+
+#if defined(__USE_DB2)
+static int db_init(dbiIndex dbi, const char *home, int dbflags,
+                       DB_ENV **dbenvp, DB_INFO **dbinfop)
+{
+    DB_ENV *dbenv = xcalloc(1, sizeof(*dbenv));
+    DB_INFO *dbinfo = xcalloc(1, sizeof(*dbinfo));
+    int rc;
+
+    if (dbenvp) *dbenvp = NULL;
+    if (dbinfop) *dbinfop = NULL;
+
+    dbenv->db_errfile = stderr;
+    dbenv->db_errpfx = "rpmdb";
+    dbenv->mp_size = 1024 * 1024;
+
+#define _DBFMASK       (DB_CREATE|DB_NOMMAP|DB_THREAD)
+    rc = db_appinit(home, NULL, dbenv, (dbflags & _DBFMASK));
+    if (rc)
+       goto errxit;
+
+    dbinfo->db_pagesize = 1024;
+
+    if (dbenvp)
+       *dbenvp = dbenv;
+    else
+       free(dbenv);
+
+    if (dbinfop)
+       *dbinfop = dbinfo;
+    else
+       free(dbinfo);
+
+    return 0;
+
+errxit:
+    if (dbenv) free(dbenv);
+    if (dbinfo)        free(dbinfo);
+    return rc;
+}
+#endif
+
+int db2open(dbiIndex dbi)
+{
+    int rc = 0;
+
+#if defined(__USE_DB2)
+    char * dbhome = NULL;
+    DB * db = NULL;
+    DB_ENV * dbenv = NULL;
+    DB_INFO * dbinfo = NULL;
+    u_int32_t dbflags;
+
+    dbflags = (        !(dbi->dbi_flags & O_RDWR) ? DB_RDONLY :
+               ((dbi->dbi_flags & O_CREAT) ? DB_CREATE : 0));
+
+    rc = db_init(dbi, dbhome, dbflags, &dbenv, &dbinfo);
+
+    if (rc == 0)
+       rc = db_open(dbi->dbi_file, dbi_to_dbtype(dbi->dbi_type), dbflags,
+                       dbi->dbi_perms, dbenv, dbinfo, &db);
+
+    dbi->dbi_db = db;
+    dbi->dbi_dbenv = dbenv;
+    dbi->dbi_dbinfo = dbinfo;
+
+#else
+    dbi->dbi_db = dbopen(dbi->dbi_file, dbi->dbi_flags, dbi->dbi_perms,
+               dbi_to_dbtype(dbi->dbi_type), dbi->dbi_openinfo);
+#endif
+
+    if (rc == 0 && dbi->dbi_db != NULL) {
+       rc = 0;
+       dbi->dbi_major = DB_VERSION_MAJOR;
+       dbi->dbi_minor = DB_VERSION_MINOR;
+       dbi->dbi_patch = DB_VERSION_PATCH;
+    } else
+       rc = 1;
+
+    return rc;
+}
+
+int db2close(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    DB_ENV * dbenv = (DB_ENV *)dbi->dbi_dbenv;
+    DB_INFO * dbinfo = (DB_INFO *)dbi->dbi_dbinfo;
+    DBC * dbcursor = (DBC *)dbi->dbi_dbcursor;
+
+    if (dbcursor) {
+       (void)dbcursor->c_close(dbcursor);
+       dbi->dbi_dbcursor = NULL;
+    }
+
+    rc = db->close(db, 0);
+    dbi->dbi_db = NULL;
+
+    if (dbinfo) {
+       free(dbinfo);
+       dbi->dbi_dbinfo = NULL;
+    }
+    if (dbenv) {
+       (void) db_appexit(dbenv);
+       free(dbenv);
+       dbi->dbi_dbenv = NULL;
+    }
+#else
+    rc = db->close(db);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db2sync(dbiIndex dbi, unsigned int flags) {
+    DB * db = GetDB(dbi);
+    int rc;
+
+#if defined(__USE_DB2)
+    rc = db->sync(db, flags);
+#else
+    rc = db->sync(db, flags);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       break;
+    }
+
+    return rc;
+}
+
+int db2GetFirstKey(dbiIndex dbi, const char ** keyp) {
+    DBT key, data;
+    DB * db;
+    int rc;
+
+    if (dbi == NULL || dbi->dbi_db == NULL)
+       return 1;
+
+    db = GetDB(dbi);
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = NULL;
+    key.size = 0;
+
+#if defined(__USE_DB2)
+    {  DBC * dbcursor = NULL;
+       rc = db->cursor(db, NULL, &dbcursor);
+       if (rc == 0)
+           rc = dbcursor->c_get(dbcursor, &key, &data, DB_FIRST);
+       if (dbcursor)
+           (void)dbcursor->c_close(dbcursor);
+    }
+#else
+    rc = db->seq(db, &key, &data, R_FIRST);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (keyp) {
+           char *k = xmalloc(key.size + 1);
+           memcpy(k, key.data, key.size);
+           k[key.size] = '\0';
+           *keyp = k;
+       }
+       break;
+    }
+
+    return rc;
+}
+
+int db2SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) {
+    DBT key, data;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    if (set) *set = NULL;
+    _mymemset(&key, 0, sizeof(key));
+    _mymemset(&data, 0, sizeof(data));
+
+    key.data = (void *)str;
+    key.size = strlen(str);
+    data.data = NULL;
+    data.size = 0;
+
+#if defined(__USE_DB2)
+    rc = db->get(db, NULL, &key, &data, 0);
+#else
+    rc = db->get(db, &key, &data, 0);
+#endif
+
+    switch (rc) {
+    default:
+    case RET_ERROR:    /* -1 */
+       rc = -1;
+       break;
+    case RET_SPECIAL:  /* 1 */
+       rc = 1;
+       break;
+    case RET_SUCCESS:  /* 0 */
+       rc = 0;
+       if (set) {
+           *set = dbiCreateIndexSet();
+           (*set)->recs = xmalloc(data.size);
+           memcpy((*set)->recs, data.data, data.size);
+           (*set)->count = data.size / sizeof(*(*set)->recs);
+       }
+       break;
+    }
+    return rc;
+}
+
+/*@-compmempass@*/
+int db2UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) {
+    DBT key;
+    DB * db = GetDB(dbi);
+    int rc;
+
+    _mymemset(&key, 0, sizeof(key));
+    key.data = (void *)str;
+    key.size = strlen(str);
+
+    if (set->count) {
+       DBT data;
+
+       _mymemset(&data, 0, sizeof(data));
+       data.data = set->recs;
+       data.size = set->count * sizeof(*(set->recs));
+
+#if defined(__USE_DB2)
+       rc = db->put(db, NULL, &key, &data, 0);
+#else
+       rc = db->put(db, &key, &data, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    } else {
+
+#if defined(__USE_DB2)
+       rc = db->del(db, NULL, &key, 0);
+#else
+       rc = db->del(db, &key, 0);
+#endif
+
+       switch (rc) {
+       default:
+       case RET_ERROR:         /* -1 */
+       case RET_SPECIAL:       /* 1 */
+           rc = 1;
+           break;
+       case RET_SUCCESS:       /* 0 */
+           rc = 0;
+           break;
+       }
+    }
+
+    return rc;
+}
+/*@=compmempass@*/
+#endif /* DB_VERSION_MAJOR == 2 */
diff --git a/lib/db2.h b/lib/db2.h
new file mode 100644 (file)
index 0000000..eeaff45
--- /dev/null
+++ b/lib/db2.h
@@ -0,0 +1,68 @@
+#ifndef H_DB2
+#define H_DB2
+
+/** \file lib/db2.h
+ * Access RPM indices using Berkeley db-2.x API.
+ */
+
+#define        RET_ERROR       1
+#define        RET_SUCCESS     0
+#define        RET_SPECIAL     -1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Return handle for an index database.
+ * @param dbi  index database handle
+ * @return     0 success 1 fail
+ */
+int db2open(dbiIndex dbi);
+
+/**
+ * Close index database.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db2close(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Flush pending operations to disk.
+ * @param dbi  index database handle
+ * @param flags
+ */
+int db2sync(dbiIndex dbi, unsigned int flags);
+
+/**
+ * Return first index database key.
+ * @param dbi  index database handle
+ * @param key  address of first key
+ * @return     0 success - fails if rec is not found
+ */
+int db2GetFirstKey(dbiIndex dbi, const char ** keyp);
+
+/**
+ * Return items that match criteria.
+ * @param dbi  index database handle
+ * @param str  search key
+ * @param set  items retrieved from index database
+ * @return     -1 error, 0 success, 1 not found
+ */
+int db2SearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set);
+
+/**
+ * Change/delete items that match criteria.
+ * @param dbi  index database handle
+ * @param str  update key
+ * @param set  items to update in index database
+ * @return     0 success, 1 not found
+ */
+int db2UpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* H_DB2 */
+
index 5e8659f..3a49711 100644 (file)
 #include <rpmlib.h>
 #include <rpmurl.h>
 
+#include "dbindex.h"
+/*@access dbiIndex@*/
+/*@access dbiIndexSet@*/
+/*@access dbiIndexRecord@*/
+
+#include "db0.h"
+#include "db1.h"
+#include "db2.h"
+
 unsigned int dbiIndexSetCount(dbiIndexSet set) {
-    return set.count;
+    return set->count;
 }
 
-/* structure return */
 dbiIndexRecord dbiReturnIndexRecordInstance(unsigned int recOffset, unsigned int fileNumber) {
-    dbiIndexRecord rec;
-    rec.recOffset = recOffset;
-    rec.fileNumber = fileNumber;
+    dbiIndexRecord rec = xmalloc(sizeof(*rec));
+    rec->recOffset = recOffset;
+    rec->fileNumber = fileNumber;
     return rec;
 }
 
+void dbiFreeIndexRecordInstance(dbiIndexRecord rec) {
+    if (rec) free(rec);
+}
+
 unsigned int dbiIndexRecordOffset(dbiIndexSet set, int recno) {
-    return set.recs[recno].recOffset;
+    return set->recs[recno].recOffset;
 }
 
 unsigned int dbiIndexRecordFileNumber(dbiIndexSet set, int recno) {
-    return set.recs[recno].fileNumber;
+    return set->recs[recno].fileNumber;
+}
+
+void dbiIndexRecordOffsetSave(dbiIndexSet set, int recno, unsigned int recoff) {
+    set->recs[recno].recOffset = recoff;
 }
 
-dbiIndex * dbiOpenIndex(const char * urlfn, int flags, int perms, DBTYPE type) {
-    dbiIndex * dbi;
+static dbiIndex newDBI(void) {
+    dbiIndex dbi = xcalloc(1, sizeof(*dbi));
+    return dbi;
+}
+
+static void freeDBI( /*@only@*/ /*@null@*/ dbiIndex dbi) {
+    if (dbi) {
+       if (dbi->dbi_dbenv)     free(dbi->dbi_dbenv);
+       if (dbi->dbi_dbinfo)    free(dbi->dbi_dbinfo);
+       if (dbi->dbi_file)      xfree(dbi->dbi_file);
+       xfree(dbi);
+    }
+}
+
+dbiIndex dbiOpenIndex(const char * urlfn, int flags, int perms, DBI_TYPE type) {
+    dbiIndex dbi;
     const char * filename;
-        
+    int rc;
+
     (void) urlPath(urlfn, &filename);
-    dbi = xmalloc(sizeof(*dbi));
-    if (*filename == '\0' ||
-       (dbi->db = dbopen(filename, flags, perms, type, NULL)) == NULL) {
-       free(dbi);
-       rpmError(RPMERR_DBOPEN, _("cannot open file %s: %s"), urlfn, 
+    if (*filename == '\0') {
+       rpmError(RPMERR_DBOPEN, _("bad db file %s"), urlfn);
+       return NULL;
+    }
+
+    dbi = newDBI();
+    dbi->dbi_file = xstrdup(filename);
+    dbi->dbi_flags = flags;
+    dbi->dbi_perms = perms;
+    dbi->dbi_type = type;
+    dbi->dbi_openinfo = NULL;
+    dbi->dbi_major = 1;
+
+    rc = db0open(dbi);
+
+    if (rc) {
+       freeDBI(dbi);
+       rpmError(RPMERR_DBOPEN, _("cannot open file %s: %s"), urlfn,
                              strerror(errno));
        return NULL;
     }
-    dbi->indexname = xstrdup(filename);
     return dbi;
 }
 
-void dbiCloseIndex(dbiIndex * dbi) {
-    dbi->db->close(dbi->db);
-    xfree(dbi->indexname);
-    free(dbi);
+int dbiCloseIndex(dbiIndex dbi) {
+    int rc;
+
+    switch (dbi->dbi_major) {
+    case 2:
+       rc = db2close(dbi, 0);
+       break;
+    case 1:
+       rc = db1close(dbi, 0);
+       break;
+    default:
+    case 0:
+       rc = db0close(dbi, 0);
+       break;
+    }
+    freeDBI(dbi);
+    return rc;
 }
 
-void dbiSyncIndex(dbiIndex * dbi) {
-    dbi->db->sync(dbi->db, 0);
+int dbiSyncIndex(dbiIndex dbi) {
+    int rc;
+
+    switch (dbi->dbi_major) {
+    case 2:
+       rc = db2sync(dbi, 0);
+       break;
+    case 1:
+       rc = db1sync(dbi, 0);
+       break;
+    default:
+    case 0:
+       rc = db0sync(dbi, 0);
+       break;
+    }
+    return rc;
 }
 
-int dbiGetFirstKey(dbiIndex * dbi, const char ** keyp) {
-    DBT key, data;
+int dbiGetFirstKey(dbiIndex dbi, const char ** keyp) {
     int rc;
 
-    if (dbi == NULL || dbi->db == NULL)
+    if (dbi == NULL)
        return 1;
-    
-    key.data = NULL;
-    key.size = 0;
-    rc = dbi->db->seq(dbi->db, &key, &data, R_FIRST);
-    if (rc) {
-       return 1;
-    }
 
-    {  char *k = xmalloc(key.size + 1);
-       memcpy(k, key.data, key.size);
-       k[key.size] = '\0';
-       *keyp = k;
+    switch (dbi->dbi_major) {
+    case 2:
+       rc = db2GetFirstKey(dbi, keyp);
+       break;
+    case 1:
+       rc = db1GetFirstKey(dbi, keyp);
+       break;
+    default:
+    case 0:
+       rc = db0GetFirstKey(dbi, keyp);
+       break;
     }
-
-    return 0;
+    return rc;
 }
 
-int dbiSearchIndex(dbiIndex * dbi, const char * str, dbiIndexSet * set) {
-    DBT key, data;
+int dbiSearchIndex(dbiIndex dbi, const char * str, dbiIndexSet * set) {
     int rc;
 
-    key.data = (void *)str;
-    key.size = strlen(str);
-    data.data = NULL;
-    data.size = 0;
+    switch (dbi->dbi_major) {
+    case 2:
+       rc = db2SearchIndex(dbi, str, set);
+       break;
+    case 1:
+       rc = db1SearchIndex(dbi, str, set);
+       break;
+    default:
+    case 0:
+       rc = db0SearchIndex(dbi, str, set);
+       break;
+    }
 
-    rc = dbi->db->get(dbi->db, &key, &data, 0);
-    if (rc == -1) {
+    switch (rc) {
+    case -1:
        rpmError(RPMERR_DBGETINDEX, _("error getting record %s from %s"),
-               str, dbi->indexname);
-       return -1;
-    } else if (rc == 1) {
-       return 1;
-    } 
-
-    set->recs = xmalloc(data.size);
-    memcpy(set->recs, data.data, data.size);
-    set->count = data.size / sizeof(dbiIndexRecord);
-    return 0;
+               str, dbi->dbi_file);
+       break;
+    }
+    return rc;
 }
 
-int dbiUpdateIndex(dbiIndex * dbi, const char * str, dbiIndexSet * set) {
-   /* 0 on success */
-    DBT key, data;
+int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set) {
     int rc;
 
-    key.data = (void *)str;
-    key.size = strlen(str);
+    switch (dbi->dbi_major) {
+    default:
+    case 2:
+       rc = db2UpdateIndex(dbi, str, set);
+       break;
+    case 1:
+       rc = db1UpdateIndex(dbi, str, set);
+       break;
+    case 0:
+       rc = db0UpdateIndex(dbi, str, set);
+       break;
+    }
 
     if (set->count) {
-       data.data = set->recs;
-       data.size = set->count * sizeof(dbiIndexRecord);
-
-       rc = dbi->db->put(dbi->db, &key, &data, 0);
        if (rc) {
            rpmError(RPMERR_DBPUTINDEX, _("error storing record %s into %s"),
-                   str, dbi->indexname);
-           return 1;
+                   str, dbi->dbi_file);
        }
     } else {
-       rc = dbi->db->del(dbi->db, &key, 0);
        if (rc) {
            rpmError(RPMERR_DBPUTINDEX, _("error removing record %s into %s"),
-                   str, dbi->indexname);
-           return 1;
+                   str, dbi->dbi_file);
        }
     }
 
-    return 0;
+    return rc;
 }
 
-int dbiAppendIndexRecord(dbiIndexSet * set, dbiIndexRecord rec) {
+int dbiAppendIndexRecord(dbiIndexSet set,
+       unsigned int recOffset, unsigned int fileNumber)
+{
     set->count++;
 
     if (set->count == 1) {
-       set->recs = xmalloc(set->count * sizeof(dbiIndexRecord));
+       set->recs = xmalloc(set->count * sizeof(*(set->recs)));
     } else {
-       set->recs = xrealloc(set->recs, set->count * sizeof(dbiIndexRecord));
+       set->recs = xrealloc(set->recs, set->count * sizeof(*(set->recs)));
     }
-    set->recs[set->count - 1] = rec;
+    set->recs[set->count - 1].recOffset = recOffset;
+    set->recs[set->count - 1].fileNumber = fileNumber;
 
     return 0;
 }
 
-/* structure return */
-dbiIndexSet dbiCreateIndexRecord(void) {
-    dbiIndexSet set;
+dbiIndexSet dbiCreateIndexSet(void) {
+    dbiIndexSet set = xmalloc(sizeof(*set));
 
-    set.recs = NULL;
-    set.count = 0;
+    set->recs = NULL;
+    set->count = 0;
     return set;
 }
-    
-void dbiFreeIndexRecord(dbiIndexSet set) {
-    if (set.recs) free(set.recs);
-    set.recs = NULL;
+
+void dbiFreeIndexSet(dbiIndexSet set) {
+    if (set) {
+       if (set->recs) free(set->recs);
+       free(set);
+    }
 }
 
 /* returns 1 on failure */
-int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec) {
+int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec) {
     int from;
     int to = 0;
     int num = set->count;
     int numCopied = 0;
-  
+
     for (from = 0; from < num; from++) {
-       if (rec.recOffset != set->recs[from].recOffset ||
-           rec.fileNumber != set->recs[from].fileNumber) {
+       if (rec->recOffset != set->recs[from].recOffset ||
+           rec->fileNumber != set->recs[from].fileNumber) {
+           /* structure assignment */
            if (from != to) set->recs[to] = set->recs[from];
            to++;
            numCopied++;
index b7e15ca..694d39e 100644 (file)
 #ifndef H_DBINDEX
 #define H_DBINDEX
 
-#ifdef HAVE_DB1_DB_H
-#include <db1/db.h>
-#else
-#ifdef HAVE_DB_185_H
-#include <db_185.h>
-#else
-#include <db.h>
-#endif
-#endif
+/** \file lib/dbindex.h
+ * Access RPM indices using Berkeley db[123] interface.
+ */
 
-/* this will break if sizeof(int) != 4 */
+typedef void DBI_t;
+typedef enum { DBI_BTREE, DBI_HASH, DBI_RECNO } DBI_TYPE;
 
-typedef /*@abstract@*/ struct {
-    unsigned int recOffset;
-    unsigned int fileNumber;
-} dbiIndexRecord;
+typedef /*@abstract@*/ struct _dbiIndexRecord * dbiIndexRecord;
+typedef /*@abstract@*/ struct _dbiIndex * dbiIndex;
 
-typedef /*@abstract@*/ struct {
-    /*@only@*/ dbiIndexRecord * recs;
-    int count;
-} dbiIndexSet;
+/* this will break if sizeof(int) != 4 */
+/**
+ * A single item in an index database.
+ * Note: In rpm-3.0.4 and earlier, this structure was passed by value.
+ */
+struct _dbiIndexRecord {
+    unsigned int recOffset;            /*!< byte offset of header in db */
+    unsigned int fileNumber;           /*!< file array index */
+};
 
-typedef /*@abstract@*/ struct {
-    DB * db;
-    const char * indexname;
-} dbiIndex;
+/**
+ * Items retrieved from the index database.
+ */
+struct _dbiIndexSet {
+/*@owned@*/ struct _dbiIndexRecord * recs; /*!< array of records */
+    int count;                         /*!< number of records */
+};
+
+/**
+ * Describes an index database (implemented on Berkeley db[123] API).
+ */
+struct _dbiIndex {
+    void * dbi_db;                     /*<! Berkeley db[123] handle */
+    void * dbi_dbenv;
+    void * dbi_dbinfo;
+    void * dbi_dbcursor;
+    const char * dbi_file;             /*<! name of index database */
+    int dbi_flags;                     /*<! flags to use on open */
+    int dbi_perms;                     /*<! file permission to use on open */
+    DBI_TYPE dbi_type;                 /*<! type of access */
+    const void * dbi_openinfo;         /*<! private data passed on open */
+    int dbi_major;                     /*<! Berkeley db version major */
+    int dbi_minor;                     /*<! Berkeley db version minor */
+    int dbi_patch;                     /*<! Berkeley db version patch */
+};
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/*@only@*/ dbiIndex * dbiOpenIndex(const char * filename, int flags, int perms, DBTYPE type);
-void dbiCloseIndex( /*@only@*/ dbiIndex * dbi);
-void dbiSyncIndex(dbiIndex * dbi);
-int dbiSearchIndex(dbiIndex * dbi, const char * str, /*@out@*/ dbiIndexSet * set);
-   /* -1 error, 0 success, 1 not found */
-int dbiUpdateIndex(dbiIndex * dbi, const char * str, dbiIndexSet * set);
-   /* 0 on success */
-int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet * set, dbiIndexRecord rec);
-   /* 0 on success - should never fail */
-int dbiRemoveIndexRecord(dbiIndexSet * set, dbiIndexRecord rec);
-   /* 0 on success - fails if rec is not found */
-dbiIndexSet dbiCreateIndexRecord(void);
-void dbiFreeIndexRecord(dbiIndexSet set);
-int dbiGetFirstKey(dbiIndex * dbi, /*@out@*/ const char ** key);
-
-extern unsigned int dbiIndexSetCount(dbiIndexSet set);
-
-/* structure return */
-extern dbiIndexRecord dbiReturnIndexRecordInstance(unsigned int recOffset, unsigned int fileNumber);
-
-extern unsigned int dbiIndexRecordOffset(dbiIndexSet set, int recno);
-
-extern unsigned int dbiIndexRecordFileNumber(dbiIndexSet set, int recno);
+/**
+ * Return handle for an index database.
+ * @param filename     file name of database
+ * @param flags                type of open
+ * @param perm         permissions on database file
+ * @param type         one of { DBI_BTREE, DBI_HASH, DBI_RECNO }
+ * @return             index database handle
+ */
+/*@only@*/ dbiIndex dbiOpenIndex(const char * filename, int flags, int perms,
+               DBI_TYPE type);
+
+/**
+ * Close index database.
+ * @param dbi  index database handle
+ */
+int dbiCloseIndex( /*@only@*/ dbiIndex dbi);
+
+/**
+ * Flush pending operations to disk.
+ * @param dbi  index database handle
+ */
+int dbiSyncIndex(dbiIndex dbi);
+
+/**
+ * Return items that match criteria.
+ * @param dbi  index database handle
+ * @param str  search key
+ * @param set  items retrieved from index database
+ * @return     -1 error, 0 success, 1 not found
+ */
+int dbiSearchIndex(dbiIndex dbi, const char * str, /*@out@*/ dbiIndexSet * set);
+
+/**
+ * Change/delete items that match criteria.
+ * @param dbi  index database handle
+ * @param str  update key
+ * @param set  items to update in index database
+ * @return     0 success, 1 not found
+ */
+int dbiUpdateIndex(dbiIndex dbi, const char * str, dbiIndexSet set);
+
+/**
+ * Append element to set of index database items.
+ * @param set  set of index database items
+ * @param rec  item to append to set
+ * @return     0 success (always)
+ */
+int dbiAppendIndexRecord( /*@out@*/ dbiIndexSet set, unsigned int recOffset, unsigned int fileNumber);
+
+/**
+ * Create empty set of index database items.
+ * @return     empty set of index database items
+ */
+/*@only@*/ dbiIndexSet dbiCreateIndexSet(void);
+
+/**
+ * Remove element from set of index database items.
+ * @param set  set of index database items
+ * @param rec  item to remove from set
+ * @return     0 success, 1 failure
+ */
+int dbiRemoveIndexRecord(dbiIndexSet set, dbiIndexRecord rec);
+
+/**
+ * Return first index database key.
+ * @param dbi  index database handle
+ * @param key  address of first key
+ * @return     0 success - fails if rec is not found
+ */
+int dbiGetFirstKey(dbiIndex dbi, /*@out@*/ const char ** key);
+
+/**
+ * Create and initialize element of index database set.
+ * @param recOffset    byte offset of header in db
+ * @param fileNumber   file array index
+ * @return     new element
+ */
+/*@only@*/ dbiIndexRecord dbiReturnIndexRecordInstance(unsigned int recOffset,
+               unsigned int fileNumber);
+/**
+ * Destroy element of index database set.
+ * @param rec  element of index database set.
+ */
+void dbiFreeIndexRecordInstance( /*@only@*/ dbiIndexRecord rec);
 
 #ifdef __cplusplus
 }
index 38722f7..c0e706c 100644 (file)
@@ -610,7 +610,7 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
                        const void * key, int upgrade, rpmRelocation * relocs)
 {
     /* this is an install followed by uninstalls */
-    dbiIndexSet matches;
+    dbiIndexSet matches = NULL;
     char * name;
     int count, i, j;
     const char ** obsoletes;
@@ -658,8 +658,6 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
                removePackage(rpmdep, dbiIndexRecordOffset(matches, i), alNum);
            headerFree(h2);
        }
-
-       dbiFreeIndexRecord(matches);
     }
 
     if (headerGetEntry(h, RPMTAG_OBSOLETENAME, NULL, (void **) &obsoletes, &count)) {
@@ -671,12 +669,19 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
 
        for (j = 0; j < count; j++) {
 
+           if (matches) {
+               dbiFreeIndexSet(matches);
+               matches = NULL;
+           }
+
            /* XXX avoid self-obsoleting packages. */
            if (!strcmp(name, obsoletes[j]))
                continue;
 
-           if (rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches))
+           if (rpmdbFindPackage(rpmdep->db, obsoletes[j], &matches)) {
                continue;
+           }
+
            for (i = 0; i < dbiIndexSetCount(matches); i++) {
                unsigned int recOffset = dbiIndexRecordOffset(matches, i);
                 if (bsearch(&recOffset,
@@ -695,14 +700,17 @@ int rpmtransAddPackage(rpmTransactionSet rpmdep, Header h, FD_t fd,
                        removePackage(rpmdep, recOffset, alNum);
                }
            }
-
-           dbiFreeIndexRecord(matches);
        }
 
        if (obsoletesEVR) free(obsoletesEVR);
        free(obsoletes);
     }
 
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
+
     return 0;
 }
 
@@ -855,7 +863,7 @@ static int unsatisfiedDepend(rpmTransactionSet rpmdep,
        const char * keyName, const char * keyEVR, int keyFlags,
        /*@out@*/ struct availablePackage ** suggestion)
 {
-    dbiIndexSet matches;
+    dbiIndexSet matches = NULL;
     int rc = 0;        /* assume dependency is satisfied */
     int i;
 
@@ -894,13 +902,16 @@ static int unsatisfiedDepend(rpmTransactionSet rpmdep,
                    break;
                }
 
-               dbiFreeIndexRecord(matches);
                if (i < dbiIndexSetCount(matches)) {
                    rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by db file lists.\n"), keyType, keyDepend);
                    goto exit;
                }
            }
        }
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
 
        if (!rpmdbFindByProvides(rpmdep->db, keyName, &matches)) {
            for (i = 0; i < dbiIndexSetCount(matches); i++) {
@@ -916,12 +927,15 @@ static int unsatisfiedDepend(rpmTransactionSet rpmdep,
                }
            }
 
-           dbiFreeIndexRecord(matches);
            if (i < dbiIndexSetCount(matches)) {
                rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by db provides.\n"), keyType, keyDepend);
                goto exit;
            }
        }
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
 
        if (!rpmdbFindPackage(rpmdep->db, keyName, &matches)) {
            for (i = 0; i < dbiIndexSetCount(matches); i++) {
@@ -938,12 +952,15 @@ static int unsatisfiedDepend(rpmTransactionSet rpmdep,
                }
            }
 
-           dbiFreeIndexRecord(matches);
            if (i < dbiIndexSetCount(matches)) {
                rpmMessage(RPMMESS_DEBUG, _("%s: %s satisfied by db packages.\n"), keyType, keyDepend);
                goto exit;
            }
        }
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
 
        /*
         * New features in rpm spec files add implicit dependencies on rpm
@@ -967,6 +984,10 @@ static int unsatisfiedDepend(rpmTransactionSet rpmdep,
     rc = 1;    /* dependency is unsatisfied */
 
 exit:
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
     return rc;
 }
 
@@ -1114,13 +1135,13 @@ static int checkPackageDeps(rpmTransactionSet rpmdep, struct problemsSet * psp,
 /* Adding: check name/provides key against each conflict match. */
 /* Erasing: check name/provides/filename key against each requiredby match. */
 static int checkPackageSet(rpmTransactionSet rpmdep, struct problemsSet * psp,
-       const char * key, dbiIndexSet matches)
+       const char * key, dbiIndexSet matches)
 {
     Header h;
     int i;
 
-    for (i = 0; i < matches->count; i++) {
-       unsigned int recOffset = dbiIndexRecordOffset(*matches, i);
+    for (i = 0; i < dbiIndexSetCount(matches); i++) {
+       unsigned int recOffset = dbiIndexRecordOffset(matches, i);
        if (bsearch(&recOffset, rpmdep->removedPackages,
                    rpmdep->numRemovedPackages, sizeof(int), intcmp))
            continue;
@@ -1148,15 +1169,13 @@ static int checkPackageSet(rpmTransactionSet rpmdep, struct problemsSet * psp,
 static int checkDependentPackages(rpmTransactionSet rpmdep,
                        struct problemsSet * psp, const char * key)
 {
-    dbiIndexSet matches;
-    int rc;
-
-    if (rpmdbFindByRequiredBy(rpmdep->db, key, &matches))
-       return 0;
-
-    rc = checkPackageSet(rpmdep, psp, key, &matches);
-    dbiFreeIndexRecord(matches);
+    dbiIndexSet matches = NULL;
+    int rc = 0;
 
+    if (!rpmdbFindByRequiredBy(rpmdep->db, key, &matches))
+       rc = checkPackageSet(rpmdep, psp, key, matches);
+    if (matches)
+       dbiFreeIndexSet(matches);
     return rc;
 }
 
@@ -1164,17 +1183,15 @@ static int checkDependentPackages(rpmTransactionSet rpmdep,
 static int checkDependentConflicts(rpmTransactionSet rpmdep,
                struct problemsSet * psp, const char * key)
 {
-    dbiIndexSet matches;
-    int rc;
-
-    if (rpmdep->db == NULL)
-       return 0;
-
-    if (rpmdbFindByConflicts(rpmdep->db, key, &matches))
-       return 0;
+    int rc = 0;
 
-    rc = checkPackageSet(rpmdep, psp, key, &matches);
-    dbiFreeIndexRecord(matches);
+    if (rpmdep->db) {
+       dbiIndexSet matches = NULL;
+       if (!rpmdbFindByConflicts(rpmdep->db, key, &matches))
+           rc = checkPackageSet(rpmdep, psp, key, matches);
+       if (matches)
+           dbiFreeIndexSet(matches);
+    }
 
     return rc;
 }
index c08c472..c2ba5b7 100644 (file)
@@ -85,7 +85,7 @@ static fingerPrint doLookup(fingerPrintCache cache,
            if (end[-1] != '/') *end++ = '/';
            end = stpncpy(end, cleanDirName, sizeof(dir) - (end - dir));
            *end = '\0';
-           rpmCleanPath(dir);  /* XXX possible /../ from concatenation */
+           (void)rpmCleanPath(dir); /* XXX possible /../ from concatenation */
            end = dir + strlen(dir);
            if (end[-1] != '/') *end++ = '/';
            *end = '\0';
@@ -104,6 +104,8 @@ static fingerPrint doLookup(fingerPrintCache cache,
     }
 
     fp.entry = NULL;
+    fp.subDir = NULL;
+    fp.baseName = NULL;
     while (1) {
 
        /* as we're stating paths here, we want to follow symlinks */
index 3b1c980..73f37a2 100644 (file)
@@ -1,24 +1,38 @@
+/** \file lib/hash.c
+ * Hash table implemenation
+ */
+
 #include "system.h"
 
 #include <rpmlib.h>
 #include "hash.h"
 
+typedef /*@owned@*/ const void * voidptr;
+
+/** */
 struct hashBucket {
-    /*@owned@*/const void * key;
-    /*@owned@*/const void ** data;
-    int dataCount;
-    /*@dependent@*/struct hashBucket * next;
+    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;
-    int keySize;
-    int freeData;
-    struct hashBucket ** buckets;
-    hashFunctionType fn;
-    hashEqualityType eq;
+    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@*/ struct hashBucket * findEntry(hashTable ht, const void * key)
 {
     unsigned int hash;
@@ -142,7 +156,7 @@ int htGetEntry(hashTable ht, const void * key, const void *** data,
        return 1;
 
     if (data)
-       *data = b->data;
+       *data = (const void **) b->data;
     if (dataCount)
        *dataCount = b->dataCount;
     if (tableKey)
index b5e0af2..eb8d8fd 100644 (file)
@@ -1,28 +1,82 @@
 #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);
+/** */
+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);
 
-/* if keySize > 0, the key is duplicated within the table (which costs
-   memory, but may be usefull anyway */
+/**
+ * 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); 
-void htAddEntry(hashTable ht, const void * key, const void * data);
+
+/**
+ * Destroy hash table.
+ * @param ht            pointer to hash table
+ */
 void htFree( /*@only@*/ hashTable ht);
-/* returns 0 on success, 1 if the item is not found. tableKey may be NULL */
+
+/**
+ * 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);
+
+/**
+ * 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, /*@out@*/ const void *** data,
                /*@out@*/ int * dataCount, /*@out@*/const void ** tableKey);
-/* returns 1 if the item is present, 0 otherwise */
+
+/**
+ * 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
index 2864d60..572ad70 100644 (file)
@@ -19,14 +19,14 @@ struct callbackInfo {
 };
 
 struct fileMemory {
-    /*@owned@*/ const char ** names;
-    /*@owned@*/ const char ** cpioNames;
-    /*@owned@*/ struct fileInfo * files;
+/*@owned@*/ const char ** names;
+/*@owned@*/ const char ** cpioNames;
+/*@owned@*/ struct fileInfo * files;
 };
 
 struct fileInfo {
-    /*@dependent@*/ const char * cpioPath;
-    /*@dependent@*/ const char * relativePath; /* relative to root */
+/*@dependent@*/ const char * cpioPath;
+/*@dependent@*/ const char * relativePath;     /* relative to root */
     uid_t uid;
     gid_t gid;
     uint_32 flags;
@@ -51,6 +51,7 @@ static struct tagMacro {
        { NULL, 0 }
 };
 
+/** */
 static int rpmInstallLoadMacros(Header h)
 {
     struct tagMacro *tagm;
@@ -74,6 +75,7 @@ static int rpmInstallLoadMacros(Header h)
     return 0;
 }
 
+/** */
 static /*@only@*/ struct fileMemory *newFileMemory(void)
 {
     struct fileMemory *fileMem = xmalloc(sizeof(*fileMem));
@@ -83,6 +85,7 @@ static /*@only@*/ struct fileMemory *newFileMemory(void)
     return fileMem;
 }
 
+/** */
 static void freeFileMemory( /*@only@*/ struct fileMemory *fileMem)
 {
     if (fileMem->files) free(fileMem->files);
@@ -92,6 +95,7 @@ static void freeFileMemory( /*@only@*/ struct fileMemory *fileMem)
 }
 
 /* files should not be preallocated */
+/** */
 static int assembleFileList(Header h, /*@out@*/ struct fileMemory ** memPtr,
         /*@out@*/ int * fileCountPtr, /*@out@*/ struct fileInfo ** filesPtr,
         int stripPrefixLength, enum fileActions * actions)
@@ -146,6 +150,7 @@ static int assembleFileList(Header h, /*@out@*/ struct fileMemory ** memPtr,
     return 0;
 }
 
+/** */
 static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
 {
     char ** fileOwners;
@@ -177,6 +182,7 @@ static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
     free(fileGroups);
 }
 
+/** */
 static void trimChangelog(Header h)
 {
     int * times;
@@ -227,6 +233,7 @@ static void trimChangelog(Header h)
     free(texts);
 }
 
+/** */
 static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList)
 {
     struct sharedFileInfo * fileInfo;
@@ -273,6 +280,7 @@ static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList)
     return 0;
 }
 
+/** */
 static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
 {
     struct callbackInfo * ourInfo = data;
@@ -292,6 +300,7 @@ static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
 }
 
 /* NULL files means install all files */
+/** */
 static int installArchive(FD_t fd, struct fileInfo * files,
                          int fileCount, rpmCallbackFunction notify,
                          void * notifyData, const void * pkgKey, Header h,
@@ -383,6 +392,7 @@ static int installArchive(FD_t fd, struct fileInfo * files,
 /* 0 success */
 /* 1 bad magic */
 /* 2 error */
+/** */
 static int installSources(Header h, const char * rootdir, FD_t fd,
                          const char ** specFilePtr, rpmCallbackFunction notify,
                          void * notifyData)
@@ -686,7 +696,7 @@ int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
     char * fileStates = NULL;
     int i;
     int otherOffset = 0;
-    dbiIndexSet matches;
+    dbiIndexSet matches = NULL;
     int scriptArg;
     int stripSize = 1;         /* strip at least first / for cpio */
     struct fileMemory *fileMem = NULL;
@@ -708,16 +718,21 @@ int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
        /*@notreached@*/ break;
     case 0:
        scriptArg = dbiIndexSetCount(matches) + 1;
-       dbiFreeIndexRecord(matches);
        break;
     default:
        scriptArg = 1;
        break;
     }
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
 
-    if (!rpmdbFindByHeader(db, h, &matches)) {
+    if (!rpmdbFindByHeader(db, h, &matches))
        otherOffset = dbiIndexRecordOffset(matches, 0);
-       dbiFreeIndexRecord(matches);
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
     }
 
     if (rootdir) {
@@ -927,6 +942,10 @@ int installBinaryPackage(const char * rootdir, rpmdb db, FD_t fd, Header h,
     rc = 0;
 
 exit:
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
     if (rootdir && currDir) {
        /*@-unrecog@*/ chroot("."); /*@=unrecog@*/
        chdir(currDir);
index fea5efc..14b99be 100644 (file)
@@ -1,6 +1,8 @@
 #include "system.h"
 
 #include <rpmlib.h>
+
+#include "dbindex.h"   /* XXX prototypes */
 #include "lookup.h"
 
 /* XXX used in transaction.c */
@@ -13,29 +15,36 @@ int findMatches(rpmdb db, const char * name, const char * version,
     int gotMatches;
     int rc;
     int i;
-    const char * pkgRelease, * pkgVersion;
-    int goodRelease, goodVersion;
-    Header h;
 
     if ((rc = rpmdbFindPackage(db, name, matches))) {
-       if (rc == -1) return 2; else return 1;
+       rc = ((rc == -1) ? 2 : 1);
+       goto exit;
     }
 
-    if (!version && !release) return 0;
+    if (!version && !release) {
+       rc = 0;
+       goto exit;
+    }
 
     gotMatches = 0;
 
     /* make sure the version and releases match */
-    for (i = 0; i < matches->count; i++) {
-       if (matches->recs[i].recOffset == 0)
+    for (i = 0; i < dbiIndexSetCount(*matches); i++) {
+       unsigned int recoff = dbiIndexRecordOffset(*matches, i);
+       int goodRelease, goodVersion;
+       const char * pkgVersion;
+       const char * pkgRelease;
+       Header h;
+
+       if (recoff == 0)
            continue;
 
-       h = rpmdbGetRecord(db, matches->recs[i].recOffset);
+       h = rpmdbGetRecord(db, recoff);
        if (h == NULL) {
            rpmError(RPMERR_DBCORRUPT,_("cannot read header at %d for lookup"), 
-               matches->recs[i].recOffset);
-           dbiFreeIndexRecord(*matches);
-           return 2;
+               recoff);
+           rc = 2;
+           goto exit;
        }
 
        headerNVR(h, NULL, &pkgVersion, &pkgRelease);
@@ -48,17 +57,23 @@ int findMatches(rpmdb db, const char * name, const char * version,
        if (goodRelease && goodVersion) 
            gotMatches = 1;
        else 
-           matches->recs[i].recOffset = 0;
+           dbiIndexRecordOffsetSave(*matches, i, 0);
 
        headerFree(h);
     }
 
     if (!gotMatches) {
-       dbiFreeIndexRecord(*matches);
-       return 1;
+       rc = 1;
+       goto exit;
     }
-    
-    return 0;
+    rc = 0;
+
+exit:
+    if (rc && matches && *matches) {
+       dbiFreeIndexSet(*matches);
+       *matches = NULL;
+    }
+    return rc;
 }
 
 /* 0 found matches */
index 7ba2a16..8a364b8 100644 (file)
@@ -7,8 +7,9 @@
 extern "C" {
 #endif
 
+/* XXX only for the benefit of runTransactions() */
 int findMatches(rpmdb db, const char * name, const char * version,
-       const char * release, /*@out@*/dbiIndexSet * matches);
+       const char * release, /*@out@*/ dbiIndexSet * matches);
 
 #ifdef __cplusplus
 }
index abacabf..27d2a54 100644 (file)
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -20,7 +20,7 @@
 #include "md5.h"
 
 static int _ie = 0x44332211;
-static union _endian { int i; char b[4]; } *_endian = (union _endian *)&_ie;
+static union _mendian { int i; char b[4]; } *_endian = (union _mendian *)&_ie;
 #define        IS_BIG_ENDIAN()         (_endian->b[0] == '\x44')
 #define        IS_LITTLE_ENDIAN()      (_endian->b[0] == '\x11')
 
index 456c3a7..344830f 100644 (file)
@@ -728,7 +728,7 @@ fprintf(stderr, "*** rpmGlob argv[%d] \"%s\"\n", argc, av[j]);
        globRoot += nb;
        *globRoot = '\0';
 if (_debug)
-fprintf(stderr, "*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", maxb, nb, nb, av[j], globURL, globURL);
+fprintf(stderr, "*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", (int)maxb, (int)nb, (int)nb, av[j], globURL, globURL);
        
        if (argc == 0)
            argv = xmalloc((gl.gl_pathc+1) * sizeof(*argv));
@@ -781,6 +781,7 @@ int rpmHeaderGetEntry(Header h, int_32 tag, int_32 *type,
        if (count > 0) {
            *p = fl;
            if (c)      *c = count;
+           if (type)   *type = RPM_STRING_ARRAY_TYPE;
            return 1;
        }
        if (c)  *c = 0;
index b4f15c7..30afc9c 100644 (file)
@@ -41,7 +41,8 @@ void  buildOrigFileList(Header h, /*@out@*/ const char *** fileListPtr,
                        /*@out@*/ int * fileCountPtr);
 
 int myGlobPatternP (const char *patternURL);
-int rpmGlob(const char * patterns, int * argcPtr, const char *** argvPtr);
+int rpmGlob(const char * patterns, /*@out@*/ int * argcPtr,
+                       /*@out@*/ const char *** argvPtr);
 
 #ifdef __cplusplus
 }
index 1b1a843..ef0b7dd 100644 (file)
@@ -455,7 +455,7 @@ void        (*freeSpecVec) (Spec spec) = NULL;
 int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
        rpmdb db, QVF_t showPackage)
 {
-    dbiIndexSet matches;
+    dbiIndexSet matches = NULL;
     Header h;
     int offset;
     int rc;
@@ -582,7 +582,6 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
            retcode = 1;
        } else {
            retcode = showMatches(qva, db, matches, showPackage);
-           dbiFreeIndexRecord(matches);
        }
        break;
 
@@ -592,7 +591,6 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
            retcode = 1;
        } else {
            retcode = showMatches(qva, db, matches, showPackage);
-           dbiFreeIndexRecord(matches);
        }
        break;
 
@@ -602,7 +600,6 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
            retcode = 1;
        } else {
            retcode = showMatches(qva, db, matches, showPackage);
-           dbiFreeIndexRecord(matches);
        }
        break;
 
@@ -613,7 +610,6 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
                retcode = 1;
            } else {
                retcode = showMatches(qva, db, matches, showPackage);
-               dbiFreeIndexRecord(matches);
            }
            break;
        }
@@ -634,7 +630,6 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
            retcode = 1;
        } else {
            retcode = showMatches(qva, db, matches, showPackage);
-           dbiFreeIndexRecord(matches);
        }
        break;
 
@@ -665,11 +660,14 @@ int rpmQueryVerify(QVA_t *qva, enum rpmQVSources source, const char * arg,
            fprintf(stderr, _("error looking for package %s\n"), arg);
        } else {
            retcode = showMatches(qva, db, matches, showPackage);
-           dbiFreeIndexRecord(matches);
        }
        break;
     }
    
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
     return retcode;
 }
 
index 82a740d..e909419 100644 (file)
@@ -38,7 +38,7 @@ int rpmdbRebuild(const char * rootdir)
        char *t;
        sprintf(pidbuf, "rebuilddb.%d", (int) getpid());
        t = xmalloc(strlen(dbpath) + strlen(pidbuf) + 1);
-       stpcpy(stpcpy(t, dbpath), pidbuf);
+       (void)stpcpy(stpcpy(t, dbpath), pidbuf);
        if (tfn) xfree(tfn);
        tfn = t;
        nocleanup = 0;
@@ -92,7 +92,7 @@ int rpmdbRebuild(const char * rootdir)
                headerIsEntry(h, RPMTAG_VERSION) &&
                headerIsEntry(h, RPMTAG_RELEASE) &&
                headerIsEntry(h, RPMTAG_BUILDTIME)) {
-               dbiIndexSet matches;
+               dbiIndexSet matches = NULL;
                int skip;
 
                /* XXX always eliminate duplicate entries */
@@ -104,9 +104,12 @@ int rpmdbRebuild(const char * rootdir)
                        _("duplicated database entry: %s-%s-%s -- skipping."),
                        name, version, release);
                    skip = 1;
-                   dbiFreeIndexRecord(matches);
                } else
                    skip = 0;
+               if (matches) {
+                   dbiFreeIndexSet(matches);
+                   matches = NULL;
+               }
 
                if (skip == 0 && rpmdbAdd(newdb, h)) {
                    rpmError(RPMERR_INTERNAL,
index ea86399..ccb4f17 100644 (file)
@@ -8,14 +8,15 @@
 #include <rpmurl.h>
 #include <rpmmacro.h>  /* XXX for rpmGetPath */
 
+#include "dbindex.h"
+/*@access dbiIndexSet@*/
+/*@access dbiIndexRecord@*/
+
 #include "falloc.h"
 #include "fprint.h"
 #include "misc.h"
 #include "rpmdb.h"
 
-/*@access dbiIndexSet@*/
-/*@access dbiIndexRecord@*/
-
 extern int _noDirTokens;
 
 const char *rpmdb_filenames[] = {
@@ -43,8 +44,8 @@ const char *rpmdb_filenames[] = {
 
 struct rpmdb_s {
     FD_t pkgs;
-    dbiIndex * nameIndex, * fileIndex, * groupIndex, * providesIndex;
-    dbiIndex * requiredbyIndex, * conflictsIndex, * triggerIndex;
+    dbiIndex nameIndex, fileIndex, groupIndex, providesIndex;
+    dbiIndex requiredbyIndex, conflictsIndex, triggerIndex;
 };
 
 static sigset_t signalMask;
@@ -63,7 +64,7 @@ static void unblockSignals(void)
 }
 
 static int openDbFile(const char * prefix, const char * dbpath, const char * shortName, 
-        int justCheck, int mode, int perms, dbiIndex ** db, DBTYPE type)
+        int justCheck, int mode, int perms, dbiIndex * db, DBI_TYPE type)
 {
     int len = (prefix ? strlen(prefix) : 0) + strlen(dbpath) + strlen(shortName) + 1;
     char * filename = alloca(len);
@@ -80,10 +81,8 @@ static int openDbFile(const char * prefix, const char * dbpath, const char * sho
     strcat(filename, shortName);
 
     if (!justCheck || !rpmfileexists(filename)) {
-       *db = dbiOpenIndex(filename, mode, perms, type);
-       if (!*db) {
+       if ((*db = dbiOpenIndex(filename, mode, perms, type)) == NULL)
            return 1;
-       }
     }
 
     return 0;
@@ -143,7 +142,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo
        break;
     }
     strcat(filename, dbpath);
-    rpmCleanPath(filename);
+    (void)rpmCleanPath(filename);
 
     rpmMessage(RPMMESS_DEBUG, _("opening database mode 0x%x in %s\n"),
        mode, filename);
@@ -188,7 +187,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo
     }
 
     rc = openDbFile(prefix, dbpath, "nameindex.rpm", justcheck, mode, perms,
-                   &db->nameIndex, DB_HASH);
+                   &db->nameIndex, DBI_HASH);
 
     if (minimal) {
        *rpmdbp = xmalloc(sizeof(struct rpmdb_s));
@@ -201,7 +200,7 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo
 
     if (!rc)
        rc = openDbFile(prefix, dbpath, "fileindex.rpm", justcheck, mode, perms,
-                       &db->fileIndex, DB_HASH);
+                       &db->fileIndex, DBI_HASH);
 
     /* We used to store the fileindexes as complete paths, rather then
        plain basenames. Let's see which version we are... */
@@ -220,19 +219,19 @@ int openDatabase(const char * prefix, const char * dbpath, rpmdb *rpmdbp, int mo
 
     if (!rc)
        rc = openDbFile(prefix, dbpath, "providesindex.rpm", justcheck, mode, perms,
-                       &db->providesIndex, DB_HASH);
+                       &db->providesIndex, DBI_HASH);
     if (!rc)
        rc = openDbFile(prefix, dbpath, "requiredby.rpm", justcheck, mode, perms,
-                       &db->requiredbyIndex, DB_HASH);
+                       &db->requiredbyIndex, DBI_HASH);
     if (!rc)
        rc = openDbFile(prefix, dbpath, "conflictsindex.rpm", justcheck, mode, perms,
-                       &db->conflictsIndex, DB_HASH);
+                       &db->conflictsIndex, DBI_HASH);
     if (!rc)
        rc = openDbFile(prefix, dbpath, "groupindex.rpm", justcheck, mode, perms,
-                       &db->groupIndex, DB_HASH);
+                       &db->groupIndex, DBI_HASH);
     if (!rc)
        rc = openDbFile(prefix, dbpath, "triggerindex.rpm", justcheck, mode, perms,
-                       &db->triggerIndex, DB_HASH);
+                       &db->triggerIndex, DBI_HASH);
 
     if (rc || justcheck || rpmdbp == NULL)
        rpmdbClose(db);
@@ -361,10 +360,11 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches)
     const char * dirName;
     const char * baseName;
     fingerPrint fp1, fp2;
-    dbiIndexSet allMatches;
+    dbiIndexSet allMatches = NULL;
     int i, rc;
     fingerPrintCache fpc;
 
+    *matches = NULL;
     if ((baseName = strrchr(filespec, '/')) != NULL) {
        char * t;
        size_t len;
@@ -384,18 +384,22 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches)
 
     rc = dbiSearchIndex(db->fileIndex, baseName, &allMatches);
     if (rc) {
+       dbiFreeIndexSet(allMatches);
+       allMatches = NULL;
        fpCacheFree(fpc);
        return rc;
     }
 
-    *matches = dbiCreateIndexRecord();
+    *matches = dbiCreateIndexSet();
     i = 0;
-    while (i < allMatches.count) {
+    while (i < dbiIndexSetCount(allMatches)) {
        const char ** baseNames, ** dirNames;
        int_32 * dirIndexes;
+       unsigned int recoff = dbiIndexRecordOffset(allMatches, i);
+       unsigned int prevoff;
        Header h;
 
-       if ((h = rpmdbGetRecord(db, allMatches.recs[i].recOffset)) == NULL) {
+       if ((h = rpmdbGetRecord(db, recoff)) == NULL) {
            i++;
            continue;
        }
@@ -408,28 +412,33 @@ int rpmdbFindByFile(rpmdb db, const char * filespec, dbiIndexSet * matches)
                                (void **) &dirNames, NULL);
 
        do {
-           int num = allMatches.recs[i].fileNumber;
+           int num = dbiIndexRecordFileNumber(allMatches, i);
 
            fp2 = fpLookup(fpc, dirNames[dirIndexes[num]], baseNames[num], 1);
            if (FP_EQUAL(fp1, fp2))
-               dbiAppendIndexRecord(matches, allMatches.recs[i]);
+               dbiAppendIndexRecord(*matches, dbiIndexRecordOffset(allMatches, i), dbiIndexRecordFileNumber(allMatches, i));
 
+           prevoff = recoff;
            i++;
-       } while ((i < allMatches.count) && 
-                       ((i == 0) || (allMatches.recs[i].recOffset == 
-                               allMatches.recs[i - 1].recOffset)));
+           recoff = dbiIndexRecordOffset(allMatches, i);
+       } while (i < dbiIndexSetCount(allMatches) && 
+               (i == 0 || recoff == prevoff));
 
        free(baseNames);
        free(dirNames);
        headerFree(h);
     }
 
-    dbiFreeIndexRecord(allMatches);
+    if (allMatches) {
+       dbiFreeIndexSet(allMatches);
+       allMatches = NULL;
+    }
 
     fpCacheFree(fpc);
 
-    if (!matches->count) {
-       dbiFreeIndexRecord(*matches);
+    if (dbiIndexSetCount(*matches) == 0) {
+       dbiFreeIndexSet(*matches);
+       *matches = NULL; 
        return 1;
     }
 
@@ -460,24 +469,22 @@ int rpmdbFindPackage(rpmdb db, const char * name, dbiIndexSet * matches) {
     return dbiSearchIndex(db->nameIndex, name, matches);
 }
 
-static void removeIndexEntry(dbiIndex * dbi, char * key, dbiIndexRecord rec,
-                            int tolerant, char * idxName)
+static void removeIndexEntry(dbiIndex dbi, const char * key, dbiIndexRecord rec,
+                            int tolerant, const char * idxName)
 {
+    dbiIndexSet matches = NULL;
     int rc;
-    dbiIndexSet matches;
     
     rc = dbiSearchIndex(dbi, key, &matches);
     switch (rc) {
       case 0:
-       if (dbiRemoveIndexRecord(&matches, rec) && !tolerant) {
+       if (dbiRemoveIndexRecord(matches, rec) && !tolerant) {
            rpmError(RPMERR_DBCORRUPT, _("package %s not listed in %s"),
                  key, idxName);
        } else {
-           dbiUpdateIndex(dbi, key, &matches);
+           dbiUpdateIndex(dbi, key, matches);
               /* errors from above will be reported from dbindex.c */
        }
-
-       dbiFreeIndexRecord(matches);
        break;
       case 1:
        if (!tolerant) 
@@ -487,6 +494,10 @@ static void removeIndexEntry(dbiIndex * dbi, char * key, dbiIndexRecord rec,
       case 2:
        break;   /* error message already generated from dbindex.c */
     }
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
 }
 
 int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant)
@@ -500,8 +511,6 @@ int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant)
     char ** conflictList, ** triggerList;
     int i;
 
-    /* structure assignment */
-    rec = dbiReturnIndexRecordInstance(offset, 0);
 
     h = rpmdbGetRecord(db, offset);
     if (h == NULL) {
@@ -510,6 +519,8 @@ int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant)
        return 1;
     }
 
+    rec = dbiReturnIndexRecordInstance(offset, 0);
+
     blockSignals();
 
     if (!headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count)) {
@@ -598,30 +609,43 @@ int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant)
 
     unblockSignals();
 
+    dbiFreeIndexRecordInstance(rec);
     headerFree(h);
 
     return 0;
 }
 
-static int addIndexEntry(dbiIndex *idx, const char *index, unsigned int offset,
+static int addIndexEntry(dbiIndex idx, const char *index, unsigned int offset,
                         unsigned int fileNumber)
 {
-    dbiIndexSet set;
-    dbiIndexRecord irec;   
+    dbiIndexSet set = NULL;
     int rc;
 
-    irec = dbiReturnIndexRecordInstance(offset, fileNumber);
-
     rc = dbiSearchIndex(idx, index, &set);
-    if (rc == -1)              /* error */
+    switch (rc) {
+    case -1:                   /* error */
+       if (set) {
+           dbiFreeIndexSet(set);
+           set = NULL;
+       }
        return 1;
+       /*@notreached@*/ break;
+    case 1:                    /* new item */
+       set = dbiCreateIndexSet();
+       break;
+    default:
+       break;
+    }
+
+    dbiAppendIndexRecord(set, offset, fileNumber);
+    if (dbiUpdateIndex(idx, index, set))
+       exit(EXIT_FAILURE);     /* XXX W2DO? return 1; */
+
+    if (set) {
+       dbiFreeIndexSet(set);
+       set = NULL;
+    }
 
-    if (rc == 1)               /* new item */
-       set = dbiCreateIndexRecord();
-    dbiAppendIndexRecord(&set, irec);
-    if (dbiUpdateIndex(idx, index, &set))
-       exit(EXIT_FAILURE);
-    dbiFreeIndexRecord(set);
     return 0;
 }
 
@@ -852,7 +876,8 @@ int rpmdbMoveDatabase(const char * rootdir, const char * olddbpath, const char *
 }
 
 struct intMatch {
-    dbiIndexRecord rec;
+    unsigned int recOffset;
+    unsigned int fileNumber;
     int fpNum;
 };
 
@@ -861,9 +886,9 @@ static int intMatchCmp(const void * one, const void * two)
     const struct intMatch * a = one;
     const struct intMatch * b = two;
 
-    if (a->rec.recOffset < b->rec.recOffset)
+    if (a->recOffset < b->recOffset)
        return -1;
-    else if (a->rec.recOffset > b->rec.recOffset)
+    else if (a->recOffset > b->recOffset)
        return 1;
 
     return 0;
@@ -891,11 +916,15 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList,
 
     /* Gather all matches from the database */
     for (i = 0; i < numItems; i++) {
-       dbiIndexSet matches;
+       dbiIndexSet matches = NULL;
        switch (dbiSearchIndex(db->fileIndex, fpList[i].baseName, &matches)) {
        default:
            break;
        case 2:
+           if (matches) {
+               dbiFreeIndexSet(matches);
+               matches = NULL;
+           }
            free(intMatches);
            return 1;
            /*@notreached@*/ break;
@@ -908,21 +937,26 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList,
            }
 
            for (j = 0; j < dbiIndexSetCount(matches); j++) {
-               /* structure assignment */
-               intMatches[numIntMatches].rec = matches.recs[j];
-               intMatches[numIntMatches++].fpNum = i;
+               
+               intMatches[numIntMatches].recOffset = dbiIndexRecordOffset(matches, j);
+               intMatches[numIntMatches].fileNumber = dbiIndexRecordFileNumber(matches, j);
+               intMatches[numIntMatches].fpNum = i;
+               numIntMatches++;
            }
 
-           dbiFreeIndexRecord(matches);
            break;
        }
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
     }
 
     qsort(intMatches, numIntMatches, sizeof(*intMatches), intMatchCmp);
     /* intMatches is now sorted by (recnum, filenum) */
 
     for (i = 0; i < numItems; i++)
-       matchList[i] = dbiCreateIndexRecord();
+       matchList[i] = dbiCreateIndexSet();
 
     fpc = fpCacheCreate(numIntMatches);
 
@@ -936,13 +970,13 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList,
 
        /* Find the end of the set of matched files in this package. */
        for (end = start + 1; end < numIntMatches; end++) {
-           if (im->rec.recOffset != intMatches[end].rec.recOffset)
+           if (im->recOffset != intMatches[end].recOffset)
                break;
        }
        num = end - start;
 
        /* Compute fingerprints for each file match in this package. */
-       h = rpmdbGetRecord(db, im->rec.recOffset);
+       h = rpmdbGetRecord(db, im->recOffset);
        if (h == NULL) {
            free(intMatches);
            return 1;
@@ -958,8 +992,8 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList,
        baseNames = xcalloc(num, sizeof(*baseNames));
        dirIndexes = xcalloc(num, sizeof(*dirIndexes));
        for (i = 0; i < num; i++) {
-           baseNames[i] = fullBaseNames[im[i].rec.fileNumber];
-           dirIndexes[i] = fullDirIndexes[im[i].rec.fileNumber];
+           baseNames[i] = fullBaseNames[im[i].fileNumber];
+           dirIndexes[i] = fullDirIndexes[im[i].fileNumber];
        }
 
        fps = xcalloc(num, sizeof(*fps));
@@ -974,7 +1008,7 @@ int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, dbiIndexSet * matchList,
        for (i = 0; i < num; i++) {
            j = im[i].fpNum;
            if (FP_EQUAL_DIFFERENT_CACHE(fps[i], fpList[j]))
-               dbiAppendIndexRecord(&matchList[j], im[i].rec);
+               dbiAppendIndexRecord(matchList[j], im[i].recOffset, im[i].fileNumber);
        }
 
        headerFree(h);
index b02fd83..ec27500 100644 (file)
@@ -1,7 +1,11 @@
 #ifndef H_RPMDB
 #define H_RPMDB
 
+/** \file lib/rpmdb.h
+ */
+
 #include <rpmlib.h>
+
 #include "fprint.h"
 
 /* for RPM's internal use only */
 extern "C" {
 #endif
 
+/**
+ */
 int openDatabase(const char * prefix, const char * dbpath, /*@out@*/rpmdb *rpmdbp, int mode,
                 int perms, int flags);
+
+/**
+ */
 int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant);
+
+/**
+ */
 int rpmdbAdd(rpmdb db, Header dbentry);
+
+/**
+ */
 int rpmdbUpdateRecord(rpmdb db, int secOffset, Header secHeader);
+
+/**
+ */
 void rpmdbRemoveDatabase(const char * rootdir, const char * dbpath);
+
+/**
+ */
 int rpmdbMoveDatabase(const char * rootdir, const char * olddbpath, const char * newdbpath);
-/* matchList must be preallocated!!! */
+
+/**
+ * matchList must be preallocated!!!
+ */
 int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, /*@out@*/dbiIndexSet * matchList, 
                    int numItems);
 
index 9053d16..45c1bb1 100644 (file)
@@ -375,8 +375,8 @@ int rpmInstall(const char * rootdir, const char ** fileArgv, int transFlags,
        Unlink(tmppkgURL[i]);
        xfree(tmppkgURL[i]);
     }
-    xfree(tmppkgURL);
-    xfree(pkgURL);
+    xfree(tmppkgURL);  tmppkgURL = NULL;
+    xfree(pkgURL);     pkgURL = NULL;
 
     /* FIXME how do we close our various fd's? */
 
@@ -397,9 +397,10 @@ errxit:
 }
 
 int rpmErase(const char * rootdir, const char ** argv, int transFlags,
-                int interfaceFlags) {
+                int interfaceFlags)
+{
     rpmdb db;
-    dbiIndexSet matches;
+    dbiIndexSet matches = NULL;
     int i, j;
     int mode;
     int rc;
@@ -459,9 +460,12 @@ int rpmErase(const char * rootdir, const char ** argv, int transFlags,
                }
            }
 
-           dbiFreeIndexRecord(matches);
            break;
        }
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
     }
 
     if (!(interfaceFlags & UNINSTALL_NODEPS)) {
@@ -510,8 +514,14 @@ int rpmInstallSource(const char * rootdir, const char * arg, const char ** specF
                                 cookie);
     if (rc == 1) {
        rpmMessage(RPMMESS_ERROR, _("%s cannot be installed\n"), arg);
-       if (specFile && *specFile) xfree(*specFile);
-       if (cookie && *cookie) free(*cookie);
+       if (specFile && *specFile) {
+           xfree(*specFile);
+           *specFile = NULL;
+       }
+       if (cookie && *cookie) {
+           free(*cookie);
+           *cookie = NULL;
+       }
     }
 
     Fclose(fd);
index bc23b8c..0fee66e 100644 (file)
@@ -93,13 +93,13 @@ int Link    (const char * oldpath, const char * newpath);
 int    Unlink  (const char * path);
 int    Readlink(const char * path, char * buf, size_t bufsiz);
 
-int    Stat    (const char * path, struct stat * st);
-int    Lstat   (const char * path, struct stat * st);
+int    Stat    (const char * path, /*@out@*/ struct stat * st);
+int    Lstat   (const char * path, /*@out@*/ struct stat * st);
 int    Access  (const char * path, int amode);
 
 int    Glob    (const char * pattern, int flags,
-               int errfunc(const char * epath, int eerrno), glob_t * pglob);
-void   Globfree(glob_t * pglob);
+               int errfunc(const char * epath, int eerrno), /*@out@*/ glob_t * pglob);
+void   Globfree( /*@only@*/ glob_t * pglob);
 
 DIR *  Opendir (const char * name);
 struct dirent *        Readdir (DIR * dir);
@@ -124,9 +124,9 @@ int fdGetRdTimeoutSecs(FD_t fd);
 long int fdGetCpioPos(FD_t fd);
 void   fdSetCpioPos(FD_t fd, long int cpioPos);
 
-extern /*@null@*/ FD_t fdDup(int fdno);
+/*@null@*/ FD_t fdDup(int fdno);
 #ifdef UNUSED
-extern /*@null@*/ FILE *fdFdopen( /*@only@*/ void * cookie, const char * mode);
+/*@null@*/ FILE *fdFdopen( /*@only@*/ void * cookie, const char * mode);
 #endif
 
 /* XXX legacy interface used in rpm2html */
index 525cd67..8d3d51e 100644 (file)
@@ -6,14 +6,57 @@
 /* and it shouldn't need these :-( */
 
 #include <rpmio.h>
-#include <dbindex.h>
 #include <header.h>
 #include <popt.h>
 
+#if DEAD
+typedef /*@abstract@*/ struct _dbiIndexRecord * dbiIndexRecord;
+typedef /*@abstract@*/ struct _dbiIndex * dbiIndex;
+#endif
+
+typedef /*@abstract@*/ struct _dbiIndexSet * dbiIndexSet;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * Destroy set of index database items.
+ * @param set  set of index database items
+ */
+void dbiFreeIndexSet(/*@only@*/ /*@null@*/ dbiIndexSet set);
+
+/**
+ * Count items in index database set.
+ * @param set  set of index database items
+ * @return     number of items
+ */
+unsigned int dbiIndexSetCount(dbiIndexSet set);
+
+/**
+ * Return record offset of header from element in index database set.
+ * @param set  set of index database items
+ * @param recno        index of item in set
+ * @return     record offset of header
+ */
+unsigned int dbiIndexRecordOffset(dbiIndexSet set, int recno);
+
+/**
+ * Return file index from element in index database set.
+ * @param set  set of index database items
+ * @param recno        index of item in set
+ * @return     file index
+ */
+unsigned int dbiIndexRecordFileNumber(dbiIndexSet set, int recno);
+
+/**
+ * Change record offset of header within element in index database set.
+ * @param set  set of index database items
+ * @param recno        index of item in set
+ * @param recoff new record offset
+ */
+void dbiIndexRecordOffsetSave(dbiIndexSet set, int recno, unsigned int recoff);
+
 int rpmReadPackageInfo(FD_t fd, /*@out@*/ Header * signatures,
        /*@out@*/ Header * hdr);
 int rpmReadPackageHeader(FD_t fd, /*@out@*/ Header * hdr,
index b70d072..8376766 100644 (file)
 
 static const char *defrcfiles = LIBRPMRC_FILENAME ":/etc/rpmrc:~/.rpmrc";
 
+typedef /*@owned@*/ const char * cptr_t;
+
 struct machCacheEntry {
     const char * name;
     int count;
-    const char ** equivs;
+    cptr_t * equivs;
     int visited;
 };
 
@@ -52,19 +54,20 @@ struct rpmOption {
 };
 
 struct defaultEntry {
-    char *name;
-    char *defName;
+/*@owned@*/ const char * name;
+/*@owned@*/ const char * defName;
 };
 
 struct canonEntry {
-    char *name;
-    char *short_name;
+/*@owned@*/ const char * name;
+/*@owned@*/ const char * short_name;
     short num;
 };
 
 /* tags are 'key'canon, 'key'translate, 'key'compat
-
-   for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work */
+ *
+ * for giggles, 'key'_canon, 'key'_compat, and 'key'_canon will also work
+ */
 struct tableType {
     const char * const key;
     const int hasCanon;
@@ -100,13 +103,13 @@ static int optionTableSize = sizeof(optionTable) / sizeof(*optionTable);
 #define OS     0
 #define ARCH   1
 
-static char * current[2];
+static cptr_t current[2];
 static int currTables[2] = { RPM_MACHTABLE_INSTOS, RPM_MACHTABLE_INSTARCH };
 static struct rpmvarValue values[RPMVAR_NUM];
 static int defaultsInitialized = 0;
 
 /* prototypes */
-static int doReadRC(FD_t fd, const char * urlfn);
+static int doReadRC( /*@killref@*/ FD_t fd, const char * urlfn);
 static void rpmSetVarArch(int var, const char * val, const char * arch);
 static void rebuildCompatTables(int type, const char *name);
 
@@ -117,8 +120,8 @@ static int optionCompare(const void * a, const void * b) {
 
 static void rpmRebuildTargetVars(const char **target, const char ** canontarget);
 
-static struct machCacheEntry * machCacheFindEntry(struct machCache * cache,
-                                                 const char * key)
+static /*@observer@*/ struct machCacheEntry *
+machCacheFindEntry(struct machCache * cache, const char * key)
 {
     int i;
 
@@ -196,8 +199,8 @@ static int machCompatCacheAdd(char * name, const char * fn, int linenum,
     return 0;
 }
 
-static struct machEquivInfo * machEquivSearch(
-               struct machEquivTable * table, const char * name)
+static /*@observer@*/ struct machEquivInfo *
+       machEquivSearch(const struct machEquivTable * table, const char * name)
 {
     int i;
 
@@ -366,9 +369,9 @@ static int addDefault(struct defaultEntry **table, int *tableLen, char *line,
     return 0;
 }
 
-static struct canonEntry *lookupInCanonTable(char *name,
-                                            struct canonEntry *table,
-                                            int tableLen) {
+static /*@null@*/ const struct canonEntry *lookupInCanonTable(const char *name,
+       const struct canonEntry *table, int tableLen)
+{
     while (tableLen) {
        tableLen--;
        if (!strcmp(name, table[tableLen].name)) {
@@ -379,8 +382,9 @@ static struct canonEntry *lookupInCanonTable(char *name,
     return NULL;
 }
 
-static const char *lookupInDefaultTable(const char *name, struct defaultEntry *table,
-                                 int tableLen) {
+static /*@observer@*/ const char * lookupInDefaultTable(const char *name,
+               const struct defaultEntry *table, int tableLen)
+{
     while (tableLen) {
        tableLen--;
        if (!strcmp(name, table[tableLen].name)) {
@@ -800,11 +804,12 @@ static int doReadRC( /*@killref@*/ FD_t fd, const char * urlfn)
     return 0;
 }
 
-static void defaultMachine(const char ** arch, const char ** os) {
+static void defaultMachine(/*@out@*/ const char ** arch, /*@out@*/ const char ** os)
+{
     static struct utsname un;
     static int gotDefaults = 0;
     char * chptr;
-    struct canonEntry * canon;
+    const struct canonEntry * canon;
 
     if (!gotDefaults) {
        uname(&un);
@@ -977,7 +982,7 @@ static void defaultMachine(const char ** arch, const char ** os) {
     if (os) *os = un.sysname;
 }
 
-static const char * rpmGetVarArch(int var, char * arch) {
+static const char * rpmGetVarArch(int var, const char * arch) {
     struct rpmvarValue * next;
 
     if (!arch) arch = current[ARCH];
@@ -1110,14 +1115,14 @@ void rpmSetMachine(const char * arch, const char * os) {
     }
 
     if (!current[ARCH] || strcmp(arch, current[ARCH])) {
-       if (current[ARCH]) free(current[ARCH]);
+       if (current[ARCH]) xfree(current[ARCH]);
        current[ARCH] = xstrdup(arch);
        rebuildCompatTables(ARCH, host_cpu);
     }
 
     if (!current[OS] || strcmp(os, current[OS])) {
-       if (current[OS]) free(current[OS]);
-       current[OS] = xstrdup(os);
+       char * t = xstrdup(os);
+       if (current[OS]) xfree(current[OS]);
        /*
         * XXX Capitalizing the 'L' is needed to insure that old
         * XXX os-from-uname (e.g. "Linux") is compatible with the new
@@ -1126,8 +1131,10 @@ void rpmSetMachine(const char * arch, const char * os) {
         * XXX used by rpmInstallPackage->{os,arch}Okay->rpmMachineScore->
         * XXX to verify correct arch/os from headers.
         */
-       if (!strcmp(current[OS], "linux"))
-           *current[OS]= 'L';
+       if (!strcmp(t, "linux"))
+           *t = 'L';
+       current[OS] = t;
+       
        rebuildCompatTables(OS, host_os);
     }
 }
@@ -1138,10 +1145,10 @@ static void rebuildCompatTables(int type, const char * name) {
                   name);
 }
 
-static void getMachineInfo(int type, /*@only@*/ /*@out@*/ const char ** name,
+static void getMachineInfo(int type, /*@out@*/ const char ** name,
                        /*@out@*/int * num)
 {
-    struct canonEntry * canon;
+    const struct canonEntry * canon;
     int which = currTables[type];
 
     /* use the normal canon tables, even if we're looking up build stuff */
index cc6f580..c456a6f 100644 (file)
@@ -1190,7 +1190,7 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
     int rc, ourrc = 0;
     struct availablePackage * alp;
     rpmProblemSet probs;
-    dbiIndexSet dbi, * matches;
+    dbiIndexSet dbi = NULL;
     Header * hdrs;
     int fileCount;
     int totalFileCount = 0;
@@ -1280,25 +1280,49 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
 
        if (!(ignoreSet & RPMPROB_FILTER_OLDPACKAGE)) {
            rc = rpmdbFindPackage(ts->db, alp->name, &dbi);
-           if (rc == 2) {
+           switch (rc) {
+           case 2:
+               if (dbi) {
+                   dbiFreeIndexSet(dbi);
+                   dbi = NULL;
+               }
                return -1;
-           } else if (!rc) {
+               /*@notreached@*/ break;
+           case 0:
                for (i = 0; i < dbiIndexSetCount(dbi); i++)
                    ensureOlder(ts->db, alp->h, dbiIndexRecordOffset(dbi, i),
                                      probs, alp->key);
 
-               dbiFreeIndexRecord(dbi);
+               break;
+           default:
+               break;
+           }
+           if (dbi) {
+               dbiFreeIndexSet(dbi);
+               dbi = NULL;
            }
        }
 
        rc = findMatches(ts->db, alp->name, alp->version, alp->release, &dbi);
-       if (rc == 2) {
+       switch (rc) {
+       case 2:
+           if (dbi) {
+               dbiFreeIndexSet(dbi);
+               dbi = NULL;
+           }
            return -1;
-       } else if (!rc) {
+           /*@notreached@*/ break;
+       case 0:
            if (!(ignoreSet & RPMPROB_FILTER_REPLACEPKG))
                psAppend(probs, RPMPROB_PKG_INSTALLED, alp->key, alp->h, NULL,
                         NULL, 0);
-           dbiFreeIndexRecord(dbi);
+           break;
+       default:
+           break;
+       }
+       if (dbi) {
+           dbiFreeIndexSet(dbi);
+           dbi = NULL;
        }
 
        if (headerGetEntry(alp->h, RPMTAG_BASENAMES, NULL, NULL, 
@@ -1454,13 +1478,14 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
      * Compute file disposition for each package in transaction set.
      */
     for (fi = flList; (fi - flList) < flEntries; fi++) {
+       dbiIndexSet * matches;
        int knownBad;
 
        NOTIFY((NULL, RPMCALLBACK_TRANS_PROGRESS, (fi - flList), flEntries,
               NULL, notifyData));
 
        /* Extract file info for all files in this package from the database. */
-       matches = xmalloc(sizeof(*matches) * fi->fc);
+       matches = xcalloc(sizeof(*matches), fi->fc);
        if (rpmdbFindFpList(ts->db, fi->fps, matches, fi->fc)) return 1;
 
        numShared = 0;
@@ -1495,11 +1520,14 @@ int rpmRunTransactions(rpmTransactionSet ts, rpmCallbackFunction notify,
                shared->isRemoved = (knownBad == ro);
                shared++;
            }
-           dbiFreeIndexRecord(matches[i]);
+           if (matches[i]) {
+               dbiFreeIndexSet(matches[i]);
+               matches[i] = NULL;
+           }
        }
        numShared = shared - sharedList;
        shared->otherPkg = -1;
-       free(matches);
+       xfree(matches);
 
        /* Sort file info by other package index (otherPkg) */
        qsort(sharedList, numShared, sizeof(*shared), sharedCmp);
index 0d711d0..fbb0db8 100644 (file)
@@ -4,6 +4,7 @@
 #include <rpmurl.h>
 #include <rpmmacro.h>  /* XXX for rpmExpand */
 
+#include "dbindex.h"   /* XXX prototypes */
 #include "depends.h"
 #include "install.h"
 #include "md5.h"
@@ -24,7 +25,7 @@ static int removeFile(const char * file, unsigned int flags, short mode,
 
       case FA_BACKUP:
        newfile = alloca(strlen(file) + sizeof(SUFFIX_RPMSAVE));
-       stpcpy(stpcpy(newfile, file), SUFFIX_RPMSAVE);
+       (void)stpcpy(stpcpy(newfile, file), SUFFIX_RPMSAVE);
 
        if (rename(file, newfile)) {
            rpmError(RPMERR_RENAME, _("rename of %s to %s failed: %s"),
@@ -103,12 +104,12 @@ int removeBinaryPackage(const char * prefix, rpmdb db, unsigned int offset,
        if (rpmdbFindPackage(db, name, &matches)) {
            rpmError(RPMERR_DBCORRUPT, _("cannot read packages named %s for uninstall"),
                name);
-           dbiFreeIndexRecord(matches);
+           dbiFreeIndexSet(matches);
            rc = 1;
            goto exit;
        }
        scriptArg = dbiIndexSetCount(matches) - 1;
-       dbiFreeIndexRecord(matches);
+       dbiFreeIndexSet(matches);
     }
 
     if (!(flags & RPMTRANS_FLAG_NOTRIGGERS)) {
@@ -170,7 +171,7 @@ int removeBinaryPackage(const char * prefix, rpmdb db, unsigned int offset,
 
        if (prefixlen) {
            strcpy(fileName, prefix);
-           rpmCleanPath(fileName);
+           (void)rpmCleanPath(fileName);
            prefixlen = strlen(fileName);
        } else
            *fileName = '\0';
@@ -186,7 +187,7 @@ int removeBinaryPackage(const char * prefix, rpmdb db, unsigned int offset,
        for (i = fileCount - 1; i >= 0; i--) {
 
            /* XXX this assumes that dirNames always starts/ends with '/' */
-           stpcpy(stpcpy(fileName+prefixlen, dirNames[dirIndexes[i]]), baseNames[i]);
+           (void)stpcpy(stpcpy(fileName+prefixlen, dirNames[dirIndexes[i]]), baseNames[i]);
 
            rpmMessage(RPMMESS_DEBUG, _("   file: %s action: %s\n"),
                        fileName, fileActionString(actions[i]));
@@ -228,9 +229,8 @@ int removeBinaryPackage(const char * prefix, rpmdb db, unsigned int offset,
     rc = 0;
 
  exit:
-    if (h) {
+    if (h)
        headerFree(h);
-    }
     return rc;
 }
 
@@ -453,7 +453,6 @@ static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourc
     int rc = 0;
     int i;
     int index;
-    dbiIndexSet matches;
     int skip;
 
     if (!headerGetEntry(triggeredH, RPMTAG_TRIGGERNAME, NULL, 
@@ -470,6 +469,8 @@ static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourc
                   (void **) &triggerEVR, NULL);
 
     for (i = 0; i < numTriggers; i++) {
+       dbiIndexSet matches;
+
        if (!(triggerFlags[i] & sense)) continue;
        if (strcmp(triggerNames[i], sourceName)) continue;
 
@@ -497,8 +498,9 @@ static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourc
 
        headerGetEntry(triggeredH, RPMTAG_NAME, NULL, 
                       (void **) &triggerPackageName, NULL);
+
+       matches = NULL;
        rpmdbFindPackage(db, triggerPackageName, &matches);
-       dbiFreeIndexRecord(matches);
 
        index = triggerIndices[i];
        if (!triggersAlreadyRun || !triggersAlreadyRun[index]) {
@@ -509,6 +511,10 @@ static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourc
            if (triggersAlreadyRun) triggersAlreadyRun[index] = 1;
        }
 
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
        free(triggerScripts);
        free(triggerProgs);
 
@@ -526,8 +532,8 @@ static int handleOneTrigger(const char * root, rpmdb db, int sense, Header sourc
 int runTriggers(const char * root, rpmdb db, int sense, Header h,
                int countCorrection, FD_t scriptFd)
 {
-    char * packageName;
-    dbiIndexSet matches, otherMatches;
+    const char * packageName;
+    dbiIndexSet matches;
     Header triggeredH;
     int numPackage;
     int rc;
@@ -535,20 +541,31 @@ int runTriggers(const char * root, rpmdb db, int sense, Header h,
 
     headerGetEntry(h, RPMTAG_NAME, NULL, (void **) &packageName, NULL);
 
-    if ((rc = rpmdbFindByTriggeredBy(db, packageName, &matches)) < 0)
-       return 1;
-    else if (rc)
-       return 0;
+    matches = NULL;
+    if ((rc = rpmdbFindByTriggeredBy(db, packageName, &matches)) < 0) {
+       rc = 1;
+       goto exit;
+    } else if (rc) {
+       rc = 0;
+       goto exit;
+    }
 
-    rpmdbFindPackage(db, packageName, &otherMatches);
-    numPackage = dbiIndexSetCount(otherMatches) + countCorrection;
-    dbiFreeIndexRecord(otherMatches);
+    {  dbiIndexSet otherMatches = NULL;
+       rpmdbFindPackage(db, packageName, &otherMatches);
+       if (otherMatches) {
+           numPackage = dbiIndexSetCount(otherMatches) + countCorrection;
+           dbiFreeIndexSet(otherMatches);
+       } else
+           numPackage = 0;
+    }
 
     rc = 0;
     for (i = 0; i < dbiIndexSetCount(matches); i++) {
        unsigned int recOffset = dbiIndexRecordOffset(matches, i);
-       if ((triggeredH = rpmdbGetRecord(db, recOffset)) == NULL) 
-           return 1;
+       if ((triggeredH = rpmdbGetRecord(db, recOffset)) == NULL) {
+           rc = 1;
+           break;
+       }
 
        rc |= handleOneTrigger(root, db, sense, h, triggeredH, 0, numPackage, 
                               NULL, scriptFd);
@@ -556,18 +573,21 @@ int runTriggers(const char * root, rpmdb db, int sense, Header h,
        headerFree(triggeredH);
     }
 
-    dbiFreeIndexRecord(matches);
+exit:
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
 
     return rc;
-    
 }
 
 /** */
 int runImmedTriggers(const char * root, rpmdb db, int sense, Header h,
                     int countCorrection, FD_t scriptFd)
 {
-    int rc = 0;
     dbiIndexSet matches;
+    int rc = 0;
     char ** triggerNames;
     int numTriggers;
     int i, j;
@@ -583,7 +603,14 @@ int runImmedTriggers(const char * root, rpmdb db, int sense, Header h,
     triggersRun = alloca(sizeof(*triggersRun) * i);
     memset(triggersRun, 0, sizeof(*triggersRun) * i);
 
+    matches = NULL;
     for (i = 0; i < numTriggers; i++) {
+
+       if (matches) {
+           dbiFreeIndexSet(matches);
+           matches = NULL;
+       }
+
        if (triggersRun[triggerIndices[i]]) continue;
        
         if ((j = rpmdbFindPackage(db, triggerNames[i], &matches))) {
@@ -593,17 +620,22 @@ int runImmedTriggers(const char * root, rpmdb db, int sense, Header h,
 
        for (j = 0; j < dbiIndexSetCount(matches); j++) {
            unsigned int recOffset = dbiIndexRecordOffset(matches, j);
-           if ((sourceH = rpmdbGetRecord(db, recOffset)) == NULL) 
-               return 1;
+           if ((sourceH = rpmdbGetRecord(db, recOffset)) == NULL) {
+               rc = 1;
+               goto exit;
+           }
            rc |= handleOneTrigger(root, db, sense, sourceH, h, 
                                   countCorrection, dbiIndexSetCount(matches), 
                                   triggersRun, scriptFd);
            headerFree(sourceH);
            if (triggersRun[triggerIndices[i]]) break;
        }
-
-       dbiFreeIndexRecord(matches);
     }
 
+exit:
+    if (matches) {
+       dbiFreeIndexSet(matches);
+       matches = NULL;
+    }
     return rc;
 }
index af3180e..ca148f4 100644 (file)
@@ -10,7 +10,7 @@
 #include <rpmurl.h>
 
 static int _ie = 0x44332211;
-static union _endian { int i; char b[4]; } *_endian = (union _endian *)&_ie;
+static union _vendian { int i; char b[4]; } *_endian = (union _vendian *)&_ie;
 #define        IS_BIG_ENDIAN()         (_endian->b[0] == '\x44')
 #define        IS_LITTLE_ENDIAN()      (_endian->b[0] == '\x11')
 
index 02baf9f..6bc0f37 100644 (file)
@@ -8,7 +8,7 @@ WriteMakefile(
              'OBJECT'  => 'rpm.o constant.o',
              'VERSION_FROM' => 'rpm.pm',               # finds $VERSION
              'MAKEFILE'=> 'PMakefile',
-             'LIBS'    => [' -L/usr/local/lib  -ldb1 -lz -lbz2'],                      # e.g., '-lm' 
+             'LIBS'    => [' -L/usr/local/lib  -ldb -lz -lbz2'],                       # e.g., '-lm' 
              'CCFLAGS' => '-g -O2 -D_GNU_SOURCE -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wno-char-subscripts',
              'OPTIMIZE'=> '-g',
              'DEFINE'  => '-Dbool=char -DHAS_BOOL',
index ef17f55..ef4b6a3 100644 (file)
@@ -76,6 +76,7 @@ CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CPP = @CPP@
 DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
 DLLTOOL = @DLLTOOL@
 FINDPROVIDES = @FINDPROVIDES@
 FINDREQUIRES = @FINDREQUIRES@
index 235b275..c5d2bf5 100644 (file)
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-03-11 15:21-0500\n"
+"POT-Creation-Date: 2000-03-23 09:14-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -14,7 +14,7 @@ msgstr ""
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: ENCODING\n"
 
-#: build.c:25 lib/rpminstall.c:250 lib/rpminstall.c:424
+#: build.c:25 lib/rpminstall.c:250 lib/rpminstall.c:425
 #, c-format
 msgid "cannot open %s/packages.rpm\n"
 msgstr ""
@@ -1660,113 +1660,113 @@ msgstr ""
 msgid "line %d: Second %%files list"
 msgstr ""
 
-#: build/parsePreamble.c:149
+#: build/parsePreamble.c:148
 #, c-format
 msgid "Architecture is excluded: %s"
 msgstr ""
 
-#: build/parsePreamble.c:154
+#: build/parsePreamble.c:153
 #, c-format
 msgid "Architecture is not included: %s"
 msgstr ""
 
-#: build/parsePreamble.c:159
+#: build/parsePreamble.c:158
 #, c-format
 msgid "OS is excluded: %s"
 msgstr ""
 
-#: build/parsePreamble.c:164
+#: build/parsePreamble.c:163
 #, c-format
 msgid "OS is not included: %s"
 msgstr ""
 
-#: build/parsePreamble.c:178
+#: build/parsePreamble.c:177
 #, c-format
 msgid "%s field must be present in package: %s"
 msgstr ""
 
-#: build/parsePreamble.c:203
+#: build/parsePreamble.c:202
 #, c-format
 msgid "Duplicate %s entries in package: %s"
 msgstr ""
 
-#: build/parsePreamble.c:250
+#: build/parsePreamble.c:249
 #, c-format
 msgid "Unable to open icon %s: %s"
 msgstr ""
 
-#: build/parsePreamble.c:268
+#: build/parsePreamble.c:267
 #, c-format
 msgid "Unable to read icon %s: %s"
 msgstr ""
 
-#: build/parsePreamble.c:281
+#: build/parsePreamble.c:280
 #, c-format
 msgid "Unknown icon type: %s"
 msgstr ""
 
-#: build/parsePreamble.c:344
+#: build/parsePreamble.c:343
 #, c-format
 msgid "line %d: Malformed tag: %s"
 msgstr ""
 
 #. Empty field
-#: build/parsePreamble.c:352
+#: build/parsePreamble.c:351
 #, c-format
 msgid "line %d: Empty tag: %s"
 msgstr ""
 
-#: build/parsePreamble.c:375 build/parsePreamble.c:382
+#: build/parsePreamble.c:374 build/parsePreamble.c:381
 #, c-format
 msgid "line %d: Illegal char '-' in %s: %s"
 msgstr ""
 
-#: build/parsePreamble.c:446 build/parseSpec.c:375
+#: build/parsePreamble.c:445 build/parseSpec.c:375
 #, c-format
 msgid "BuildRoot can not be \"/\": %s"
 msgstr ""
 
-#: build/parsePreamble.c:459
+#: build/parsePreamble.c:458
 #, c-format
 msgid "line %d: Prefixes must not end with \"/\": %s"
 msgstr ""
 
-#: build/parsePreamble.c:471
+#: build/parsePreamble.c:470
 #, c-format
 msgid "line %d: Docdir must begin with '/': %s"
 msgstr ""
 
-#: build/parsePreamble.c:483
+#: build/parsePreamble.c:482
 #, c-format
 msgid "line %d: Epoch/Serial field must be a number: %s"
 msgstr ""
 
-#: build/parsePreamble.c:546
+#: build/parsePreamble.c:545
 #, c-format
 msgid "line %d: Bad BuildArchitecture format: %s"
 msgstr ""
 
-#: build/parsePreamble.c:556
+#: build/parsePreamble.c:555
 #, c-format
 msgid "Internal error: Bogus tag %d"
 msgstr ""
 
-#: build/parsePreamble.c:695
+#: build/parsePreamble.c:694
 #, c-format
 msgid "Bad package specification: %s"
 msgstr ""
 
-#: build/parsePreamble.c:701
+#: build/parsePreamble.c:700
 #, c-format
 msgid "Package already exists: %s"
 msgstr ""
 
-#: build/parsePreamble.c:728
+#: build/parsePreamble.c:727
 #, c-format
 msgid "line %d: Unknown tag: %s"
 msgstr ""
 
-#: build/parsePreamble.c:753
+#: build/parsePreamble.c:752
 msgid "Spec file can't use BuildRoot"
 msgstr ""
 
@@ -1923,85 +1923,90 @@ msgstr ""
 msgid "archive = %s, fs = %s\n"
 msgstr ""
 
-#: build/spec.c:246
+#: build/spec.c:245
 #, c-format
 msgid "line %d: Bad number: %s"
 msgstr ""
 
-#: build/spec.c:252
+#: build/spec.c:251
 #, c-format
 msgid "line %d: Bad no%s number: %d"
 msgstr ""
 
-#: build/spec.c:311
+#: build/spec.c:310
 #, c-format
 msgid "line %d: Bad %s number: %s\n"
 msgstr ""
 
-#: lib/cpio.c:345
+#: lib/cpio.c:351
 #, c-format
 msgid "can't rename %s to %s: %s\n"
 msgstr ""
 
-#: lib/cpio.c:351
+#: lib/cpio.c:357
 #, c-format
 msgid "can't unlink %s: %s\n"
 msgstr ""
 
-#: lib/cpio.c:549
+#: lib/cpio.c:599
 #, c-format
 msgid "getNextHeader: %s\n"
 msgstr ""
 
-#: lib/cpio.c:1018
+#: lib/cpio.c:1048
 #, c-format
 msgid "(error 0x%x)"
 msgstr ""
 
-#: lib/cpio.c:1021
+#: lib/cpio.c:1051
 msgid "Bad magic"
 msgstr ""
 
-#: lib/cpio.c:1022
+#: lib/cpio.c:1052
 msgid "Bad/unreadable  header"
 msgstr ""
 
-#: lib/cpio.c:1040
+#: lib/cpio.c:1070
 msgid "Header size too big"
 msgstr ""
 
-#: lib/cpio.c:1041
+#: lib/cpio.c:1071
 msgid "Unknown file type"
 msgstr ""
 
-#: lib/cpio.c:1042
+#: lib/cpio.c:1072
 msgid "Missing hard link"
 msgstr ""
 
-#: lib/cpio.c:1043
+#: lib/cpio.c:1073
 msgid "Internal error"
 msgstr ""
 
-#: lib/cpio.c:1052
+#: lib/cpio.c:1082
 msgid " failed - "
 msgstr ""
 
-#: lib/dbindex.c:35
+#: lib/dbindex.c:63
+#, c-format
+msgid "bad db file %s"
+msgstr ""
+
+#: lib/dbindex.c:79
 #, c-format
 msgid "cannot open file %s: %s"
 msgstr ""
 
-#: lib/dbindex.c:87
+#: lib/dbindex.c:162
 #, c-format
 msgid "error getting record %s from %s"
 msgstr ""
 
-#: lib/dbindex.c:114
+#: lib/dbindex.c:187
 #, c-format
 msgid "error storing record %s into %s"
 msgstr ""
 
-#: lib/dbindex.c:121
+#: lib/dbindex.c:192
 #, c-format
 msgid "error removing record %s into %s"
 msgstr ""
@@ -2023,69 +2028,69 @@ msgstr ""
 msgid "dbrecMatchesDepFlags() failed to read header"
 msgstr ""
 
-#: lib/depends.c:784
+#: lib/depends.c:792
 #, c-format
 msgid "%s: %s satisfied by added file list.\n"
 msgstr ""
 
-#: lib/depends.c:823
+#: lib/depends.c:831
 #, c-format
 msgid "%s: %s satisfied by added package.\n"
 msgstr ""
 
-#: lib/depends.c:840
+#: lib/depends.c:848
 #, c-format
 msgid "%s: %s satisfied by added provide.\n"
 msgstr ""
 
-#: lib/depends.c:871
+#: lib/depends.c:879
 #, c-format
 msgid "%s: %s satisfied by rpmrc provides.\n"
 msgstr ""
 
-#: lib/depends.c:899
+#: lib/depends.c:906
 #, c-format
 msgid "%s: %s satisfied by db file lists.\n"
 msgstr ""
 
-#: lib/depends.c:921
+#: lib/depends.c:931
 #, c-format
 msgid "%s: %s satisfied by db provides.\n"
 msgstr ""
 
-#: lib/depends.c:943
+#: lib/depends.c:956
 #, c-format
 msgid "%s: %s satisfied by db packages.\n"
 msgstr ""
 
-#: lib/depends.c:956
+#: lib/depends.c:973
 #, c-format
 msgid "%s: %s satisfied by rpmlib version.\n"
 msgstr ""
 
-#: lib/depends.c:966
+#: lib/depends.c:983
 #, c-format
 msgid "%s: %s unsatisfied.\n"
 msgstr ""
 
 #. requirements are not satisfied.
-#: lib/depends.c:1014
+#: lib/depends.c:1035
 #, c-format
 msgid "package %s require not satisfied: %s\n"
 msgstr ""
 
 #. conflicts exist.
-#: lib/depends.c:1076
+#: lib/depends.c:1097
 #, c-format
 msgid "package %s conflicts: %s\n"
 msgstr ""
 
-#: lib/depends.c:1131 lib/depends.c:1430
+#: lib/depends.c:1152 lib/depends.c:1447
 #, c-format
 msgid "cannot read header at %d for dependency check"
 msgstr ""
 
-#: lib/depends.c:1226
+#: lib/depends.c:1243
 #, c-format
 msgid "loop in prerequisite chain: %s"
 msgstr ""
@@ -2205,111 +2210,111 @@ msgstr ""
 msgid "(unknown type)"
 msgstr ""
 
-#: lib/install.c:142 lib/uninstall.c:191
+#: lib/install.c:146 lib/uninstall.c:192
 #, c-format
 msgid "   file: %s action: %s\n"
 msgstr ""
 
-#: lib/install.c:160
+#: lib/install.c:165
 #, c-format
 msgid "user %s does not exist - using root"
 msgstr ""
 
-#: lib/install.c:168
+#: lib/install.c:173
 #, c-format
 msgid "group %s does not exist - using root"
 msgstr ""
 
-#: lib/install.c:196
+#: lib/install.c:202
 msgid "%%instchangelog value in macro file should be a number, but isn't"
 msgstr ""
 
 #. this would probably be a good place to check if disk space
 #. was used up - if so, we should return a different error
-#: lib/install.c:362
+#: lib/install.c:371
 #, c-format
 msgid "unpacking of archive failed%s%s: %s"
 msgstr ""
 
-#: lib/install.c:363
+#: lib/install.c:372
 msgid " on file "
 msgstr ""
 
-#: lib/install.c:406
+#: lib/install.c:416
 msgid "installing a source package\n"
 msgstr ""
 
-#: lib/install.c:426
+#: lib/install.c:436
 #, c-format
 msgid "cannot create sourcedir %s"
 msgstr ""
 
-#: lib/install.c:432 lib/install.c:462
+#: lib/install.c:442 lib/install.c:472
 #, c-format
 msgid "cannot write to %s"
 msgstr ""
 
-#: lib/install.c:436
+#: lib/install.c:446
 #, c-format
 msgid "sources in: %s\n"
 msgstr ""
 
-#: lib/install.c:456
+#: lib/install.c:466
 #, c-format
 msgid "cannot create specdir %s"
 msgstr ""
 
-#: lib/install.c:466
+#: lib/install.c:476
 #, c-format
 msgid "spec file in: %s\n"
 msgstr ""
 
-#: lib/install.c:500 lib/install.c:528
+#: lib/install.c:510 lib/install.c:538
 msgid "source package contains no .spec file"
 msgstr ""
 
-#: lib/install.c:550
+#: lib/install.c:560
 #, c-format
 msgid "renaming %s to %s\n"
 msgstr ""
 
-#: lib/install.c:552 lib/install.c:831 lib/uninstall.c:30
+#: lib/install.c:562 lib/install.c:846 lib/uninstall.c:31
 #, c-format
 msgid "rename of %s to %s failed: %s"
 msgstr ""
 
-#: lib/install.c:643
+#: lib/install.c:653
 msgid "source package expected, binary found"
 msgstr ""
 
-#: lib/install.c:700
+#: lib/install.c:710
 #, c-format
 msgid "package: %s-%s-%s files test = %d\n"
 msgstr ""
 
-#: lib/install.c:761
+#: lib/install.c:776
 msgid "stopping install as we're running --test\n"
 msgstr ""
 
-#: lib/install.c:766
+#: lib/install.c:781
 msgid "running preinstall script (if any)\n"
 msgstr ""
 
-#: lib/install.c:791
+#: lib/install.c:806
 #, c-format
 msgid "warning: %s created as %s"
 msgstr ""
 
-#: lib/install.c:827
+#: lib/install.c:842
 #, c-format
 msgid "warning: %s saved as %s"
 msgstr ""
 
-#: lib/install.c:901
+#: lib/install.c:916
 msgid "running postinstall scripts (if any)\n"
 msgstr ""
 
-#: lib/lookup.c:35
+#: lib/lookup.c:44
 #, c-format
 msgid "cannot read header at %d for lookup"
 msgstr ""
@@ -2586,121 +2591,121 @@ msgstr ""
 msgid "group %s does not contain any packages\n"
 msgstr ""
 
-#: lib/query.c:591
+#: lib/query.c:590
 #, c-format
 msgid "no package triggers %s\n"
 msgstr ""
 
-#: lib/query.c:601
+#: lib/query.c:599
 #, c-format
 msgid "no package requires %s\n"
 msgstr ""
 
-#: lib/query.c:612
+#: lib/query.c:609
 #, c-format
 msgid "no package provides %s\n"
 msgstr ""
 
-#: lib/query.c:628
+#: lib/query.c:624
 #, c-format
 msgid "file %s: %s\n"
 msgstr ""
 
-#: lib/query.c:631
+#: lib/query.c:627
 #, c-format
 msgid "file %s is not owned by any package\n"
 msgstr ""
 
-#: lib/query.c:644
+#: lib/query.c:639
 #, c-format
 msgid "invalid package number: %s\n"
 msgstr ""
 
-#: lib/query.c:647
+#: lib/query.c:642
 #, c-format
 msgid "package record number: %d\n"
 msgstr ""
 
-#: lib/query.c:650
+#: lib/query.c:645
 #, c-format
 msgid "record %d could not be read\n"
 msgstr ""
 
-#: lib/query.c:662 lib/rpminstall.c:435
+#: lib/query.c:657 lib/rpminstall.c:436
 #, c-format
 msgid "package %s is not installed\n"
 msgstr ""
 
-#: lib/query.c:665
+#: lib/query.c:660
 #, c-format
 msgid "error looking for package %s\n"
 msgstr ""
 
-#: lib/query.c:687
+#: lib/query.c:685
 msgid "rpmQuery: rpmdbOpen() failed\n"
 msgstr ""
 
-#: lib/query.c:746
+#: lib/query.c:744
 msgid "query package owning file"
 msgstr ""
 
-#: lib/query.c:748
+#: lib/query.c:746
 msgid "query packages in group"
 msgstr ""
 
-#: lib/query.c:750
+#: lib/query.c:748
 msgid "query a package file"
 msgstr ""
 
-#: lib/query.c:754
+#: lib/query.c:752
 msgid "query a spec file"
 msgstr ""
 
-#: lib/query.c:756
+#: lib/query.c:754
 msgid "query the pacakges triggered by the package"
 msgstr ""
 
-#: lib/query.c:758
+#: lib/query.c:756
 msgid "query the packages which require a capability"
 msgstr ""
 
-#: lib/query.c:760
+#: lib/query.c:758
 msgid "query the packages which provide a capability"
 msgstr ""
 
-#: lib/query.c:799
+#: lib/query.c:797
 msgid "list all configuration files"
 msgstr ""
 
-#: lib/query.c:801
+#: lib/query.c:799
 msgid "list all documentation files"
 msgstr ""
 
-#: lib/query.c:803
+#: lib/query.c:801
 msgid "dump basic file information"
 msgstr ""
 
-#: lib/query.c:805
+#: lib/query.c:803
 msgid "list files in package"
 msgstr ""
 
-#: lib/query.c:809
+#: lib/query.c:807
 msgid "use the following query format"
 msgstr ""
 
-#: lib/query.c:811
+#: lib/query.c:809
 msgid "substitute i18n sections into spec file"
 msgstr ""
 
-#: lib/query.c:813
+#: lib/query.c:811
 msgid "display the states of the listed files"
 msgstr ""
 
-#: lib/query.c:815
+#: lib/query.c:813
 msgid "display a verbose file listing"
 msgstr ""
 
-#: lib/rebuilddb.c:26 lib/rpmdb.c:252
+#: lib/rebuilddb.c:26 lib/rpmdb.c:251
 msgid "no dbpath has been set"
 msgstr ""
 
@@ -2742,30 +2747,30 @@ msgstr ""
 msgid "duplicated database entry: %s-%s-%s -- skipping."
 msgstr ""
 
-#: lib/rebuilddb.c:113
+#: lib/rebuilddb.c:116
 #, c-format
 msgid "cannot add record originally at %d"
 msgstr ""
 
-#: lib/rebuilddb.c:119
+#: lib/rebuilddb.c:122
 #, c-format
 msgid "record number %d in database is bad -- skipping."
 msgstr ""
 
-#: lib/rebuilddb.c:132
+#: lib/rebuilddb.c:135
 msgid "failed to rebuild database; original database remains in place\n"
 msgstr ""
 
-#: lib/rebuilddb.c:140
+#: lib/rebuilddb.c:143
 msgid "failed to replace old database with new database!\n"
 msgstr ""
 
-#: lib/rebuilddb.c:142
+#: lib/rebuilddb.c:145
 #, c-format
 msgid "replaces files in %s with files from %s to recover"
 msgstr ""
 
-#: lib/rebuilddb.c:148
+#: lib/rebuilddb.c:151
 #, c-format
 msgid "failed to remove directory %s: %s\n"
 msgstr ""
@@ -2853,105 +2858,105 @@ msgstr ""
 msgid "OK"
 msgstr ""
 
-#: lib/rpmdb.c:148
+#: lib/rpmdb.c:147
 #, c-format
 msgid "opening database mode 0x%x in %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:160 lib/url.c:445
+#: lib/rpmdb.c:159 lib/url.c:445
 #, c-format
 msgid "failed to open %s: %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:174 lib/rpmdb.c:182
+#: lib/rpmdb.c:173 lib/rpmdb.c:181
 #, c-format
 msgid "cannot get %s lock on database"
 msgstr ""
 
-#: lib/rpmdb.c:175
+#: lib/rpmdb.c:174
 msgid "exclusive"
 msgstr ""
 
-#: lib/rpmdb.c:183
+#: lib/rpmdb.c:182
 msgid "shared"
 msgstr ""
 
-#: lib/rpmdb.c:214
+#: lib/rpmdb.c:213
 msgid ""
 "old format database is present; use --rebuilddb to generate a new format "
 "database"
 msgstr ""
 
-#: lib/rpmdb.c:473
+#: lib/rpmdb.c:482
 #, c-format
 msgid "package %s not listed in %s"
 msgstr ""
 
-#: lib/rpmdb.c:484
+#: lib/rpmdb.c:491
 #, c-format
 msgid "package %s not found in %s"
 msgstr ""
 
-#: lib/rpmdb.c:508 lib/uninstall.c:90
+#: lib/rpmdb.c:517 lib/uninstall.c:91
 #, c-format
 msgid "cannot read header at %d for uninstall"
 msgstr ""
 
-#: lib/rpmdb.c:516
+#: lib/rpmdb.c:527
 msgid "package has no name"
 msgstr ""
 
-#: lib/rpmdb.c:518
+#: lib/rpmdb.c:529
 msgid "removing name index\n"
 msgstr ""
 
-#: lib/rpmdb.c:523
+#: lib/rpmdb.c:534
 msgid "package has no group\n"
 msgstr ""
 
-#: lib/rpmdb.c:525
+#: lib/rpmdb.c:536
 msgid "removing group index\n"
 msgstr ""
 
-#: lib/rpmdb.c:532
+#: lib/rpmdb.c:543
 #, c-format
 msgid "removing provides index for %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:547
+#: lib/rpmdb.c:558
 #, c-format
 msgid "removing requiredby index for %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:559
+#: lib/rpmdb.c:570
 #, c-format
 msgid "removing trigger index for %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:570
+#: lib/rpmdb.c:581
 #, c-format
 msgid "removing conflict index for %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:581
+#: lib/rpmdb.c:592
 #, c-format
 msgid "removing file index for %s\n"
 msgstr ""
 
-#: lib/rpmdb.c:590
+#: lib/rpmdb.c:601
 msgid "package has no files\n"
 msgstr ""
 
-#: lib/rpmdb.c:696
+#: lib/rpmdb.c:720
 msgid "cannot allocate space for database"
 msgstr ""
 
-#: lib/rpmdb.c:755
+#: lib/rpmdb.c:779
 #, c-format
 msgid "cannot read header at %d for update"
 msgstr ""
 
-#: lib/rpmdb.c:768
+#: lib/rpmdb.c:792
 msgid "header changed size!"
 msgstr ""
 
@@ -3000,7 +3005,7 @@ msgstr ""
 msgid "cannot open file %s: %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:235 lib/rpminstall.c:512
+#: lib/rpminstall.c:235 lib/rpminstall.c:516
 #, c-format
 msgid "%s cannot be installed\n"
 msgstr ""
@@ -3033,26 +3038,26 @@ msgstr ""
 msgid "installing binary packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:439
+#: lib/rpminstall.c:440
 #, c-format
 msgid "searching for package %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:448
+#: lib/rpminstall.c:449
 #, c-format
 msgid "\"%s\" specifies multiple packages\n"
 msgstr ""
 
-#: lib/rpminstall.c:474
+#: lib/rpminstall.c:478
 msgid "removing these packages would break dependencies:\n"
 msgstr ""
 
-#: lib/rpminstall.c:501
+#: lib/rpminstall.c:505
 #, c-format
 msgid "cannot open %s: %s\n"
 msgstr ""
 
-#: lib/rpminstall.c:507
+#: lib/rpminstall.c:511
 #, c-format
 msgid "Installing %s\n"
 msgstr ""
@@ -3119,93 +3124,93 @@ msgstr ""
 msgid "read failed: %s (%d)"
 msgstr ""
 
-#: lib/rpmrc.c:144
+#: lib/rpmrc.c:147
 #, c-format
 msgid "missing second ':' at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:147
+#: lib/rpmrc.c:150
 #, c-format
 msgid "missing architecture name at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:307
+#: lib/rpmrc.c:310
 #, c-format
 msgid "Incomplete data line at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:311
+#: lib/rpmrc.c:314
 #, c-format
 msgid "Too many args in data line at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:318
+#: lib/rpmrc.c:321
 #, c-format
 msgid "Bad arch/os number: %s (%s:%d)"
 msgstr ""
 
-#: lib/rpmrc.c:353
+#: lib/rpmrc.c:356
 #, c-format
 msgid "Incomplete default line at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:358
+#: lib/rpmrc.c:361
 #, c-format
 msgid "Too many args in default line at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:547
+#: lib/rpmrc.c:551
 #, c-format
 msgid "Cannot expand %s"
 msgstr ""
 
-#: lib/rpmrc.c:562
+#: lib/rpmrc.c:566
 #, c-format
 msgid "Unable to open %s for reading: %s."
 msgstr ""
 
 #. XXX Feof(fd)
-#: lib/rpmrc.c:607
+#: lib/rpmrc.c:611
 #, c-format
 msgid "Failed to read %s: %s."
 msgstr ""
 
-#: lib/rpmrc.c:644
+#: lib/rpmrc.c:648
 #, c-format
 msgid "missing ':' (found 0x%02x) at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:661 lib/rpmrc.c:735
+#: lib/rpmrc.c:665 lib/rpmrc.c:739
 #, c-format
 msgid "missing argument for %s at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:678 lib/rpmrc.c:700
+#: lib/rpmrc.c:682 lib/rpmrc.c:704
 #, c-format
 msgid "%s expansion failed at %s:%d \"%s\""
 msgstr ""
 
-#: lib/rpmrc.c:687
+#: lib/rpmrc.c:691
 #, c-format
 msgid "cannot open %s at %s:%d: %s"
 msgstr ""
 
-#: lib/rpmrc.c:727
+#: lib/rpmrc.c:731
 #, c-format
 msgid "missing architecture for %s at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:794
+#: lib/rpmrc.c:798
 #, c-format
 msgid "bad option '%s' at %s:%d"
 msgstr ""
 
-#: lib/rpmrc.c:1162
+#: lib/rpmrc.c:1169
 #, c-format
 msgid "Unknown system: %s\n"
 msgstr ""
 
-#: lib/rpmrc.c:1163
+#: lib/rpmrc.c:1170
 msgid "Please contact rpm-list@redhat.com\n"
 msgstr ""
 
@@ -3371,36 +3376,36 @@ msgstr ""
 msgid "%s skipped due to missingok flag\n"
 msgstr ""
 
-#: lib/uninstall.c:41
+#: lib/uninstall.c:42
 #, c-format
 msgid "cannot remove %s - directory not empty"
 msgstr ""
 
-#: lib/uninstall.c:44
+#: lib/uninstall.c:45
 #, c-format
 msgid "rmdir of %s failed: %s"
 msgstr ""
 
-#: lib/uninstall.c:52
+#: lib/uninstall.c:53
 #, c-format
 msgid "removal of %s failed: %s"
 msgstr ""
 
-#: lib/uninstall.c:104
+#: lib/uninstall.c:105
 #, c-format
 msgid "cannot read packages named %s for uninstall"
 msgstr ""
 
-#: lib/uninstall.c:137
+#: lib/uninstall.c:138
 #, c-format
 msgid "will remove files test = %d\n"
 msgstr ""
 
-#: lib/uninstall.c:205
+#: lib/uninstall.c:206
 msgid "running postuninstall script (if any)\n"
 msgstr ""
 
-#: lib/uninstall.c:219
+#: lib/uninstall.c:220
 msgid "removing database entry\n"
 msgstr ""
 
index 5f088d3..0a39e01 100644 (file)
@@ -76,6 +76,7 @@ CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CPP = @CPP@
 DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
 DLLTOOL = @DLLTOOL@
 FINDPROVIDES = @FINDPROVIDES@
 FINDREQUIRES = @FINDREQUIRES@
@@ -171,6 +172,7 @@ LDADD =
 pythondir = $(prefix)/lib/python1.5/site-packages
 python_PROGRAMS = rpmmodule.so
 rpmmodule_so_SOURCES = 
+# XXX rpmmodule_so_LDFLAGS = -L../lib/.libs -lrpm -L../popt/.libs -lpopt $(LIBS) -shared -Wl,-soname,rpmmodule.so
 rpmmodule_so_LDFLAGS = -lrpm -lpopt $(LIBS) -shared -Wl,-soname,rpmmodule.so
 
 noinst_LTLIBRARIES = librpmmodule.la
index 6b2d843..bc60112 100644 (file)
--- a/rpm.spec
+++ b/rpm.spec
@@ -2,7 +2,7 @@ Summary: The Red Hat package management system.
 Name: rpm
 %define version 3.1
 Version: %{version}
-Release: 0.0
+Release: 0.1
 Group: System Environment/Base
 Source: ftp://ftp.rpm.org/pub/rpm/dist/rpm-3.0.x/rpm-%{version}.tar.gz
 Copyright: GPL
@@ -219,5 +219,11 @@ fi
 /usr/include/popt.h
 
 %changelog
+* Thu Mar 23 10:48:35 EST 2000
+- use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
+- configure.in fiddles for BSD systems (Patrick Schoo).
+- API: change dbi to pass by reference, not value.
+- cram all of db1, db_185, and db2 interfaces into rpmlib.
+
 * Mon Mar 13 2000 Jeff Johnson <jbj@redhat.com>
 - start rpm-3.1 development.
index 6c1e522..5e48ae0 100644 (file)
@@ -76,6 +76,7 @@ CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CPP = @CPP@
 DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
 DLLTOOL = @DLLTOOL@
 FINDPROVIDES = @FINDPROVIDES@
 FINDREQUIRES = @FINDREQUIRES@