RPM Community Forums

Mailing List Message of <rpm-cvs>

[CVS] RPM: rpm/ CHANGES TODO rpm/build/ files.c parsePreamble.c rpm/li...

From: Jeff Johnson <jbj@rpm5.org>
Date: Mon 26 Nov 2007 - 03:03:11 CET
Message-Id: <20071126020311.0AC1334847C@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:   26-Nov-2007 03:03:11
  Branch: HEAD                             Handle: 2007112602030802

  Modified files:
    rpm                     CHANGES TODO
    rpm/build               files.c parsePreamble.c
    rpm/lib                 psm.c rpmchecksig.c rpmds.c rpmte.c
    rpm/perl                RPM_Header.xs RPM_Spec.xs rpmxs.c
    rpm/python              header-py.c rpmts-py.c
    rpm/rpmdb               hdrNVR.c hdrfmt.c hdrinline.h header.c header.h
                            librpmdb.vers rpmdb.c rpmtag.h

  Log:
    - insure that HE_t in headerGet/headerNext is initialized sanely.
    - python: lose rpmMergeHeaderFoo methods.
    - eliminate headerFreeData, w00t!, just free all tag data.
    - finalize headerInit/headerNext/headerFini, add to the ABI.

  Summary:
    Revision    Changes     Path
    1.1888      +4  -0      rpm/CHANGES
    1.26        +16 -19     rpm/TODO
    1.295       +7  -7      rpm/build/files.c
    2.148       +12 -9      rpm/build/parsePreamble.c
    2.269       +4  -4      rpm/lib/psm.c
    1.201       +10 -9      rpm/lib/rpmchecksig.c
    2.86        +3  -0      rpm/lib/rpmds.c
    2.72        +4  -4      rpm/lib/rpmte.c
    1.16        +19 -11     rpm/perl/RPM_Header.xs
    1.7         +1  -0      rpm/perl/RPM_Spec.xs
    1.7         +5  -5      rpm/perl/rpmxs.c
    1.86        +13 -144    rpm/python/header-py.c
    1.81        +9  -3      rpm/python/rpmts-py.c
    1.39        +32 -28     rpm/rpmdb/hdrNVR.c
    1.43        +157 -125   rpm/rpmdb/hdrfmt.c
    1.43        +0  -82     rpm/rpmdb/hdrinline.h
    1.136       +92 -98     rpm/rpmdb/header.c
    1.77        +0  -76     rpm/rpmdb/header.h
    1.34        +3  -0      rpm/rpmdb/librpmdb.vers
    1.222       +1  -4      rpm/rpmdb/rpmdb.c
    1.15        +26 -0      rpm/rpmdb/rpmtag.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.1887 -r1.1888 CHANGES
  --- rpm/CHANGES	24 Nov 2007 23:55:00 -0000	1.1887
  +++ rpm/CHANGES	26 Nov 2007 02:03:08 -0000	1.1888
  @@ -1,4 +1,8 @@
   5.0a2 -> 5.0a3:
  +    - jbj: insure that HE_t in headerGet/headerNext is initialized sanely.
  +    - jbj: python: lose rpmMergeHeaderFoo methods.
  +    - jbj: eliminate headerFreeData, w00t!, just free all tag data.
  +    - jbj: finalize headerInit/headerNext/headerFini, add to the ABI.
       - jbj: include <header.h> only where needed, doco remaining destruction.
       - jbj: finalize headerMod, add to the ABI, remove HME_t goop.
       - jbj: finalize headerDel, add to the ABI, remove HRE_t goop.
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/TODO
  ============================================================================
  $ cvs diff -u -r1.25 -r1.26 TODO
  --- rpm/TODO	24 Nov 2007 19:04:09 -0000	1.25
  +++ rpm/TODO	26 Nov 2007 02:03:08 -0000	1.26
  @@ -53,9 +53,6 @@
       - rse: xar/ has weak (think RPM_CHECK_LIB) support its third-party libraries LibXML, OpenSSL, etc.
       - jbj: RPM_I18NSTRING_TYPE is likely still wonky, certainly true for
   	rpm-python h['summary'] access.
  -    - jbj: C++ and C have different rules regarding typedef'd enums like rpmTag.
  -	The definitions and usage are currently split awkwardly between
  -	rpmtag.h and header.h.
       - jbj: markReplacedFiles() subtly rewrites header back into rpmdb
   	with altered RPMTAG_FILESTATES data. get/del/add sequence
   	is needed instead.
  @@ -64,25 +61,25 @@
   	returning rpmRC in some cases now, with accidental collision with
   	PART_FOO values that drive the spec file parser. Renumbering enum
   	rpmParseState to avoid the collisions should fix most of the problem.
  -    - jbj: choose between db-4.5.20 and db-4.6.18. db-4.5.20 may have fewer
  -	upgrade/downgrade issues because of the db-4.6.18 DB_HASH change,
  +    - jbj: choose between db-4.5.20 and db-4.6.21. db-4.5.20 may have fewer
  +	upgrade/downgrade issues because of the db-4.6.21 DB_HASH change,
   	but rpm-5.0 already uses DB_BTREE for Packages.
  -    - jbj: this memory leak seen with "valgrind rpm -qa" no idea what pkg yet:
  -	==5186== 112 bytes in 16 blocks are definitely lost in loss record 2 of 2
  -	==5186==    at 0x4805525: malloc (vg_replace_malloc.c:149)
  -	==5186==    by 0x48E3923: formatValue (header.c:3403)
  -	==5186==    by 0x48E3FAB: singleSprintf (header.c:3557)
  -	==5186==    by 0x48E4C1E: headerSprintf (header.c:3872)
  -	==5186==    by 0x487C075: headerSprintf (hdrinline.h:515)
  -	==5186==    by 0x487BFFB: queryHeader (query.c:118)
  -	==5186==    by 0x487B4A9: showQueryPackage (query.c:162)
  -	==5186==    by 0x487C29D: rpmgiShowMatches (query.c:410)
  -	==5186==    by 0x487C48D: rpmQueryVerify (query.c:475)
  -	==5186==    by 0x487D4AC: rpmcliArgIter (query.c:739)
  -	==5186==    by 0x487DB08: rpmcliQuery (query.c:855)
  -	==5186==    by 0x46F9: main (rpmqv.c:738)
       - jbj: rpm-5.0 is almost compilation warning free, some effort to remove
   	the Mickey Mouse warnings that remain should be undertaken.
  +    - jbj: headerNEVRA now malloc's the returned strinsg. rpmbuild likely has
  +	a few new memory leaks (install/erase/query paths are clean).
  +    - jbj: memory leak seen with repackaging
  +==4811== 249 bytes in 3 blocks are definitely lost in loss record 1 of 1
  +==4811==    at 0x4805525: malloc (vg_replace_malloc.c:149)
  +==4811==    by 0x48E1C14: copyEntry (header.c:1446)
  +==4811==    by 0x48E33A6: headerNext (header.c:2208)
  +==4811==    by 0x48DF183: headerRegenSigHeader (hdrNVR.c:303)
  +==4811==    by 0x4877D11: rpmpsmStage (psm.c:1904)
  +==4811==    by 0x4876C7D: rpmpsmNext (psm.c:1580)
  +==4811==    by 0x48790C2: rpmpsmStage (psm.c:2244)
  +==4811==    by 0x48A9C83: rpmtsRun (transaction.c:1689)
  +==4811==    by 0x4897D28: rpmErase (rpminstall.c:627)
  +==4811==    by 0x43FC: main (rpmqv.c:678)
   
     o to be resolved before RPM 5.0.0:
       - rse: NEWS polishing
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/build/files.c
  ============================================================================
  $ cvs diff -u -r1.294 -r1.295 files.c
  --- rpm/build/files.c	24 Nov 2007 23:55:00 -0000	1.294
  +++ rpm/build/files.c	26 Nov 2007 02:03:08 -0000	1.295
  @@ -17,7 +17,7 @@
   #include <rpmio_internal.h>
   #include <fts.h>
   
  -#include <header.h>		/* XXX headerIsEntry, headerFreeData, headerInitIterator, headerNextIterator, headerFreeIterator, headerMacrosLoad, headerMacrosUnload */
  +#include <header.h>		/* XXX headerIsEntry, headerMacrosLoad, headerMacrosUnload */
   #include <rpmbuild.h>
   
   #include "cpio.h"
  @@ -1666,8 +1666,8 @@
       if (fl->buildRootURL)
   	fi->astriplen = strlen(fl->buildRootURL);
       fi->striplen = 0;
  -    fi->fuser = headerFreeData(fi->fuser, -1);		/* XXX memory leak */
  -    fi->fgroup = headerFreeData(fi->fgroup, -1);	/* XXX memory leak */
  +    fi->fuser = _free(fi->fuser);
  +    fi->fgroup = _free(fi->fgroup);
   
       /* Make the cpio list */
       if (fi->dil != NULL)	/* XXX can't happen */
  @@ -2528,9 +2528,9 @@
       /* Only specific tags are added to the source package header */
       /*@-branchstate@*/
     if (!spec->sourceHdrInit) {
  -    for (hi = headerInitIterator(spec->packages->header);
  -	headerNextIterator(hi, &he->tag, &he->t, &he->p, &he->c);
  -	he->p.ptr = headerFreeData(he->p.ptr, he->t))
  +    for (hi = headerInit(spec->packages->header);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
       {
   	switch (he->tag) {
   	case RPMTAG_NAME:
  @@ -2563,7 +2563,7 @@
   	    /*@switchbreak@*/ break;
   	}
       }
  -    hi = headerFreeIterator(hi);
  +    hi = headerFini(hi);
       /*@=branchstate@*/
   
       if (spec->BANames && spec->BACount > 0) {
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/build/parsePreamble.c
  ============================================================================
  $ cvs diff -u -r2.147 -r2.148 parsePreamble.c
  --- rpm/build/parsePreamble.c	24 Nov 2007 23:55:00 -0000	2.147
  +++ rpm/build/parsePreamble.c	26 Nov 2007 02:03:08 -0000	2.148
  @@ -7,7 +7,7 @@
   
   #include <rpmio_internal.h>
   
  -#include <header.h>		/* XXX headerIsEntry, headerInitIterator, headerNextIterator, headerFreeIterator, headerAddI18NString, headerCopyTags */
  +#include <header.h>		/* XXX headerIsEntry, headerAddI18NString, headerCopyTags */
   #define	_RPMEVR_INTERNAL
   #include <rpmbuild.h>
   #include "debug.h"
  @@ -306,21 +306,24 @@
   static int checkForDuplicates(Header h, const char * NVR)
   	/*@modifies h @*/
   {
  -    int res = 0;
  -    rpmTag lastTag, tag;
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       HeaderIterator hi;
  +    rpmTag lastTag = 0;
  +    int res = 0;
       
  -    for (hi = headerInitIterator(h), lastTag = 0;
  -	headerNextIterator(hi, &tag, NULL, NULL, NULL);
  -	lastTag = tag)
  +    for (hi = headerInit(h);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
       {
  -	if (tag != lastTag)
  +	if (he->tag != lastTag) {
  +	    lastTag = he->tag;
   	    continue;
  +	}
   	rpmlog(RPMLOG_ERR, _("Duplicate %s entries in package: %s\n"),
  -		     tagName(tag), NVR);
  +		     tagName(he->tag), NVR);
   	res = 1;
       }
  -    hi = headerFreeIterator(hi);
  +    hi = headerFini(hi);
   
       return res;
   }
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/psm.c
  ============================================================================
  $ cvs diff -u -r2.268 -r2.269 psm.c
  --- rpm/lib/psm.c	24 Nov 2007 23:55:01 -0000	2.268
  +++ rpm/lib/psm.c	26 Nov 2007 02:03:09 -0000	2.269
  @@ -1855,15 +1855,15 @@
   			/* XXX this is headerCopy w/o headerReload() */
   			psm->oh = headerNew();
   
  -			for (hi = headerInitExtension(oh);
  -			     headerNextExtension(hi, he, 0);
  -			     he->p.ptr = headerFreeData(he->p.ptr, he->t))
  +			for (hi = headerInit(oh);
  +			     headerNext(hi, he, 0);
  +			     he->p.ptr = _free(he->p.ptr))
   			{
   			    if (he->tag == RPMTAG_ARCHIVESIZE)
   				noArchiveSize = 1;
   			    xx = headerPut(psm->oh, he, 0);
   			}
  -			hi = headerFreeIterator(hi);
  +			hi = headerFini(hi);
   
   			oh = headerFree(oh);
   			uh = _free(uh);
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/rpmchecksig.c
  ============================================================================
  $ cvs diff -u -r1.200 -r1.201 rpmchecksig.c
  --- rpm/lib/rpmchecksig.c	24 Nov 2007 23:55:01 -0000	1.200
  +++ rpm/lib/rpmchecksig.c	26 Nov 2007 02:03:09 -0000	1.201
  @@ -278,15 +278,15 @@
   	    }
   
   	    oh = headerCopyLoad(he->p.ptr);
  -	    for (hi = headerInitExtension(oh);
  -		headerNextExtension(hi, ohe, 0);
  -		ohe->p.ptr = headerFreeData(ohe->p.ptr, ohe->t))
  +	    for (hi = headerInit(oh);
  +		headerNext(hi, ohe, 0);
  +		ohe->p.ptr = _free(ohe->p.ptr))
   	    {
   		if (ohe->p.ptr) {
   		    xx = headerPut(nh, ohe, 0);
   		}
   	    }
  -	    hi = headerFreeIterator(hi);
  +	    hi = headerFini(hi);
   	    oh = headerFree(oh);
   
   	    sigh = headerFree(sigh);
  @@ -808,7 +808,8 @@
   	    xx = headerGet(h, he, 0);
   	    if (!xx || he->p.ptr == NULL) {
   		h = headerFree(h);
  -		rpmlog(RPMLOG_ERR, _("%s: headerGetEntry failed\n"), fn);
  +		rpmlog(RPMLOG_ERR, "%s: %s: %s\n", fn, _("headerGet failed"),
  +			_("failed to retrieve original header\n"));
   		rc = RPMRC_FAIL;
   		goto exit;
   	    }
  @@ -985,9 +986,9 @@
   	b += strlen(b);
   
   	if (sigh != NULL)
  -	for (hi = headerInitExtension(sigh);
  -	    headerNextExtension(hi, she, 0) != 0;
  -	    she->p.ptr = headerFreeData(she->p.ptr, she->t))
  +	for (hi = headerInit(sigh);
  +	    headerNext(hi, she, 0) != 0;
  +	    she->p.ptr = _free(she->p.ptr))
   	{
   
   assert(she->p.ptr != NULL);
  @@ -1094,7 +1095,7 @@
   		}
   	    }
   	}
  -	hi = headerFreeIterator(hi);
  +	hi = headerFini(hi);
   	/* XXX clear the already free'd signature data. */
   /*@-noeffect@*/
   	xx = pgpSetSig(dig, 0, 0, NULL, 0);
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/rpmds.c
  ============================================================================
  $ cvs diff -u -r2.85 -r2.86 rpmds.c
  --- rpm/lib/rpmds.c	24 Nov 2007 23:55:01 -0000	2.85
  +++ rpm/lib/rpmds.c	26 Nov 2007 02:03:09 -0000	2.86
  @@ -520,6 +520,7 @@
       *t = '\0';
       N[0] = t;
       t = stpcpy(t, Name);
  +    Name = _free(Name);
   
       t = xmalloc(sizeof(*EVR) + 20 + strlen(V) + strlen(R) + sizeof("-"));
       EVR = (const char **) t;
  @@ -529,6 +530,8 @@
       sprintf(t, "%d:", E);
       t += strlen(t);
       t = stpcpy( stpcpy( stpcpy( t, V), "-"), R);
  +    V = _free(V);
  +    R = _free(R);
   
       ds = xcalloc(1, sizeof(*ds));
       ds->Type = Type;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/rpmte.c
  ============================================================================
  $ cvs diff -u -r2.71 -r2.72 rpmte.c
  --- rpm/lib/rpmte.c	24 Nov 2007 23:55:01 -0000	2.71
  +++ rpm/lib/rpmte.c	26 Nov 2007 02:03:09 -0000	2.72
  @@ -102,7 +102,7 @@
       he->tag = RPMTAG_NVRA;
       xx = headerGet(h, he, 0);
   assert(he->p.str != NULL);
  -    p->NEVR = he->p.str;
  +    p->NEVR = (xx ? he->p.str : xstrdup("?N-?V-?R.?A"));
       p->name = xstrdup(p->NEVR);
       if ((p->release = strrchr(p->name, '-')) != NULL)
   	*p->release++ = '\0';
  @@ -113,7 +113,7 @@
   
       he->tag = RPMTAG_HDRID;
       xx = headerGet(h, he, 0);
  -    p->hdrid = he->p.str;
  +    p->hdrid = (xx ? he->p.str : xstrdup("?RPMTAG_HDRID?"));
   
       he->tag = RPMTAG_PKGID;
       xx = headerGet(h, he, 0);
  @@ -134,11 +134,11 @@
   
       he->tag = RPMTAG_ARCH;
       xx = headerGet(h, he, 0);
  -    p->arch = he->p.str;
  +    p->arch = (xx ? he->p.str : xstrdup("?RPMTAG_ARCH?"));
   
       he->tag = RPMTAG_OS;
       xx = headerGet(h, he, 0);
  -    p->os = he->p.str;
  +    p->os = (xx ? he->p.str : xstrdup("?RPMTAG_OS?"));
   
       p->isSource =
   	(headerIsEntry(h, RPMTAG_SOURCERPM) == 0 &&
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/perl/RPM_Header.xs
  ============================================================================
  $ cvs diff -u -r1.15 -r1.16 RPM_Header.xs
  --- rpm/perl/RPM_Header.xs	24 Nov 2007 19:46:06 -0000	1.15
  +++ rpm/perl/RPM_Header.xs	26 Nov 2007 02:03:09 -0000	1.16
  @@ -297,14 +297,16 @@
   listtag(h)
       Header h
       PREINIT:
  -    HeaderIterator iterator;
  -    rpmTag tag;
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
  +    HeaderIterator hi;
       PPCODE:
  -    iterator = headerInitIterator(h);
  -    while (headerNextIterator(iterator, &tag, NULL, NULL, NULL)) {
  -        XPUSHs(sv_2mortal(newSViv(tag)));
  +    for (hi = headerInit(h);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
  +    {
  +        XPUSHs(sv_2mortal(newSViv(he->tag)));
       }
  -    headerFreeIterator(iterator);
  +    hi = headerFini(hi);
       
   int
   hastag(h, sv_tag)
  @@ -338,8 +340,9 @@
       } else if (SvPOK(sv_tag)) {
           he->tag = tagValue(SvPV_nolen(sv_tag));
       }
  -    if (he->tag > 0)
  -        if (headerGetEntry(h, he->tag, &he->t, &he->p, &he->c)) {
  +    if (he->tag > 0) {
  +        int xx = headerGet(h, he, 0);
  +        if (xx) {
               switch(he->t) {
                   case RPM_STRING_ARRAY_TYPE:
                       {
  @@ -374,8 +377,9 @@
                   default:
                       croak("unknown rpm tag type %d", he->t);
               }
  +	    he->p.ptr = _free(he->p.ptr);
           }
  -    he->p.ptr = headerFreeData(he->p.ptr, he->t);
  +    }
   
   int
   tagtype(h, sv_tag)
  @@ -390,9 +394,13 @@
           he->tag = tagValue(SvPV_nolen(sv_tag));
       }
       RETVAL = 0;
  -    if (he->tag > 0)
  -        if (headerGetEntry(h, he->tag, &he->t, NULL, &he->c))
  +    if (he->tag > 0) {
  +        int xx = headerGet(h, he, 0);
  +        if (xx) {
               RETVAL = he->t;
  +	    he->p.ptr = _free(he->p.ptr);
  +	}
  +    }
       OUTPUT:
       RETVAL
       
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/perl/RPM_Spec.xs
  ============================================================================
  $ cvs diff -u -r1.6 -r1.7 RPM_Spec.xs
  --- rpm/perl/RPM_Spec.xs	24 Nov 2007 19:46:06 -0000	1.6
  +++ rpm/perl/RPM_Spec.xs	26 Nov 2007 02:03:09 -0000	1.7
  @@ -6,6 +6,7 @@
   #undef Mkdir
   #undef Stat
   
  +#include "header.h"	/* XXX headerIsEntry, headerLink */
   #include "rpmlib.h"
   #include "rpmio.h"
   #include "rpmcli.h"
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/perl/rpmxs.c
  ============================================================================
  $ cvs diff -u -r1.6 -r1.7 rpmxs.c
  --- rpm/perl/rpmxs.c	22 Nov 2007 22:28:16 -0000	1.6
  +++ rpm/perl/rpmxs.c	26 Nov 2007 02:03:09 -0000	1.7
  @@ -122,16 +122,16 @@
   }
   
   int _headername_vs_dep(Header h, rpmds dep, int nopromote) {
  -    rpmTagType type;
  -    rpmTagData name;
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       int rc = 0;
       CHECK_RPMDS_IX(dep);
  -    headerGetEntry(h, RPMTAG_NAME, &type, &name, NULL);
  -    if (strcmp(name.str, rpmdsN(dep)) != 0)
  +    he->tag = RPMTAG_NAME;
  +    headerGet(h, he, 0);
  +    if (strcmp(he->p.str, rpmdsN(dep)) != 0)
           rc = 0;
       else
           rc = rpmdsNVRMatchesDep(h, dep, nopromote);
  -    name.ptr = headerFreeData(name.ptr, type);
  +    he->p.ptr = _free(he->p.ptr);
       return rc;
       /* return 1 if match */
   }
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/python/header-py.c
  ============================================================================
  $ cvs diff -u -r1.85 -r1.86 header-py.c
  --- rpm/python/header-py.c	24 Nov 2007 23:15:32 -0000	1.85
  +++ rpm/python/header-py.c	26 Nov 2007 02:03:09 -0000	1.86
  @@ -125,10 +125,9 @@
    * 	print hdr['release']
    * \endcode
    *
  - * This method of access is a teensy bit slower because the name must be
  - * translated into the tag number dynamically. You also must make sure
  - * the strings in header lookups don't get translated, or the lookups
  - * will fail.
  + * This method of access is slower because the name must be translated
  + * into the tag number dynamically. You also must make sure the strings
  + * in header lookups don't get translated, or the lookups will fail.
    */
   
   /** \ingroup py_c
  @@ -136,14 +135,6 @@
   struct hdrObject_s {
       PyObject_HEAD
       Header h;
  -    char ** md5list;
  -    char ** fileList;
  -    char ** linkList;
  -    uint32_t * fileSizes;
  -    uint32_t * mtimes;
  -    uint32_t * uids, * gids;	/* XXX these tags are not used anymore */
  -    unsigned short * rdevs;
  -    unsigned short * modes;
   } ;
   
   /**
  @@ -165,21 +156,20 @@
   static PyObject * hdrKeyList(hdrObject * s)
   	/*@*/
   {
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       PyObject * list, *o;
       HeaderIterator hi;
  -    rpmTag tag;
  -    rpmTagType type;
   
       list = PyList_New(0);
   
  -    hi = headerInitIterator(s->h);
  -    while (headerNextIterator(hi, &tag, &type, NULL, NULL)) {
  -        if (tag == HEADER_I18NTABLE) continue;
  -
  -	switch (type) {
  +    for (hi = headerInit(s->h);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
  +    {
  +        if (he->tag == HEADER_I18NTABLE) continue;
  +	switch (he->t) {
   	case RPM_I18NSTRING_TYPE:
  -	    continue;
  -	    /*@notreached@*/ break;
  +	    break;
   	case RPM_BIN_TYPE:
   	case RPM_UINT64_TYPE:
   	case RPM_UINT32_TYPE:
  @@ -187,12 +177,12 @@
   	case RPM_UINT8_TYPE:
   	case RPM_STRING_ARRAY_TYPE:
   	case RPM_STRING_TYPE:
  -	    PyList_Append(list, o=PyInt_FromLong(tag));
  +	    PyList_Append(list, o=PyInt_FromLong(he->tag));
   	    Py_DECREF(o);
   	    break;
   	}
       }
  -    headerFreeIterator(hi);
  +    hi = headerFini(hi);
   
       return list;
   }
  @@ -341,9 +331,6 @@
   	/*@*/
   {
       if (s->h) headerFree(s->h);
  -    s->md5list = _free(s->md5list);
  -    s->fileList = _free(s->fileList);
  -    s->linkList = _free(s->linkList);
       PyObject_Del(s);
   }
   
  @@ -632,9 +619,6 @@
   {
       hdrObject * hdr = PyObject_New(hdrObject, &hdr_Type);
       hdr->h = headerLink(h);
  -    hdr->fileList = hdr->linkList = hdr->md5list = NULL;
  -    hdr->uids = hdr->gids = hdr->mtimes = hdr->fileSizes = NULL;
  -    hdr->modes = hdr->rdevs = NULL;
       return hdr;
   }
   
  @@ -773,121 +757,6 @@
   }
   
   /**
  - * This assumes the order of list matches the order of the new headers, and
  - * throws an exception if that isn't true.
  - */
  -int rpmMergeHeaders(PyObject * list, FD_t fd, int matchTag)
  -{
  -    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
  -    Header h;
  -    HeaderIterator hi;
  -    rpmTagData newMatch;
  -    rpmTagData oldMatch;
  -    hdrObject * hdr;
  -    uint32_t count = 0;
  -    int xx;
  -
  -    Py_BEGIN_ALLOW_THREADS
  -    {   const char item[] = "Header";
  -	const char * msg = NULL;
  -	rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
  -	if (rc != RPMRC_OK)
  -	    rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "headerRead", item, msg);
  -	msg = _free(msg);
  -    }
  -    Py_END_ALLOW_THREADS
  -
  -    while (h) {
  -	he->tag = matchTag;
  -	xx = headerGet(hdr->h, he, 0);
  -	newMatch.ptr = he->p.ptr;
  -	if (!xx) {
  -	    PyErr_SetString(pyrpmError, "match tag missing in new header");
  -	    return 1;
  -	}
  -
  -	hdr = (hdrObject *) PyList_GetItem(list, count++);
  -	if (!hdr) {
  -	    PyErr_SetString(pyrpmError, "match list item missing");
  -	    return 1;
  -	}
  -
  -	he->tag = matchTag;
  -	xx = headerGet(hdr->h, he, 0);
  -	oldMatch.ptr = he->p.ptr;
  -	if (!xx) {
  -	    PyErr_SetString(pyrpmError, "match tag missing in old header");
  -	    return 1;
  -	}
  -
  -	if (*newMatch.ui32p != *oldMatch.ui32p) {
  -	    PyErr_SetString(pyrpmError, "match tag mismatch");
  -	    return 1;
  -	}
  -
  -	hdr->md5list = _free(hdr->md5list);
  -	hdr->fileList = _free(hdr->fileList);
  -	hdr->linkList = _free(hdr->linkList);
  -
  -	for (hi = headerInitIterator(h);
  -	    headerNextIterator(hi, &he->tag, &he->t, &he->p, &he->c);
  -	    he->p.ptr = headerFreeData(he->p.ptr, he->t))
  -	{
  -	    /* could be dupes */
  -	    xx = headerDel(hdr->h, he, 0);
  -	    xx = headerPut(hdr->h, he, 0);
  -	}
  -
  -	headerFreeIterator(hi);
  -	h = headerFree(h);
  -
  -	Py_BEGIN_ALLOW_THREADS
  -	{   const char item[] = "Header";
  -	    const char * msg = NULL;
  -	    rpmRC rc = rpmpkgRead(item, fd, &h, &msg);
  -	    if (rc != RPMRC_OK)
  -		rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "headerRead", item, msg);
  -	    msg = _free(msg);
  -	}
  -	Py_END_ALLOW_THREADS
  -    }
  -
  -    return 0;
  -}
  -
  -PyObject *
  -rpmMergeHeadersFromFD(PyObject * self, PyObject * args, PyObject * kwds)
  -{
  -    FD_t fd;
  -    int fileno;
  -    PyObject * list;
  -    int rc;
  -    int matchTag;
  -    char * kwlist[] = {"list", "fd", "matchTag", NULL};
  -
  -    if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oii", kwlist, &list,
  -	    &fileno, &matchTag))
  -	return NULL;
  -
  -    if (!PyList_Check(list)) {
  -	PyErr_SetString(PyExc_TypeError, "first parameter must be a list");
  -	return NULL;
  -    }
  -
  -    fd = fdDup(fileno);
  -
  -    rc = rpmMergeHeaders (list, fd, matchTag);
  -    Fclose(fd);
  -
  -    if (rc) {
  -	return NULL;
  -    }
  -
  -    Py_INCREF(Py_None);
  -    return Py_None;
  -}
  -
  -/**
    */
   PyObject *
   rpmSingleHeaderFromFD(PyObject * self, PyObject * args, PyObject * kwds)
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/python/rpmts-py.c
  ============================================================================
  $ cvs diff -u -r1.80 -r1.81 rpmts-py.c
  --- rpm/python/rpmts-py.c	24 Nov 2007 23:55:03 -0000	1.80
  +++ rpm/python/rpmts-py.c	26 Nov 2007 02:03:09 -0000	1.81
  @@ -236,9 +236,15 @@
       /* Synthesize a python object for callback (if necessary). */
       if (pkgObj == NULL) {
   	if (h) {
  -	    rpmTagData n = { .ptr = NULL };
  -	    (void) headerGetEntry(h, RPMTAG_NAME, NULL, &n, NULL);
  -	    pkgObj = Py_BuildValue("s", n.str);
  +	    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
  +	    he->tag = RPMTAG_NAME;
  +	    if (headerGet(h, he, 0)) {
  +		pkgObj = Py_BuildValue("s", he->p.str);
  +		he->p.ptr = _free(he->p.ptr);
  +	    } else {
  +		pkgObj = Py_None;
  +		Py_INCREF(pkgObj);
  +	    }
   	} else {
   	    pkgObj = Py_None;
   	    Py_INCREF(pkgObj);
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/hdrNVR.c
  ============================================================================
  $ cvs diff -u -r1.38 -r1.39 hdrNVR.c
  --- rpm/rpmdb/hdrNVR.c	24 Nov 2007 23:15:33 -0000	1.38
  +++ rpm/rpmdb/hdrNVR.c	26 Nov 2007 02:03:10 -0000	1.39
  @@ -155,46 +155,52 @@
   		/*@unused@*/ const char **ep, const char **vp, const char **rp,
   		const char **ap)
   {
  -    rpmTagType t;
  -    rpmTagData p;
  -    rpmTagCount c;
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
   
   /*@-onlytrans@*/
       if (np) {
  -	if (headerGetEntry(h, RPMTAG_NAME, &t, &p, &c)
  -	 && t == RPM_STRING_TYPE && c == 1)
  -	    *np = p.str;
  +	he->tag = RPMTAG_NAME;
  +	if (headerGet(h, he, 0)
  +	 && he->t == RPM_STRING_TYPE && he->c == 1)
  +	    *np = xstrdup(he->p.str);
   	else
   	    *np = NULL;
  +	he->p.ptr = _free(he->p.ptr);
       }
       if (vp) {
  -	if (headerGetEntry(h, RPMTAG_VERSION, &t, &p, &c)
  -	 && t == RPM_STRING_TYPE && c == 1)
  -	    *vp = p.str;
  +	he->tag = RPMTAG_VERSION;
  +	if (headerGet(h, he, 0)
  +	 && he->t == RPM_STRING_TYPE && he->c == 1)
  +	    *vp = xstrdup(he->p.str);
   	else
   	    *vp = NULL;
  +	he->p.ptr = _free(he->p.ptr);
       }
       if (rp) {
  -	if (headerGetEntry(h, RPMTAG_RELEASE, &t, &p, &c)
  -	 && t == RPM_STRING_TYPE && c == 1)
  -	    *rp = p.str;
  +	he->tag = RPMTAG_RELEASE;
  +	if (headerGet(h, he, 0)
  +	 && he->t == RPM_STRING_TYPE && he->c == 1)
  +	    *rp = xstrdup(he->p.str);
   	else
   	    *rp = NULL;
  +	he->p.ptr = _free(he->p.ptr);
       }
       if (ap) {
  +	he->tag = RPMTAG_ARCH;
   /*@-observertrans -readonlytrans@*/
  -	if (!headerIsEntry(h, RPMTAG_ARCH))
  -	    *ap = "pubkey";
  +	if (!headerIsEntry(h, he->tag))
  +	    *ap = xstrdup("pubkey");
   	else
   	if (!headerIsEntry(h, RPMTAG_SOURCERPM))
  -	    *ap = "src";
  +	    *ap = xstrdup("src");
   /*@=observertrans =readonlytrans@*/
   	else
  -	if (headerGetEntry(h, RPMTAG_ARCH, &t, &p, &c)
  -	 && t == RPM_STRING_TYPE && c == 1)
  -	    *ap = p.str;
  +	if (headerGet(h, he, 0)
  +	 && he->t == RPM_STRING_TYPE && he->c == 1)
  +	    *ap = xstrdup(he->p.str);
   	else
   	    *ap = NULL;
  +	he->p.ptr = _free(he->p.ptr);
       }
   /*@=onlytrans@*/
       return 0;
  @@ -221,7 +227,6 @@
   
   void headerMergeLegacySigs(Header h, const Header sigh)
   {
  -    HFD_t hfd = (HFD_t) headerFreeData;
       HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       HeaderIterator hi;
       int xx;
  @@ -229,9 +234,9 @@
       if (h == NULL || sigh == NULL)
   	return;
   
  -    for (hi = headerInitExtension(sigh);
  -        headerNextExtension(hi, he, 0);
  -        he->p.ptr = hfd(he->p.ptr, he->t))
  +    for (hi = headerInit(sigh);
  +        headerNext(hi, he, 0);
  +        he->p.ptr = _free(he->p.ptr))
       {
   	/* XXX Translate legacy signature tag values. */
   	switch ((rpmSigTag)he->tag) {
  @@ -284,20 +289,19 @@
   assert(xx == 1);
   	}
       }
  -    hi = headerFreeIterator(hi);
  +    hi = headerFini(hi);
   }
   
   Header headerRegenSigHeader(const Header h, int noArchiveSize)
   {
  -    HFD_t hfd = (HFD_t) headerFreeData;
       HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       Header sigh = headerNew();
       HeaderIterator hi;
       int xx;
   
  -    for (hi = headerInitExtension(h);
  -        headerNextExtension(hi, he, 0);
  -        he->p.ptr = hfd(he->p.ptr, he->t))
  +    for (hi = headerInit(h);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
       {
   	/* XXX Translate legacy signature tag values. */
   	switch (he->tag) {
  @@ -328,6 +332,6 @@
   assert(xx == 1);
   	}
       }
  -    hi = headerFreeIterator(hi);
  +    hi = headerFini(hi);
       return sigh;
   }
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/hdrfmt.c
  ============================================================================
  $ cvs diff -u -r1.42 -r1.43 hdrfmt.c
  --- rpm/rpmdb/hdrfmt.c	24 Nov 2007 22:07:30 -0000	1.42
  +++ rpm/rpmdb/hdrfmt.c	26 Nov 2007 02:03:10 -0000	1.43
  @@ -1026,21 +1026,18 @@
   static int instprefixTag(Header h, HE_t he)
   	/*@modifies he @*/
   {
  -    rpmTagType ipt;
  -    rpmTagData array;
  -
       he->tag = RPMTAG_INSTALLPREFIX;
  -    if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, &he->t, &he->p, &he->c)) {
  -	he->freeData = 0;
  +    if (headerGet(h, he, 0))
   	return 0;
  -    }
  +
       he->tag = RPMTAG_INSTPREFIXES;
  -    if (headerGetEntry(h, he->tag, &ipt, &array, &he->c)) {
  +    if (headerGet(h, he, 0)) {
  +	rpmTagData array = { .argv = he->p.argv };
   	he->t = RPM_STRING_TYPE;
   	he->c = 1;
   	he->p.str = xstrdup(array.argv[0]);
   	he->freeData = 1;
  -	array.ptr = headerFreeData(array.ptr, ipt);
  +	array.ptr = _free(array.ptr);
   	return 0;
       }
       return 1;
  @@ -1056,40 +1053,64 @@
   	/*@modifies he @*/
   {
       HE_t _he = memset(alloca(sizeof(*_he)), 0, sizeof(*_he));
  -    rpmTagData flags;
  -    rpmTagData indices;
  -    rpmTagData names;
  -    rpmTagData versions;
  -    const char ** conds;
  +    rpmTagData flags = { .ptr = NULL };
  +    rpmTagData indices = { .ptr = NULL };
  +    rpmTagData names = { .ptr = NULL };
  +    rpmTagData versions = { .ptr = NULL };
       rpmTagData s;
  -    char * item, * flagsStr;
  -    char * chptr;
  -    uint32_t numNames, numScripts;
  +    rpmTagCount numNames;
  +    rpmTagCount numScripts;
       unsigned i, j;
  +    int rc = 1;		/* assume failure */
       int xx;
   
       he->freeData = 0;
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, &names, &numNames);
  -    if (!xx)
  -	return 0;
  +
  +    _he->tag = RPMTAG_TRIGGERNAME;
  +    xx = headerGet(h, _he, 0);
  +    names.argv = _he->p.argv;
  +    numNames = _he->c;
  +    if (!xx) {		/* no triggers, succeed anyways */
  +	rc = 0;
  +	goto exit;
  +    }
  +
  +    _he->tag = RPMTAG_TRIGGERINDEX;
  +    xx = headerGet(h, _he, 0);
  +    indices.ui32p = _he->p.ui32p;
  +    if (!xx) goto exit;
  +
  +    _he->tag = RPMTAG_TRIGGERFLAGS;
  +    xx = headerGet(h, _he, 0);
  +    flags.ui32p = _he->p.ui32p;
  +    if (!xx) goto exit;
  +
  +    _he->tag = RPMTAG_TRIGGERVERSION;
  +    xx = headerGet(h, _he, 0);
  +    versions.argv = _he->p.argv;
  +    if (!xx) goto exit;
  +
  +    _he->tag = RPMTAG_TRIGGERSCRIPTS;
  +    xx = headerGet(h, _he, 0);
  +    s.argv = _he->p.argv;
  +    numScripts = _he->c;
  +    if (!xx) goto exit;
   
       _he->tag = he->tag;
       _he->t = RPM_UINT32_TYPE;
       _he->p.ui32p = NULL;
       _he->c = 1;
  -    _he->freeData = -1;
  -
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, &indices, NULL);
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, &flags, NULL);
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, &versions, NULL);
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, &s, &numScripts);
  +    _he->freeData = 0;
   
       he->t = RPM_STRING_ARRAY_TYPE;
       he->c = numScripts;
   
       he->freeData = 1;
  -    he->p.argv = conds = xmalloc(sizeof(*conds) * numScripts);
  -    for (i = 0; i < (unsigned) numScripts; i++) {
  +    he->p.argv = xmalloc(sizeof(*he->p.argv) * he->c);
  +    for (i = 0; i < (unsigned) he->c; i++) {
  +	char * item, * flagsStr;
  +	char * chptr;
  +
   	chptr = xstrdup("");
   
   	for (j = 0; j < (unsigned) numNames; j++) {
  @@ -1111,14 +1132,18 @@
   	    item = _free(item);
   	}
   
  -	conds[i] = chptr;
  +	he->p.argv[i] = chptr;
       }
  +    rc = 0;
   
  -    names.ptr = headerFreeData(names.ptr, -1);
  -    versions.ptr = headerFreeData(versions.ptr, -1);
  -    s.ptr = headerFreeData(s.ptr, -1);
  +exit:
  +    indices.ptr = _free(indices.ptr);
  +    flags.ptr = _free(flags.ptr);
  +    names.ptr = _free(names.ptr);
  +    versions.ptr = _free(versions.ptr);
  +    s.ptr = _free(s.ptr);
   
  -    return 0;
  +    return rc;
   }
   
   /**
  @@ -1130,46 +1155,65 @@
   static int triggertypeTag(Header h, HE_t he)
   	/*@modifies he @*/
   {
  +    HE_t _he = memset(alloca(sizeof(*_he)), 0, sizeof(*_he));
       rpmTagData indices;
       rpmTagData flags;
  -    const char ** conds;
       rpmTagData s;
  -    uint32_t numScripts, numNames;
  +    rpmTagCount numNames;
  +    rpmTagCount numScripts;
       unsigned i, j;
  +    int rc = 1;		/* assume failure */
       int xx;
   
       he->freeData = 0;
  -    if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, &indices, &numNames))
  -	return 1;
   
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, &flags, NULL);
  -    xx = headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, &s, &numScripts);
  +    _he->tag = RPMTAG_TRIGGERINDEX;
  +    xx = headerGet(h, _he, 0);
  +    indices.ui32p = _he->p.ui32p;
  +    numNames = _he->c;
  +    if (!xx) goto exit;
  +
  +    _he->tag = RPMTAG_TRIGGERFLAGS;
  +    xx = headerGet(h, _he, 0);
  +    flags.ui32p = _he->p.ui32p;
  +    if (!xx) goto exit;
  +
  +    _he->tag = RPMTAG_TRIGGERSCRIPTS;
  +    xx = headerGet(h, _he, 0);
  +    s.argv = _he->p.argv;
  +    numScripts = _he->c;
  +    if (!xx) goto exit;
   
       he->t = RPM_STRING_ARRAY_TYPE;
       he->c = numScripts;
   
       he->freeData = 1;
  -    he->p.argv = conds = xmalloc(sizeof(*conds) * numScripts);
  -    for (i = 0; i < (unsigned) numScripts; i++) {
  +    he->p.argv = xmalloc(sizeof(*he->p.argv) * he->c);
  +    for (i = 0; i < (unsigned) he->c; i++) {
   	for (j = 0; j < (unsigned) numNames; j++) {
   	    if (indices.ui32p[j] != i)
   		/*@innercontinue@*/ continue;
   
  +	    /* XXX FIXME: there's memory leaks here. */
   	    if (flags.ui32p[j] & RPMSENSE_TRIGGERPREIN)
  -		conds[i] = xstrdup("prein");
  +		he->p.argv[i] = xstrdup("prein");
   	    else if (flags.ui32p[j] & RPMSENSE_TRIGGERIN)
  -		conds[i] = xstrdup("in");
  +		he->p.argv[i] = xstrdup("in");
   	    else if (flags.ui32p[j] & RPMSENSE_TRIGGERUN)
  -		conds[i] = xstrdup("un");
  +		he->p.argv[i] = xstrdup("un");
   	    else if (flags.ui32p[j] & RPMSENSE_TRIGGERPOSTUN)
  -		conds[i] = xstrdup("postun");
  +		he->p.argv[i] = xstrdup("postun");
   	    else
  -		conds[i] = xstrdup("");
  +		he->p.argv[i] = xstrdup("");
   	    /*@innerbreak@*/ break;
   	}
       }
  +    rc = 0;
   
  -    s.ptr = headerFreeData(s.ptr, -1);
  +exit:
  +    indices.ptr = _free(indices.ptr);
  +    flags.ptr = _free(flags.ptr);
  +    s.ptr = _free(s.ptr);
       return 0;
   }
   
  @@ -1290,52 +1334,49 @@
   static int localeTag(Header h, HE_t he)
   	/*@modifies he @*/
   {
  -    rpmTagType t;
  -    rpmTagData p;
  -    rpmTagCount c;
  -    const char ** argv;
  -    char * te;
       int rc;
   
  -    rc = headerGetEntry(h, he->tag, &t, &p, &c);
  -    if (!rc || p.ptr == NULL || c == 0) {
  +    rc = headerGetEntry(h, he->tag, &he->t, &he->p, &he->c);
  +    if (!rc || he->p.str == NULL || he->c == 0) {
   	he->t = RPM_STRING_TYPE;
  -	he->p.str = NULL;
  -	he->c = 0;
   	he->freeData = 0;
   	return 1;
       }
   
  -    if (t == RPM_STRING_TYPE) {
  -	p.str = xstrdup(p.str);
  -	p.str = xstrtolocale(p.str);
  +    switch (he->t) {
  +    default:
  +	he->freeData = 0;
  +	break;
  +    case RPM_STRING_TYPE:
  +	he->p.str = xstrdup(he->p.str);
  +	he->p.str = xstrtolocale(he->p.str);
   	he->freeData = 1;
  -    } else if (t == RPM_STRING_ARRAY_TYPE) {
  +	break;
  +    case RPM_STRING_ARRAY_TYPE:
  +    {	const char ** argv;
  +	char * te;
   	size_t l = 0;
   	unsigned i;
  -	for (i = 0; i < (unsigned)c; i++) {
  -	    p.argv[i] = xstrdup(p.argv[i]);
  -	    p.argv[i] = xstrtolocale(p.argv[i]);
  -assert(p.argv[i] != NULL);
  -	    l += strlen(p.argv[i]) + 1;
  -	}
  -	argv = xmalloc(c * sizeof(*argv) + l);
  -	te = (char *)&argv[c];
  -	for (i = 0; i < (unsigned) c; i++) {
  +	for (i = 0; i < (unsigned) he->c; i++) {
  +	    he->p.argv[i] = xstrdup(he->p.argv[i]);
  +	    he->p.argv[i] = xstrtolocale(he->p.argv[i]);
  +assert(he->p.argv[i] != NULL);
  +	    l += strlen(he->p.argv[i]) + 1;
  +	}
  +	argv = xmalloc(he->c * sizeof(*argv) + l);
  +	te = (char *)&argv[he->c];
  +	for (i = 0; i < (unsigned) he->c; i++) {
   	    argv[i] = te;
  -	    te = stpcpy(te, p.argv[i]);
  +	    te = stpcpy(te, he->p.argv[i]);
   	    te++;
  -	    p.argv[i] = _free(p.argv[i]);
  +	    he->p.argv[i] = _free(he->p.argv[i]);
   	}
  -	p.ptr = _free(p.ptr);
  -	p.argv = argv;
  +	he->p.ptr = _free(he->p.ptr);
  +	he->p.argv = argv;
   	he->freeData = 1;
  -    } else
  -	he->freeData = 0;
  +    }	break;
  +    }
   
  -    he->t = t;
  -    he->p.ptr = p.ptr;
  -    he->c = c;
       return 0;
   }
   
  @@ -1446,6 +1487,10 @@
       if (V)	t = stpcpy( stpcpy(t, "-"), V);
       if (R)	t = stpcpy( stpcpy(t, "-"), R);
       if (A)	t = stpcpy( stpcpy(t, "."), A);
  +    N = _free(N);
  +    V = _free(V);
  +    R = _free(R);
  +    A = _free(A);
       return NVRA;
   }
   
  @@ -1492,15 +1537,15 @@
   		/*@null@*/ /*@out@*/ rpmTagCount * fcp)
   	/*@modifies *fnp, *fcp @*/
   {
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
  +    rpmTag dirNameTag = 0;
  +    rpmTag dirIndexesTag = 0;
       rpmTagData baseNames;
       rpmTagData dirNames;
       rpmTagData dirIndexes;
       rpmTagData fileNames;
       rpmTagCount count;
       size_t size;
  -    rpmTag dirNameTag = 0;
  -    rpmTag dirIndexesTag = 0;
  -    rpmTagType bnt, dnt;
       char * t;
       unsigned i;
       int xx;
  @@ -1511,16 +1556,31 @@
       } else if (tagN == RPMTAG_ORIGBASENAMES) {
   	dirNameTag = RPMTAG_ORIGDIRNAMES;
   	dirIndexesTag = RPMTAG_ORIGDIRINDEXES;
  +    } else {
  +	if (fnp) *fnp = NULL;
  +	if (fcp) *fcp = 0;
  +	return;		/* programmer error */
       }
   
  -    if (!headerGetEntry(h, tagN, &bnt, &baseNames, &count)) {
  +    he->tag = tagN;
  +    xx = headerGet(h, he, 0);
  +    baseNames.argv = he->p.argv;
  +    count = he->c;
  +
  +    if (!xx) {
   	if (fnp) *fnp = NULL;
   	if (fcp) *fcp = 0;
   	return;		/* no file list */
       }
   
  -    xx = headerGetEntry(h, dirNameTag, &dnt, &dirNames, NULL);
  -    xx = headerGetEntry(h, dirIndexesTag, NULL, &dirIndexes, &count);
  +    he->tag = dirNameTag;
  +    xx = headerGet(h, he, 0);
  +    dirNames.argv = he->p.argv;
  +
  +    he->tag = dirIndexesTag;
  +    xx = headerGet(h, he, 0);
  +    dirIndexes.ui32p = he->p.ui32p;
  +    count = he->c;
   
       size = sizeof(*fileNames.argv) * count;
       for (i = 0; i < (unsigned)count; i++) {
  @@ -1538,8 +1598,9 @@
   	t = stpcpy( stpcpy(t, dn), baseNames.argv[i]);
   	*t++ = '\0';
       }
  -    baseNames.ptr = headerFreeData(baseNames.ptr, bnt);
  -    dirNames.ptr = headerFreeData(dirNames.ptr, dnt);
  +    baseNames.ptr = _free(baseNames.ptr);
  +    dirNames.ptr = _free(dirNames.ptr);
  +    dirIndexes.ptr = _free(dirIndexes.ptr);
   
   /*@-onlytrans@*/
       if (fnp)
  @@ -1815,29 +1876,6 @@
   }
   
   /**
  - * Mark a tag container with headerGetEntry() freeData.
  - * @param he		tag container
  - */
  -/*@relnull@*/
  -static HE_t rpmheMark(/*@returned@*/ /*@null@*/ HE_t he)
  -	/*@modifies he @*/
  -{
  -    /* Set he->freeData as appropriate for headerGetEntry() . */
  -    if (he)
  -    switch (he->t) {
  -    default:
  -	he->freeData = 0;
  -	break;
  -    case RPM_I18NSTRING_TYPE:
  -    case RPM_STRING_ARRAY_TYPE:
  -    case RPM_BIN_TYPE:
  -	he->freeData = 1;
  -	break;
  -    }
  -    return he;
  -}
  -
  -/**
    * Clean a tag container, free'ing attached malloc's.
    * @param he		tag container
    */
  @@ -1916,7 +1954,7 @@
       if (hsa != NULL) {
   	hsa->i = 0;
   	if (tag != NULL && tag->tagno == -2)
  -	    hsa->hi = headerInitIterator(hsa->h);
  +	    hsa->hi = headerInit(hsa->h);
       }
   /*@-nullret@*/
       return hsa;
  @@ -1946,12 +1984,11 @@
   	    hsa->i++;
   	} else {
   	    HE_t he = rpmheClean(&tag->he);
  -	    if (!headerNextIterator(hsa->hi, &he->tag, &he->t, &he->p, &he->c))
  +	    if (!headerNext(hsa->hi, he, 0))
   	    {
   		tag->tagno = 0;
   		return NULL;
   	    }
  -	    he = rpmheMark(he);
   	    he->avail = 1;
   	    tag->tagno = he->tag;
   	}
  @@ -1971,7 +2008,7 @@
   	/*@modifies hsa */
   {
       if (hsa != NULL) {
  -	hsa->hi = headerFreeIterator(hsa->hi);
  +	hsa->hi = headerFini(hsa->hi);
   	hsa->i = 0;
       }
   /*@-nullret@*/
  @@ -2481,7 +2518,7 @@
    * @param fn		function
    * @retval he		tag container
    * @retval ec		extension cache
  - * @return		0 on success, 1 on failure
  + * @return		1 on success, 0 on failure
    */
   static int getExtension(headerSprintfArgs hsa, headerTagTagFunction fn,
   		HE_t he, HE_t ec)
  @@ -2497,6 +2534,7 @@
       } else
   	*he = *ec;	/* structure copy. */
       he->freeData = 0;
  +    rc = (rc == 0);	/* XXX invert getExtension return. */
       return rc;
   }
   
  @@ -2523,20 +2561,18 @@
       int xx;
   
       if (!he->avail) {
  -	if (tag->ext) {
  +	if (tag->ext)
   	    xx = getExtension(hsa, tag->ext, he, hsa->ec + tag->extNum);
  -	} else {
  +	else {
   	    he->tag = tag->tagno;	/* XXX necessary? */
   	    xx = headerGet(hsa->h, he, 0);
  -	    if (xx)		/* XXX 1 on success */
  -		he->freeData = 1;
  -	    xx = (xx == 0);	/* XXX invert headerGetEntry return. */
   	}
  -	if (xx) {
  +	if (!xx) {
   	    (void) rpmheClean(he);
   	    he->t = RPM_STRING_TYPE;	
   	    he->p.str = xstrdup("(none)");
   	    he->c = 1;
  +	    he->freeData = 1;
   	}
   	he->avail = 1;
       }
  @@ -2733,13 +2769,9 @@
   		he->tag = tag->tagno;
   		if (tag->ext)
   		    xx = getExtension(hsa, tag->ext, he, hsa->ec + tag->extNum);
  -		else {
  +		else
   		    xx = headerGet(hsa->h, he, 0);
  -		    if (xx)
  -			he->freeData = 1;
  -		    xx = (xx == 0);     /* XXX invert headerGet return. */
  -		}
  -		if (xx) {
  +		if (!xx) {
   		    (void) rpmheClean(he);
   		    continue;
   		}
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/hdrinline.h
  ============================================================================
  $ cvs diff -u -r1.42 -r1.43 hdrinline.h
  --- rpm/rpmdb/hdrinline.h	24 Nov 2007 23:15:33 -0000	1.42
  +++ rpm/rpmdb/hdrinline.h	26 Nov 2007 02:03:10 -0000	1.43
  @@ -224,44 +224,6 @@
   }
   
   /** \ingroup header
  - * Destroy header tag container iterator.
  - * @param hi		header tag container iterator
  - * @return		NULL always
  - */
  -/*@unused@*/ static inline
  -HeaderIterator headerFreeExtension(/*@only@*/ HeaderIterator hi)
  -	/*@modifies hi @*/
  -{
  -    return hdrVec->hdrfreeiter(hi);
  -}
  -
  -/** \ingroup header
  - * Create header tag iterator.
  - * @param h		header
  - * @return		header tag iterator
  - */
  -/*@unused@*/ static inline
  -HeaderIterator headerInitExtension(Header h)
  -	/*@modifies h */
  -{
  -    return hdrVec->hdrinititer(h);
  -}
  -
  -/** \ingroup header
  - * Return next tag from header.
  - * @param hi		header tag iterator
  - * @param he		tag container
  - * @param flags		(unused)
  - * @return		1 on success, 0 on failure
  - */
  -/*@unused@*/ static inline
  -int headerNextExtension(HeaderIterator hi, HE_t he, /*@unused@*/ unsigned int flags)
  -	/*@modifies hi, he @*/
  -{
  -    return hdrVec->hdrnextiter(hi, &he->tag, &he->t, &he->p, &he->c);
  -}
  -
  -/** \ingroup header
    * Retrieve tag value.
    * Will never return RPM_I18NSTRING_TYPE! RPM_STRING_TYPE elements with
    * RPM_I18NSTRING_TYPE equivalent entries are translated (if HEADER_I18NTABLE
  @@ -425,50 +387,6 @@
   }
   
   /** \ingroup header
  - * Destroy header tag iterator.
  - * @param hi		header tag iterator
  - * @return		NULL always
  - */
  -/*@unused@*/ static inline
  -HeaderIterator headerFreeIterator(/*@only@*/ HeaderIterator hi)
  -	/*@modifies hi @*/
  -{
  -    return hdrVec->hdrfreeiter(hi);
  -}
  -
  -/** \ingroup header
  - * Create header tag iterator.
  - * @param h		header
  - * @return		header tag iterator
  - */
  -/*@unused@*/ static inline
  -HeaderIterator headerInitIterator(Header h)
  -	/*@modifies h */
  -{
  -    return hdrVec->hdrinititer(h);
  -}
  -
  -/** \ingroup header
  - * Return next tag from header.
  - * @param hi		header tag iterator
  - * @retval *tag		tag
  - * @retval *type	tag value data type
  - * @retval *p		pointer to tag value(s)
  - * @retval *c		number of values
  - * @return		1 on success, 0 on failure
  - */
  -/*@unused@*/ static inline
  -int headerNextIterator(HeaderIterator hi,
  -		/*@null@*/ /*@out@*/ rpmTag * tag,
  -		/*@null@*/ /*@out@*/ rpmTagType * type,
  -		/*@null@*/ /*@out@*/ rpmTagData * p,
  -		/*@null@*/ /*@out@*/ rpmTagCount * c)
  -	/*@modifies hi, *tag, *type, *p, *c @*/
  -{
  -    return hdrVec->hdrnextiter(hi, tag, type, p, c);
  -}
  -
  -/** \ingroup header
    * Return header magic.
    * @param h		header
    * @param *magicp	magic array
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/header.c
  ============================================================================
  $ cvs diff -u -r1.135 -r1.136 header.c
  --- rpm/rpmdb/header.c	24 Nov 2007 23:15:33 -0000	1.135
  +++ rpm/rpmdb/header.c	26 Nov 2007 02:03:10 -0000	1.136
  @@ -2097,6 +2097,61 @@
   }
   
   /**
  + * Always realloc HE_t memory.
  + * @param he		tag container
  + * @return		1 on success, 0 on failure
  + */
  +static int rpmheRealloc(HE_t he)
  +	/*@modifies he @*/
  +{
  +    size_t nb = 0;
  +    int rc = 1;		/* assume success */
  +
  +    switch (he->t) {
  +    default:
  +assert(0);	/* XXX stop unimplemented oversights. */
  +	break;
  +    case RPM_BIN_TYPE:
  +	he->freeData = 1;	/* XXX RPM_BIN_TYPE is malloc'd */
  +	/*@fallthrough@*/
  +    case RPM_UINT8_TYPE:
  +	nb = he->c * sizeof(*he->p.ui8p);
  +	break;
  +    case RPM_UINT16_TYPE:
  +	nb = he->c * sizeof(*he->p.ui16p);
  +	break;
  +    case RPM_UINT32_TYPE:
  +	nb = he->c * sizeof(*he->p.ui32p);
  +	break;
  +    case RPM_UINT64_TYPE:
  +	nb = he->c * sizeof(*he->p.ui64p);
  +	break;
  +    case RPM_I18NSTRING_TYPE:
  +assert(he->c == 1);	/* XXX stop unimplemented oversights. */
  +	/*@fallthrough@*/
  +    case RPM_STRING_TYPE:
  +	if (he->p.str)
  +	    nb = strlen(he->p.str) + 1;
  +	else
  +	    rc = 0;
  +	break;
  +    case RPM_STRING_ARRAY_TYPE:
  +	break;
  +    }
  +
  +    /* Allocate all returned storage (if not already). */
  +    if (he->p.ptr && nb && !he->freeData) {
  +	void * ptr = memcpy(xmalloc(nb), he->p.ptr, nb);
  +	he->p.ptr = ptr;
  +    }
  +
  +    if (rc)
  +	he->freeData = 1;
  +
  +    return rc;
  +}
  +
  +/**
    * Header tag iterator data structure.
    */
   struct headerIterator_s {
  @@ -2104,14 +2159,7 @@
       size_t next_index;	/*!< Next tag index. */
   };
   
  -/** \ingroup header
  - * Destroy header tag iterator.
  - * @param hi		header tag iterator
  - * @return		NULL always
  - */
  -static /*@null@*/
  -HeaderIterator headerFreeIterator(/*@only@*/ HeaderIterator hi)
  -	/*@modifies hi @*/
  +HeaderIterator headerFini(/*@only@*/ HeaderIterator hi)
   {
       if (hi != NULL) {
   	hi->h = headerFree(hi->h);
  @@ -2120,14 +2168,7 @@
       return hi;
   }
   
  -/** \ingroup header
  - * Create header tag iterator.
  - * @param h		header
  - * @return		header tag iterator
  - */
  -static
  -HeaderIterator headerInitIterator(Header h)
  -	/*@modifies h */
  +HeaderIterator headerInit(Header h)
   {
       HeaderIterator hi = xmalloc(sizeof(*hi));
   
  @@ -2138,24 +2179,7 @@
       return hi;
   }
   
  -/** \ingroup header
  - * Return next tag from header.
  - * @param hi		header tag iterator
  - * @retval *tag		tag
  - * @retval *type	tag value data type
  - * @retval *p		pointer to tag value(s)
  - * @retval *c		number of values
  - * @return		1 on success, 0 on failure
  - */
  -static
  -int headerNextIterator(HeaderIterator hi,
  -		/*@null@*/ /*@out@*/ rpmTag * tag,
  -		/*@null@*/ /*@out@*/ rpmTagType * type,
  -		/*@null@*/ /*@out@*/ rpmTagData * p,
  -		/*@null@*/ /*@out@*/ rpmTagCount * c)
  -	/*@modifies hi, *tag, *type, *p, *c @*/
  -	/*@requires maxSet(tag) >= 0 /\ maxSet(type) >= 0
  -		/\ maxSet(p) >= 0 /\ maxSet(c) >= 0 @*/
  +int headerNext(HeaderIterator hi, HE_t he, /*@unused@*/ unsigned int flags)
   {
       void * sw;
       Header h = hi->h;
  @@ -2163,6 +2187,9 @@
       indexEntry entry = NULL;
       int rc;
   
  +    /* Insure that *he is reliably initialized. */
  +    memset(he, 0, sizeof(*he));
  +
       for (slot = hi->next_index; slot < h->indexUsed; slot++) {
   	entry = h->index + slot;
   	if (!ENTRY_IS_REGION(entry))
  @@ -2172,17 +2199,15 @@
       if (entry == NULL || slot >= h->indexUsed)
   	return 0;
   
  -    /*@-noeffect@*/	/* LCL: no clue */
       hi->next_index++;
  -    /*@=noeffect@*/
   
       if ((sw = headerGetStats(h, 19)) != NULL)	/* RPMTS_OP_HDRGET */
   	(void) rpmswEnter(sw, 0);
   
  -    if (tag)
  -	*tag = entry->info.tag;
  -
  -    rc = copyEntry(entry, (rpmTagType *)type, (rpmTagData *)p, (rpmTagCount *)c, 0);
  +    he->tag = entry->info.tag;
  +    rc = copyEntry(entry, &he->t, &he->p, &he->c, 0);
  +    if (rc)
  +	rc = rpmheRealloc(he);
   
       if (sw != NULL)	(void) rpmswExit(sw, 0);
   
  @@ -2203,13 +2228,13 @@
       Header nh = headerNew();
       HeaderIterator hi;
      
  -    for (hi = headerInitIterator(h);
  -	headerNextIterator(hi, &he->tag, &he->t, &he->p, &he->c);
  -	he->p.ptr = headerFreeData(he->p.ptr, he->t))
  +    for (hi = headerInit(h);
  +	headerNext(hi, he, 0);
  +	he->p.ptr = _free(he->p.ptr))
       {
   	if (he->p.ptr) (void) headerAddEntry(nh, he->tag, he->t, he->p.ptr, he->c);
       }
  -    hi = headerFreeIterator(hi);
  +    hi = headerFini(hi);
   
       return headerReload(nh, HEADER_IMAGE);
   }
  @@ -2224,21 +2249,21 @@
   void headerCopyTags(Header headerFrom, Header headerTo, rpmTag * tagstocopy)
   	/*@modifies headerTo @*/
   {
  +    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
       rpmTag * tagno;
  +    int xx;
   
       if (headerFrom == headerTo)
   	return;
   
       for (tagno = tagstocopy; *tagno != 0; tagno++) {
  -	rpmTagType t;
  -	rpmTagData p = { .ptr = NULL };
  -	rpmTagCount c;
   	if (headerIsEntry(headerTo, *tagno))
   	    continue;
  -	if (!headerGetEntry(headerFrom, *tagno, &t, &p, &c))
  +	he->tag = *tagno;
  +	if (!headerGet(headerFrom, he, 0))
   	    continue;
  -	(void) headerAddEntry(headerTo, *tagno, t, p.ptr, c);
  -	p.ptr = headerFreeData(p.ptr, t);
  +	xx = headerPut(headerTo, he, 0);
  +	he->p.ptr = _free(he->p.ptr);
       }
   }
   
  @@ -2266,9 +2291,6 @@
       headerModifyEntry,
       headerRemoveEntry,
       headerCopyTags,
  -    headerFreeIterator,
  -    headerInitIterator,
  -    headerNextIterator,
       headerGetMagic,
       headerSetMagic,
       headerGetOrigin,
  @@ -2291,11 +2313,16 @@
       const char * name;
       headerSprintfExtension exts = headerCompoundFormats;
       headerSprintfExtension ext;
  -    size_t nb = 0;
       int extNum;
       int rc;
   
       if (h == NULL || he == NULL)	return 0;	/* XXX this is nutty. */
  +
  +    /* Insure that *he is reliably initialized. */
  +    {	rpmTag tag = he->tag;
  +	memset(he, 0, sizeof(*he));
  +	he->tag = tag;
  +    }
       name = tagName(he->tag);
   
       if ((sw = headerGetStats(h, 19)) != NULL)	/* RPMTS_OP_HDRGET */
  @@ -2311,53 +2338,15 @@
   	    break;
       }
   
  -    if (ext && ext->name != NULL && ext->type == HEADER_EXT_TAG)
  +    if (ext && ext->name != NULL && ext->type == HEADER_EXT_TAG) {
   	rc = ext->u.tagFunction(h, he);
  -    else
  +	rc = (rc == 0);		/* XXX invert extension return. */
  +    } else
   	rc = intGetEntry(h, he->tag, &he->t, &he->p, &he->c, 0);
   
  -    if (!rc)
  -	goto exit;
  -
  -    switch (he->t) {
  -    default:
  -assert(0);	/* XXX stop unimplemented oversights. */
  -	break;
  -    case RPM_BIN_TYPE:
  -	he->freeData = 1;	/* XXX RPM_BIN_TYPE is malloc'd */
  -	/*@fallthrough@*/
  -    case RPM_UINT8_TYPE:
  -	nb = he->c * sizeof(*he->p.ui8p);
  -	break;
  -    case RPM_UINT16_TYPE:
  -	nb = he->c * sizeof(*he->p.ui16p);
  -	break;
  -    case RPM_UINT32_TYPE:
  -	nb = he->c * sizeof(*he->p.ui32p);
  -	break;
  -    case RPM_UINT64_TYPE:
  -	nb = he->c * sizeof(*he->p.ui64p);
  -	break;
  -    case RPM_I18NSTRING_TYPE:
  -assert(he->c == 1);	/* XXX stop unimplemented oversights. */
  -	/*@fallthrough@*/
  -    case RPM_STRING_TYPE:
  -	if (he->p.str)
  -	    nb = strlen(he->p.str) + 1;
  -	else
  -	    rc = 0;
  -	break;
  -    case RPM_STRING_ARRAY_TYPE:
  -	break;
  -    }
  -
  -    /* Allocate all returned storage (if not already). */
  -    if (he->p.ptr && nb && !he->freeData) {
  -	void * ptr = memcpy(xmalloc(nb), he->p.ptr, nb);
  -	he->p.ptr = ptr;
  -    }
  +    if (rc)
  +	rc = rpmheRealloc(he);
   
  -exit:
       if (sw != NULL)	(void) rpmswExit(sw, 0);
   
   #if defined(SUPPORT_IMPLICIT_TAG_DATA_TYPES)
  @@ -2368,6 +2357,12 @@
   /*@=modfilesys@*/
   #endif
   
  +    if (!((rc == 0 && he->freeData == 0 && he->p.ptr == NULL) ||
  +	  (rc == 1 && he->freeData == 1 && he->p.ptr != NULL)))
  +    {
  +fprintf(stderr, "==> %s(%u) %u %p[%u] free %u rc %d\n", name, (unsigned) he->tag, (unsigned) he->t, he->p.ptr, (unsigned) he->c, he->freeData, rc);
  +    }
  +
       return rc;
   }
   
  @@ -2386,7 +2381,6 @@
   	rc = headerAddOrAppendEntry(h, he->tag, he->t, he->p.ptr, he->c);
       else
   	rc = headerAddEntry(h, he->tag, he->t, he->p.ptr, he->c);
  -assert(rc == 1);
   
       return rc;
   }
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/header.h
  ============================================================================
  $ cvs diff -u -r1.76 -r1.77 header.h
  --- rpm/rpmdb/header.h	24 Nov 2007 23:15:33 -0000	1.76
  +++ rpm/rpmdb/header.h	26 Nov 2007 02:03:10 -0000	1.77
  @@ -86,17 +86,6 @@
   extern "C" {
   #endif
   
  -/**
  - * Prototype for headerFreeData() vector.
  - *
  - * @param data		address of data (or NULL)
  - * @param type		type of data (or -1 to force free)
  - * @return		NULL always
  - */
  -typedef /*@null@*/
  -    void * (*HFD_t) (/*@only@*/ /*@null@*/ const void * data, rpmTagType type)
  -	/*@modifies data @*/;
  -
   /** \ingroup header
    * Create new (empty) header instance.
    * @return		header
  @@ -360,41 +349,6 @@
   	/*@modifies headerFrom, headerTo @*/;
   
   /** \ingroup header
  - * Destroy header tag iterator.
  - * @param hi		header tag iterator
  - * @return		NULL always
  - */
  -typedef
  -HeaderIterator (*HDRfreeiter) (/*@only@*/ HeaderIterator hi)
  -	/*@modifies hi @*/;
  -
  -/** \ingroup header
  - * Create header tag iterator.
  - * @param h		header
  - * @return		header tag iterator
  - */
  -typedef
  -HeaderIterator (*HDRinititer) (Header h)
  -	/*@modifies h */;
  -
  -/** \ingroup header
  - * Return next tag from header.
  - * @param hi		header tag iterator
  - * @retval *tag		tag
  - * @retval *type	tag value data type
  - * @retval *p		tag value(s)
  - * @retval *c		number of values
  - * @return		1 on success, 0 on failure
  - */
  -typedef
  -int (*HDRnextiter) (HeaderIterator hi,
  -		/*@null@*/ /*@out@*/ rpmTag * tag,
  -		/*@null@*/ /*@out@*/ rpmTagType * type,
  -		/*@null@*/ /*@out@*/ rpmTagData * p,
  -		/*@null@*/ /*@out@*/ rpmTagCount * c)
  -	/*@modifies hi, *tag, *type, *p, *c @*/;
  -
  -/** \ingroup header
    * Return header magic.
    * @param h		header
    * @param *magicp	magic array
  @@ -492,9 +446,6 @@
       HDRmodify	hdrmodify;
       HDRremove	hdrremove;
       HDRcopytags	hdrcopytags;
  -    HDRfreeiter	hdrfreeiter;
  -    HDRinititer	hdrinititer;
  -    HDRnextiter	hdrnextiter;
       HDRgetmagic hdrgetmagic;
       HDRsetmagic hdrsetmagic;
       HDRgetorigin hdrgetorigin;
  @@ -510,33 +461,6 @@
   };
   #endif
   
  -#if !defined(SWIG)
  -/** \ingroup header
  - * Free data allocated when retrieved from header.
  - * @deprecated Use headerFreeTag() instead.
  - * @todo Remove from API.
  - *
  - * @param data		address of data (or NULL)
  - * @param type		type of data (or -1 to force free)
  - * @return		NULL always
  - */
  -/*@unused@*/ static inline /*@null@*/
  -void * headerFreeData( /*@only@*/ /*@null@*/ const void * data, rpmTagType type)
  -	/*@modifies data @*/
  -{
  -    if (data) {
  -	/*@-branchstate@*/
  -	if (type == -1 ||
  -	    type == RPM_STRING_ARRAY_TYPE ||
  -	    type == RPM_I18NSTRING_TYPE ||
  -	    type == RPM_BIN_TYPE)
  -		free((void *)data);
  -	/*@=branchstate@*/
  -    }
  -    return NULL;
  -}
  -#endif
  -
   #if !defined(__HEADER_PROTOTYPES__)
   #include "hdrinline.h"
   #endif
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/librpmdb.vers
  ============================================================================
  $ cvs diff -u -r1.33 -r1.34 librpmdb.vers
  --- rpm/rpmdb/librpmdb.vers	24 Nov 2007 23:15:33 -0000	1.33
  +++ rpm/rpmdb/librpmdb.vers	26 Nov 2007 02:03:10 -0000	1.34
  @@ -31,12 +31,15 @@
       headerCompoundFormats;
       headerDefaultFormats;
       headerDel;
  +    headerFini;
       headerGet;
  +    headerInit;
       headerMacrosLoad;
       headerMacrosUnload;
       headerMergeLegacySigs;
       headerMod;
       headerNEVRA;
  +    headerNext;
       headerPut;
       headerRegenSigHeader;
       headerSprintf;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/rpmdb.c
  ============================================================================
  $ cvs diff -u -r1.221 -r1.222 rpmdb.c
  --- rpm/rpmdb/rpmdb.c	24 Nov 2007 23:15:33 -0000	1.221
  +++ rpm/rpmdb/rpmdb.c	26 Nov 2007 02:03:10 -0000	1.222
  @@ -2893,11 +2893,8 @@
   		/*@notreached@*/ /*@switchbreak@*/ break;
   	    default:
   		xx = headerGet(h, he, 0);
  -		if (!xx) {
  -		    /* XXX FIXME: headerGetExtension shouldn't malloc. */
  -		    he->p.ptr = _free(he->p.ptr);
  +		if (!xx)
   		    continue;
  -		}
   		/*@switchbreak@*/ break;
   
   	    }
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/rpmtag.h
  ============================================================================
  $ cvs diff -u -r1.14 -r1.15 rpmtag.h
  --- rpm/rpmdb/rpmtag.h	24 Nov 2007 23:15:33 -0000	1.14
  +++ rpm/rpmdb/rpmtag.h	26 Nov 2007 02:03:10 -0000	1.15
  @@ -697,6 +697,32 @@
   int headerMod(Header h, HE_t he, /*@unused@*/ unsigned int flags)
   	/*@modifies h @*/;
   
  +/** \ingroup header
  + * Destroy header tag container iterator.
  + * @param hi		header tag container iterator
  + * @return		NULL always
  + */
  +HeaderIterator headerFini(/*@only@*/ HeaderIterator hi)
  +	/*@modifies hi @*/;
  +
  +/** \ingroup header
  + * Create header tag iterator.
  + * @param h		header
  + * @return		header tag iterator
  + */
  +HeaderIterator headerInit(Header h)
  +	/*@modifies h */;
  +
  +/** \ingroup header
  + * Return next tag from header.
  + * @param hi		header tag iterator
  + * @param he		tag container
  + * @param flags		(unused)
  + * @return		1 on success, 0 on failure
  + */
  +int headerNext(HeaderIterator hi, HE_t he, /*@unused@*/ unsigned int flags)
  +	/*@modifies hi, he @*/;
  +
   #ifdef __cplusplus
   }
   #endif
  @@ .
Received on Mon Nov 26 03:03:11 2007
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.