summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/.lclintrc3
-rw-r--r--lib/Makefile.am42
-rw-r--r--lib/cpio.c470
-rw-r--r--lib/cpio.h29
-rw-r--r--lib/db0.c327
-rw-r--r--lib/db0.h64
-rw-r--r--lib/db1.c326
-rw-r--r--lib/db1.h68
-rw-r--r--lib/db2.c329
-rw-r--r--lib/db2.h68
-rw-r--r--lib/dbindex.c251
-rw-r--r--lib/dbindex.h170
-rw-r--r--lib/depends.c79
-rw-r--r--lib/fprint.c4
-rw-r--r--lib/hash.c36
-rw-r--r--lib/hash.h68
-rw-r--r--lib/install.c37
-rw-r--r--lib/lookup.c47
-rw-r--r--lib/lookup.h3
-rw-r--r--lib/md5.c2
-rw-r--r--lib/misc.c3
-rw-r--r--lib/misc.h3
-rw-r--r--lib/query.c12
-rw-r--r--lib/rebuilddb.c9
-rw-r--r--lib/rpmdb.c162
-rw-r--r--lib/rpmdb.h26
-rw-r--r--lib/rpminstall.c24
-rw-r--r--lib/rpmio.h12
-rw-r--r--lib/rpmlib.h45
-rw-r--r--lib/rpmrc.c63
-rw-r--r--lib/transaction.c48
-rw-r--r--lib/uninstall.c86
-rw-r--r--lib/verify.c2
33 files changed, 2318 insertions, 600 deletions
diff --git a/lib/.lclintrc b/lib/.lclintrc
index 5ff453c20..d4ad2d041 100644
--- a/lib/.lclintrc
+++ b/lib/.lclintrc
@@ -7,6 +7,9 @@
+unixlib
+# XXX ignore doxygen markings
+-unrecogcomments
+
# don't-bother-me-yet parameters
-branchstate
#-immediatetrans
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e6abb9c14..ee21c3ee7 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -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
diff --git a/lib/cpio.c b/lib/cpio.c
index 93c49728f..5babb3955 100644
--- a/lib/cpio.c
+++ b/lib/cpio.c
@@ -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;
diff --git a/lib/cpio.h b/lib/cpio.h
index ed19f89d8..fb95c72eb 100644
--- a/lib/cpio.h
+++ b/lib/cpio.h
@@ -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).
*
*/
@@ -52,35 +52,36 @@
#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
index 000000000..008967a43
--- /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
index 000000000..08f038da5
--- /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
index 000000000..e57b9ec3f
--- /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
index 000000000..35d9aa785
--- /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
index 000000000..fa5e01f0e
--- /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
index 000000000..eeaff4509
--- /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 */
+
diff --git a/lib/dbindex.c b/lib/dbindex.c
index 5e8659f47..3a497113c 100644
--- a/lib/dbindex.c
+++ b/lib/dbindex.c
@@ -3,167 +3,242 @@
#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++;
diff --git a/lib/dbindex.h b/lib/dbindex.h
index b7e15caca..694d39e54 100644
--- a/lib/dbindex.h
+++ b/lib/dbindex.h
@@ -1,60 +1,140 @@
#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
}
diff --git a/lib/depends.c b/lib/depends.c
index 38722f7a7..c0e706c95 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -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;
}
diff --git a/lib/fprint.c b/lib/fprint.c
index c08c472fd..c2ba5b7fc 100644
--- a/lib/fprint.c
+++ b/lib/fprint.c
@@ -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 */
diff --git a/lib/hash.c b/lib/hash.c
index 3b1c98036..73f37a24b 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -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)
diff --git a/lib/hash.h b/lib/hash.h
index b5e0af295..eb8d8fd47 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -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
diff --git a/lib/install.c b/lib/install.c
index 2864d6008..572ad7033 100644
--- a/lib/install.c
+++ b/lib/install.c
@@ -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);
diff --git a/lib/lookup.c b/lib/lookup.c
index fea5efc07..14b99be9a 100644
--- a/lib/lookup.c
+++ b/lib/lookup.c
@@ -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 */
diff --git a/lib/lookup.h b/lib/lookup.h
index 7ba2a160d..8a364b85b 100644
--- a/lib/lookup.h
+++ b/lib/lookup.h
@@ -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
}
diff --git a/lib/md5.c b/lib/md5.c
index abacabf4f..27d2a5499 100644
--- 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')
diff --git a/lib/misc.c b/lib/misc.c
index 456c3a7af..344830f60 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -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;
diff --git a/lib/misc.h b/lib/misc.h
index b4f15c71c..30afc9c76 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -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
}
diff --git a/lib/query.c b/lib/query.c
index 1b1a8439b..ef0b7dd90 100644
--- a/lib/query.c
+++ b/lib/query.c
@@ -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;
}
diff --git a/lib/rebuilddb.c b/lib/rebuilddb.c
index 82a740d9e..e909419c9 100644
--- a/lib/rebuilddb.c
+++ b/lib/rebuilddb.c
@@ -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,
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index ea86399e8..ccb4f1777 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -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);
diff --git a/lib/rpmdb.h b/lib/rpmdb.h
index b02fd837f..ec275008d 100644
--- a/lib/rpmdb.h
+++ b/lib/rpmdb.h
@@ -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 */
@@ -13,14 +17,34 @@
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);
diff --git a/lib/rpminstall.c b/lib/rpminstall.c
index 9053d16cd..45c1bb126 100644
--- a/lib/rpminstall.c
+++ b/lib/rpminstall.c
@@ -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);
diff --git a/lib/rpmio.h b/lib/rpmio.h
index bc23b8c84..0fee66ee5 100644
--- a/lib/rpmio.h
+++ b/lib/rpmio.h
@@ -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 */
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index 525cd67f1..8d3d51e8d 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -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,
diff --git a/lib/rpmrc.c b/lib/rpmrc.c
index b70d0726a..837676633 100644
--- a/lib/rpmrc.c
+++ b/lib/rpmrc.c
@@ -15,10 +15,12 @@
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 */
diff --git a/lib/transaction.c b/lib/transaction.c
index cc6f58092..c456a6f72 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -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);
diff --git a/lib/uninstall.c b/lib/uninstall.c
index 0d711d0c8..fbb0db8a8 100644
--- a/lib/uninstall.c
+++ b/lib/uninstall.c
@@ -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;
}
diff --git a/lib/verify.c b/lib/verify.c
index af3180e44..ca148f4d4 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -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')