RPM Community Forums

Mailing List Message of <rpm-cvs>

[CVS] RPM: rpm-5_1: rpm/ CHANGES rpm/rpmio/ Makefile.am bzdio.c gzdio....

From: Jeff Johnson <jbj@rpm5.org>
Date: Tue 19 Aug 2008 - 01:18:18 CEST
Message-Id: <20080818231818.570F8714F4@rpm5.org>
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
  Module: rpm                              Date:   19-Aug-2008 01:18:18
  Branch: rpm-5_1                          Handle: 2008081823181700

  Added files:              (Branch: rpm-5_1)
    rpm/rpmio               bzdio.c gzdio.c
  Modified files:           (Branch: rpm-5_1)
    rpm                     CHANGES
    rpm/rpmio               Makefile.am lzdio.c rpmio.c rpmio.h

  Log:
    - at: gzdio: fixed and re-enabled rsyncable_gzwrite()
    - rse: fix building under --with-lzma by providing the necessary 64-bit defines for inclusion of <lzma.h>
    - jbj: gzdio: quadruple check with external -lz. still no fix => disabled.
    - jbj: gzdio: integrate the cpio tracking patch (needs to be done elsewhere)
    - jbj: gzdio: disable rsync flushing until a fix can be attempted.
    - jbj: gzdio: remove c99'ism.
    - at: gzdio: return partial "best effort" bytes written with gzfoo errors.
    - at: gzdio: do gzflush only after RSYNC_WIN boundaries.
    - at: gzdio: push gzFile into a private container.
    - jbj: make gzdio.c standalone.
    - rpm.org: Teach Fflush about lzdio.
    - jbj: add _flush to FDIO_t, make bzdio.c standalone.

  Summary:
    Revision    Changes     Path
    1.2288.2.89 +12 -0      rpm/CHANGES
    1.162.2.7   +2  -2      rpm/rpmio/Makefile.am
    2.2.2.2     +208 -0     rpm/rpmio/bzdio.c
    2.12.2.2    +461 -0     rpm/rpmio/gzdio.c
    1.4.2.5     +88 -37     rpm/rpmio/lzdio.c
    1.127.2.3   +11 -430    rpm/rpmio/rpmio.c
    1.68.2.3    +8  -0      rpm/rpmio/rpmio.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.2288.2.88 -r1.2288.2.89 CHANGES
  --- rpm/CHANGES	18 Aug 2008 22:18:17 -0000	1.2288.2.88
  +++ rpm/CHANGES	18 Aug 2008 23:18:17 -0000	1.2288.2.89
  @@ -15,10 +15,22 @@
       - jbj: WR: Use %{_host_vendor} and %{_host_os} for platform.
       - jbj: WR: fakeroot maps devices to files. avoid /dev/* in checkfiles.
       - jbj: db_tool: remove gcc whinings.
  +    - at: gzdio: fixed and re-enabled rsyncable_gzwrite()
  +    - rse: fix building under --with-lzma by providing the necessary 64-bit defines for inclusion of <lzma.h>
  +    - jbj: gzdio: quadruple check with external -lz. still no fix => disabled.
  +    - jbj: gzdio: integrate the cpio tracking patch (needs to be done elsewhere)
  +    - jbj: gzdio: disable rsync flushing until a fix can be attempted.
  +    - jbj: gzdio: remove c99'ism.
       - jbj: QNX: use strtouq() instead of strtoul() in rpmmtree.
       - jbj: QNX: retrofit asprintf.h (from XAR) for the deprived. rpmmtree uses
           (rewrite to eliminate asprintf is an alternative).
       - jbj: QNX: supply missing typedef's for uint32_t.
  +    - at: gzdio: return partial "best effort" bytes written with gzfoo errors.
  +    - at: gzdio: do gzflush only after RSYNC_WIN boundaries.
  +    - at: gzdio: push gzFile into a private container.
  +    - jbj: make gzdio.c standalone.
  +    - rpm.org: Teach Fflush about lzdio.
  +    - jbj: add _flush to FDIO_t, make bzdio.c standalone.
       - jbj: move glob/fnmatch into -lrpmio from -lrpmmisc.
       - jbj: lua: don't exit chroot if already within running script.
       - jbj: rescusitate "make check".
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/Makefile.am
  ============================================================================
  $ cvs diff -u -r1.162.2.6 -r1.162.2.7 Makefile.am
  --- rpm/rpmio/Makefile.am	13 Aug 2008 17:05:26 -0000	1.162.2.6
  +++ rpm/rpmio/Makefile.am	18 Aug 2008 23:18:17 -0000	1.162.2.7
  @@ -67,8 +67,8 @@
   usrlibdir = $(libdir)
   usrlib_LTLIBRARIES = librpmio.la
   librpmio_la_SOURCES = \
  -	ar.c argv.c cpio.c digest.c fnmatch.c fts.c glob.c getdate.c getpass.c \
  -	iosm.c lzdio.c macro.c mire.c mount.c \
  +	ar.c argv.c bzdio.c cpio.c digest.c fnmatch.c fts.c getdate.c getpass.c \
  +	glob.c gzdio.c iosm.c lzdio.c macro.c mire.c mount.c \
   	md2.c md4.c poptIO.c rmd128.c rmd160.c rmd256.c rmd320.c sha224.c \
   	salsa10.c salsa20.c tiger.c \
   	rpmbc.c rpmdav.c rpmgc.c rpmhash.c rpmhook.c rpmio.c rpmio-stub.c \
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/bzdio.c
  ============================================================================
  $ cvs diff -u -r0 -r2.2.2.2 bzdio.c
  --- /dev/null	2008-08-19 01:15:30 +0200
  +++ bzdio.c	2008-08-19 01:18:18 +0200
  @@ -0,0 +1,208 @@
  +/** \ingroup rpmio
  + * \file rpmio/bzdio.c
  + * Support for BZIP2 compression library.
  + */
  +
  +#include "system.h"
  +#include "rpmio_internal.h"
  +#include <rpmmacro.h>
  +#include <rpmcb.h>
  +
  +#if defined(HAVE_BZLIB_H)
  +
  +#include <bzlib.h>
  +
  +#include "debug.h"
  +
  +/*@access FD_t @*/
  +
  +#define	BZDONLY(fd)	assert(fdGetIo(fd) == bzdio)
  +
  +/* =============================================================== */
  +
  +/*@-moduncon@*/
  +
  +static inline /*@dependent@*/ void * bzdFileno(FD_t fd)
  +	/*@*/
  +{
  +    void * rc = NULL;
  +    int i;
  +
  +    FDSANE(fd);
  +    for (i = fd->nfps; i >= 0; i--) {
  +	FDSTACK_t * fps = &fd->fps[i];
  +	if (fps->io != bzdio)
  +	    continue;
  +	rc = fps->fp;
  +	break;
  +    }
  +
  +    return rc;
  +}
  +
  +/*@-globuse@*/
  +static /*@null@*/ FD_t bzdOpen(const char * path, const char * fmode)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd;
  +    BZFILE *bzfile;
  +    mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
  +
  +    if ((bzfile = BZ2_bzopen(path, fmode)) == NULL)
  +	return NULL;
  +    fd = fdNew("open (bzdOpen)");
  +    fdPop(fd); fdPush(fd, bzdio, bzfile, -1);
  +    fdSetOpen(fd, path, -1, mode);
  +    return fdLink(fd, "bzdOpen");
  +}
  +/*@=globuse@*/
  +
  +/*@-globuse@*/
  +static /*@null@*/ FD_t bzdFdopen(void * cookie, const char * fmode)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    int fdno;
  +    BZFILE *bzfile;
  +
  +    if (fmode == NULL) return NULL;
  +    fdno = fdFileno(fd);
  +    fdSetFdno(fd, -1);		/* XXX skip the fdio close */
  +    if (fdno < 0) return NULL;
  +    bzfile = BZ2_bzdopen(fdno, fmode);
  +    if (bzfile == NULL) return NULL;
  +
  +    fdPush(fd, bzdio, bzfile, fdno);		/* Push bzdio onto stack */
  +
  +    return fdLink(fd, "bzdFdopen");
  +}
  +/*@=globuse@*/
  +
  +/*@-globuse@*/
  +static int bzdFlush(void * cookie)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    return BZ2_bzflush(bzdFileno(fd));
  +}
  +/*@=globuse@*/
  +
  +/* =============================================================== */
  +/*@-globuse@*/
  +/*@-mustmod@*/		/* LCL: *buf is modified */
  +static ssize_t bzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies *buf, fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    BZFILE *bzfile;
  +    ssize_t rc = 0;
  +
  +    if (fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  +    bzfile = bzdFileno(fd);
  +    fdstat_enter(fd, FDSTAT_READ);
  +    if (bzfile)
  +	/*@-compdef@*/
  +	rc = BZ2_bzread(bzfile, buf, (int)count);
  +	/*@=compdef@*/
  +    if (rc == -1) {
  +	int zerror = 0;
  +	if (bzfile)
  +	    fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  +    } else if (rc >= 0) {
  +	fdstat_exit(fd, FDSTAT_READ, rc);
  +	/*@-compdef@*/
  +	if (fd->ndigests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
  +	/*@=compdef@*/
  +    }
  +    return rc;
  +}
  +/*@=mustmod@*/
  +/*@=globuse@*/
  +
  +/*@-globuse@*/
  +static ssize_t bzdWrite(void * cookie, const char * buf, size_t count)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    BZFILE *bzfile;
  +    ssize_t rc;
  +
  +    if (fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  +
  +    if (fd->ndigests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
  +
  +    bzfile = bzdFileno(fd);
  +    fdstat_enter(fd, FDSTAT_WRITE);
  +    rc = BZ2_bzwrite(bzfile, (void *)buf, (int)count);
  +    if (rc == -1) {
  +	int zerror = 0;
  +	fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  +    } else if (rc > 0) {
  +	fdstat_exit(fd, FDSTAT_WRITE, rc);
  +    }
  +    return rc;
  +}
  +/*@=globuse@*/
  +
  +static inline int bzdSeek(void * cookie, /*@unused@*/ _libio_pos_t pos,
  +			/*@unused@*/ int whence)
  +	/*@*/
  +{
  +    FD_t fd = c2f(cookie);
  +
  +    BZDONLY(fd);
  +    return -2;
  +}
  +
  +static int bzdClose( /*@only@*/ void * cookie)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    BZFILE *bzfile;
  +    int rc;
  +
  +    bzfile = bzdFileno(fd);
  +
  +    if (bzfile == NULL) return -2;
  +    fdstat_enter(fd, FDSTAT_CLOSE);
  +    /*@-noeffectuncon@*/ /* FIX: check rc */
  +    BZ2_bzclose(bzfile);
  +    /*@=noeffectuncon@*/
  +    rc = 0;	/* XXX FIXME */
  +
  +    /* XXX TODO: preserve fd if errors */
  +
  +    if (fd) {
  +	if (rc == -1) {
  +	    int zerror = 0;
  +	    fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  +	} else if (rc >= 0) {
  +	    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  +	}
  +    }
  +
  +DBGIO(fd, (stderr, "==>\tbzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
  +
  +    if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "BZDIO", stderr);
  +    if (rc == 0)
  +	fd = fdFree(fd, "open (bzdClose)");
  +    return rc;
  +}
  +
  +/*@-type@*/ /* LCL: function typedefs */
  +static struct FDIO_s bzdio_s = {
  +  bzdRead, bzdWrite, bzdSeek, bzdClose,	bzdOpen, bzdFdopen, bzdFlush,
  +};
  +/*@=type@*/
  +
  +FDIO_t bzdio = /*@-compmempass@*/ &bzdio_s /*@=compmempass@*/ ;
  +
  +/*@=moduncon@*/
  +#endif
  +
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/gzdio.c
  ============================================================================
  $ cvs diff -u -r0 -r2.12.2.2 gzdio.c
  --- /dev/null	2008-08-19 01:15:30 +0200
  +++ gzdio.c	2008-08-19 01:18:18 +0200
  @@ -0,0 +1,461 @@
  +/** \ingroup rpmio
  + * \file rpmio/gzdio.c
  + * Support for ZLIB compression library.
  + */
  +
  +#include "system.h"
  +
  +#if	defined(NOTYET) || defined(__LCLINT__)
  +#include <stdbool.h>
  +#else
  +typedef	enum { true = 1, false = 0 } bool;
  +#endif
  +
  +#include "rpmio_internal.h"
  +#include <rpmmacro.h>
  +#include <rpmcb.h>
  +
  +#ifdef	HAVE_ZLIB_H
  +
  +/*@-noparams@*/
  +#include <zlib.h>
  +/*@=noparams@*/
  +
  +#include "debug.h"
  +
  +/*@access FD_t @*/
  +
  +#define	GZDONLY(fd)	assert(fdGetIo(fd) == gzdio)
  +
  +typedef struct cpio_state_s {
  +    uint32_t n;			/* byte progress in cpio header */
  +    uint32_t mode;			/* file attributes */
  +    uint32_t nlnk;
  +    uint32_t size;
  +} * cpio_state;
  +
  +#define RSYNC_WIN 4096
  +
  +typedef struct rsync_state_s {
  +    uint32_t n;			/* number of elements in the window */
  +    uint32_t sum;			/* current sum */
  +    unsigned char win[RSYNC_WIN];	/* window elements */
  +} * rsync_state;
  +
  +typedef struct rpmGZFILE_s {
  +    gzFile gz;				/* gzFile is a pointer */
  +    struct rsync_state_s rs;
  +    struct cpio_state_s cs;
  +    uint32_t nb;			/* bytes pending for sync */
  +} * rpmGZFILE;				/* like FILE, to use with star */
  +
  +/* Should gzflush be called only after RSYNC_WIN boundaries? */
  +/*@unchecked@*/
  +static int enable_rsync = 1;
  +
  +/* =============================================================== */
  +/* from ../lib/cpio.h */
  +#define CPIO_NEWC_MAGIC "070701"
  +#define PHYS_HDR_SIZE 110
  +
  +#define OFFSET_MODE (sizeof(CPIO_NEWC_MAGIC)-1 + 1*8)
  +#define OFFSET_NLNK (sizeof(CPIO_NEWC_MAGIC)-1 + 4*8)
  +#define OFFSET_SIZE (sizeof(CPIO_NEWC_MAGIC)-1 + 6*8)
  +
  +static inline
  +int hex(char c)
  +{
  +    if (c >= '0' && c <= '9')
  +	return (int)(c - '0');
  +    else if (c >= 'a' && c <= 'f')
  +	return (int)(c - 'a') + 10;
  +    else if (c >= 'A' && c <= 'F')
  +	return (int)(c - 'A') + 10;
  +    return -1;
  +}
  +
  +static inline
  +bool cpio_next(cpio_state s, unsigned char c)
  +	/*@modifies s @*/
  +{
  +    if (s->n >= sizeof(CPIO_NEWC_MAGIC)-1) {
  +	int d = hex(c);
  +	if (d < 0) {
  +	    s->n = 0;
  +	    return false;
  +	}
  +	if (0){} /* indent */
  +	else if (s->n >= OFFSET_MODE && s->n < OFFSET_MODE+8) {
  +	    if (s->n == OFFSET_MODE)
  +		s->mode = 0;
  +	    else
  +		s->mode <<= 4;
  +	    s->mode |= d;
  +	}
  +	else if (s->n >= OFFSET_NLNK && s->n < OFFSET_NLNK+8) {
  +	    if (s->n == OFFSET_NLNK)
  +		s->nlnk = 0;
  +	    else
  +		s->nlnk <<= 4;
  +	    s->nlnk |= d;
  +	}
  +	else if (s->n >= OFFSET_SIZE && s->n < OFFSET_SIZE+8) {
  +	    if (s->n == OFFSET_SIZE)
  +		s->size = 0;
  +	    else
  +		s->size <<= 4;
  +	    s->size |= d;
  +	}
  +	s->n++;
  +	if (s->n >= PHYS_HDR_SIZE) {
  +	    s->n = 0;
  +	    if (!S_ISREG(s->mode) || s->nlnk != 1)
  +		/* no file data */
  +		s->size = 0;
  +	    return true;
  +	}
  +    }
  +    else if (CPIO_NEWC_MAGIC[s->n] == c) {
  +	s->n++;
  +    }
  +    else {
  +	s->n = 0;
  +    }
  +    return false;
  +}
  +
  +/* =============================================================== */
  +static inline
  +bool rsync_next(rsync_state s, unsigned char c)
  +	/*@modifies s @*/
  +{
  +    uint32_t i;
  +
  +    if (s->n < RSYNC_WIN) {		/* not enough elements */
  +	s->sum += (uint32_t)c;	/* update the sum */
  +	s->win[s->n++] = c;		/* remember the element */
  +	return false;			/* no match */
  +    }
  +    i = s->n++ % RSYNC_WIN;		/* wrap up */
  +    s->sum -= (uint32_t)s->win[i];	/* move the window on */
  +    s->sum += (uint32_t)c;
  +    s->win[i] = c;
  +    if (s->sum % RSYNC_WIN == 0) {	/* match */
  +	s->n = 0;			/* reset */
  +	s->sum = 0;
  +	return true;
  +    }
  +    return false;
  +}
  +
  +#define CHUNK 4096
  +
  +static inline
  +bool sync_hint(rpmGZFILE rpmgz, unsigned char c)
  +	/*@modifies rpmgz @*/
  +{
  +    bool cpio_hint;
  +    bool rsync_hint;
  +
  +    rpmgz->nb++;
  +    cpio_hint = cpio_next(&rpmgz->cs, c);
  +    if (cpio_hint) {
  +	/* cpio header/data boundary */
  +	rpmgz->rs.n = rpmgz->rs.sum = 0;
  +	if (rpmgz->nb >= 2*CHUNK)
  +	    /* better sync here */
  +	    goto cpio_sync;
  +	if (rpmgz->cs.size < CHUNK)
  +	    /* file is too small */
  +	    return false;
  +	if (rpmgz->nb < CHUNK/2)
  +	    /* not enough pending bytes */
  +	    return false;
  +    cpio_sync:
  +	rpmgz->nb = 0;
  +	return true;
  +    }
  +    rsync_hint = rsync_next(&rpmgz->rs, c);
  +    if (rsync_hint) {
  +	/* rolling checksum match */
  +	assert(rpmgz->nb >= RSYNC_WIN);
  +	rpmgz->nb = 0;
  +	return true;
  +    }
  +    return false;
  +}
  +
  +static ssize_t
  +rsyncable_gzwrite(rpmGZFILE rpmgz, const unsigned char *const buf, const size_t len)
  +	/*@globals fileSystem @*/
  +	/*@modifies rpmgz, fileSystem @*/
  +{
  +    ssize_t rc;
  +    size_t n;
  +    ssize_t n_written = 0;
  +    const unsigned char *begin = buf;
  +    size_t i;
  +
  +    for (i = 0; i < len; i++) {
  +	if (!sync_hint(rpmgz, buf[i]))
  +	    continue;
  +	n = i + 1 - (begin - buf);
  +	rc = gzwrite(rpmgz->gz, begin, (unsigned)n);
  +	if (rc < 0)
  +	    return (n_written ? n_written : rc);
  +	n_written += rc;
  +	if (rc < (ssize_t)n)
  +	    return n_written;
  +	begin += n;
  +	rc = gzflush(rpmgz->gz, Z_SYNC_FLUSH);
  +	if (rc < 0)
  +	    return (n_written ? n_written : rc);
  +    }
  +    if (begin < buf + len) {
  +	n = len - (begin - buf);
  +	rc = gzwrite(rpmgz->gz, begin, (unsigned)n);
  +	if (rc < 0)
  +	    return (n_written ? n_written : rc);
  +	n_written += rc;
  +    }
  +    return n_written;
  +}
  +
  +/* =============================================================== */
  +/*@-moduncon@*/
  +
  +static inline /*@dependent@*/ /*@null@*/ void * gzdFileno(FD_t fd)
  +	/*@*/
  +{
  +    void * rc = NULL;
  +    int i;
  +
  +    FDSANE(fd);
  +    for (i = fd->nfps; i >= 0; i--) {
  +	FDSTACK_t * fps = &fd->fps[i];
  +	if (fps->io != gzdio)
  +	    continue;
  +	rc = fps->fp;
  +	break;
  +    }
  +
  +    return rc;
  +}
  +
  +static /*@null@*/
  +FD_t gzdOpen(const char * path, const char * fmode)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd;
  +    rpmGZFILE rpmgz;
  +    mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
  +
  +    rpmgz = xcalloc(1, sizeof(*rpmgz));
  +    rpmgz->gz = gzopen(path, fmode);
  +    if (rpmgz->gz == NULL) {
  +	rpmgz = _free(rpmgz);
  +	return NULL;
  +    }
  +    fd = fdNew("open (gzdOpen)");
  +    fdPop(fd); fdPush(fd, gzdio, rpmgz, -1);
  +    fdSetOpen(fd, path, -1, mode);
  +
  +DBGIO(fd, (stderr, "==>\tgzdOpen(\"%s\", \"%s\") fd %p %s\n", path, fmode, (fd ? fd : NULL), fdbg(fd)));
  +    return fdLink(fd, "gzdOpen");
  +}
  +
  +static /*@null@*/ FD_t gzdFdopen(void * cookie, const char *fmode)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    int fdno;
  +    rpmGZFILE rpmgz;
  +
  +    if (fmode == NULL) return NULL;
  +    fdno = fdFileno(fd);
  +    fdSetFdno(fd, -1);		/* XXX skip the fdio close */
  +    if (fdno < 0) return NULL;
  +    rpmgz = xcalloc(1, sizeof(*rpmgz));
  +    rpmgz->gz = gzdopen(fdno, fmode);
  +    if (rpmgz->gz == NULL) {
  +	rpmgz = _free(rpmgz);
  +	return NULL;
  +    }
  +
  +    fdPush(fd, gzdio, rpmgz, fdno);		/* Push gzdio onto stack */
  +
  +    return fdLink(fd, "gzdFdopen");
  +}
  +
  +static int gzdFlush(void * cookie)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    rpmGZFILE rpmgz;
  +    rpmgz = gzdFileno(fd);
  +    if (rpmgz == NULL) return -2;
  +    return gzflush(rpmgz->gz, Z_SYNC_FLUSH);	/* XXX W2DO? */
  +}
  +
  +/* =============================================================== */
  +static ssize_t gzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies buf, fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    rpmGZFILE rpmgz;
  +    ssize_t rc;
  +
  +    if (fd == NULL || fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  +
  +    rpmgz = gzdFileno(fd);
  +    if (rpmgz == NULL) return -2;	/* XXX can't happen */
  +
  +    fdstat_enter(fd, FDSTAT_READ);
  +    rc = gzread(rpmgz->gz, buf, (unsigned)count);
  +DBGIO(fd, (stderr, "==>\tgzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
  +    if (rc < 0) {
  +	int zerror = 0;
  +	fd->errcookie = gzerror(rpmgz->gz, &zerror);
  +	if (zerror == Z_ERRNO) {
  +	    fd->syserrno = errno;
  +	    fd->errcookie = strerror(fd->syserrno);
  +	}
  +    } else {
  +	fdstat_exit(fd, FDSTAT_READ, (rc > 0 ? rc : 0));
  +	if (fd->ndigests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
  +    }
  +    return rc;
  +}
  +
  +static ssize_t gzdWrite(void * cookie, const char * buf, size_t count)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    rpmGZFILE rpmgz;
  +    ssize_t rc;
  +
  +    if (fd == NULL || fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  +
  +    if (fd->ndigests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
  +
  +    rpmgz = gzdFileno(fd);
  +    if (rpmgz == NULL) return -2;	/* XXX can't happen */
  +
  +    fdstat_enter(fd, FDSTAT_WRITE);
  +    if (enable_rsync)
  +	rc = rsyncable_gzwrite(rpmgz, (void *)buf, (unsigned)count);
  +    else
  +	rc = gzwrite(rpmgz->gz, (void *)buf, (unsigned)count);
  +DBGIO(fd, (stderr, "==>\tgzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
  +    if (rc < (ssize_t)count) {
  +	int zerror = 0;
  +	fd->errcookie = gzerror(rpmgz->gz, &zerror);
  +	if (zerror == Z_ERRNO) {
  +	    fd->syserrno = errno;
  +	    fd->errcookie = strerror(fd->syserrno);
  +	}
  +    }
  +    if (rc > 0)
  +	fdstat_exit(fd, FDSTAT_WRITE, rc);
  +    return rc;
  +}
  +
  +/* XXX zlib-1.0.4 has not */
  +#define	HAVE_GZSEEK	/* XXX autoFu doesn't set this anymore. */
  +static inline int gzdSeek(void * cookie, _libio_pos_t pos, int whence)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    int rc;
  +#if defined(HAVE_GZSEEK)
  +#ifdef USE_COOKIE_SEEK_POINTER
  +    _IO_off64_t p = *pos;
  +#else
  +    off_t p = pos;
  +#endif
  +    FD_t fd = c2f(cookie);
  +    rpmGZFILE rpmgz;
  +
  +    if (fd == NULL) return -2;
  +    assert(fd->bytesRemain == -1);	/* XXX FIXME */
  +
  +    rpmgz = gzdFileno(fd);
  +    if (rpmgz == NULL) return -2;	/* XXX can't happen */
  +
  +    fdstat_enter(fd, FDSTAT_SEEK);
  +    rc = gzseek(rpmgz->gz, (long)p, whence);
  +DBGIO(fd, (stderr, "==>\tgzdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, whence, (unsigned long)rc, fdbg(fd)));
  +    if (rc < 0) {
  +	int zerror = 0;
  +	fd->errcookie = gzerror(rpmgz->gz, &zerror);
  +	if (zerror == Z_ERRNO) {
  +	    fd->syserrno = errno;
  +	    fd->errcookie = strerror(fd->syserrno);
  +	}
  +    }
  +    if (rc > 0)
  +	fdstat_exit(fd, FDSTAT_SEEK, rc);
  +#else
  +    rc = -2;
  +#endif
  +    return rc;
  +}
  +
  +static int gzdClose( /*@only@*/ void * cookie)
  +	/*@globals fileSystem, internalState @*/
  +	/*@modifies fileSystem, internalState @*/
  +{
  +    FD_t fd = c2f(cookie);
  +    rpmGZFILE rpmgz;
  +    int rc;
  +
  +    rpmgz = gzdFileno(fd);
  +    if (rpmgz == NULL) return -2;	/* XXX can't happen */
  +
  +    fdstat_enter(fd, FDSTAT_CLOSE);
  +    /*@-dependenttrans@*/
  +    rc = gzclose(rpmgz->gz);
  +    /*@=dependenttrans@*/
  +    rpmgz->gz = NULL;
  +/*@-dependenttrans@*/
  +    rpmgz = _free(rpmgz);
  +/*@=dependenttrans@*/
  +
  +    /* XXX TODO: preserve fd if errors */
  +
  +    if (fd) {
  +DBGIO(fd, (stderr, "==>\tgzdClose(%p) zerror %d %s\n", cookie, rc, fdbg(fd)));
  +	if (rc < 0) {
  +	    fd->errcookie = "gzclose error";
  +	    if (rc == Z_ERRNO) {
  +		fd->syserrno = errno;
  +		fd->errcookie = strerror(fd->syserrno);
  +	    }
  +	} else if (rc >= 0) {
  +	    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  +	}
  +    }
  +
  +DBGIO(fd, (stderr, "==>\tgzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
  +
  +    if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "GZDIO", stderr);
  +    if (rc == 0)
  +	fd = fdFree(fd, "open (gzdClose)");
  +    return rc;
  +}
  +
  +/*@-type@*/ /* LCL: function typedefs */
  +static struct FDIO_s gzdio_s = {
  +  gzdRead, gzdWrite, gzdSeek, gzdClose,	gzdOpen, gzdFdopen, gzdFlush,
  +};
  +/*@=type@*/
  +
  +FDIO_t gzdio = /*@-compmempass@*/ &gzdio_s /*@=compmempass@*/ ;
  +
  +/*@=moduncon@*/
  +#endif	/* HAVE_ZLIB_H */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/lzdio.c
  ============================================================================
  $ cvs diff -u -r1.4.2.4 -r1.4.2.5 lzdio.c
  --- rpm/rpmio/lzdio.c	14 Jun 2008 15:41:37 -0000	1.4.2.4
  +++ rpm/rpmio/lzdio.c	18 Aug 2008 23:18:17 -0000	1.4.2.5
  @@ -1,4 +1,6 @@
  -/* Support for LZMA library.
  +/** \ingroup rpmio
  + * \file rpmio/lzdio.c
  + * Support for LZMA compression library.
    */
   
   #include "system.h"
  @@ -8,28 +10,53 @@
   
   #if defined(HAVE_LZMA_H)
   
  +/* provide necessary defines for inclusion of <lzma.h>
  +   similar to LZMAUtils's internal <common.h> and as
  +   explicitly stated in the top-level comment of <lzma.h> */
  +#ifndef UINT32_C
  +#	define UINT32_C(n) n ## U
  +#endif
  +#ifndef UINT32_MAX
  +#	define UINT32_MAX UINT32_C(4294967295)
  +#endif
  +#if SIZEOF_UNSIGNED_LONG == 4
  +#	ifndef UINT64_C
  +#		define UINT64_C(n) n ## ULL
  +#	endif
  +#else
  +#	ifndef UINT64_C
  +#		define UINT64_C(n) n ## UL
  +#	endif
  +#endif
  +#ifndef UINT64_MAX
  +#	define UINT64_MAX UINT64_C(18446744073709551615)
  +#endif
  +
   #include "lzma.h"
   
   #include "debug.h"
   
  +/*@access FD_t @*/
  +
   #define	LZDONLY(fd)	assert(fdGetIo(fd) == lzdio)
   
   #define kBufferSize (1 << 15)
   
   typedef struct lzfile {
  -  /* IO buffer */
  -    uint8_t buf[kBufferSize];
  -
  -    lzma_stream strm;
  -
  -    FILE *fp;
  -
  +/*@only@*/
  +    uint8_t buf[kBufferSize];	/*!< IO buffer */
  +    lzma_stream strm;		/*!< LZMA stream */
  +/*@dependent@*/
  +    FILE * fp;
       int encoding;
       int eof;
  -
   } LZFILE;
   
  +/*@-globstate@*/
  +/*@null@*/
   static LZFILE *lzopen_internal(const char *path, const char *mode, int fd)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
   {
       int level = 5;
       int encoding = 0;
  @@ -37,24 +64,24 @@
       LZFILE *lzfile;
       lzma_ret ret;
   
  -    for (; *mode; mode++) {
  +    for (; *mode != '\0'; mode++) {
   	if (*mode == 'w')
   	    encoding = 1;
   	else if (*mode == 'r')
   	    encoding = 0;
   	else if (*mode >= '1' && *mode <= '9')
  -	    level = *mode - '0';
  +	    level = (int)(*mode - '0');
       }
       if (fd != -1)
   	fp = fdopen(fd, encoding ? "w" : "r");
       else
   	fp = fopen(path, encoding ? "w" : "r");
       if (!fp)
  -	return 0;
  +	return NULL;
       lzfile = calloc(1, sizeof(*lzfile));
       if (!lzfile) {
  -	fclose(fp);
  -	return 0;
  +	(void) fclose(fp);
  +	return NULL;
       }
       lzfile->fp = fp;
       lzfile->encoding = encoding;
  @@ -62,50 +89,63 @@
       lzfile->strm = LZMA_STREAM_INIT_VAR;
       if (encoding) {
   	lzma_options_alone alone;
  +/*@-unrecog@*/
   	alone.uncompressed_size = LZMA_VLI_VALUE_UNKNOWN;
  +/*@=unrecog@*/
   	memcpy(&alone.lzma, &lzma_preset_lzma[level - 1], sizeof(alone.lzma));
   	ret = lzma_alone_encoder(&lzfile->strm, &alone);
       } else {
   	ret = lzma_auto_decoder(&lzfile->strm, 0, 0);
       }
       if (ret != LZMA_OK) {
  -	fclose(fp);
  +	(void) fclose(fp);
  +	memset(lzfile, 0, sizeof(*lzfile));
   	free(lzfile);
  -	return 0;
  +	return NULL;
       }
       return lzfile;
   }
  +/*@=globstate@*/
   
  +/*@null@*/
   static LZFILE *lzopen(const char *path, const char *mode)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
   {
       return lzopen_internal(path, mode, -1);
   }
   
  +/*@null@*/
   static LZFILE *lzdopen(int fd, const char *mode)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
   {
       if (fd < 0)
  -	return 0;
  +	return NULL;
       return lzopen_internal(0, mode, fd);
   }
   
  -#ifdef	UNUSED
   static int lzflush(LZFILE *lzfile)
  +	/*@globals fileSystem @*/
  +	/*@modifies lzfile, fileSystem @*/
   {
       return fflush(lzfile->fp);
   }
  -#endif
   
  -static int lzclose(LZFILE *lzfile)
  +static int lzclose(/*@only@*/ LZFILE *lzfile)
  +	/*@globals fileSystem @*/
  +	/*@modifies *lzfile, fileSystem @*/
   {
       lzma_ret ret;
       size_t n;
  +    int rc;
   
       if (!lzfile)
   	return -1;
       if (lzfile->encoding) {
   	for (;;) {
   	    lzfile->strm.avail_out = kBufferSize;
  -	    lzfile->strm.next_out = lzfile->buf;
  +	    lzfile->strm.next_out = (uint8_t *)lzfile->buf;
   	    ret = lzma_code(&lzfile->strm, LZMA_FINISH);
   	    if (ret != LZMA_OK && ret != LZMA_STREAM_END)
   		return -1;
  @@ -117,11 +157,16 @@
   	}
       }
       lzma_end(&lzfile->strm);
  -    return fclose(lzfile->fp);
  +    rc = fclose(lzfile->fp);
  +    memset(lzfile, 0, sizeof(*lzfile));
       free(lzfile);
  +    return rc;
   }
   
  +/*@-mustmod@*/
   static ssize_t lzread(LZFILE *lzfile, void *buf, size_t len)
  +	/*@globals fileSystem @*/
  +	/*@modifies lzfile, *buf, fileSystem @*/
   {
       lzma_ret ret;
       int eof = 0;
  @@ -130,11 +175,13 @@
         return -1;
       if (lzfile->eof)
         return 0;
  +/*@-temptrans@*/
       lzfile->strm.next_out = buf;
  +/*@=temptrans@*/
       lzfile->strm.avail_out = len;
       for (;;) {
   	if (!lzfile->strm.avail_in) {
  -	    lzfile->strm.next_in = lzfile->buf;
  +	    lzfile->strm.next_in = (uint8_t *)lzfile->buf;
   	    lzfile->strm.avail_in = fread(lzfile->buf, 1, kBufferSize, lzfile->fp);
   	    if (!lzfile->strm.avail_in)
   		eof = 1;
  @@ -151,9 +198,13 @@
   	if (eof)
   	    return -1;
         }
  +    /*@notreached@*/
   }
  +/*@=mustmod@*/
   
   static ssize_t lzwrite(LZFILE *lzfile, void *buf, size_t len)
  +	/*@globals fileSystem @*/
  +	/*@modifies lzfile, fileSystem @*/
   {
       lzma_ret ret;
       size_t n;
  @@ -162,10 +213,12 @@
   	return -1;
       if (!len)
   	return 0;
  +/*@-temptrans@*/
       lzfile->strm.next_in = buf;
  +/*@=temptrans@*/
       lzfile->strm.avail_in = len;
       for (;;) {
  -	lzfile->strm.next_out = lzfile->buf;
  +	lzfile->strm.next_out = (uint8_t *)lzfile->buf;
   	lzfile->strm.avail_out = kBufferSize;
   	ret = lzma_code(&lzfile->strm, LZMA_RUN);
   	if (ret != LZMA_OK)
  @@ -176,6 +229,7 @@
   	if (!lzfile->strm.avail_in)
   	    return len;
       }
  +    /*@notreached@*/
   }
   
   /* =============================================================== */
  @@ -237,16 +291,15 @@
   }
   /*@=globuse@*/
   
  -#ifdef	UNUSED
   /*@-globuse@*/
  -static int lzdFlush(FD_t fd)
  +static int lzdFlush(void * cookie)
   	/*@globals fileSystem @*/
   	/*@modifies fileSystem @*/
   {
  +    FD_t fd = c2f(cookie);
       return lzflush(lzdFileno(fd));
   }
   /*@=globuse@*/
  -#endif
   
   /* =============================================================== */
   /*@-globuse@*/
  @@ -259,6 +312,7 @@
       LZFILE *lzfile;
       ssize_t rc = -1;
   
  +assert(fd != NULL);
       if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */
       lzfile = lzdFileno(fd);
   assert(lzfile != NULL);
  @@ -322,25 +376,22 @@
   {
       FD_t fd = c2f(cookie);
       LZFILE *lzfile;
  +    const char * errcookie;
       int rc;
   
       lzfile = lzdFileno(fd);
   
       if (lzfile == NULL) return -2;
  +    errcookie = strerror(ferror(lzfile->fp));
  +
       fdstat_enter(fd, FDSTAT_CLOSE);
       /*@-dependenttrans@*/
       rc = lzclose(lzfile);
       /*@=dependenttrans@*/
  +    fdstat_exit(fd, FDSTAT_CLOSE, rc);
   
  -    /* XXX TODO: preserve fd if errors */
  -
  -    if (fd) {
  -	if (rc == -1) {
  -	    fd->errcookie = strerror(ferror(lzfile->fp));
  -	} else if (rc >= 0) {
  -	    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  -	}
  -    }
  +    if (fd && rc == -1)
  +	fd->errcookie = errcookie;
   
   DBGIO(fd, (stderr, "==>\tlzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
   
  @@ -354,7 +405,7 @@
   
   /*@-type@*/ /* LCL: function typedefs */
   static struct FDIO_s lzdio_s = {
  -  lzdRead, lzdWrite, lzdSeek, lzdClose, lzdOpen, lzdFdopen,
  +  lzdRead, lzdWrite, lzdSeek, lzdClose, lzdOpen, lzdFdopen, lzdFlush,
   };
   /*@=type@*/
   
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.c
  ============================================================================
  $ cvs diff -u -r1.127.2.2 -r1.127.2.3 rpmio.c
  --- rpm/rpmio/rpmio.c	14 Jun 2008 15:41:37 -0000	1.127.2.2
  +++ rpm/rpmio/rpmio.c	18 Aug 2008 23:18:17 -0000	1.127.2.3
  @@ -123,8 +123,6 @@
   #define FDCPIOPOS(fd)	(fd ? ((FD_t)fd)->fd_cpioPos : -99)
   
   #define	FDONLY(fd)	assert(fdGetIo(fd) == fdio)
  -#define	GZDONLY(fd)	assert(fdGetIo(fd) == gzdio)
  -#define	BZDONLY(fd)	assert(fdGetIo(fd) == bzdio)
   
   #define	UFDONLY(fd)	/* assert(fdGetIo(fd) == ufdio) */
   
  @@ -553,7 +551,7 @@
   
   /*@-type@*/ /* LCL: function typedefs */
   static struct FDIO_s fdio_s = {
  -  fdRead, fdWrite, fdSeek, fdClose, NULL, NULL,
  +  fdRead, fdWrite, fdSeek, fdClose, NULL, NULL, NULL,
   };
   /*@=type@*/
   
  @@ -2301,434 +2299,13 @@
   
   /*@-type@*/ /* LCL: function typedefs */
   static struct FDIO_s ufdio_s = {
  -  ufdRead, ufdWrite, ufdSeek, ufdClose,	NULL, NULL,
  +  ufdRead, ufdWrite, ufdSeek, ufdClose,	NULL, NULL, NULL,
   };
   /*@=type@*/
   
   FDIO_t ufdio = /*@-compmempass@*/ &ufdio_s /*@=compmempass@*/ ;
   
   /* =============================================================== */
  -/* Support for GZIP library.
  - */
  -#ifdef	HAVE_ZLIB_H
  -/*@-moduncon@*/
  -
  -/*@-noparams@*/
  -#include <zlib.h>
  -/*@=noparams@*/
  -
  -static inline /*@dependent@*/ /*@null@*/ void * gzdFileno(FD_t fd)
  -	/*@*/
  -{
  -    void * rc = NULL;
  -    int i;
  -
  -    FDSANE(fd);
  -    for (i = fd->nfps; i >= 0; i--) {
  -	FDSTACK_t * fps = &fd->fps[i];
  -	if (fps->io != gzdio)
  -	    continue;
  -	rc = fps->fp;
  -	break;
  -    }
  -
  -    return rc;
  -}
  -
  -static /*@null@*/
  -FD_t gzdOpen(const char * path, const char * fmode)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd;
  -    gzFile gzfile;
  -    mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
  -
  -    if ((gzfile = gzopen(path, fmode)) == NULL)
  -	return NULL;
  -    fd = fdNew("open (gzdOpen)");
  -    fdPop(fd); fdPush(fd, gzdio, gzfile, -1);
  -    fdSetOpen(fd, path, -1, mode);
  -
  -DBGIO(fd, (stderr, "==>\tgzdOpen(\"%s\", \"%s\") fd %p %s\n", path, fmode, (fd ? fd : NULL), fdbg(fd)));
  -    return fdLink(fd, "gzdOpen");
  -}
  -
  -static /*@null@*/ FD_t gzdFdopen(void * cookie, const char *fmode)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    int fdno;
  -    gzFile gzfile;
  -
  -    if (fmode == NULL) return NULL;
  -    fdno = fdFileno(fd);
  -    fdSetFdno(fd, -1);		/* XXX skip the fdio close */
  -    if (fdno < 0) return NULL;
  -    gzfile = gzdopen(fdno, fmode);
  -    if (gzfile == NULL) return NULL;
  -
  -    fdPush(fd, gzdio, gzfile, fdno);		/* Push gzdio onto stack */
  -
  -    return fdLink(fd, "gzdFdopen");
  -}
  -
  -static int gzdFlush(FD_t fd)
  -	/*@globals fileSystem @*/
  -	/*@modifies fileSystem @*/
  -{
  -    gzFile gzfile;
  -    gzfile = gzdFileno(fd);
  -    if (gzfile == NULL) return -2;
  -    return gzflush(gzfile, Z_SYNC_FLUSH);	/* XXX W2DO? */
  -}
  -
  -/* =============================================================== */
  -static ssize_t gzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies buf, fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    gzFile gzfile;
  -    ssize_t rc;
  -
  -    if (fd == NULL || fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  -
  -    gzfile = gzdFileno(fd);
  -    if (gzfile == NULL) return -2;	/* XXX can't happen */
  -
  -    fdstat_enter(fd, FDSTAT_READ);
  -    rc = gzread(gzfile, buf, (unsigned)count);
  -DBGIO(fd, (stderr, "==>\tgzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
  -    if (rc < 0) {
  -	int zerror = 0;
  -	fd->errcookie = gzerror(gzfile, &zerror);
  -	if (zerror == Z_ERRNO) {
  -	    fd->syserrno = errno;
  -	    fd->errcookie = strerror(fd->syserrno);
  -	}
  -    } else if (rc >= 0) {
  -	fdstat_exit(fd, FDSTAT_READ, rc);
  -	if (fd->ndigests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
  -    }
  -    return rc;
  -}
  -
  -static ssize_t gzdWrite(void * cookie, const char * buf, size_t count)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    gzFile gzfile;
  -    ssize_t rc;
  -
  -    if (fd == NULL || fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  -
  -    if (fd->ndigests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
  -
  -    gzfile = gzdFileno(fd);
  -    if (gzfile == NULL) return -2;	/* XXX can't happen */
  -
  -    fdstat_enter(fd, FDSTAT_WRITE);
  -    rc = gzwrite(gzfile, (void *)buf, (unsigned)count);
  -DBGIO(fd, (stderr, "==>\tgzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd)));
  -    if (rc < 0) {
  -	int zerror = 0;
  -	fd->errcookie = gzerror(gzfile, &zerror);
  -	if (zerror == Z_ERRNO) {
  -	    fd->syserrno = errno;
  -	    fd->errcookie = strerror(fd->syserrno);
  -	}
  -    } else if (rc > 0) {
  -	fdstat_exit(fd, FDSTAT_WRITE, rc);
  -    }
  -    return rc;
  -}
  -
  -/* XXX zlib-1.0.4 has not */
  -#define	HAVE_GZSEEK	/* XXX autoFu doesn't set this anymore. */
  -static inline int gzdSeek(void * cookie, _libio_pos_t pos, int whence)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    int rc;
  -#if defined(HAVE_GZSEEK)
  -#ifdef USE_COOKIE_SEEK_POINTER
  -    _IO_off64_t p = *pos;
  -#else
  -    off_t p = pos;
  -#endif
  -    FD_t fd = c2f(cookie);
  -    gzFile gzfile;
  -
  -    if (fd == NULL) return -2;
  -    assert(fd->bytesRemain == -1);	/* XXX FIXME */
  -
  -    gzfile = gzdFileno(fd);
  -    if (gzfile == NULL) return -2;	/* XXX can't happen */
  -
  -    fdstat_enter(fd, FDSTAT_SEEK);
  -    rc = gzseek(gzfile, (long)p, whence);
  -DBGIO(fd, (stderr, "==>\tgzdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, whence, (unsigned long)rc, fdbg(fd)));
  -    if (rc < 0) {
  -	int zerror = 0;
  -	fd->errcookie = gzerror(gzfile, &zerror);
  -	if (zerror == Z_ERRNO) {
  -	    fd->syserrno = errno;
  -	    fd->errcookie = strerror(fd->syserrno);
  -	}
  -    } else if (rc >= 0) {
  -	fdstat_exit(fd, FDSTAT_SEEK, rc);
  -    }
  -#else
  -    rc = -2;
  -#endif
  -    return rc;
  -}
  -
  -static int gzdClose( /*@only@*/ void * cookie)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    gzFile gzfile;
  -    int rc;
  -
  -    gzfile = gzdFileno(fd);
  -    if (gzfile == NULL) return -2;	/* XXX can't happen */
  -
  -    fdstat_enter(fd, FDSTAT_CLOSE);
  -    /*@-dependenttrans@*/
  -    rc = gzclose(gzfile);
  -    /*@=dependenttrans@*/
  -
  -    /* XXX TODO: preserve fd if errors */
  -
  -    if (fd) {
  -DBGIO(fd, (stderr, "==>\tgzdClose(%p) zerror %d %s\n", cookie, rc, fdbg(fd)));
  -	if (rc < 0) {
  -	    fd->errcookie = "gzclose error";
  -	    if (rc == Z_ERRNO) {
  -		fd->syserrno = errno;
  -		fd->errcookie = strerror(fd->syserrno);
  -	    }
  -	} else if (rc >= 0) {
  -	    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  -	}
  -    }
  -
  -DBGIO(fd, (stderr, "==>\tgzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
  -
  -    if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "GZDIO", stderr);
  -    if (rc == 0)
  -	fd = fdFree(fd, "open (gzdClose)");
  -    return rc;
  -}
  -
  -/*@-type@*/ /* LCL: function typedefs */
  -static struct FDIO_s gzdio_s = {
  -  gzdRead, gzdWrite, gzdSeek, gzdClose,	gzdOpen, gzdFdopen,
  -};
  -/*@=type@*/
  -
  -FDIO_t gzdio = /*@-compmempass@*/ &gzdio_s /*@=compmempass@*/ ;
  -
  -/*@=moduncon@*/
  -#endif	/* HAVE_ZLIB_H */
  -
  -/* =============================================================== */
  -/* Support for BZIP2 library.
  - */
  -#if defined(HAVE_BZLIB_H)
  -/*@-moduncon@*/
  -
  -#include <bzlib.h>
  -
  -static inline /*@dependent@*/ void * bzdFileno(FD_t fd)
  -	/*@*/
  -{
  -    void * rc = NULL;
  -    int i;
  -
  -    FDSANE(fd);
  -    for (i = fd->nfps; i >= 0; i--) {
  -	FDSTACK_t * fps = &fd->fps[i];
  -	if (fps->io != bzdio)
  -	    continue;
  -	rc = fps->fp;
  -	break;
  -    }
  -
  -    return rc;
  -}
  -
  -/*@-globuse@*/
  -static /*@null@*/ FD_t bzdOpen(const char * path, const char * fmode)
  -	/*@globals fileSystem @*/
  -	/*@modifies fileSystem @*/
  -{
  -    FD_t fd;
  -    BZFILE *bzfile;;
  -    mode_t mode = (fmode && fmode[0] == 'w' ? O_WRONLY : O_RDONLY);
  -
  -    if ((bzfile = BZ2_bzopen(path, fmode)) == NULL)
  -	return NULL;
  -    fd = fdNew("open (bzdOpen)");
  -    fdPop(fd); fdPush(fd, bzdio, bzfile, -1);
  -    fdSetOpen(fd, path, -1, mode);
  -    return fdLink(fd, "bzdOpen");
  -}
  -/*@=globuse@*/
  -
  -/*@-globuse@*/
  -static /*@null@*/ FD_t bzdFdopen(void * cookie, const char * fmode)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    int fdno;
  -    BZFILE *bzfile;
  -
  -    if (fmode == NULL) return NULL;
  -    fdno = fdFileno(fd);
  -    fdSetFdno(fd, -1);		/* XXX skip the fdio close */
  -    if (fdno < 0) return NULL;
  -    bzfile = BZ2_bzdopen(fdno, fmode);
  -    if (bzfile == NULL) return NULL;
  -
  -    fdPush(fd, bzdio, bzfile, fdno);		/* Push bzdio onto stack */
  -
  -    return fdLink(fd, "bzdFdopen");
  -}
  -/*@=globuse@*/
  -
  -/*@-globuse@*/
  -static int bzdFlush(FD_t fd)
  -	/*@globals fileSystem @*/
  -	/*@modifies fileSystem @*/
  -{
  -    return BZ2_bzflush(bzdFileno(fd));
  -}
  -/*@=globuse@*/
  -
  -/* =============================================================== */
  -/*@-globuse@*/
  -/*@-mustmod@*/		/* LCL: *buf is modified */
  -static ssize_t bzdRead(void * cookie, /*@out@*/ char * buf, size_t count)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies *buf, fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    BZFILE *bzfile;
  -    ssize_t rc = 0;
  -
  -    if (fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  -    bzfile = bzdFileno(fd);
  -    fdstat_enter(fd, FDSTAT_READ);
  -    if (bzfile)
  -	/*@-compdef@*/
  -	rc = BZ2_bzread(bzfile, buf, (int)count);
  -	/*@=compdef@*/
  -    if (rc == -1) {
  -	int zerror = 0;
  -	if (bzfile)
  -	    fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  -    } else if (rc >= 0) {
  -	fdstat_exit(fd, FDSTAT_READ, rc);
  -	/*@-compdef@*/
  -	if (fd->ndigests && rc > 0) fdUpdateDigests(fd, (void *)buf, rc);
  -	/*@=compdef@*/
  -    }
  -    return rc;
  -}
  -/*@=mustmod@*/
  -/*@=globuse@*/
  -
  -/*@-globuse@*/
  -static ssize_t bzdWrite(void * cookie, const char * buf, size_t count)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    BZFILE *bzfile;
  -    ssize_t rc;
  -
  -    if (fd->bytesRemain == 0) return 0;	/* XXX simulate EOF */
  -
  -    if (fd->ndigests && count > 0) fdUpdateDigests(fd, (void *)buf, count);
  -
  -    bzfile = bzdFileno(fd);
  -    fdstat_enter(fd, FDSTAT_WRITE);
  -    rc = BZ2_bzwrite(bzfile, (void *)buf, (int)count);
  -    if (rc == -1) {
  -	int zerror = 0;
  -	fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  -    } else if (rc > 0) {
  -	fdstat_exit(fd, FDSTAT_WRITE, rc);
  -    }
  -    return rc;
  -}
  -/*@=globuse@*/
  -
  -static inline int bzdSeek(void * cookie, /*@unused@*/ _libio_pos_t pos,
  -			/*@unused@*/ int whence)
  -	/*@*/
  -{
  -    FD_t fd = c2f(cookie);
  -
  -    BZDONLY(fd);
  -    return -2;
  -}
  -
  -static int bzdClose( /*@only@*/ void * cookie)
  -	/*@globals fileSystem, internalState @*/
  -	/*@modifies fileSystem, internalState @*/
  -{
  -    FD_t fd = c2f(cookie);
  -    BZFILE *bzfile;
  -    int rc;
  -
  -    bzfile = bzdFileno(fd);
  -
  -    if (bzfile == NULL) return -2;
  -    fdstat_enter(fd, FDSTAT_CLOSE);
  -    /*@-noeffectuncon@*/ /* FIX: check rc */
  -    BZ2_bzclose(bzfile);
  -    /*@=noeffectuncon@*/
  -    rc = 0;	/* XXX FIXME */
  -
  -    /* XXX TODO: preserve fd if errors */
  -
  -    if (fd) {
  -	if (rc == -1) {
  -	    int zerror = 0;
  -	    fd->errcookie = BZ2_bzerror(bzfile, &zerror);
  -	} else if (rc >= 0) {
  -	    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  -	}
  -    }
  -
  -DBGIO(fd, (stderr, "==>\tbzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd)));
  -
  -    if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "BZDIO", stderr);
  -    if (rc == 0)
  -	fd = fdFree(fd, "open (bzdClose)");
  -    return rc;
  -}
  -
  -/*@-type@*/ /* LCL: function typedefs */
  -static struct FDIO_s bzdio_s = {
  -  bzdRead, bzdWrite, bzdSeek, bzdClose,	bzdOpen, bzdFdopen,
  -};
  -/*@=type@*/
  -
  -FDIO_t bzdio = /*@-compmempass@*/ &bzdio_s /*@=compmempass@*/ ;
  -
  -/*@=moduncon@*/
  -#endif	/* HAVE_BZLIB_H */
  -
  -/* =============================================================== */
   /*@observer@*/
   static const char * getFdErrstr (FD_t fd)
   	/*@*/
  @@ -3230,12 +2807,16 @@
   
       vh = fdGetFp(fd);
   #if defined(HAVE_ZLIB_H)
  -    if (vh && fdGetIo(fd) == gzdio)
  -	return gzdFlush(vh);
  +    if (vh && fdGetIo(fd) == gzdio && gzdio->_flush != NULL)
  +	return (*gzdio->_flush) ((void *)fd);
   #endif
   #if defined(HAVE_BZLIB_H)
  -    if (vh && fdGetIo(fd) == bzdio)
  -	return bzdFlush(vh);
  +    if (vh && fdGetIo(fd) == bzdio && bzdio->_flush != NULL)
  +	return (*bzdio->_flush) ((void *)fd);
  +#endif
  +#if defined(HAVE_LZMA_H)
  +    if (vh && fdGetIo(fd) == lzdio && lzdio->_flush != NULL)
  +	return (*lzdio->_flush) ((void *)fd);
   #endif
   
       return 0;
  @@ -3577,7 +3158,7 @@
   
   /*@-type@*/ /* LCL: function typedefs */
   static struct FDIO_s fpio_s = {
  -  ufdRead, ufdWrite, fdSeek, ufdClose, NULL, NULL,
  +  ufdRead, ufdWrite, fdSeek, ufdClose, NULL, NULL, NULL,
   };
   /*@=type@*/
   
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.h
  ============================================================================
  $ cvs diff -u -r1.68.2.2 -r1.68.2.3 rpmio.h
  --- rpm/rpmio/rpmio.h	31 May 2008 16:59:03 -0000	1.68.2.2
  +++ rpm/rpmio/rpmio.h	18 Aug 2008 23:18:17 -0000	1.68.2.3
  @@ -100,6 +100,12 @@
   	/*@globals errno, fileSystem @*/
   	/*@modifies errno, fileSystem @*/;
   
  +/**
  + */
  +typedef int (*fdio_flush_function_t) (void * cookie)
  +	/*@globals errno, fileSystem @*/
  +	/*@modifies errno, fileSystem @*/;
  +
   /*@}*/
   
   
  @@ -112,6 +118,8 @@
     fdio_close_function_t		close;
     fdio_fopen_function_t		_fopen;
     fdio_fdopen_function_t	_fdopen;
  +/*@null@*/
  +  fdio_flush_function_t		_flush;
   };
   
   
  @@ .
Received on Tue Aug 19 01:18:18 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.