- cram all of db1, db_185, and db2 interfaces into rpmlib.
CVS patchset: 3636
CVS date: 2000/03/23 15:49:50
3.0.4 -> 3.1
- use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
- configure.in fiddles for BSD systems (Patrick Schoo).
+ - API: change dbi to pass by reference, not value.
+ - cram all of db1, db_185, and db2 interfaces into rpmlib.
3.0.3 -> 3.0.4
- use compressed filenames on install side.
const char **argv;
poptParseArgvString(line, &argc, &argv);
- if (argc) {
+ if (argc)
headerAddOrAppendEntry(h, tag, RPM_STRING_ARRAY_TYPE, argv, argc);
- }
FREE(argv);
}
return 0;
}
-static int checkForRequired(Header h, char *name)
+static int checkForRequired(Header h, const char *name)
{
int res = 0;
int *p;
return res;
}
-static int checkForDuplicates(Header h, char *name)
+static int checkForDuplicates(Header h, const char *name)
{
int res = 0;
int lastTag, tag;
{
Package p;
- while (spec->packages) {
- p = spec->packages;
- spec->packages = spec->packages->next;
+ while ((p = spec->packages) != NULL) {
+ spec->packages = p->next;
p->next = NULL;
freePackage(p);
}
dnl will fail.
AC_CHECK_LIB(port, writev)
-AC_CHECK_FUNC(dbopen, [],
- AC_CHECK_LIB(db1, dbopen, [LIBS="$LIBS -ldb1"],
- AC_CHECK_LIB(db, dbopen, [LIBS="$LIBS -ldb"],
- AC_MSG_ERROR([sorry rpm requires a db-1.85 API])))
- )
+DBLIBOBJS=""
+dnl Check for Berkeley db2 API.
+AC_CHECK_FUNC(db_open, [DBLIBOBJS="$DBLIBOBJS db2.c"],
+ AC_CHECK_LIB(db, db_open, [LIBS="$LIBS -ldb"; DBLIBOBJS="$DBLIBOBJS db2.c"])
+)
+dnl Check for Berkeley db1 API retrofit to db2 database.
+AC_CHECK_FUNC(dbopen, [DBLIBOBJS="$DBLIBOBJS db1.c"],
+ AC_CHECK_LIB(db, dbopen, [DBLIBOBJS="$DBLIBOBJS db1.c"])
+)
+dnl Check for Berkeley db1 API in glibc.
+AC_CHECK_LIB(db1, dbopen, [DBLIBOBJS="$DBLIBOBJS db0.c"])
+
+if test X"$DBLIBOBJS" = X; then
+ AC_MSG_ERROR([sorry rpm requires libdb.a or libdb1.a (from the Berkeley db package)])
+fi
+dnl AC_DEFINE_UNQUOTED(DBLIBOBJS, "$DBLIBOBJS")
+AC_SUBST(DBLIBOBJS)
AC_CHECK_FUNC(fork, [], [echo "using vfork() instead of fork()";
LIBOBJS=fakefork.o])
+unixlib
+# XXX ignore doxygen markings
+-unrecogcomments
+
# don't-bother-me-yet parameters
-branchstate
#-immediatetrans
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
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
+/** \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;
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];
/** */
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;
};
/** */
{
int buf[10];
int amount;
-
+
amount = (modulo - fdGetCpioPos(cfd) % modulo) % modulo;
(void)ourread(cfd, buf, amount);
}
amount -= nb;
}
- return rc;
+ return rc;
}
/** */
{
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;
}
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);
/* 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;
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 {
{
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
}
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;
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));
/* 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;
}
{
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)) {
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])) {
{
char buf[4096];
int bite;
-
+
while (amount) {
bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
if (ourread(cfd, buf, bite) != bite)
}
/** */
-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;
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);
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;
}
}
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];
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 */
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);
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;
#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;
#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;
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;
}
/** */
-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,
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);
}
}
- 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;
}
}
/** */
-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)
{
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)
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;
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));
/* 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;
* standard cpio.
* The implementation is pretty close, but it has some behaviors which are
* more to RPM's liking. I tried to document the differing behavior in cpio.c,
- * but I may have missed some.
+ * but I may have missed some (ewt).
*
*/
#define CPIO_MAP_GID (1 << 3)
#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */
-/** The structure used to define a cpio payload file. */
+/**
+ * Defines a single file to be included in a cpio payload.
+ */
struct cpioFileMapping {
-/*@{*/
- /*@owned@*/ const char * archivePath; /*!< Path to store in cpio archive. */
- /*@owned@*/ const char * fsPath; /*!< Location of payload file. */
+/*@dependent@*/ const char * archivePath; /*!< Path to store in cpio archive. */
+/*@dependent@*/ const char * fsPath; /*!< Location of payload file. */
mode_t finalMode; /*!< Mode of payload file (from header). */
uid_t finalUid; /*!< Uid of payload file (from header). */
gid_t finalGid; /*!< Gid of payload file (from header). */
int mapFlags;
-/*@}*/
};
-/** The structure passed as first argument during a cpio progress callback.
+/**
+ * The first argument passed in a cpio progress callback.
*
* Note: When building the cpio payload, only "file" is filled in.
*/
struct cpioCallbackInfo {
-/*@{*/
- /*@dependent@*/ const char * file; /*!< File name being installed. */
+/*@dependent@*/ const char * file; /*!< File name being installed. */
long fileSize; /*!< Total file size. */
long fileComplete; /*!< Amount of file unpacked. */
long bytesProcessed; /*!< No. bytes in archive read. */
-/*@}*/
};
#ifdef __cplusplus
extern "C" {
#endif
+/**
+ */
typedef void (*cpioCallback) (struct cpioCallbackInfo * filespec, void * data);
/**
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
--- /dev/null
+#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@*/
--- /dev/null
+#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 */
+
--- /dev/null
+#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 */
--- /dev/null
+#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 */
+
--- /dev/null
+#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 */
--- /dev/null
+#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 */
+
#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++;
#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
}
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;
removePackage(rpmdep, dbiIndexRecordOffset(matches, i), alNum);
headerFree(h2);
}
-
- dbiFreeIndexRecord(matches);
}
if (headerGetEntry(h, RPMTAG_OBSOLETENAME, NULL, (void **) &obsoletes, &count)) {
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,
removePackage(rpmdep, recOffset, alNum);
}
}
-
- dbiFreeIndexRecord(matches);
}
if (obsoletesEVR) free(obsoletesEVR);
free(obsoletes);
}
+ if (matches) {
+ dbiFreeIndexSet(matches);
+ matches = NULL;
+ }
+
return 0;
}
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;
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++) {
}
}
- 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++) {
}
}
- 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
rc = 1; /* dependency is unsatisfied */
exit:
+ if (matches) {
+ dbiFreeIndexSet(matches);
+ matches = NULL;
+ }
return rc;
}
/* 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;
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;
}
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;
}
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';
}
fp.entry = NULL;
+ fp.subDir = NULL;
+ fp.baseName = NULL;
while (1) {
/* as we're stating paths here, we want to follow symlinks */
+/** \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;
return 1;
if (data)
- *data = b->data;
+ *data = (const void **) b->data;
if (dataCount)
*dataCount = b->dataCount;
if (tableKey)
#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
};
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;
{ NULL, 0 }
};
+/** */
static int rpmInstallLoadMacros(Header h)
{
struct tagMacro *tagm;
return 0;
}
+/** */
static /*@only@*/ struct fileMemory *newFileMemory(void)
{
struct fileMemory *fileMem = xmalloc(sizeof(*fileMem));
return fileMem;
}
+/** */
static void freeFileMemory( /*@only@*/ struct fileMemory *fileMem)
{
if (fileMem->files) free(fileMem->files);
}
/* 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)
return 0;
}
+/** */
static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
{
char ** fileOwners;
free(fileGroups);
}
+/** */
static void trimChangelog(Header h)
{
int * times;
free(texts);
}
+/** */
static int markReplacedFiles(rpmdb db, struct sharedFileInfo * replList)
{
struct sharedFileInfo * fileInfo;
return 0;
}
+/** */
static void callback(struct cpioCallbackInfo * cpioInfo, void * data)
{
struct callbackInfo * ourInfo = 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,
/* 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)
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;
/*@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) {
rc = 0;
exit:
+ if (matches) {
+ dbiFreeIndexSet(matches);
+ matches = NULL;
+ }
if (rootdir && currDir) {
/*@-unrecog@*/ chroot("."); /*@=unrecog@*/
chdir(currDir);
#include "system.h"
#include <rpmlib.h>
+
+#include "dbindex.h" /* XXX prototypes */
#include "lookup.h"
/* XXX used in transaction.c */
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);
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 */
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
}
#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')
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));
if (count > 0) {
*p = fl;
if (c) *c = count;
+ if (type) *type = RPM_STRING_ARRAY_TYPE;
return 1;
}
if (c) *c = 0;
/*@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
}
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;
retcode = 1;
} else {
retcode = showMatches(qva, db, matches, showPackage);
- dbiFreeIndexRecord(matches);
}
break;
retcode = 1;
} else {
retcode = showMatches(qva, db, matches, showPackage);
- dbiFreeIndexRecord(matches);
}
break;
retcode = 1;
} else {
retcode = showMatches(qva, db, matches, showPackage);
- dbiFreeIndexRecord(matches);
}
break;
retcode = 1;
} else {
retcode = showMatches(qva, db, matches, showPackage);
- dbiFreeIndexRecord(matches);
}
break;
}
retcode = 1;
} else {
retcode = showMatches(qva, db, matches, showPackage);
- dbiFreeIndexRecord(matches);
}
break;
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;
}
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;
headerIsEntry(h, RPMTAG_VERSION) &&
headerIsEntry(h, RPMTAG_RELEASE) &&
headerIsEntry(h, RPMTAG_BUILDTIME)) {
- dbiIndexSet matches;
+ dbiIndexSet matches = NULL;
int skip;
/* XXX always eliminate duplicate entries */
_("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,
#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[] = {
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;
}
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);
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;
break;
}
strcat(filename, dbpath);
- rpmCleanPath(filename);
+ (void)rpmCleanPath(filename);
rpmMessage(RPMMESS_DEBUG, _("opening database mode 0x%x in %s\n"),
mode, filename);
}
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));
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... */
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);
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;
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;
}
(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;
}
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)
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)
char ** conflictList, ** triggerList;
int i;
- /* structure assignment */
- rec = dbiReturnIndexRecordInstance(offset, 0);
h = rpmdbGetRecord(db, offset);
if (h == NULL) {
return 1;
}
+ rec = dbiReturnIndexRecordInstance(offset, 0);
+
blockSignals();
if (!headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count)) {
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;
}
}
struct intMatch {
- dbiIndexRecord rec;
+ unsigned int recOffset;
+ unsigned int fileNumber;
int fpNum;
};
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;
/* 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;
}
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);
/* 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;
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));
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);
#ifndef H_RPMDB
#define H_RPMDB
+/** \file lib/rpmdb.h
+ */
+
#include <rpmlib.h>
+
#include "fprint.h"
/* for RPM's internal use only */
extern "C" {
#endif
+/**
+ */
int openDatabase(const char * prefix, const char * dbpath, /*@out@*/rpmdb *rpmdbp, int mode,
int perms, int flags);
+
+/**
+ */
int rpmdbRemove(rpmdb db, unsigned int offset, int tolerant);
+
+/**
+ */
int rpmdbAdd(rpmdb db, Header dbentry);
+
+/**
+ */
int rpmdbUpdateRecord(rpmdb db, int secOffset, Header secHeader);
+
+/**
+ */
void rpmdbRemoveDatabase(const char * rootdir, const char * dbpath);
+
+/**
+ */
int rpmdbMoveDatabase(const char * rootdir, const char * olddbpath, const char * newdbpath);
-/* matchList must be preallocated!!! */
+
+/**
+ * matchList must be preallocated!!!
+ */
int rpmdbFindFpList(rpmdb db, fingerPrint * fpList, /*@out@*/dbiIndexSet * matchList,
int numItems);
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? */
}
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;
}
}
- dbiFreeIndexRecord(matches);
break;
}
+ if (matches) {
+ dbiFreeIndexSet(matches);
+ matches = NULL;
+ }
}
if (!(interfaceFlags & UNINSTALL_NODEPS)) {
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);
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);
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 */
/* 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,
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;
};
};
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;
#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);
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;
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;
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)) {
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)) {
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);
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];
}
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
* 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);
}
}
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 */
int rc, ourrc = 0;
struct availablePackage * alp;
rpmProblemSet probs;
- dbiIndexSet dbi, * matches;
+ dbiIndexSet dbi = NULL;
Header * hdrs;
int fileCount;
int totalFileCount = 0;
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,
* 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;
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);
#include <rpmurl.h>
#include <rpmmacro.h> /* XXX for rpmExpand */
+#include "dbindex.h" /* XXX prototypes */
#include "depends.h"
#include "install.h"
#include "md5.h"
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"),
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)) {
if (prefixlen) {
strcpy(fileName, prefix);
- rpmCleanPath(fileName);
+ (void)rpmCleanPath(fileName);
prefixlen = strlen(fileName);
} else
*fileName = '\0';
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]));
rc = 0;
exit:
- if (h) {
+ if (h)
headerFree(h);
- }
return rc;
}
int rc = 0;
int i;
int index;
- dbiIndexSet matches;
int skip;
if (!headerGetEntry(triggeredH, RPMTAG_TRIGGERNAME, NULL,
(void **) &triggerEVR, NULL);
for (i = 0; i < numTriggers; i++) {
+ dbiIndexSet matches;
+
if (!(triggerFlags[i] & sense)) continue;
if (strcmp(triggerNames[i], sourceName)) continue;
headerGetEntry(triggeredH, RPMTAG_NAME, NULL,
(void **) &triggerPackageName, NULL);
+
+ matches = NULL;
rpmdbFindPackage(db, triggerPackageName, &matches);
- dbiFreeIndexRecord(matches);
index = triggerIndices[i];
if (!triggersAlreadyRun || !triggersAlreadyRun[index]) {
if (triggersAlreadyRun) triggersAlreadyRun[index] = 1;
}
+ if (matches) {
+ dbiFreeIndexSet(matches);
+ matches = NULL;
+ }
free(triggerScripts);
free(triggerProgs);
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;
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);
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;
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))) {
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;
}
#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')
'OBJECT' => 'rpm.o constant.o',
'VERSION_FROM' => 'rpm.pm', # finds $VERSION
'MAKEFILE'=> 'PMakefile',
- 'LIBS' => [' -L/usr/local/lib -ldb1 -lz -lbz2'], # e.g., '-lm'
+ 'LIBS' => [' -L/usr/local/lib -ldb -lz -lbz2'], # e.g., '-lm'
'CCFLAGS' => '-g -O2 -D_GNU_SOURCE -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wno-char-subscripts',
'OPTIMIZE'=> '-g',
'DEFINE' => '-Dbool=char -DHAS_BOOL',
CC = @CC@
CPP = @CPP@
DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
DLLTOOL = @DLLTOOL@
FINDPROVIDES = @FINDPROVIDES@
FINDREQUIRES = @FINDREQUIRES@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-03-11 15:21-0500\n"
+"POT-Creation-Date: 2000-03-23 09:14-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
-#: build.c:25 lib/rpminstall.c:250 lib/rpminstall.c:424
+#: build.c:25 lib/rpminstall.c:250 lib/rpminstall.c:425
#, c-format
msgid "cannot open %s/packages.rpm\n"
msgstr ""
msgid "line %d: Second %%files list"
msgstr ""
-#: build/parsePreamble.c:149
+#: build/parsePreamble.c:148
#, c-format
msgid "Architecture is excluded: %s"
msgstr ""
-#: build/parsePreamble.c:154
+#: build/parsePreamble.c:153
#, c-format
msgid "Architecture is not included: %s"
msgstr ""
-#: build/parsePreamble.c:159
+#: build/parsePreamble.c:158
#, c-format
msgid "OS is excluded: %s"
msgstr ""
-#: build/parsePreamble.c:164
+#: build/parsePreamble.c:163
#, c-format
msgid "OS is not included: %s"
msgstr ""
-#: build/parsePreamble.c:178
+#: build/parsePreamble.c:177
#, c-format
msgid "%s field must be present in package: %s"
msgstr ""
-#: build/parsePreamble.c:203
+#: build/parsePreamble.c:202
#, c-format
msgid "Duplicate %s entries in package: %s"
msgstr ""
-#: build/parsePreamble.c:250
+#: build/parsePreamble.c:249
#, c-format
msgid "Unable to open icon %s: %s"
msgstr ""
-#: build/parsePreamble.c:268
+#: build/parsePreamble.c:267
#, c-format
msgid "Unable to read icon %s: %s"
msgstr ""
-#: build/parsePreamble.c:281
+#: build/parsePreamble.c:280
#, c-format
msgid "Unknown icon type: %s"
msgstr ""
-#: build/parsePreamble.c:344
+#: build/parsePreamble.c:343
#, c-format
msgid "line %d: Malformed tag: %s"
msgstr ""
#. Empty field
-#: build/parsePreamble.c:352
+#: build/parsePreamble.c:351
#, c-format
msgid "line %d: Empty tag: %s"
msgstr ""
-#: build/parsePreamble.c:375 build/parsePreamble.c:382
+#: build/parsePreamble.c:374 build/parsePreamble.c:381
#, c-format
msgid "line %d: Illegal char '-' in %s: %s"
msgstr ""
-#: build/parsePreamble.c:446 build/parseSpec.c:375
+#: build/parsePreamble.c:445 build/parseSpec.c:375
#, c-format
msgid "BuildRoot can not be \"/\": %s"
msgstr ""
-#: build/parsePreamble.c:459
+#: build/parsePreamble.c:458
#, c-format
msgid "line %d: Prefixes must not end with \"/\": %s"
msgstr ""
-#: build/parsePreamble.c:471
+#: build/parsePreamble.c:470
#, c-format
msgid "line %d: Docdir must begin with '/': %s"
msgstr ""
-#: build/parsePreamble.c:483
+#: build/parsePreamble.c:482
#, c-format
msgid "line %d: Epoch/Serial field must be a number: %s"
msgstr ""
-#: build/parsePreamble.c:546
+#: build/parsePreamble.c:545
#, c-format
msgid "line %d: Bad BuildArchitecture format: %s"
msgstr ""
-#: build/parsePreamble.c:556
+#: build/parsePreamble.c:555
#, c-format
msgid "Internal error: Bogus tag %d"
msgstr ""
-#: build/parsePreamble.c:695
+#: build/parsePreamble.c:694
#, c-format
msgid "Bad package specification: %s"
msgstr ""
-#: build/parsePreamble.c:701
+#: build/parsePreamble.c:700
#, c-format
msgid "Package already exists: %s"
msgstr ""
-#: build/parsePreamble.c:728
+#: build/parsePreamble.c:727
#, c-format
msgid "line %d: Unknown tag: %s"
msgstr ""
-#: build/parsePreamble.c:753
+#: build/parsePreamble.c:752
msgid "Spec file can't use BuildRoot"
msgstr ""
msgid "archive = %s, fs = %s\n"
msgstr ""
-#: build/spec.c:246
+#: build/spec.c:245
#, c-format
msgid "line %d: Bad number: %s"
msgstr ""
-#: build/spec.c:252
+#: build/spec.c:251
#, c-format
msgid "line %d: Bad no%s number: %d"
msgstr ""
-#: build/spec.c:311
+#: build/spec.c:310
#, c-format
msgid "line %d: Bad %s number: %s\n"
msgstr ""
-#: lib/cpio.c:345
+#: lib/cpio.c:351
#, c-format
msgid "can't rename %s to %s: %s\n"
msgstr ""
-#: lib/cpio.c:351
+#: lib/cpio.c:357
#, c-format
msgid "can't unlink %s: %s\n"
msgstr ""
-#: lib/cpio.c:549
+#: lib/cpio.c:599
#, c-format
msgid "getNextHeader: %s\n"
msgstr ""
-#: lib/cpio.c:1018
+#: lib/cpio.c:1048
#, c-format
msgid "(error 0x%x)"
msgstr ""
-#: lib/cpio.c:1021
+#: lib/cpio.c:1051
msgid "Bad magic"
msgstr ""
-#: lib/cpio.c:1022
+#: lib/cpio.c:1052
msgid "Bad/unreadable header"
msgstr ""
-#: lib/cpio.c:1040
+#: lib/cpio.c:1070
msgid "Header size too big"
msgstr ""
-#: lib/cpio.c:1041
+#: lib/cpio.c:1071
msgid "Unknown file type"
msgstr ""
-#: lib/cpio.c:1042
+#: lib/cpio.c:1072
msgid "Missing hard link"
msgstr ""
-#: lib/cpio.c:1043
+#: lib/cpio.c:1073
msgid "Internal error"
msgstr ""
-#: lib/cpio.c:1052
+#: lib/cpio.c:1082
msgid " failed - "
msgstr ""
-#: lib/dbindex.c:35
+#: lib/dbindex.c:63
+#, c-format
+msgid "bad db file %s"
+msgstr ""
+
+#: lib/dbindex.c:79
#, c-format
msgid "cannot open file %s: %s"
msgstr ""
-#: lib/dbindex.c:87
+#: lib/dbindex.c:162
#, c-format
msgid "error getting record %s from %s"
msgstr ""
-#: lib/dbindex.c:114
+#: lib/dbindex.c:187
#, c-format
msgid "error storing record %s into %s"
msgstr ""
-#: lib/dbindex.c:121
+#: lib/dbindex.c:192
#, c-format
msgid "error removing record %s into %s"
msgstr ""
msgid "dbrecMatchesDepFlags() failed to read header"
msgstr ""
-#: lib/depends.c:784
+#: lib/depends.c:792
#, c-format
msgid "%s: %s satisfied by added file list.\n"
msgstr ""
-#: lib/depends.c:823
+#: lib/depends.c:831
#, c-format
msgid "%s: %s satisfied by added package.\n"
msgstr ""
-#: lib/depends.c:840
+#: lib/depends.c:848
#, c-format
msgid "%s: %s satisfied by added provide.\n"
msgstr ""
-#: lib/depends.c:871
+#: lib/depends.c:879
#, c-format
msgid "%s: %s satisfied by rpmrc provides.\n"
msgstr ""
-#: lib/depends.c:899
+#: lib/depends.c:906
#, c-format
msgid "%s: %s satisfied by db file lists.\n"
msgstr ""
-#: lib/depends.c:921
+#: lib/depends.c:931
#, c-format
msgid "%s: %s satisfied by db provides.\n"
msgstr ""
-#: lib/depends.c:943
+#: lib/depends.c:956
#, c-format
msgid "%s: %s satisfied by db packages.\n"
msgstr ""
-#: lib/depends.c:956
+#: lib/depends.c:973
#, c-format
msgid "%s: %s satisfied by rpmlib version.\n"
msgstr ""
-#: lib/depends.c:966
+#: lib/depends.c:983
#, c-format
msgid "%s: %s unsatisfied.\n"
msgstr ""
#. requirements are not satisfied.
-#: lib/depends.c:1014
+#: lib/depends.c:1035
#, c-format
msgid "package %s require not satisfied: %s\n"
msgstr ""
#. conflicts exist.
-#: lib/depends.c:1076
+#: lib/depends.c:1097
#, c-format
msgid "package %s conflicts: %s\n"
msgstr ""
-#: lib/depends.c:1131 lib/depends.c:1430
+#: lib/depends.c:1152 lib/depends.c:1447
#, c-format
msgid "cannot read header at %d for dependency check"
msgstr ""
-#: lib/depends.c:1226
+#: lib/depends.c:1243
#, c-format
msgid "loop in prerequisite chain: %s"
msgstr ""
msgid "(unknown type)"
msgstr ""
-#: lib/install.c:142 lib/uninstall.c:191
+#: lib/install.c:146 lib/uninstall.c:192
#, c-format
msgid " file: %s action: %s\n"
msgstr ""
-#: lib/install.c:160
+#: lib/install.c:165
#, c-format
msgid "user %s does not exist - using root"
msgstr ""
-#: lib/install.c:168
+#: lib/install.c:173
#, c-format
msgid "group %s does not exist - using root"
msgstr ""
-#: lib/install.c:196
+#: lib/install.c:202
msgid "%%instchangelog value in macro file should be a number, but isn't"
msgstr ""
#. this would probably be a good place to check if disk space
#. was used up - if so, we should return a different error
-#: lib/install.c:362
+#: lib/install.c:371
#, c-format
msgid "unpacking of archive failed%s%s: %s"
msgstr ""
-#: lib/install.c:363
+#: lib/install.c:372
msgid " on file "
msgstr ""
-#: lib/install.c:406
+#: lib/install.c:416
msgid "installing a source package\n"
msgstr ""
-#: lib/install.c:426
+#: lib/install.c:436
#, c-format
msgid "cannot create sourcedir %s"
msgstr ""
-#: lib/install.c:432 lib/install.c:462
+#: lib/install.c:442 lib/install.c:472
#, c-format
msgid "cannot write to %s"
msgstr ""
-#: lib/install.c:436
+#: lib/install.c:446
#, c-format
msgid "sources in: %s\n"
msgstr ""
-#: lib/install.c:456
+#: lib/install.c:466
#, c-format
msgid "cannot create specdir %s"
msgstr ""
-#: lib/install.c:466
+#: lib/install.c:476
#, c-format
msgid "spec file in: %s\n"
msgstr ""
-#: lib/install.c:500 lib/install.c:528
+#: lib/install.c:510 lib/install.c:538
msgid "source package contains no .spec file"
msgstr ""
-#: lib/install.c:550
+#: lib/install.c:560
#, c-format
msgid "renaming %s to %s\n"
msgstr ""
-#: lib/install.c:552 lib/install.c:831 lib/uninstall.c:30
+#: lib/install.c:562 lib/install.c:846 lib/uninstall.c:31
#, c-format
msgid "rename of %s to %s failed: %s"
msgstr ""
-#: lib/install.c:643
+#: lib/install.c:653
msgid "source package expected, binary found"
msgstr ""
-#: lib/install.c:700
+#: lib/install.c:710
#, c-format
msgid "package: %s-%s-%s files test = %d\n"
msgstr ""
-#: lib/install.c:761
+#: lib/install.c:776
msgid "stopping install as we're running --test\n"
msgstr ""
-#: lib/install.c:766
+#: lib/install.c:781
msgid "running preinstall script (if any)\n"
msgstr ""
-#: lib/install.c:791
+#: lib/install.c:806
#, c-format
msgid "warning: %s created as %s"
msgstr ""
-#: lib/install.c:827
+#: lib/install.c:842
#, c-format
msgid "warning: %s saved as %s"
msgstr ""
-#: lib/install.c:901
+#: lib/install.c:916
msgid "running postinstall scripts (if any)\n"
msgstr ""
-#: lib/lookup.c:35
+#: lib/lookup.c:44
#, c-format
msgid "cannot read header at %d for lookup"
msgstr ""
msgid "group %s does not contain any packages\n"
msgstr ""
-#: lib/query.c:591
+#: lib/query.c:590
#, c-format
msgid "no package triggers %s\n"
msgstr ""
-#: lib/query.c:601
+#: lib/query.c:599
#, c-format
msgid "no package requires %s\n"
msgstr ""
-#: lib/query.c:612
+#: lib/query.c:609
#, c-format
msgid "no package provides %s\n"
msgstr ""
-#: lib/query.c:628
+#: lib/query.c:624
#, c-format
msgid "file %s: %s\n"
msgstr ""
-#: lib/query.c:631
+#: lib/query.c:627
#, c-format
msgid "file %s is not owned by any package\n"
msgstr ""
-#: lib/query.c:644
+#: lib/query.c:639
#, c-format
msgid "invalid package number: %s\n"
msgstr ""
-#: lib/query.c:647
+#: lib/query.c:642
#, c-format
msgid "package record number: %d\n"
msgstr ""
-#: lib/query.c:650
+#: lib/query.c:645
#, c-format
msgid "record %d could not be read\n"
msgstr ""
-#: lib/query.c:662 lib/rpminstall.c:435
+#: lib/query.c:657 lib/rpminstall.c:436
#, c-format
msgid "package %s is not installed\n"
msgstr ""
-#: lib/query.c:665
+#: lib/query.c:660
#, c-format
msgid "error looking for package %s\n"
msgstr ""
-#: lib/query.c:687
+#: lib/query.c:685
msgid "rpmQuery: rpmdbOpen() failed\n"
msgstr ""
-#: lib/query.c:746
+#: lib/query.c:744
msgid "query package owning file"
msgstr ""
-#: lib/query.c:748
+#: lib/query.c:746
msgid "query packages in group"
msgstr ""
-#: lib/query.c:750
+#: lib/query.c:748
msgid "query a package file"
msgstr ""
-#: lib/query.c:754
+#: lib/query.c:752
msgid "query a spec file"
msgstr ""
-#: lib/query.c:756
+#: lib/query.c:754
msgid "query the pacakges triggered by the package"
msgstr ""
-#: lib/query.c:758
+#: lib/query.c:756
msgid "query the packages which require a capability"
msgstr ""
-#: lib/query.c:760
+#: lib/query.c:758
msgid "query the packages which provide a capability"
msgstr ""
-#: lib/query.c:799
+#: lib/query.c:797
msgid "list all configuration files"
msgstr ""
-#: lib/query.c:801
+#: lib/query.c:799
msgid "list all documentation files"
msgstr ""
-#: lib/query.c:803
+#: lib/query.c:801
msgid "dump basic file information"
msgstr ""
-#: lib/query.c:805
+#: lib/query.c:803
msgid "list files in package"
msgstr ""
-#: lib/query.c:809
+#: lib/query.c:807
msgid "use the following query format"
msgstr ""
-#: lib/query.c:811
+#: lib/query.c:809
msgid "substitute i18n sections into spec file"
msgstr ""
-#: lib/query.c:813
+#: lib/query.c:811
msgid "display the states of the listed files"
msgstr ""
-#: lib/query.c:815
+#: lib/query.c:813
msgid "display a verbose file listing"
msgstr ""
-#: lib/rebuilddb.c:26 lib/rpmdb.c:252
+#: lib/rebuilddb.c:26 lib/rpmdb.c:251
msgid "no dbpath has been set"
msgstr ""
msgid "duplicated database entry: %s-%s-%s -- skipping."
msgstr ""
-#: lib/rebuilddb.c:113
+#: lib/rebuilddb.c:116
#, c-format
msgid "cannot add record originally at %d"
msgstr ""
-#: lib/rebuilddb.c:119
+#: lib/rebuilddb.c:122
#, c-format
msgid "record number %d in database is bad -- skipping."
msgstr ""
-#: lib/rebuilddb.c:132
+#: lib/rebuilddb.c:135
msgid "failed to rebuild database; original database remains in place\n"
msgstr ""
-#: lib/rebuilddb.c:140
+#: lib/rebuilddb.c:143
msgid "failed to replace old database with new database!\n"
msgstr ""
-#: lib/rebuilddb.c:142
+#: lib/rebuilddb.c:145
#, c-format
msgid "replaces files in %s with files from %s to recover"
msgstr ""
-#: lib/rebuilddb.c:148
+#: lib/rebuilddb.c:151
#, c-format
msgid "failed to remove directory %s: %s\n"
msgstr ""
msgid "OK"
msgstr ""
-#: lib/rpmdb.c:148
+#: lib/rpmdb.c:147
#, c-format
msgid "opening database mode 0x%x in %s\n"
msgstr ""
-#: lib/rpmdb.c:160 lib/url.c:445
+#: lib/rpmdb.c:159 lib/url.c:445
#, c-format
msgid "failed to open %s: %s\n"
msgstr ""
-#: lib/rpmdb.c:174 lib/rpmdb.c:182
+#: lib/rpmdb.c:173 lib/rpmdb.c:181
#, c-format
msgid "cannot get %s lock on database"
msgstr ""
-#: lib/rpmdb.c:175
+#: lib/rpmdb.c:174
msgid "exclusive"
msgstr ""
-#: lib/rpmdb.c:183
+#: lib/rpmdb.c:182
msgid "shared"
msgstr ""
-#: lib/rpmdb.c:214
+#: lib/rpmdb.c:213
msgid ""
"old format database is present; use --rebuilddb to generate a new format "
"database"
msgstr ""
-#: lib/rpmdb.c:473
+#: lib/rpmdb.c:482
#, c-format
msgid "package %s not listed in %s"
msgstr ""
-#: lib/rpmdb.c:484
+#: lib/rpmdb.c:491
#, c-format
msgid "package %s not found in %s"
msgstr ""
-#: lib/rpmdb.c:508 lib/uninstall.c:90
+#: lib/rpmdb.c:517 lib/uninstall.c:91
#, c-format
msgid "cannot read header at %d for uninstall"
msgstr ""
-#: lib/rpmdb.c:516
+#: lib/rpmdb.c:527
msgid "package has no name"
msgstr ""
-#: lib/rpmdb.c:518
+#: lib/rpmdb.c:529
msgid "removing name index\n"
msgstr ""
-#: lib/rpmdb.c:523
+#: lib/rpmdb.c:534
msgid "package has no group\n"
msgstr ""
-#: lib/rpmdb.c:525
+#: lib/rpmdb.c:536
msgid "removing group index\n"
msgstr ""
-#: lib/rpmdb.c:532
+#: lib/rpmdb.c:543
#, c-format
msgid "removing provides index for %s\n"
msgstr ""
-#: lib/rpmdb.c:547
+#: lib/rpmdb.c:558
#, c-format
msgid "removing requiredby index for %s\n"
msgstr ""
-#: lib/rpmdb.c:559
+#: lib/rpmdb.c:570
#, c-format
msgid "removing trigger index for %s\n"
msgstr ""
-#: lib/rpmdb.c:570
+#: lib/rpmdb.c:581
#, c-format
msgid "removing conflict index for %s\n"
msgstr ""
-#: lib/rpmdb.c:581
+#: lib/rpmdb.c:592
#, c-format
msgid "removing file index for %s\n"
msgstr ""
-#: lib/rpmdb.c:590
+#: lib/rpmdb.c:601
msgid "package has no files\n"
msgstr ""
-#: lib/rpmdb.c:696
+#: lib/rpmdb.c:720
msgid "cannot allocate space for database"
msgstr ""
-#: lib/rpmdb.c:755
+#: lib/rpmdb.c:779
#, c-format
msgid "cannot read header at %d for update"
msgstr ""
-#: lib/rpmdb.c:768
+#: lib/rpmdb.c:792
msgid "header changed size!"
msgstr ""
msgid "cannot open file %s: %s\n"
msgstr ""
-#: lib/rpminstall.c:235 lib/rpminstall.c:512
+#: lib/rpminstall.c:235 lib/rpminstall.c:516
#, c-format
msgid "%s cannot be installed\n"
msgstr ""
msgid "installing binary packages\n"
msgstr ""
-#: lib/rpminstall.c:439
+#: lib/rpminstall.c:440
#, c-format
msgid "searching for package %s\n"
msgstr ""
-#: lib/rpminstall.c:448
+#: lib/rpminstall.c:449
#, c-format
msgid "\"%s\" specifies multiple packages\n"
msgstr ""
-#: lib/rpminstall.c:474
+#: lib/rpminstall.c:478
msgid "removing these packages would break dependencies:\n"
msgstr ""
-#: lib/rpminstall.c:501
+#: lib/rpminstall.c:505
#, c-format
msgid "cannot open %s: %s\n"
msgstr ""
-#: lib/rpminstall.c:507
+#: lib/rpminstall.c:511
#, c-format
msgid "Installing %s\n"
msgstr ""
msgid "read failed: %s (%d)"
msgstr ""
-#: lib/rpmrc.c:144
+#: lib/rpmrc.c:147
#, c-format
msgid "missing second ':' at %s:%d"
msgstr ""
-#: lib/rpmrc.c:147
+#: lib/rpmrc.c:150
#, c-format
msgid "missing architecture name at %s:%d"
msgstr ""
-#: lib/rpmrc.c:307
+#: lib/rpmrc.c:310
#, c-format
msgid "Incomplete data line at %s:%d"
msgstr ""
-#: lib/rpmrc.c:311
+#: lib/rpmrc.c:314
#, c-format
msgid "Too many args in data line at %s:%d"
msgstr ""
-#: lib/rpmrc.c:318
+#: lib/rpmrc.c:321
#, c-format
msgid "Bad arch/os number: %s (%s:%d)"
msgstr ""
-#: lib/rpmrc.c:353
+#: lib/rpmrc.c:356
#, c-format
msgid "Incomplete default line at %s:%d"
msgstr ""
-#: lib/rpmrc.c:358
+#: lib/rpmrc.c:361
#, c-format
msgid "Too many args in default line at %s:%d"
msgstr ""
-#: lib/rpmrc.c:547
+#: lib/rpmrc.c:551
#, c-format
msgid "Cannot expand %s"
msgstr ""
-#: lib/rpmrc.c:562
+#: lib/rpmrc.c:566
#, c-format
msgid "Unable to open %s for reading: %s."
msgstr ""
#. XXX Feof(fd)
-#: lib/rpmrc.c:607
+#: lib/rpmrc.c:611
#, c-format
msgid "Failed to read %s: %s."
msgstr ""
-#: lib/rpmrc.c:644
+#: lib/rpmrc.c:648
#, c-format
msgid "missing ':' (found 0x%02x) at %s:%d"
msgstr ""
-#: lib/rpmrc.c:661 lib/rpmrc.c:735
+#: lib/rpmrc.c:665 lib/rpmrc.c:739
#, c-format
msgid "missing argument for %s at %s:%d"
msgstr ""
-#: lib/rpmrc.c:678 lib/rpmrc.c:700
+#: lib/rpmrc.c:682 lib/rpmrc.c:704
#, c-format
msgid "%s expansion failed at %s:%d \"%s\""
msgstr ""
-#: lib/rpmrc.c:687
+#: lib/rpmrc.c:691
#, c-format
msgid "cannot open %s at %s:%d: %s"
msgstr ""
-#: lib/rpmrc.c:727
+#: lib/rpmrc.c:731
#, c-format
msgid "missing architecture for %s at %s:%d"
msgstr ""
-#: lib/rpmrc.c:794
+#: lib/rpmrc.c:798
#, c-format
msgid "bad option '%s' at %s:%d"
msgstr ""
-#: lib/rpmrc.c:1162
+#: lib/rpmrc.c:1169
#, c-format
msgid "Unknown system: %s\n"
msgstr ""
-#: lib/rpmrc.c:1163
+#: lib/rpmrc.c:1170
msgid "Please contact rpm-list@redhat.com\n"
msgstr ""
msgid "%s skipped due to missingok flag\n"
msgstr ""
-#: lib/uninstall.c:41
+#: lib/uninstall.c:42
#, c-format
msgid "cannot remove %s - directory not empty"
msgstr ""
-#: lib/uninstall.c:44
+#: lib/uninstall.c:45
#, c-format
msgid "rmdir of %s failed: %s"
msgstr ""
-#: lib/uninstall.c:52
+#: lib/uninstall.c:53
#, c-format
msgid "removal of %s failed: %s"
msgstr ""
-#: lib/uninstall.c:104
+#: lib/uninstall.c:105
#, c-format
msgid "cannot read packages named %s for uninstall"
msgstr ""
-#: lib/uninstall.c:137
+#: lib/uninstall.c:138
#, c-format
msgid "will remove files test = %d\n"
msgstr ""
-#: lib/uninstall.c:205
+#: lib/uninstall.c:206
msgid "running postuninstall script (if any)\n"
msgstr ""
-#: lib/uninstall.c:219
+#: lib/uninstall.c:220
msgid "removing database entry\n"
msgstr ""
CC = @CC@
CPP = @CPP@
DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
DLLTOOL = @DLLTOOL@
FINDPROVIDES = @FINDPROVIDES@
FINDREQUIRES = @FINDREQUIRES@
pythondir = $(prefix)/lib/python1.5/site-packages
python_PROGRAMS = rpmmodule.so
rpmmodule_so_SOURCES =
+# XXX rpmmodule_so_LDFLAGS = -L../lib/.libs -lrpm -L../popt/.libs -lpopt $(LIBS) -shared -Wl,-soname,rpmmodule.so
rpmmodule_so_LDFLAGS = -lrpm -lpopt $(LIBS) -shared -Wl,-soname,rpmmodule.so
noinst_LTLIBRARIES = librpmmodule.la
Name: rpm
%define version 3.1
Version: %{version}
-Release: 0.0
+Release: 0.1
Group: System Environment/Base
Source: ftp://ftp.rpm.org/pub/rpm/dist/rpm-3.0.x/rpm-%{version}.tar.gz
Copyright: GPL
/usr/include/popt.h
%changelog
+* Thu Mar 23 10:48:35 EST 2000
+- use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
+- configure.in fiddles for BSD systems (Patrick Schoo).
+- API: change dbi to pass by reference, not value.
+- cram all of db1, db_185, and db2 interfaces into rpmlib.
+
* Mon Mar 13 2000 Jeff Johnson <jbj@redhat.com>
- start rpm-3.1 development.
CC = @CC@
CPP = @CPP@
DATADIRNAME = @DATADIRNAME@
+DBLIBOBJS = @DBLIBOBJS@
DLLTOOL = @DLLTOOL@
FINDPROVIDES = @FINDPROVIDES@
FINDREQUIRES = @FINDREQUIRES@