gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r7507 - in Extractor: . src/main src/plugins src/plugins/rp


From: gnunet
Subject: [GNUnet-SVN] r7507 - in Extractor: . src/main src/plugins src/plugins/rpm src/test
Date: Tue, 22 Jul 2008 02:56:49 -0600 (MDT)

Author: grothoff
Date: 2008-07-22 02:56:49 -0600 (Tue, 22 Jul 2008)
New Revision: 7507

Modified:
   Extractor/ChangeLog
   Extractor/README.debian
   Extractor/configure.ac
   Extractor/src/main/extractor.c
   Extractor/src/plugins/Makefile.am
   Extractor/src/plugins/rpm/Makefile.am
   Extractor/src/plugins/rpm/rpmextractor.c
   Extractor/src/plugins/thumbnailextractorqt.cc
   Extractor/src/test/fuzz_default.sh
   Extractor/src/test/fuzz_thumbnail.sh
   Extractor/src/test/mt_plugintest2.c
Log:
use librpm

Modified: Extractor/ChangeLog
===================================================================
--- Extractor/ChangeLog 2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/ChangeLog 2008-07-22 08:56:49 UTC (rev 7507)
@@ -1,3 +1,7 @@
+Tue Jul 22 02:51:33 MDT 2008
+       Changed RPM extractor to use librpm.
+       Fixed crash in OpenOffice extractor.
+
 Sun Jul 13 19:31:35 MDT 2008
        Fixed endianess issues in mp3 extractor.
        Fixed build issues (need to link C++ code explicitly against

Modified: Extractor/README.debian
===================================================================
--- Extractor/README.debian     2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/README.debian     2008-07-22 08:56:49 UTC (rev 7507)
@@ -18,6 +18,7 @@
 libgsf-1-dev
 libmpeg2-4-dev
 libqt4-dev
+librpm-dev
 
 For Subversion access and compilation:
 

Modified: Extractor/configure.ac
===================================================================
--- Extractor/configure.ac      2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/configure.ac      2008-07-22 08:56:49 UTC (rev 7507)
@@ -194,6 +194,11 @@
         AC_DEFINE(HAVE_ZLIB,1,[Have zlib])],
         [AM_CONDITIONAL(HAVE_ZLIB, false)])
 
+AC_CHECK_LIB(rpm, rpmReadPackageFile,
+        [AM_CONDITIONAL(HAVE_LIBRPM, true)
+        AC_DEFINE(HAVE_LIBRPM,1,[Have librpm])],
+        [AM_CONDITIONAL(HAVE_LIBRPM, false)])
+
 AC_CHECK_LIB(bz2, BZ2_decompress,
         [AM_CONDITIONAL(HAVE_BZ2, true)
         AC_DEFINE(HAVE_LIBBZ2,1,[Have libbz2])],

Modified: Extractor/src/main/extractor.c
===================================================================
--- Extractor/src/main/extractor.c      2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/src/main/extractor.c      2008-07-22 08:56:49 UTC (rev 7507)
@@ -787,8 +787,20 @@
             void **libHandle,
             ExtractMethod * method)
 {
+#if 0
+  lt_dladvise advise;
+#endif
+
   LTDL_MUTEX_LOCK
+#if 0
+  lt_dladvise_init(&advise);
+  lt_dladvise_ext(&advise);
+  lt_dladvise_local(&advise);
+  *libHandle = lt_dlopenadvise (name, &advise);
+  lt_dladvise_destroy(&advise);
+#else
   *libHandle = lt_dlopenext (name);
+#endif
   if (*libHandle == NULL)
     {
 #if DEBUG
@@ -1725,6 +1737,8 @@
   }
 
   buf = malloc(inSize); /* slightly more than needed ;-) */
+  if (buf == NULL)
+    return 1; /* error */
   *out = buf;
 
   pos = 0;

Modified: Extractor/src/plugins/Makefile.am
===================================================================
--- Extractor/src/plugins/Makefile.am   2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/src/plugins/Makefile.am   2008-07-22 08:56:49 UTC (rev 7507)
@@ -6,6 +6,10 @@
 thumbffmpeg=thumbnailffmpeg
 endif
 
+if HAVE_LIBRPM
+rpm=rpm
+endif
+
 if HAVE_GLIB
 if WITH_GSF
  oledir=ole2
@@ -56,7 +60,7 @@
 
 # toggle for development
 # SUBDIRS = . 
-SUBDIRS = $(thumbgtk) $(thumbffmpeg) . $(oodir) $(printdir) hash $(oledir) rpm 
$(xpdfdir) $(exiv2dir)
+SUBDIRS = $(thumbgtk) $(thumbffmpeg) . $(oodir) $(printdir) hash $(oledir) 
$(rpm) $(xpdfdir) $(exiv2dir) 
 
 
 if HAVE_VORBISFILE

Modified: Extractor/src/plugins/rpm/Makefile.am
===================================================================
--- Extractor/src/plugins/rpm/Makefile.am       2008-07-22 06:26:37 UTC (rev 
7506)
+++ Extractor/src/plugins/rpm/Makefile.am       2008-07-22 08:56:49 UTC (rev 
7507)
@@ -12,5 +12,6 @@
 libextractor_rpm_la_SOURCES = \
  rpmextractor.c
 libextractor_rpm_la_LDFLAGS = \
+ -lrpm \
  $(PLUGINFLAGS)  $(retaincommand) \
  $(WINFLAGS)

Modified: Extractor/src/plugins/rpm/rpmextractor.c
===================================================================
--- Extractor/src/plugins/rpm/rpmextractor.c    2008-07-22 06:26:37 UTC (rev 
7506)
+++ Extractor/src/plugins/rpm/rpmextractor.c    2008-07-22 08:56:49 UTC (rev 
7507)
@@ -1,6 +1,6 @@
 /*
      This file is part of libextractor.
-     (C) 2002, 2003 Vidyut Samanta and Christian Grothoff
+     (C) 2002, 2003, 2008 Vidyut Samanta and Christian Grothoff
 
      libextractor is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -20,3136 +20,48 @@
 
 #include "platform.h"
 #include "extractor.h"
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <signal.h>
 
-/* someone was using this non-portable function.  Mac OS X
- * doesn't have it so rpmextractor wouldn't load.  I rewrite
- * the function so that it will now work.  below is the
- * original FIXME notice.  -- Filip Pizlo 2003 */
-/* FIXME: replace use of stpcpy to increase portability */
-static char *
-my_stpcpy (char *dest, const char *src)
-{
-  strcpy (dest, src);
-  return dest + strlen (src);
-}
+/* ******************** pipe feeder ************************ */
 
-/* **************** buffer-based IO ************** */
-
-typedef struct
-{
-  char *data;
+struct PipeArgs {                             
+  const char * data;
   size_t pos;
-  size_t len;
-} fdStruct;
-
-typedef fdStruct *FD_t;
-
-static int
-timedRead (FD_t f, void *dst, size_t n)
-{
-  size_t min;
-
-  if (f->len - f->pos >= n)
-    min = n;
-  else
-    min = f->len - f->pos;
-  memcpy (dst, &f->data[f->pos], min);
-  f->pos += min;
-  return min;
-}
-
-/* *************** RPM types ************************ */
-
-typedef int int_32;
-typedef unsigned int uint_32;
-
-
-/**
- * Header private tags.
- * @note General use tags should start at 1000 (RPM's tag space starts there).
- */
-#define        HEADER_IMAGE            61
-#define        HEADER_SIGNATURES       62
-#define        HEADER_IMMUTABLE        63
-#define        HEADER_REGIONS          64
-#define HEADER_I18NTABLE       100
-#define        HEADER_SIGBASE          256
-#define        HEADER_TAGBASE          1000
-
-/**
- * Tags identify data in package headers.
- * @note tags should not have value 0!
- */
-typedef enum rpmTag_e
-{
-
-  RPMTAG_HEADERIMAGE = HEADER_IMAGE,    /*!< Current image. */
-  RPMTAG_HEADERSIGNATURES = HEADER_SIGNATURES,  /*!< Signatures. */
-  RPMTAG_HEADERIMMUTABLE = HEADER_IMMUTABLE,    /*!< Original image. */
-/address@hidden@*/
-  RPMTAG_HEADERREGIONS = HEADER_REGIONS,        /*!< Regions. */
-
-  RPMTAG_HEADERI18NTABLE = HEADER_I18NTABLE,    /*!< I18N string locales. */
-/address@hidden@*/
-
-/* Retrofit (and uniqify) signature tags for use by tagName() and rpmQuery. */
-/* the md5 sum was broken *twice* on big endian machines */
-/* XXX 2nd underscore prevents tagTable generation */
-  RPMTAG_SIG_BASE = HEADER_SIGBASE,
-  RPMTAG_SIGSIZE = RPMTAG_SIG_BASE + 1,
-  RPMTAG_SIGLEMD5_1 = RPMTAG_SIG_BASE + 2,      /*!< internal - obsolate */
-  RPMTAG_SIGPGP = RPMTAG_SIG_BASE + 3,
-  RPMTAG_SIGLEMD5_2 = RPMTAG_SIG_BASE + 4,      /*!< internal - obsolate */
-  RPMTAG_SIGMD5 = RPMTAG_SIG_BASE + 5,
-  RPMTAG_SIGGPG = RPMTAG_SIG_BASE + 6,
-  RPMTAG_SIGPGP5 = RPMTAG_SIG_BASE + 7, /*!< internal - obsolate */
-
-  RPMTAG_BADSHA1_1 = RPMTAG_SIG_BASE + 8,       /*!< internal - obsolate */
-  RPMTAG_BADSHA1_2 = RPMTAG_SIG_BASE + 9,       /*!< internal - obsolate */
-
-  RPMTAG_PUBKEYS = RPMTAG_SIG_BASE + 10,
-  RPMTAG_DSAHEADER = RPMTAG_SIG_BASE + 11,
-  RPMTAG_RSAHEADER = RPMTAG_SIG_BASE + 12,
-  RPMTAG_SHA1HEADER = RPMTAG_SIG_BASE + 13,
-
-  RPMTAG_NAME = 1000,
-  RPMTAG_VERSION = 1001,
-  RPMTAG_RELEASE = 1002,
-  RPMTAG_EPOCH = 1003,
-#define        RPMTAG_SERIAL   RPMTAG_EPOCH    /* backward comaptibility */
-  RPMTAG_SUMMARY = 1004,
-  RPMTAG_DESCRIPTION = 1005,
-  RPMTAG_BUILDTIME = 1006,
-  RPMTAG_BUILDHOST = 1007,
-  RPMTAG_INSTALLTIME = 1008,
-  RPMTAG_SIZE = 1009,
-  RPMTAG_DISTRIBUTION = 1010,
-  RPMTAG_VENDOR = 1011,
-  RPMTAG_GIF = 1012,
-  RPMTAG_XPM = 1013,
-  RPMTAG_LICENSE = 1014,
-#define        RPMTAG_COPYRIGHT RPMTAG_LICENSE /* backward comaptibility */
-  RPMTAG_PACKAGER = 1015,
-  RPMTAG_GROUP = 1016,
-/address@hidden@*/
-  RPMTAG_CHANGELOG = 1017,      /*!< internal */
-/address@hidden@*/
-  RPMTAG_SOURCE = 1018,
-  RPMTAG_PATCH = 1019,
-  RPMTAG_URL = 1020,
-  RPMTAG_OS = 1021,
-  RPMTAG_ARCH = 1022,
-  RPMTAG_PREIN = 1023,
-  RPMTAG_POSTIN = 1024,
-  RPMTAG_PREUN = 1025,
-  RPMTAG_POSTUN = 1026,
-  RPMTAG_OLDFILENAMES = 1027,   /* obsolete */
-  RPMTAG_FILESIZES = 1028,
-  RPMTAG_FILESTATES = 1029,
-  RPMTAG_FILEMODES = 1030,
-  RPMTAG_FILEUIDS = 1031,       /*!< internal */
-  RPMTAG_FILEGIDS = 1032,       /*!< internal */
-  RPMTAG_FILERDEVS = 1033,
-  RPMTAG_FILEMTIMES = 1034,
-  RPMTAG_FILEMD5S = 1035,
-  RPMTAG_FILELINKTOS = 1036,
-  RPMTAG_FILEFLAGS = 1037,
-/address@hidden@*/
-  RPMTAG_ROOT = 1038,           /*!< internal - obsolete */
-/address@hidden@*/
-  RPMTAG_FILEUSERNAME = 1039,
-  RPMTAG_FILEGROUPNAME = 1040,
-/address@hidden@*/
-  RPMTAG_EXCLUDE = 1041,        /*!< internal - obsolete */
-  RPMTAG_EXCLUSIVE = 1042,      /*!< internal - obsolete */
-/address@hidden@*/
-  RPMTAG_ICON = 1043,
-  RPMTAG_SOURCERPM = 1044,
-  RPMTAG_FILEVERIFYFLAGS = 1045,
-  RPMTAG_ARCHIVESIZE = 1046,
-  RPMTAG_PROVIDENAME = 1047,
-#define        RPMTAG_PROVIDES RPMTAG_PROVIDENAME      /* backward 
comaptibility */
-  RPMTAG_REQUIREFLAGS = 1048,
-  RPMTAG_REQUIRENAME = 1049,
-  RPMTAG_REQUIREVERSION = 1050,
-  RPMTAG_NOSOURCE = 1051,       /*!< internal */
-  RPMTAG_NOPATCH = 1052,        /*!< internal */
-  RPMTAG_CONFLICTFLAGS = 1053,
-  RPMTAG_CONFLICTNAME = 1054,
-  RPMTAG_CONFLICTVERSION = 1055,
-  RPMTAG_DEFAULTPREFIX = 1056,  /*!< internal - deprecated */
-  RPMTAG_BUILDROOT = 1057,      /*!< internal */
-  RPMTAG_INSTALLPREFIX = 1058,  /*!< internal - deprecated */
-  RPMTAG_EXCLUDEARCH = 1059,
-  RPMTAG_EXCLUDEOS = 1060,
-  RPMTAG_EXCLUSIVEARCH = 1061,
-  RPMTAG_EXCLUSIVEOS = 1062,
-  RPMTAG_AUTOREQPROV = 1063,    /*!< internal */
-  RPMTAG_RPMVERSION = 1064,
-  RPMTAG_TRIGGERSCRIPTS = 1065,
-  RPMTAG_TRIGGERNAME = 1066,
-  RPMTAG_TRIGGERVERSION = 1067,
-  RPMTAG_TRIGGERFLAGS = 1068,
-  RPMTAG_TRIGGERINDEX = 1069,
-  RPMTAG_VERIFYSCRIPT = 1079,
-  RPMTAG_CHANGELOGTIME = 1080,
-  RPMTAG_CHANGELOGNAME = 1081,
-  RPMTAG_CHANGELOGTEXT = 1082,
-/address@hidden@*/
-  RPMTAG_BROKENMD5 = 1083,      /*!< internal */
-/address@hidden@*/
-  RPMTAG_PREREQ = 1084,         /*!< internal */
-  RPMTAG_PREINPROG = 1085,
-  RPMTAG_POSTINPROG = 1086,
-  RPMTAG_PREUNPROG = 1087,
-  RPMTAG_POSTUNPROG = 1088,
-  RPMTAG_BUILDARCHS = 1089,
-  RPMTAG_OBSOLETENAME = 1090,
-#define        RPMTAG_OBSOLETES RPMTAG_OBSOLETENAME    /* backward 
comaptibility */
-  RPMTAG_VERIFYSCRIPTPROG = 1091,
-  RPMTAG_TRIGGERSCRIPTPROG = 1092,
-  RPMTAG_DOCDIR = 1093,         /*!< internal */
-  RPMTAG_COOKIE = 1094,
-  RPMTAG_FILEDEVICES = 1095,
-  RPMTAG_FILEINODES = 1096,
-  RPMTAG_FILELANGS = 1097,
-  RPMTAG_PREFIXES = 1098,
-  RPMTAG_INSTPREFIXES = 1099,
-  RPMTAG_TRIGGERIN = 1100,      /*!< internal */
-  RPMTAG_TRIGGERUN = 1101,      /*!< internal */
-  RPMTAG_TRIGGERPOSTUN = 1102,  /*!< internal */
-  RPMTAG_AUTOREQ = 1103,        /*!< internal */
-  RPMTAG_AUTOPROV = 1104,       /*!< internal */
-/address@hidden@*/
-  RPMTAG_CAPABILITY = 1105,     /*!< internal - obsolete */
-/address@hidden@*/
-  RPMTAG_SOURCEPACKAGE = 1106,  /*!< internal */
-/address@hidden@*/
-  RPMTAG_OLDORIGFILENAMES = 1107,       /*!< internal - obsolete */
-/address@hidden@*/
-  RPMTAG_BUILDPREREQ = 1108,    /*!< internal */
-  RPMTAG_BUILDREQUIRES = 1109,  /*!< internal */
-  RPMTAG_BUILDCONFLICTS = 1110, /*!< internal */
-/address@hidden@*/
-  RPMTAG_BUILDMACROS = 1111,    /*!< internal */
-/address@hidden@*/
-  RPMTAG_PROVIDEFLAGS = 1112,
-  RPMTAG_PROVIDEVERSION = 1113,
-  RPMTAG_OBSOLETEFLAGS = 1114,
-  RPMTAG_OBSOLETEVERSION = 1115,
-  RPMTAG_DIRINDEXES = 1116,
-  RPMTAG_BASENAMES = 1117,
-  RPMTAG_DIRNAMES = 1118,
-  RPMTAG_ORIGDIRINDEXES = 1119, /*!< internal */
-  RPMTAG_ORIGBASENAMES = 1120,  /*!< internal */
-  RPMTAG_ORIGDIRNAMES = 1121,   /*!< internal */
-  RPMTAG_OPTFLAGS = 1122,
-  RPMTAG_DISTURL = 1123,
-  RPMTAG_PAYLOADFORMAT = 1124,
-  RPMTAG_PAYLOADCOMPRESSOR = 1125,
-  RPMTAG_PAYLOADFLAGS = 1126,
-  RPMTAG_MULTILIBS = 1127,
-  RPMTAG_INSTALLTID = 1128,
-  RPMTAG_REMOVETID = 1129,
-  RPMTAG_SHA1RHN = 1130,        /*!< internal */
-  RPMTAG_RHNPLATFORM = 1131,
-  RPMTAG_PLATFORM = 1132,
-/address@hidden@*/
-  RPMTAG_FIRSTFREE_TAG          /*!< internal */
-/address@hidden@*/
-} rpmTag;
-
-#define        RPMTAG_EXTERNAL_TAG             1000000
-
-/** \ingroup signature
- * Tags found in signature header from package.
- */
-enum rpmtagSignature
-{
-  RPMSIGTAG_SIZE = 1000,        /*!< Header+Payload size in bytes. */
-/* the md5 sum was broken *twice* on big endian machines */
-  RPMSIGTAG_LEMD5_1 = 1001,     /*!< Broken MD5, take 1 */
-  RPMSIGTAG_PGP = 1002,         /*!< PGP 2.6.3 signature. */
-  RPMSIGTAG_LEMD5_2 = 1003,     /*!< Broken MD5, take 2 */
-  RPMSIGTAG_MD5 = 1004,         /*!< MD5 signature. */
-  RPMSIGTAG_GPG = 1005,         /*!< GnuPG signature. */
-  RPMSIGTAG_PGP5 = 1006,        /*!< PGP5 signature @deprecated legacy. */
-  RPMSIGTAG_PAYLOADSIZE = 1007,
-  /*!< uncompressed payload size in bytes. */
-  RPMSIGTAG_BADSHA1_1 = RPMTAG_BADSHA1_1,       /*!< Broken SHA1, take 1. */
-  RPMSIGTAG_BADSHA1_2 = RPMTAG_BADSHA1_2,       /*!< Broken SHA1, take 2. */
-  RPMSIGTAG_SHA1 = RPMTAG_SHA1HEADER,   /*!< sha1 header digest. */
-  RPMSIGTAG_DSA = RPMTAG_DSAHEADER,     /*!< DSA header signature. */
-  RPMSIGTAG_RSA = RPMTAG_RSAHEADER      /*!< RSA header signature. */
+  size_t size;
+  int pi[2];
+  int shutdown;
 };
 
-/**
- * Dependency Attributes.
- */
-typedef enum rpmsenseFlags_e
-{
-  RPMSENSE_ANY = 0,
-/address@hidden@*/
-  RPMSENSE_SERIAL = (1 << 0),   /*!< @todo Legacy. */
-/address@hidden@*/
-  RPMSENSE_LESS = (1 << 1),
-  RPMSENSE_GREATER = (1 << 2),
-  RPMSENSE_EQUAL = (1 << 3),
-  RPMSENSE_PROVIDES = (1 << 4), /* only used internally by builds */
-  RPMSENSE_CONFLICTS = (1 << 5),        /* only used internally by builds */
-  RPMSENSE_PREREQ = (1 << 6),   /*!< @todo Legacy. */
-  RPMSENSE_OBSOLETES = (1 << 7),        /* only used internally by builds */
-  RPMSENSE_INTERP = (1 << 8),   /*!< Interpreter used by scriptlet. */
-  RPMSENSE_SCRIPT_PRE = ((1 << 9) | RPMSENSE_PREREQ),   /*!< %pre dependency. 
*/
-  RPMSENSE_SCRIPT_POST = ((1 << 10) | RPMSENSE_PREREQ), /*!< %post dependency. 
*/
-  RPMSENSE_SCRIPT_PREUN = ((1 << 11) | RPMSENSE_PREREQ),        /*!< %preun 
dependency. */
-  RPMSENSE_SCRIPT_POSTUN = ((1 << 12) | RPMSENSE_PREREQ),       /*!< %postun 
dependency. */
-  RPMSENSE_SCRIPT_VERIFY = (1 << 13),   /*!< %verify dependency. */
-  RPMSENSE_FIND_REQUIRES = (1 << 14),   /*!< find-requires generated 
dependency. */
-  RPMSENSE_FIND_PROVIDES = (1 << 15),   /*!< find-provides generated 
dependency. */
-
-  RPMSENSE_TRIGGERIN = (1 << 16),       /*!< %triggerin dependency. */
-  RPMSENSE_TRIGGERUN = (1 << 17),       /*!< %triggerun dependency. */
-  RPMSENSE_TRIGGERPOSTUN = (1 << 18),   /*!< %triggerpostun dependency. */
-  RPMSENSE_MULTILIB = (1 << 19),
-  RPMSENSE_SCRIPT_PREP = (1 << 20),     /*!< %prep build dependency. */
-  RPMSENSE_SCRIPT_BUILD = (1 << 21),    /*!< %build build dependency. */
-  RPMSENSE_SCRIPT_INSTALL = (1 << 22),  /*!< %install build dependency. */
-  RPMSENSE_SCRIPT_CLEAN = (1 << 23),    /*!< %clean build dependency. */
-  RPMSENSE_RPMLIB = ((1 << 24) | RPMSENSE_PREREQ),      /*!< rpmlib(feature) 
dependency. */
-/address@hidden@*/
-  RPMSENSE_TRIGGERPREIN = (1 << 25),    /*!< @todo Implement %triggerprein. */
-/address@hidden@*/
-
-/address@hidden@*/
-  RPMSENSE_KEYRING = (1 << 26)
-/address@hidden@*/
-} rpmsenseFlags;
-
-/** \ingroup header
- * Include calculation for 8 bytes of (magic, 0)?
- */
-enum hMagic
-{
-  HEADER_MAGIC_NO = 0,
-  HEADER_MAGIC_YES = 1
-};
-
-/**
- * Package read return codes.
- */
-typedef enum rpmRC_e
-{
-  RPMRC_OK = 0,
-  RPMRC_BADMAGIC = 1,
-  RPMRC_FAIL = 2,
-  RPMRC_BADSIZE = 3,
-  RPMRC_SHORTREAD = 4
-} rpmRC;
-
-/** \ingroup header
- * The basic types of data in tags from headers.
- */
-typedef enum rpmTagType_e
-{
-#define        RPM_MIN_TYPE            0
-  RPM_NULL_TYPE = 0,
-  RPM_CHAR_TYPE = 1,
-  RPM_INT8_TYPE = 2,
-  RPM_INT16_TYPE = 3,
-  RPM_INT32_TYPE = 4,
-/*    RPM_INT64_TYPE   = 5,   ---- These aren't supported (yet) */
-  RPM_STRING_TYPE = 6,
-  RPM_BIN_TYPE = 7,
-  RPM_STRING_ARRAY_TYPE = 8,
-  RPM_I18NSTRING_TYPE = 9
-#define        RPM_MAX_TYPE            9
-} rpmTagType;
-
-/*
- * Teach header.c about legacy tags.
- */
-#define        HEADER_OLDFILENAMES     1027
-#define        HEADER_BASENAMES        1117
-
-#define        REGION_TAG_TYPE         RPM_BIN_TYPE
-#define        REGION_TAG_COUNT        sizeof(struct entryInfo)
-
-#define        RPMLEAD_BINARY 0
-#define        RPMLEAD_SOURCE 1
-
-#define        RPMLEAD_MAGIC0 0xed
-#define        RPMLEAD_MAGIC1 0xab
-#define        RPMLEAD_MAGIC2 0xee
-#define        RPMLEAD_MAGIC3 0xdb
-
-#define        RPMLEAD_SIZE 96         /*!< Don't rely on sizeof(struct) */
-
-/** \ingroup header
- * Maximum no. of bytes permitted in a header.
- */
-/address@hidden@*/
-static size_t headerMaxbytes = (32 * 1024 * 1024);
-
-/** \ingroup lead
- * The lead data structure.
- * The lead needs to be 8 byte aligned.
- * @deprecated The lead (except for signature_type) is legacy.
- * @todo Don't use any information from lead.
- */
-struct rpmlead
-{
-  unsigned char magic[4];
-  unsigned char major, minor;
-  short type;
-  short archnum;
-  char name[66];
-  short osnum;
-  short signature_type;         /*!< Signature header type (RPMSIG_HEADERSIG) 
*/
-                                        /address@hidden@*/ char reserved[16];
-                                        /*!< Pad to 96 bytes -- 8 byte aligned 
*/
-};
-
-/** \ingroup header
- * Alignment needs (and sizeof scalars types) for internal rpm data types.
- */
-               /address@hidden@*//address@hidden@ */
-static int typeSizes[] = {
-  0,                            /*!< RPM_NULL_TYPE */
-  1,                            /*!< RPM_CHAR_TYPE */
-  1,                            /*!< RPM_INT8_TYPE */
-  2,                            /*!< RPM_INT16_TYPE */
-  4,                            /*!< RPM_INT32_TYPE */
-  -1,                           /*!< RPM_INT64_TYPE */
-  -1,                           /*!< RPM_STRING_TYPE */
-  1,                            /*!< RPM_BIN_TYPE */
-  -1,                           /*!< RPM_STRING_ARRAY_TYPE */
-  -1                            /*!< RPM_I18NSTRING_TYPE */
-};
-
-/** \ingroup header
- */
-enum headerSprintfExtenstionType
-{
-  HEADER_EXT_LAST = 0,          /*!< End of extension chain. */
-  HEADER_EXT_FORMAT,            /*!< headerTagFormatFunction() extension */
-  HEADER_EXT_MORE,              /*!< Chain to next table. */
-  HEADER_EXT_TAG                /*!< headerTagTagFunction() extension */
-};
-
-/** \ingroup signature
- * Signature types stored in rpm lead.
- */
-typedef enum sigType_e
-{
-  RPMSIGTYPE_NONE = 0,          /*!< unused, legacy. */
-  RPMSIGTYPE_PGP262_1024 = 1,   /*!< unused, legacy. */
-/address@hidden@*/
-  RPMSIGTYPE_BAD = 2,           /*!< Unknown signature type. */
-/address@hidden@*/
-  RPMSIGTYPE_MD5 = 3,           /*!< unused, legacy. */
-  RPMSIGTYPE_MD5_PGP = 4,       /*!< unused, legacy. */
-  RPMSIGTYPE_HEADERSIG = 5,     /*!< Header style signature */
-  RPMSIGTYPE_DISABLE = 6        /*!< Disable verification (debugging only) */
-} sigType;
-
-/** \ingroup header
- * HEADER_EXT_TAG format function prototype.
- * This will only ever be passed RPM_INT32_TYPE or RPM_STRING_TYPE to
- * help keep things simple.
- *
- * @param type         tag type
- * @param data         tag value
- * @param formatPrefix
- * @param padding
- * @param element
- * @return             formatted string
- */
-typedef /*only@ */ char *(*headerTagFormatFunction) (int_32 type,
-                                                     const void *data,
-                                                     char *formatPrefix,
-                                                     int padding,
-                                                     int element);
-
-
-/** \ingroup header
- * Associate tag names with numeric values.
- */
-typedef /address@hidden@ */ struct headerTagTableEntry_s *headerTagTableEntry;
-struct headerTagTableEntry_s
-{
-                                                
/address@hidden@*//address@hidden@ */ const char *name;
-                                                /*!< Tag name. */
-  int val;                      /*!< Tag numeric value. */
-};
-
-/** \ingroup header
- */
-typedef /address@hidden@ */ struct headerIteratorS *HeaderIterator;
-
-/** \ingroup header
- */
-typedef /address@hidden@ *//address@hidden@ */ struct headerToken *Header;
-
-
-typedef int_32 *hTYP_t;
-typedef const void *hPTR_t;
-typedef int_32 *hCNT_t;
-
-/** \ingroup header
- * HEADER_EXT_FORMAT format function prototype.
- * This is allowed to fail, which indicates the tag doesn't exist.
- *
- * @param h            header
- * @retval type                address of tag type
- * @retval data                address of tag value pointer
- * @retval count       address of no. of data items
- * @retval freedata    address of data-was-malloc'ed indicator
- * @return             0 on success
- */
-typedef int (*headerTagTagFunction) (Header h,
-                                     /address@hidden@ *//address@hidden@ */ 
hTYP_t type,
-                                     /address@hidden@ *//address@hidden@ */ 
hPTR_t * data,
-                                     /address@hidden@ *//address@hidden@ */ 
hCNT_t count,
-                                     /address@hidden@ *//address@hidden@ */ 
int *freeData);
-
-/** \ingroup header
- * Define header tag output formats.
- */
-typedef /address@hidden@ */ struct headerSprintfExtension_s
-  *headerSprintfExtension;
-struct headerSprintfExtension_s
-{
-  enum headerSprintfExtenstionType type;        /*!< Type of extension. */
-  /address@hidden@*//address@hidden@ */
-  const char *name;             /*!< Name of extension. */
-  union
-  {
-    /address@hidden@*//address@hidden@ */
-    void *generic;              /*!< Private extension. */
-    headerTagFormatFunction formatFunction;     /*!< HEADER_EXT_TAG extension. 
*/
-    headerTagTagFunction tagFunction;   /*!< HEADER_EXT_FORMAT extension. */
-    struct headerSprintfExtension_s *more;      /*!< Chained table extension. 
*/
-  } u;
-};
-
-/** \ingroup header
- * Create new (empty) header instance.
- * @return             header
- */
-typedef Header (*HDRnew) (void)
-        /*@ */ ;
-
-/** \ingroup header
- * Dereference a header instance.
- * @param h            header
- * @return             NULL always
- */
-typedef
-/address@hidden@*/ Header (*HDRfree) ( /address@hidden@ *//address@hidden@ */ 
Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Reference a header instance.
- * @param h            header
- * @return             referenced header instance
- */
-typedef Header (*HDRlink) (Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Dereference a header instance.
- * @param h            header
- * @return             NULL always
- */
-typedef Header (*HDRunlink) ( /address@hidden@ *//address@hidden@ */ Header h)
-         /address@hidden h @ */ ;
-
-/** \ingroup header
- * Sort tags in header.
- * @todo Eliminate from API.
- * @param h            header
- */
-typedef void (*HDRsort) (Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Restore tags in header to original ordering.
- * @todo Eliminate from API.
- * @param h            header
- */
-typedef void (*HDRunsort) (Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Return size of on-disk header representation in bytes.
- * @param h            header
- * @param magicp       include size of 8 bytes for (magic, 0)?
- * @return             size of on-disk header
- */
-typedef unsigned int (*HDRsizeof) ( /address@hidden@ */ Header h, enum hMagic 
magicp)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Convert header to on-disk representation.
- * @param h            header (with pointers)
- * @return             on-disk header blob (i.e. with offsets)
- */
-typedef
-           /address@hidden@*//address@hidden@ */ void *(*HDRunload) (Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Convert header to on-disk representation, and then reload.
- * This is used to insure that all header data is in one chunk.
- * @param h            header (with pointers)
- * @param tag          region tag
- * @return             on-disk header (with offsets)
- */
-typedef
-/address@hidden@*/ Header (*HDRreload) ( /address@hidden@ */ Header h, int tag)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Duplicate a header.
- * @param h            header
- * @return             new header instance
- */
-typedef Header (*HDRcopy) (Header h)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Convert header to in-memory representation.
- * @param uh           on-disk header blob (i.e. with offsets)
- * @return             header
- */
-typedef
-/address@hidden@*/ Header (*HDRload) ( /address@hidden@ */ void *uh)
-        /address@hidden uh @ */ ;
-
-/** \ingroup header
- * Make a copy and convert header to in-memory representation.
- * @param uh           on-disk header blob (i.e. with offsets)
- * @return             header
- */
-typedef
-/address@hidden@*/ Header (*HDRcopyload) (const void *uh)
-        /*@ */ ;
-
-/** \ingroup header
- * Read (and load) header from file handle.
- * @param fd           file handle
- * @param magicp       read (and verify) 8 bytes of (magic, 0)?
- * @return             header (or NULL on error)
- */
-typedef
-/address@hidden@*/ Header (*HDRhdrread) (FD_t fd, enum hMagic magicp)
-        /address@hidden fd @ */ ;
-
-/** \ingroup header
- * Write (with unload) header to file handle.
- * @param fd           file handle
- * @param h            header
- * @param magicp       prefix write with 8 bytes of (magic, 0)?
- * @return             0 on success, 1 on error
- */
-typedef int (*HDRhdrwrite) (FD_t fd, /address@hidden@ */ Header h, enum hMagic 
magicp)
-        /address@hidden fileSystem @ */
-        /address@hidden fd, h, fileSystem @ */ ;
-
-/** \ingroup header
- * Check if tag is in header.
- * @param h            header
- * @param tag          tag
- * @return             1 on success, 0 on failure
- */
-typedef int (*HDRisentry) ( /address@hidden@ */ Header h, int_32 tag)
-        /*@ */ ;
-
-/** \ingroup header
- * Free data allocated when retrieved from header.
- * @param h            header
- * @param data         address of data (or NULL)
- * @param type         type of data (or -1 to force free)
- * @return             NULL always
- */
-typedef
-/address@hidden@*/ void *(*HDRfreetag) (Header h,
-                                /address@hidden@ *//address@hidden@ */ const 
void *data,
-                                rpmTagType type)
-        /address@hidden data @ */ ;
-
-/** \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
- * entry is present).
- *
- * @param h            header
- * @param tag          tag
- * @retval type                address of tag value data type (or NULL)
- * @retval p           address of pointer to tag value(s) (or NULL)
- * @retval c           address of number of values (or NULL)
- * @return             1 on success, 0 on failure
- */
-typedef int (*HDRget) (Header h, int_32 tag,
-                       /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                       /address@hidden@ *//address@hidden@ */ void **p,
-                       /address@hidden@ *//address@hidden@ */ hCNT_t c)
-        /address@hidden *type, *p, *c @ */ ;
-
-/** \ingroup header
- * Retrieve tag value using header internal array.
- * Get an entry using as little extra RAM as possible to return the tag value.
- * This is only an issue for RPM_STRING_ARRAY_TYPE.
- *
- * @param h            header
- * @param tag          tag
- * @retval type                address of tag value data type (or NULL)
- * @retval p           address of pointer to tag value(s) (or NULL)
- * @retval c           address of number of values (or NULL)
- * @return             1 on success, 0 on failure
- */
-typedef int (*HDRgetmin) (Header h, int_32 tag,
-                          /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                          /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-                          /address@hidden@ *//address@hidden@ */ hCNT_t c)
-        /address@hidden *type, *p, *c @ */ ;
-
-/** \ingroup header
- * Add tag to header.
- * Duplicate tags are okay, but only defined for iteration (with the
- * exceptions noted below). While you are allowed to add i18n string
- * arrays through this function, you probably don't mean to. See
- * headerAddI18NString() instead.
- *
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-typedef
-  int (*HDRadd) (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Append element to tag array in header.
- * Appends item p to entry w/ tag and type as passed. Won't work on
- * RPM_STRING_TYPE. Any pointers into header memory returned from
- * headerGetEntryMinMemory() for this entry are invalid after this
- * call has been made!
- *
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-typedef
-  int (*HDRappend) (Header h, int_32 tag, int_32 type, const void *p,
-                    int_32 c)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Add or append element to tag array in header.
- * @todo Arg "p" should have const.
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-typedef
-  int (*HDRaddorappend) (Header h, int_32 tag, int_32 type, const void *p,
-                         int_32 c)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Add locale specific tag to header.
- * A NULL lang is interpreted as the C locale. Here are the rules:
- * \verbatim
- *     - If the tag isn't in the header, it's added with the passed string
- *        as new value.
- *     - If the tag occurs multiple times in entry, which tag is affected
- *        by the operation is undefined.
- *     - If the tag is in the header w/ this language, the entry is
- *        *replaced* (like headerModifyEntry()).
- * \endverbatim
- * This function is intended to just "do the right thing". If you need
- * more fine grained control use headerAddEntry() and headerModifyEntry().
- *
- * @param h            header
- * @param tag          tag
- * @param string       tag value
- * @param lang         locale
- * @return             1 on success, 0 on failure
- */
-typedef
-  int (*HDRaddi18n) (Header h, int_32 tag, const char *string,
-                     const char *lang)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Modify tag in header.
- * If there are multiple entries with this tag, the first one gets replaced.
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-typedef
-  int (*HDRmodify) (Header h, int_32 tag, int_32 type, const void *p,
-                    int_32 c)
-        /address@hidden h @ */ ;
-
-/** \ingroup header
- * Delete tag in header.
- * Removes all entries of type tag from the header, returns 1 if none were
- * found.
- *
- * @param h            header
- * @param tag          tag
- * @return             0 on success, 1 on failure (INCONSISTENT)
- */
-typedef int (*HDRremove) (Header h, int_32 tag)
-        /address@hidden h @ */ ;
-
-                /address@hidden@*//* LCL: no clue */
-/** \ingroup header
- */
-typedef const char *errmsg_t;
-typedef int_32 *hTAG_t;
-
-/** \ingroup header
- * Return formatted output string from header tags.
- * The returned string must be free()d.
- *
- * @param h            header
- * @param fmt          format to use
- * @param tags         array of tag name/value pairs
- * @param extensions   chained table of formatting extensions.
- * @retval errmsg      error message (if any)
- * @return             formatted output string (malloc'ed)
- */
-typedef
-/address@hidden@*/ char *(*HDRhdrsprintf) (Header h, const char *fmt,
-                                   const struct headerTagTableEntry_s * tags,
-                                   const struct headerSprintfExtension_s *
-                                   extensions,
-                                   /address@hidden@ *//address@hidden@ */ 
errmsg_t * errmsg)
-        /address@hidden *errmsg @ */ ;
-
-/** \ingroup header
- * Duplicate tag values from one header into another.
- * @param headerFrom   source header
- * @param headerTo     destination header
- * @param tagstocopy   array of tags that are copied
- */
-typedef
-  void (*HDRcopytags) (Header headerFrom, Header headerTo, hTAG_t tagstocopy)
-        /address@hidden headerFrom, headerTo @ */ ;
-
-/** \ingroup header
- * Destroy header tag iterator.
- * @param hi           header tag iterator
- * @return             NULL always
- */
-typedef HeaderIterator (*HDRfreeiter) ( /address@hidden@ */ HeaderIterator hi)
-        /address@hidden hi @ */ ;
-
-/** \ingroup header
- * Create header tag iterator.
- * @param h            header
- * @return             header tag iterator
- */
-typedef HeaderIterator (*HDRinititer) (Header h)
-        /address@hidden h */ ;
-
-/** \ingroup header
- * Return next tag from header.
- * @param hi           header tag iterator
- * @retval tag         address of tag
- * @retval type                address of tag value data type
- * @retval p           address of pointer to tag value(s)
- * @retval c           address of number of values
- * @return             1 on success, 0 on failure
- */
-typedef int (*HDRnextiter) (HeaderIterator hi,
-                            /address@hidden@ *//address@hidden@ */ hTAG_t tag,
-                            /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                            /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-                            /address@hidden@ *//address@hidden@ */ hCNT_t c)
-        /address@hidden hi, *tag, *type, *p, *c @ */ ;
-
-/** \ingroup header
- * Header method vectors.
- */
-typedef /address@hidden@ */ struct HV_s *HV_t;
-struct HV_s
-{
-  HDRnew hdrnew;
-  HDRfree hdrfree;
-  HDRlink hdrlink;
-  HDRsort hdrsort;
-  HDRunsort hdrunsort;
-  HDRsizeof hdrsizeof;
-  HDRunload hdrunload;
-  HDRreload hdrreload;
-  HDRcopy hdrcopy;
-  HDRload hdrload;
-  HDRcopyload hdrcopyload;
-  HDRhdrread hdrread;
-  HDRhdrwrite hdrwrite;
-  HDRisentry hdrisentry;
-  HDRfreetag hdrfreetag;
-  HDRget hdrget;
-  HDRgetmin hdrgetmin;
-  HDRadd hdradd;
-  HDRappend hdrappend;
-  HDRaddorappend hdraddorappend;
-  HDRaddi18n hdraddi18n;
-  HDRmodify hdrmodify;
-  HDRremove hdrremove;
-  HDRhdrsprintf hdrsprintf;
-  HDRcopytags hdrcopytags;
-  HDRfreeiter hdrfreeiter;
-  HDRinititer hdrinititer;
-  HDRnextiter hdrnextiter;
-  HDRunlink hdrunlink;
-/address@hidden@*/
-  void *hdrvecs;
-/address@hidden@*/
-  void *hdrdata;
-  int hdrversion;
-};
-
-/** \ingroup header
- * Description of tag data.
- */
-typedef /address@hidden@ */ struct entryInfo *entryInfo;
-struct entryInfo
-{
-  int_32 tag;                   /*!< Tag identifier. */
-  int_32 type;                  /*!< Tag data type. */
-  int_32 offset;                /*!< Offset into data segment (ondisk only). */
-  int_32 count;                 /*!< Number of tag elements. */
-};
-
-/** \ingroup header
- * A single tag from a Header.
- */
-typedef /address@hidden@ */ struct indexEntry *indexEntry;
-struct indexEntry
-{
-  struct entryInfo info;        /*!< Description of tag data. */
-                                /address@hidden@*/ void *data;
-                                /*!< Location of tag data. */
-  int length;                   /*!< No. bytes of data. */
-  int rdlen;                    /*!< No. bytes of data in region. */
-};
-
-/** \ingroup header
- * The Header data structure.
- */
-struct headerToken
-{
-                                /address@hidden@*/ struct HV_s hv;
-                                /*!< Header public methods. */
-  void *blob;                   /*!< Header region blob. */
-                                /address@hidden@*/ indexEntry index;
-                                /*!< Array of tags. */
-  int indexUsed;                /*!< Current size of tag array. */
-  int indexAlloced;             /*!< Allocated size of tag array. */
-  int flags;
-#define        HEADERFLAG_SORTED       (1 << 0)        /*!< Are header entries 
sorted? */
-#define        HEADERFLAG_ALLOCATED    (1 << 1)        /*!< Is 1st header 
region allocated? */
-#define        HEADERFLAG_LEGACY       (1 << 2)        /*!< Header came from 
legacy source? */
-                                /address@hidden@*/ int nrefs;
-                                /*!< Reference count. */
-};
-
-/**
- * Header tag iterator data structure.
- */
-struct headerIteratorS
-{
-                                /address@hidden@*/ Header h;
-                                /*!< Header being iterated. */
-                                /address@hidden@*/ int next_index;
-                                /*!< Next tag index. */
-};
-
-/address@hidden/
-/* ==================================================================== */
-/** \name RPMTS */
-/address@hidden/
-/**
- * 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                         /address@hidden@ */
-void *(*HFD_t) ( /address@hidden@ *//address@hidden@ */ const void *data, 
rpmTagType type)
-        /address@hidden data @ */ ;
-
-/**
- * Prototype for headerAddEntry() vector.
- * Duplicate tags are okay, but only defined for iteration (with the
- * exceptions noted below). While you are allowed to add i18n string
- * arrays through this function, you probably don't mean to. See
- * headerAddI18NString() instead.
- *
- * @param h             header
- * @param tag           tag
- * @param type          tag value data type
- * @param p             pointer to tag value(s)
- * @param c             number of values
- * @return              1 on success, 0 on failure
- */
-typedef int (*HAE_t) (Header h, rpmTag tag, rpmTagType type,
-                      const void *p, int_32 c)
-        /address@hidden h @ */ ;
-
-/**
- * Prototype for headerGetEntry() vector.
- * Will never return RPM_I18NSTRING_TYPE! RPM_STRING_TYPE elements with
- * RPM_I18NSTRING_TYPE equivalent entries are translated (if HEADER_I18NTABLE
- * entry is present).
- *
- * @param h            header
- * @param tag          tag
- * @retval type                address of tag value data type (or NULL)
- * @retval p           address of pointer to tag value(s) (or NULL)
- * @retval c           address of number of values (or NULL)
- * @return             1 on success, 0 on failure
- */
-typedef int (*HGE_t) (Header h, rpmTag tag,
-                      /address@hidden@ *//address@hidden@ */ rpmTagType * type,
-                      /address@hidden@ *//address@hidden@ */ void **p,
-                      /address@hidden@ *//address@hidden@ */ int_32 * c)
-        /address@hidden *type, *p, *c @ */ ;
-
-/**
- * Prototype for headerRemoveEntry() vector.
- * Delete tag in header.
- * Removes all entries of type tag from the header, returns 1 if none were
- * found.
- *
- * @param h            header
- * @param tag          tag
- * @return             0 on success, 1 on failure (INCONSISTENT)
- */
-typedef int (*HRE_t) (Header h, int_32 tag)
-        /address@hidden h @ */ ;
-
-#define        ENTRY_IS_REGION(_e) \
-       (((_e)->info.tag >= HEADER_IMAGE) && ((_e)->info.tag < HEADER_REGIONS))
-
-
-#define        alloca_strdup(_s)       strcpy(alloca(strlen(_s)+1), (_s))
-
-/**
- * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
- * @param p            memory to free
- * @return             NULL always
- */
-/address@hidden@*/ static /address@hidden@ */ void *
-_free ( /address@hidden@ *//address@hidden@ *//address@hidden@ */ const void 
*p) /address@hidden *p @ */
-{
-  if (p != NULL)
-    free ((void *) p);
-  return NULL;
-}
-
-/**
- */
-static int
-indexCmp (const void *avp, const void *bvp)     /*@ */
-{
-  /address@hidden@ */
-  indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
-  /address@hidden@ */
-  return (ap->info.tag - bp->info.tag);
-}
-
-/** \ingroup header
- * Sort tags in header.
- * @param h            header
- */
-static void
-headerSort (Header h)
-        /address@hidden h @ */
-{
-  if (!(h->flags & HEADERFLAG_SORTED))
-    {
-      qsort (h->index, h->indexUsed, sizeof (*h->index), indexCmp);
-      h->flags |= HEADERFLAG_SORTED;
-    }
-}
-
-/**
- * Remove occurences of trailing character from string.
- * @param s            string
- * @param c            character to strip
- * @return             string
- */
-/address@hidden@*/ static inline
-/address@hidden@*/ char *
-stripTrailingChar ( /address@hidden@ */ char *s, char c)
-        /address@hidden *s */
-{
-  char *t;
-  for (t = s + strlen (s) - 1; *t == c && t >= s; t--)
-    *t = '\0';
-  return s;
-}
-
-/** \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
- */
-                                /address@hidden@*/ static
-                                /address@hidden@ */
-void *
-headerFreeData ( /address@hidden@ *//address@hidden@ */ const void *data, 
rpmTagType type)
-        /address@hidden data @ */
-{
-  if (data)
-    {
-      /address@hidden@ */
-      if (type == -1 ||
-          type == RPM_STRING_ARRAY_TYPE ||
-          type == RPM_I18NSTRING_TYPE || type == RPM_BIN_TYPE)
-        free ((void *) data);
-      /address@hidden@ */
-    }
-  return NULL;
-}
-
-
-/**
- * Return length of entry data.
- * @todo Remove sanity check exit's.
- * @param type         entry data type
- * @param p            entry data
- * @param count                entry item count
- * @param onDisk       data is concatenated strings (with NUL's))?
- * @return             no. bytes in data
- */
-/address@hidden@*/
-static int
-dataLength (int_32 type, hPTR_t p, int_32 count, int onDisk)
-        /*@ */
-{
-  int length = 0;
-
-  switch (type)
-    {
-    case RPM_STRING_TYPE:
-      if (count == 1)
-        {                       /* Special case -- p is just the string */
-          length = strlen (p) + 1;
-          break;
-        }
-      /* This should not be allowed */
-      /address@hidden@ */
-      /address@hidden@ */
-      exit (EXIT_FAILURE);
-      /address@hidden@ */ break;
-
-    case RPM_STRING_ARRAY_TYPE:
-    case RPM_I18NSTRING_TYPE:
-      {
-        int i;
-
-        /* This is like RPM_STRING_TYPE, except it's *always* an array */
-        /* Compute sum of length of all strings, including null terminators */
-        i = count;
-
-        if (onDisk)
-          {
-            const char *chptr = p;
-            int thisLen;
-
-            while (i--)
-              {
-                thisLen = strlen (chptr) + 1;
-                length += thisLen;
-                chptr += thisLen;
-              }
-          }
-        else
-          {
-            const char **src = (const char **) p;
-            while (i--)
-              {
-                /* add one for null termination */
-                length += strlen (*src++) + 1;
-              }
-          }
-      }
-      break;
-
-    default:
-      if (typeSizes[type] != -1)
-        {
-          length = typeSizes[type] * count;
-          break;
-        }
-      /address@hidden@ */
-      /address@hidden@ */
-      exit (EXIT_FAILURE);
-      /address@hidden@ */ break;
-    }
-
-  return length;
-}
-
-/**
- */
-static void
-copyData (int_32 type, /address@hidden@ */ void *dstPtr, const void *srcPtr,
-          int_32 c, int dataLengtha)
-        /address@hidden *dstPtr @ */
-{
-  const char **src;
-  char *dst;
-  int i;
-
-  switch (type)
-    {
-    case RPM_STRING_ARRAY_TYPE:
-    case RPM_I18NSTRING_TYPE:
-      /* Otherwise, p is char** */
-      i = c;
-      src = (const char **) srcPtr;
-      dst = dstPtr;
-      while (i--)
-        {
-          if (*src)
-            {
-              int len = strlen (*src) + 1;
-              memcpy (dst, *src, len);
-              dst += len;
-            }
-          src++;
-        }
-      break;
-
-    default:
-      memmove (dstPtr, srcPtr, dataLengtha);
-      break;
-    }
-}
-
-/**
- * Return (malloc'ed) copy of entry data.
- * @param type         entry data type
- * @param p            entry data
- * @param c            entry item count
- * @retval lengthPtr   no. bytes in returned data
- * @return             (malloc'ed) copy of entry data
- */
 static void *
-grabData (int_32 type, hPTR_t p, int_32 c,
-          /address@hidden@ */ int *lengthPtr)
-        /address@hidden *lengthPtr @ */
+pipe_feeder(void * args)
 {
-  int length = dataLength (type, p, c, 0);
-  void *data = malloc (length);
+  ssize_t ret;
+  struct PipeArgs * p = args;
 
-  copyData (type, data, p, c, length);
-
-  if (lengthPtr)
-    *lengthPtr = length;
-  return data;
+  while ( (p->shutdown == 0) &&
+         (0 < (ret = WRITE(p->pi[1],
+                           &p->data[p->pos],
+                           p->size - p->pos))) )
+         p->pos += ret;
+  return NULL;                     
 }
 
-
-#define        INDEX_MALLOC_SIZE       8
-
-/** \ingroup header
- * Add tag to header.
- * Duplicate tags are okay, but only defined for iteration (with the
- * exceptions noted below). While you are allowed to add i18n string
- * arrays through this function, you probably don't mean to. See
- * headerAddI18NString() instead.
- *
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-static int
-headerAddEntry (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
-        /address@hidden h @ */
-{
-  indexEntry entry;
-
-  /* Count must always be >= 1 for headerAddEntry. */
-  if (c <= 0)
-    return 0;
-
-  /* Allocate more index space if necessary */
-  if (h->indexUsed == h->indexAlloced)
-    {
-      h->indexAlloced += INDEX_MALLOC_SIZE;
-      h->index = realloc (h->index, h->indexAlloced * sizeof (*h->index));
-    }
-
-  /* Fill in the index */
-  entry = h->index + h->indexUsed;
-  entry->info.tag = tag;
-  entry->info.type = type;
-  entry->info.count = c;
-  entry->info.offset = 0;
-  entry->data = grabData (type, p, c, &entry->length);
-
-  if (h->indexUsed > 0 && tag < h->index[h->indexUsed - 1].info.tag)
-    h->flags &= ~HEADERFLAG_SORTED;
-  h->indexUsed++;
-
-  return 1;
-}
-
-/** \ingroup header
- * Dereference a header instance.
- * @param h            header
- * @return             NULL always
- */
-static                          /address@hidden@ */
-Header headerFree ( /address@hidden@ *//address@hidden@ */ Header h);
-        /address@hidden h @ */
-
-
-/** \ingroup header
- * Destroy header tag iterator.
- * @param hi           header tag iterator
- * @return             NULL always
- */
-static                          /address@hidden@ */
-  HeaderIterator
-headerFreeIterator ( /address@hidden@ */ HeaderIterator hi)
-        /address@hidden hi @ */
-{
-  hi->h = headerFree (hi->h);
-  hi = _free (hi);
-  return hi;
-}
-
-/**
- * Find matching (tag,type) entry in header.
- * @param h            header
- * @param tag          entry tag
- * @param type         entry type
- * @return             header entry
- */
-static                          /address@hidden@ */
-  indexEntry
-findEntry ( /address@hidden@ */ Header h, int_32 tag, int_32 type)
-        /address@hidden h @ */
-{
-  indexEntry entry, entry2, last;
-  struct indexEntry key;
-
-  if (h == NULL)
-    return NULL;
-  if (!(h->flags & HEADERFLAG_SORTED))
-    headerSort (h);
-
-  key.info.tag = tag;
-
-  entry2 = entry =
-    bsearch (&key, h->index, h->indexUsed, sizeof (*h->index), indexCmp);
-  if (entry == NULL)
-    return NULL;
-
-  if (type == RPM_NULL_TYPE)
-    return entry;
-
-  /* look backwards */
-  while (entry->info.tag == tag && entry->info.type != type &&
-         entry > h->index)
-    entry--;
-
-  if (entry->info.tag == tag && entry->info.type == type)
-    return entry;
-
-  last = h->index + h->indexUsed;
-  /address@hidden@ *//* FIX: entry2 = entry. Code looks bogus as well. */
-  while (entry2->info.tag == tag && entry2->info.type != type &&
-         entry2 < last)
-    entry2++;
-  /address@hidden@ */
-
-  if (entry->info.tag == tag && entry->info.type == type)
-    return entry;
-
-  return NULL;
-}
-
-static int regionSwab ( /address@hidden@ */ indexEntry entry, int il, int dl,
-                       entryInfo pe, char *dataStart, int regionid);
-        /address@hidden *entry, *dataStart @ */
-
-/** \ingroup header
- * Retrieve data from header entry.
- * @todo Permit retrieval of regions other than HEADER_IMUTABLE.
- * @param entry                header entry
- * @retval type                address of type (or NULL)
- * @retval p           address of data (or NULL)
- * @retval c           address of count (or NULL)
- * @param minMem       string pointers refer to header memory?
- * @return             1 on success, otherwise error.
- */
-static int
-copyEntry (const indexEntry entry,
-           /address@hidden@ *//address@hidden@ */ hTYP_t type,
-           /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-           /address@hidden@ *//address@hidden@ */ hCNT_t c,
-           int minMem)
-        /address@hidden *type, *p, *c @ */
-{
-  int_32 count = entry->info.count;
-  int rc = 1;                   /* XXX 1 on success. */
-
-  if (p)
-    switch (entry->info.type)
-      {
-      case RPM_BIN_TYPE:
-        /*
-         * XXX This only works for
-         * XXX  "sealed" HEADER_IMMUTABLE/HEADER_SIGNATURES/HEADER_IMAGE.
-         * XXX This will *not* work for unsealed legacy HEADER_IMAGE (i.e.
-         * XXX a legacy header freshly read, but not yet unloaded to the 
rpmdb).
-         */
-        if (ENTRY_IS_REGION (entry))
-          {
-            int_32 *ei = ((int_32 *) entry->data) - 2;
-            /address@hidden@ */
-            entryInfo pe = (entryInfo) (ei + 2);
-            /address@hidden@ */
-            char *dataStart = (char *) (pe + ntohl (ei[0]));
-            int_32 rdl = -entry->info.offset;   /* negative offset */
-            int_32 ril = rdl / sizeof (*pe);
-
-            /address@hidden@ */
-            rdl = entry->rdlen;
-            count = 2 * sizeof (*ei) + (ril * sizeof (*pe)) + rdl;
-            if (entry->info.tag == HEADER_IMAGE)
-              {
-                ril -= 1;
-                pe += 1;
-              }
-            else
-              {
-                count += REGION_TAG_COUNT;
-                rdl += REGION_TAG_COUNT;
-              }
-
-            *p = malloc (count);
-            ei = (int_32 *) * p;
-            ei[0] = htonl (ril);
-            ei[1] = htonl (rdl);
-
-            /address@hidden@ */
-            pe = (entryInfo) memcpy (ei + 2, pe, (ril * sizeof (*pe)));
-            /address@hidden@ */
-
-            dataStart = (char *) memcpy (pe + ril, dataStart, rdl);
-            /address@hidden@ */
-
-            rc = regionSwab (NULL, ril, 0, pe, dataStart, 0);
-            /* XXX 1 on success. */
-            rc = (rc < 0) ? 0 : 1;
-          }
-        else
-          {
-            count = entry->length;
-            *p = (!minMem
-                  ? memcpy (malloc (count), entry->data, count)
-                  : entry->data);
-          }
-        break;
-      case RPM_STRING_TYPE:
-        if (count == 1)
-          {
-            *p = entry->data;
-            break;
-          }
-        /address@hidden@ */
-      case RPM_STRING_ARRAY_TYPE:
-      case RPM_I18NSTRING_TYPE:
-        {
-          const char **ptrEntry;
-          /address@hidden@ */
-          int tableSize = count * sizeof (char *);
-          /address@hidden@ */
-          char *t;
-          int i;
-
-          /address@hidden@ */
-          if (minMem)
-            {
-              *p = malloc (tableSize);
-              ptrEntry = (const char **) *p;
-              t = entry->data;
-            }
-          else
-            {
-              t = malloc (tableSize + entry->length);
-              *p = (void *) t;
-              ptrEntry = (const char **) *p;
-              t += tableSize;
-              memcpy (t, entry->data, entry->length);
-            }
-          /address@hidden@ */
-          for (i = 0; i < count; i++)
-            {
-              *ptrEntry++ = t;
-              t = strchr (t, 0);
-              t++;
-            }
-        }
-        break;
-
-      default:
-        *p = entry->data;
-        break;
-      }
-  if (type)
-    *type = entry->info.type;
-  if (c)
-    *c = count;
-  return rc;
-}
-
-#define        ENTRY_IN_REGION(_e)     ((_e)->info.offset < 0)
-
-/** \ingroup header
- * Append element to tag array in header.
- * Appends item p to entry w/ tag and type as passed. Won't work on
- * RPM_STRING_TYPE. Any pointers into header memory returned from
- * headerGetEntryMinMemory() for this entry are invalid after this
- * call has been made!
- *
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-static int
-headerAppendEntry (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
-        /address@hidden h @ */
-{
-  indexEntry entry;
-  int length;
-
-  /* First find the tag */
-  entry = findEntry (h, tag, type);
-  if (!entry)
-    return 0;
-
-  if (type == RPM_STRING_TYPE || type == RPM_I18NSTRING_TYPE)
-    {
-      /* we can't do this */
-      return 0;
-    }
-
-  length = dataLength (type, p, c, 0);
-
-  if (ENTRY_IN_REGION (entry))
-    {
-      char *t = malloc (entry->length + length);
-      memcpy (t, entry->data, entry->length);
-      entry->data = t;
-      entry->info.offset = 0;
-    }
-  else
-    entry->data = realloc (entry->data, entry->length + length);
-
-  copyData (type, ((char *) entry->data) + entry->length, p, c, length);
-
-  entry->length += length;
-
-  entry->info.count += c;
-
-  return 1;
-}
-
-/** \ingroup header
- * Add or append element to tag array in header.
- * @todo Arg "p" should have const.
- * @param h            header
- * @param tag          tag
- * @param type         tag value data type
- * @param p            pointer to tag value(s)
- * @param c            number of values
- * @return             1 on success, 0 on failure
- */
-static int
-headerAddOrAppendEntry (Header h, int_32 tag, int_32 type,
-                        const void *p, int_32 c)
-        /address@hidden h @ */
-{
-  return (findEntry (h, tag, type)
-          ? headerAppendEntry (h, tag, type, p, c)
-          : headerAddEntry (h, tag, type, p, c));
-}
-
-/**
- * Does locale match entry in header i18n table?
- *
- * \verbatim
- * The range [l,le) contains the next locale to match:
- *    address@hidden
- * where
- *    ll       ISO language code (in lowercase).
- *    CC       (optional) ISO coutnry code (in uppercase).
- *    EEEEE    (optional) encoding (not really standardized).
- *    dddd     (optional) dialect.
- * \endverbatim
- *
- * @param td           header i18n table data, NUL terminated
- * @param l            start of locale to match
- * @param le           end of locale to match
- * @return             1 on match, 0 on no match
- */
-static int
-headerMatchLocale (const char *td, const char *l, const char *le)
-        /*@ */
-{
-  const char *fe;
-
-
-#if 0
-  {
-    const char *s, *ll, *CC, *EE, *dd;
-    char *lbuf, *t.
-      /* Copy the buffer and parse out components on the fly. */
-      lbuf = alloca (le - l + 1);
-    for (s = l, ll = t = lbuf; *s; s++, t++)
-      {
-        switch (*s)
-          {
-          case '_':
-            *t = '\0';
-            CC = t + 1;
-            break;
-          case '.':
-            *t = '\0';
-            EE = t + 1;
-            break;
-          case '@':
-            *t = '\0';
-            dd = t + 1;
-            break;
-          default:
-            *t = *s;
-            break;
-          }
-      }
-
-    if (ll)                     /* ISO language should be lower case */
-      for (t = ll; *t; t++)
-        *t = tolower (*t);
-    if (CC)                     /* ISO country code should be upper case */
-      for (t = CC; *t; t++)
-        *t = toupper (*t);
-
-    /* There are a total of 16 cases to attempt to match. */
-  }
-#endif
-
-  /* First try a complete match. */
-  if (strlen (td) == (le - l) && !strncmp (td, l, (le - l)))
-    return 1;
-
-  /* Next, try stripping optional dialect and matching.  */
-  for (fe = l; fe < le && *fe != '@'; fe++)
-    {
-    };
-  if (fe < le && !strncmp (td, l, (fe - l)))
-    return 1;
-
-  /* Next, try stripping optional codeset and matching.  */
-  for (fe = l; fe < le && *fe != '.'; fe++)
-    {
-    };
-  if (fe < le && !strncmp (td, l, (fe - l)))
-    return 1;
-
-  /* Finally, try stripping optional country code and matching. */
-  for (fe = l; fe < le && *fe != '_'; fe++)
-    {
-    };
-  if (fe < le && !strncmp (td, l, (fe - l)))
-    return 1;
-
-  return 0;
-}
-
-/**
- * Return i18n string from header that matches locale.
- * @param h            header
- * @param entry                i18n string data
- * @return             matching i18n string (or 1st string if no match)
- */
-                /address@hidden@*//address@hidden@ */ static char *
-headerFindI18NString (Header h, indexEntry entry)
-        /*@ */
-{
-  const char *lang, *l, *le;
-  indexEntry table;
-
-  /* XXX Drepper sez' this is the order. */
-  if ((lang = getenv ("LANGUAGE")) == NULL &&
-      (lang = getenv ("LC_ALL")) == NULL &&
-      (lang = getenv ("LC_MESSAGES")) == NULL &&
-      (lang = getenv ("LANG")) == NULL)
-    return entry->data;
-
-  /address@hidden@ */
-  if ((table =
-       findEntry (h, HEADER_I18NTABLE, RPM_STRING_ARRAY_TYPE)) == NULL)
-    return entry->data;
-  /address@hidden@ */
-
-  for (l = lang; *l != '\0'; l = le)
-    {
-      const char *td;
-      char *ed;
-      int langNum;
-
-      while (*l && *l == ':')   /* skip leading colons */
-        l++;
-      if (*l == '\0')
-        break;
-      for (le = l; *le && *le != ':'; le++)     /* find end of this locale */
-        {
-        };
-
-      /* For each entry in the header ... */
-      for (langNum = 0, td = table->data, ed = entry->data;
-           langNum < entry->info.count;
-           langNum++, td += strlen (td) + 1, ed += strlen (ed) + 1)
-        {
-
-          if (headerMatchLocale (td, l, le))
-            return ed;
-
-        }
-    }
-
-  return entry->data;
-}
-
-/**
- * Retrieve tag data from header.
- * @param h            header
- * @param tag          tag to retrieve
- * @retval type                address of type (or NULL)
- * @retval p           address of data (or NULL)
- * @retval c           address of count (or NULL)
- * @param minMem       string pointers reference header memory?
- * @return             1 on success, 0 on not found
- */
-static int
-intGetEntry (Header h, int_32 tag,
-             /address@hidden@ *//address@hidden@ */ hTAG_t type,
-             /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-             /address@hidden@ *//address@hidden@ */ hCNT_t c,
-             int minMem)
-        /address@hidden *type, *p, *c @ */
-{
-  indexEntry entry;
-  int rc;
-
-  /* First find the tag */
-  /address@hidden@ *//*@ FIX: h modified by sort. */
-  entry = findEntry (h, tag, RPM_NULL_TYPE);
-  /address@hidden@ */
-  if (entry == NULL)
-    {
-      if (type)
-        type = 0;
-      if (p)
-        *p = NULL;
-      if (c)
-        *c = 0;
-      return 0;
-    }
-
-  switch (entry->info.type)
-    {
-    case RPM_I18NSTRING_TYPE:
-      rc = 1;
-      if (type)
-        *type = RPM_STRING_TYPE;
-      if (c)
-        *c = 1;
-      /address@hidden@ */
-      if (p)
-        *p = headerFindI18NString (h, entry);
-      /address@hidden@ */
-      break;
-    default:
-      rc = copyEntry (entry, type, p, c, minMem);
-      break;
-    }
-
-  /* XXX 1 on success */
-  return ((rc == 1) ? 1 : 0);
-}
-
-/** \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
- * entry is present).
- *
- * @param h            header
- * @param tag          tag
- * @retval type                address of tag value data type (or NULL)
- * @retval p           address of pointer to tag value(s) (or NULL)
- * @retval c           address of number of values (or NULL)
- * @return             1 on success, 0 on failure
- */
-static int
-headerGetEntry (Header h, int_32 tag,
-                /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                /address@hidden@ *//address@hidden@ */ void **p,
-                /address@hidden@ *//address@hidden@ */ hCNT_t c)
-        /address@hidden *type, *p, *c @ */
-{
-  return intGetEntry (h, tag, type, (hPTR_t *) p, c, 0);
-}
-
-/** \ingroup header
- */
-               /address@hidden@*//address@hidden@ */
-static unsigned char header_magic[8] = {
-  0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
-};
-
-/** \ingroup header
- * Return size of on-disk header representation in bytes.
- * @param h            header
- * @param magicp       include size of 8 bytes for (magic, 0)?
- * @return             size of on-disk header
- */
-static unsigned int
-headerSizeof ( /address@hidden@ */ Header h, enum hMagic magicp)
-        /address@hidden h @ */
-{
-  indexEntry entry;
-  unsigned int size = 0;
-  int i;
-
-  if (h == NULL)
-    return size;
-
-  headerSort (h);
-
-  switch (magicp)
-    {
-    case HEADER_MAGIC_YES:
-      size += sizeof (header_magic);
-      break;
-    case HEADER_MAGIC_NO:
-      break;
-    }
-
-  /address@hidden@ */
-  size += 2 * sizeof (int_32);  /* count of index entries */
-  /address@hidden@ */
-
-  for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++)
-    {
-      unsigned diff;
-      int_32 type;
-
-      /* Regions go in as is ... */
-      if (ENTRY_IS_REGION (entry))
-        {
-          size += entry->length;
-          /* XXX Legacy regions do not include the region tag and data. */
-          /address@hidden@ */
-          if (i == 0 && (h->flags & HEADERFLAG_LEGACY))
-            size += sizeof (struct entryInfo) + entry->info.count;
-          /address@hidden@ */
-          continue;
-        }
-
-      /* ... and region elements are skipped. */
-      if (entry->info.offset < 0)
-        continue;
-
-      /* Alignment */
-      type = entry->info.type;
-      if (typeSizes[type] > 1)
-        {
-          diff = typeSizes[type] - (size % typeSizes[type]);
-          if (diff != typeSizes[type])
-            {
-              size += diff;
-            }
-        }
-
-      /address@hidden@ */
-      size += sizeof (struct entryInfo) + entry->length;
-      /address@hidden@ */
-    }
-
-  return size;
-}
-
-/** \ingroup header
- * Reference a header instance.
- * @param h            header
- * @return             referenced header instance
- */
-static Header
-headerLink (Header h)
-        /address@hidden h @ */
-{
-  if (h != NULL)
-    h->nrefs++;
-  /address@hidden -nullret @ */
-  return h;
-  /address@hidden =nullret @ */
-}
-
-/** \ingroup header
- * Create header tag iterator.
- * @param h            header
- * @return             header tag iterator
- */
-static HeaderIterator
-headerInitIterator (Header h)
-        /address@hidden h */
-{
-  HeaderIterator hi = malloc (sizeof (*hi));
-
-  headerSort (h);
-
-  hi->h = headerLink (h);
-  hi->next_index = 0;
-  return hi;
-}
-
-/** \ingroup header
- * Check if tag is in header.
- * @param h            header
- * @param tag          tag
- * @return             1 on success, 0 on failure
- */
-static int
-headerIsEntry ( /address@hidden@ */ Header h, int_32 tag)
-        /*@ */
-{
-  /address@hidden@ *//*@ FIX: h modified by sort. */
-  return (findEntry (h, tag, RPM_NULL_TYPE) ? 1 : 0);
-  /address@hidden@ */
-}
-
-/** \ingroup header
- * Return next tag from header.
- * @param hi           header tag iterator
- * @retval tag         address of tag
- * @retval type                address of tag value data type
- * @retval p           address of pointer to tag value(s)
- * @retval c           address of number of values
- * @return             1 on success, 0 on failure
- */
-static int
-headerNextIterator (HeaderIterator hi,
-                    /address@hidden@ *//address@hidden@ */ hTAG_t tag,
-                    /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                    /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-                    /address@hidden@ *//address@hidden@ */ hCNT_t c,
-                    int do_copy)
-        /address@hidden hi, *tag, *type, *p, *c @ */
-{
-  Header h = hi->h;
-  int slot = hi->next_index;
-  indexEntry entry = NULL;
-  int rc;
-
-  for (slot = hi->next_index; slot < h->indexUsed; slot++)
-    {
-      entry = h->index + slot;
-      if (!ENTRY_IS_REGION (entry))
-        break;
-    }
-  hi->next_index = slot;
-  if (entry == NULL || slot >= h->indexUsed)
-    return 0;
-  /address@hidden@ *//* LCL: no clue */
-  hi->next_index++;
-  /address@hidden@ */
-
-  if (tag)
-    *tag = entry->info.tag;
-
-  rc = copyEntry (entry, type, p, c, do_copy);
-
-  /* XXX 1 on success */
-  return ((rc == 1) ? 1 : 0);
-}
-
-/** \ingroup header
- * Dereference a header instance.
- * @param h            header
- * @return             NULL always
- */
-static                          /address@hidden@ */
-  Header
-headerUnlink ( /address@hidden@ *//address@hidden@ */ Header h)
-        /address@hidden h @ */
-{
-  if (h != NULL)
-    h->nrefs--;
-  return NULL;
-}
-
-/** \ingroup header
- * Dereference a header instance.
- * @param h            header
- * @return             NULL always
- */
-static                          /address@hidden@ */
-  Header
-headerFree ( /address@hidden@ *//address@hidden@ */ Header h)
-        /address@hidden h @ */
-{
-  (void) headerUnlink (h);
-
-  /address@hidden@ */
-  if (h == NULL || h->nrefs > 0)
-    return NULL;                /* XXX return previous header? */
-
-  if (h->index)
-    {
-      indexEntry entry = h->index;
-      int i;
-      for (i = 0; i < h->indexUsed; i++, entry++)
-        {
-          if ((h->flags & HEADERFLAG_ALLOCATED) && ENTRY_IS_REGION (entry))
-            {
-              if (entry->length > 0)
-                {
-                  int_32 *ei = entry->data;
-                  if ((ei - 2) == h->blob)
-                    h->blob = _free (h->blob);
-                  entry->data = NULL;
-                }
-            }
-          else if (!ENTRY_IN_REGION (entry))
-            {
-              entry->data = _free (entry->data);
-            }
-          entry->data = NULL;
-        }
-      h->index = _free (h->index);
-    }
-
-                                        /address@hidden@ */ h = _free (h);
-                                        /address@hidden@ */
-  return h;
-  /address@hidden@ */
-}
-
-/**
- * Sanity check on no. of tags.
- * This check imposes a limit of 65K tags, more than enough.
- */
-#define hdrchkTags(_ntags)     ((_ntags) & 0xffff0000)
-
-/**
- * Sanity check on data size and/or offset.
- * This check imposes a limit of 16Mb, more than enough.
- */
-#define hdrchkData(_nbytes)    ((_nbytes) & 0xff000000)
-
-
-
-/** \ingroup header
- * Swap int_32 and int_16 arrays within header region.
- *
- * This code is way more twisty than I would like.
- *
- * A bug with RPM_I18NSTRING_TYPE in rpm-2.5.x (fixed in August 1998)
- * causes the offset and length of elements in a header region to disagree
- * regarding the total length of the region data.
- *
- * The "fix" is to compute the size using both offset and length and
- * return the larger of the two numbers as the size of the region.
- * Kinda like computing left and right Riemann sums of the data elements
- * to determine the size of a data structure, go figger :-).
- *
- * There's one other twist if a header region tag is in the set to be swabbed,
- * as the data for a header region is located after all other tag data.
- *
- * @param entry                header entry
- * @param il           no. of entries
- * @param dl           start no. bytes of data
- * @param pe           header physical entry pointer (swapped)
- * @param dataStart    header data
- * @param regionid     region offset
- * @return             no. bytes of data in region, -1 on error
- */
-static int
-regionSwab ( /address@hidden@ */ indexEntry entry, int il, int dl,
-            entryInfo pe, char *dataStart, int regionid)
-        /address@hidden *entry, *dataStart @ */
-{
-  char *tprev = NULL;
-  char *t = NULL;
-  int tdel, tl = dl;
-  struct indexEntry ieprev;
-
-  memset (&ieprev, 0, sizeof (ieprev));
-  for (; il > 0; il--, pe++)
-    {
-      struct indexEntry ie;
-      int_32 type;
-
-      ie.info.tag = ntohl (pe->tag);
-      ie.info.type = ntohl (pe->type);
-      if (ie.info.type < RPM_MIN_TYPE || ie.info.type > RPM_MAX_TYPE)
-        return -1;
-      ie.info.count = ntohl (pe->count);
-      ie.info.offset = ntohl (pe->offset);
-      ie.data = t = dataStart + ie.info.offset;
-      ie.length = dataLength (ie.info.type, ie.data, ie.info.count, 1);
-      ie.rdlen = 0;
-
-      if (entry)
-        {
-          ie.info.offset = regionid;
-          *entry = ie;          /* structure assignment */
-          entry++;
-        }
-
-      /* Alignment */
-      type = ie.info.type;
-      if (typeSizes[type] > 1)
-        {
-          unsigned diff;
-          diff = typeSizes[type] - (dl % typeSizes[type]);
-          if (diff != typeSizes[type])
-            {
-              dl += diff;
-              if (ieprev.info.type == RPM_I18NSTRING_TYPE)
-                ieprev.length += diff;
-            }
-        }
-      tdel = (tprev ? (t - tprev) : 0);
-      if (ieprev.info.type == RPM_I18NSTRING_TYPE)
-        tdel = ieprev.length;
-
-      if (ie.info.tag >= HEADER_I18NTABLE)
-        {
-          tprev = t;
-        }
-      else
-        {
-          tprev = dataStart;
-          /* XXX HEADER_IMAGE tags don't include region sub-tag. */
-          /address@hidden@ */
-          if (ie.info.tag == HEADER_IMAGE)
-            tprev -= REGION_TAG_COUNT;
-          /address@hidden@ */
-        }
-
-      /* Perform endian conversions */
-      switch (ntohl (pe->type))
-        {
-        case RPM_INT32_TYPE:
-          {
-            int_32 *it = (int_32 *) t;
-            for (; ie.info.count > 0; ie.info.count--, it += 1)
-              *it = htonl (*it);
-            t = (char *) it;
-          } /address@hidden@ */ break;
-        case RPM_INT16_TYPE:
-          {
-            unsigned short *it = (unsigned short *) t;
-            for (; ie.info.count > 0; ie.info.count--, it += 1)
-              *it = htons (*it);
-            t = (char *) it;
-          } /address@hidden@ */ break;
-        default:
-          t += ie.length;
-          /address@hidden@ */ break;
-        }
-
-      dl += ie.length;
-      tl += tdel;
-      ieprev = ie;              /* structure assignment */
-
-    }
-  tdel = (tprev ? (t - tprev) : 0);
-  tl += tdel;
-
-  /* XXX
-   * There are two hacks here:
-   *  1) tl is 16b (i.e. REGION_TAG_COUNT) short while doing headerReload().
-   *  2) the 8/98 rpm bug with inserting i18n tags needs to use tl, not dl.
-   */
-  /address@hidden@ */
-  if (tl + REGION_TAG_COUNT == dl)
-    tl += REGION_TAG_COUNT;
-  /address@hidden@ */
-
-  return dl;
-}
-
-static int headerRemoveEntry (Header h, int_32 tag);
-
-/** \ingroup header
- * Convert header to in-memory representation.
- * @param uh           on-disk header blob (i.e. with offsets)
- * @return             header
- */
-static                          /address@hidden@ */
-  Header
-headerLoad ( /address@hidden@ */ void *uh)
-        /address@hidden uh @ */
-{
-  int_32 *ei = (int_32 *) uh;
-  int_32 il = ntohl (ei[0]);    /* index length */
-  int_32 dl = ntohl (ei[1]);    /* data length */
-  /address@hidden@ */
-  size_t pvlen = sizeof (il) + sizeof (dl) +
-    (il * sizeof (struct entryInfo)) + dl;
-  /address@hidden@ */
-  void *pv = uh;
-  Header h = NULL;
-  entryInfo pe;
-  char *dataStart;
-  indexEntry entry;
-  int rdlen;
-
-  /* Sanity checks on header intro. */
-  if (hdrchkTags (il) || hdrchkData (dl))
-    goto errxit;
-
-  ei = (int_32 *) pv;
-  /address@hidden@ */
-  pe = (entryInfo) & ei[2];
-  /address@hidden@ */
-  dataStart = (char *) (pe + il);
-
-  h = calloc (1, sizeof (*h));
-  memset (h, 0, sizeof (*h));
-  /address@hidden@ */
-  /address@hidden@ */
-  /address@hidden -kepttrans@ */
-  h->blob = uh;
-  /address@hidden =kepttrans@ */
-  h->indexAlloced = il + 1;
-  h->indexUsed = il;
-  h->index = calloc (h->indexAlloced, sizeof (*h->index));
-  h->flags = HEADERFLAG_SORTED;
-  h->nrefs = 0;
-  h = headerLink (h);
-
-  /*
-   * XXX XFree86-libs, ash, and pdksh from Red Hat 5.2 have bogus
-   * %verifyscript tag that needs to be diddled.
-   */
-  if (ntohl (pe->tag) == 15 &&
-      ntohl (pe->type) == RPM_STRING_TYPE && ntohl (pe->count) == 1)
-    {
-      pe->tag = htonl (1079);
-    }
-
-  entry = h->index;
-  if (!(htonl (pe->tag) < HEADER_I18NTABLE))
-    {
-      h->flags |= HEADERFLAG_LEGACY;
-      entry->info.type = REGION_TAG_TYPE;
-      entry->info.tag = HEADER_IMAGE;
-      /address@hidden@ */
-      entry->info.count = REGION_TAG_COUNT;
-      /address@hidden@ */
-      entry->info.offset = ((char *) pe - dataStart);   /* negative offset */
-
-      /address@hidden@ */
-      entry->data = pe;
-      /address@hidden@ */
-      entry->length = pvlen - sizeof (il) - sizeof (dl);
-      rdlen =
-        regionSwab (entry + 1, il, 0, pe, dataStart, entry->info.offset);
-#if 0                           /* XXX don't check, the 8/98 i18n bug fails 
here. */
-      if (rdlen != dl)
-        goto errxit;
-#endif
-      entry->rdlen = rdlen;
-      entry++;
-      h->indexUsed++;
-    }
-  else
-    {
-      int nb = ntohl (pe->count);
-      int_32 rdl;
-      int_32 ril;
-
-      h->flags &= ~HEADERFLAG_LEGACY;
-
-      entry->info.type = htonl (pe->type);
-      if (entry->info.type < RPM_MIN_TYPE || entry->info.type > RPM_MAX_TYPE)
-        goto errxit;
-      entry->info.count = htonl (pe->count);
-
-      if (hdrchkTags (entry->info.count))
-        goto errxit;
-
-      {
-        int off = ntohl (pe->offset);
-
-        if (hdrchkData (off))
-          goto errxit;
-        if (off)
-          {
-            int_32 *stei = memcpy (alloca (nb), dataStart + off, nb);
-            rdl = -ntohl (stei[2]);     /* negative offset */
-            ril = rdl / sizeof (*pe);
-            if (hdrchkTags (ril) || hdrchkData (rdl))
-              goto errxit;
-            entry->info.tag = htonl (pe->tag);
-          }
-        else
-          {
-            ril = il;
-            /address@hidden@ */
-            rdl = (ril * sizeof (struct entryInfo));
-            /address@hidden@ */
-            entry->info.tag = HEADER_IMAGE;
-          }
-      }
-      entry->info.offset = -rdl;        /* negative offset */
-
-      /address@hidden@ */
-      entry->data = pe;
-      /address@hidden@ */
-      entry->length = pvlen - sizeof (il) - sizeof (dl);
-      rdlen =
-        regionSwab (entry + 1, ril - 1, 0, pe + 1, dataStart,
-                    entry->info.offset);
-      if (rdlen < 0)
-        goto errxit;
-      entry->rdlen = rdlen;
-
-      if (ril < h->indexUsed)
-        {
-          indexEntry newEntry = entry + ril;
-          int ne = (h->indexUsed - ril);
-          int rid = entry->info.offset + 1;
-          int rc;
-
-          /* Load dribble entries from region. */
-          rc = regionSwab (newEntry, ne, 0, pe + ril, dataStart, rid);
-          if (rc < 0)
-            goto errxit;
-          rdlen += rc;
-
-          {
-            indexEntry firstEntry = newEntry;
-            int save = h->indexUsed;
-            int j;
-
-            /* Dribble entries replace duplicate region entries. */
-            h->indexUsed -= ne;
-            for (j = 0; j < ne; j++, newEntry++)
-              {
-                (void) headerRemoveEntry (h, newEntry->info.tag);
-                if (newEntry->info.tag == HEADER_BASENAMES)
-                  (void) headerRemoveEntry (h, HEADER_OLDFILENAMES);
-              }
-
-            /* If any duplicate entries were replaced, move new entries down. 
*/
-            if (h->indexUsed < (save - ne))
-              {
-                memmove (h->index + h->indexUsed, firstEntry,
-                         (ne * sizeof (*entry)));
-              }
-            h->indexUsed += ne;
-          }
-        }
-    }
-
-  h->flags &= ~HEADERFLAG_SORTED;
-  headerSort (h);
-
-  /address@hidden -observertrans @ */
-  return h;
-  /address@hidden =observertrans @ */
-
-errxit:
-  /address@hidden@ */
-  if (h)
-    {
-      h->index = _free (h->index);
-      /address@hidden@ */
-      h = _free (h);
-      /address@hidden@ */
-    }
-  /address@hidden@ */
-  /address@hidden -globstate@ */
-  return h;
-  /address@hidden =globstate@ */
-}
-
-/** \ingroup header
- * Read (and load) header from file handle.
- * @param fd           file handle
- * @param magicp       read (and verify) 8 bytes of (magic, 0)?
- * @return             header (or NULL on error)
- */
-static                          /address@hidden@ */
-  Header
-headerRead (FD_t fd, enum hMagic magicp)
-        /address@hidden fd @ */
-{
-  int_32 block[4];
-  int_32 *ei = NULL;
-  int_32 il;
-  int_32 dl;
-  int_32 magic;
-  Header h = NULL;
-  size_t len;
-  int i;
-
-  memset (block, 0, sizeof (block));
-  i = 2;
-  if (magicp == HEADER_MAGIC_YES)
-    i += 2;
-
-  /address@hidden@ *//* FIX: cast? */
-  if (timedRead (fd, (char *) block, i * sizeof (*block)) !=
-      (i * sizeof (*block)))
-    goto exit;
-  /address@hidden@ */
-
-  i = 0;
-
-  if (magicp == HEADER_MAGIC_YES)
-    {
-      magic = block[i++];
-      if (memcmp (&magic, header_magic, sizeof (magic)))
-        goto exit;
-      i++;
-    }
-
-  il = ntohl (block[i]);
-  i++;
-  dl = ntohl (block[i]);
-  i++;
-
-  /address@hidden@ */
-  len = sizeof (il) + sizeof (dl) + (il * sizeof (struct entryInfo)) + dl;
-  /address@hidden@ */
-
-  /* Sanity checks on header intro. */
-  if (hdrchkTags (il) || hdrchkData (dl) || len > headerMaxbytes)
-    goto exit;
-
-  ei = malloc (len);
-  ei[0] = htonl (il);
-  ei[1] = htonl (dl);
-  len -= sizeof (il) + sizeof (dl);
-
-  /address@hidden@ *//* FIX: cast? */
-  if (timedRead (fd, (char *) &ei[2], len) != len)
-    goto exit;
-  /address@hidden@ */
-
-  h = headerLoad (ei);
-
-exit:
-  if (h)
-    {
-      if (h->flags & HEADERFLAG_ALLOCATED)
-        ei = _free (ei);
-      h->flags |= HEADERFLAG_ALLOCATED;
-    }
-  else if (ei)
-    ei = _free (ei);
-  /address@hidden@ *//* FIX: timedRead macro obscures annotation */
-  return h;
-  /address@hidden@ */
-}
-
-/**
- * Check package size.
- * @todo rpmio: use fdSize rather than fstat(2) to get file size.
- * @param fd                   package file handle
- * @param siglen               signature header size
- * @param pad                  signature padding
- * @param datalen              length of header+payload
- * @return                     rpmRC return code
- */
-static rpmRC
-checkSize (FD_t fd, int siglen, int pad, int datalen)
-        /address@hidden fileSystem @ */
-        /address@hidden fileSystem @ */
-{
-  rpmRC rc;
-
-  rc = (((sizeof (struct rpmlead) + siglen + pad + datalen) - fd->len)
-        ? RPMRC_BADSIZE : RPMRC_OK);
-
-  return rc;
-}
-
-/** \ingroup header
- * Create new (empty) header instance.
- * @return             header
- */
-static Header
-headerNew (void)
-        /*@ */
-{
-  Header h = calloc (1, sizeof (*h));
-
-  memset (h, 0, sizeof (*h));
-  /address@hidden@ */
-  /address@hidden@ */
-  h->blob = NULL;
-  h->indexAlloced = INDEX_MALLOC_SIZE;
-  h->indexUsed = 0;
-  h->flags = HEADERFLAG_SORTED;
-
-  h->index = (h->indexAlloced
-              ? calloc (h->indexAlloced, sizeof (*h->index)) : NULL);
-
-  /address@hidden -observertrans @ */
-  h->nrefs = 0;
-  return headerLink (h);
-  /address@hidden =observertrans @ */
-}
-
-typedef unsigned char byte;
-
-static rpmRC
-rpmReadSignature (FD_t fd, Header * headerp, sigType sig_type)
-{
-  byte buf[2048];
-  int sigSize, pad;
-  int_32 type, count;
-  int_32 *archSize;
-  Header h = NULL;
-  rpmRC rc = RPMRC_FAIL;        /* assume failure */
-
-  if (headerp)
-    *headerp = NULL;
-
-  buf[0] = 0;
-  switch (sig_type)
-    {
-    case RPMSIGTYPE_NONE:
-      rc = RPMRC_OK;
-      break;
-    case RPMSIGTYPE_PGP262_1024:
-      /* These are always 256 bytes */
-      if (timedRead (fd, buf, 256) != 256)
-        break;
-      h = headerNew ();
-      (void) headerAddEntry (h, RPMSIGTAG_PGP, RPM_BIN_TYPE, buf, 152);
-      rc = RPMRC_OK;
-      break;
-    case RPMSIGTYPE_MD5:
-    case RPMSIGTYPE_MD5_PGP:
-      break;
-    case RPMSIGTYPE_HEADERSIG:
-    case RPMSIGTYPE_DISABLE:
-      /* This is a new style signature */
-      h = headerRead (fd, HEADER_MAGIC_YES);
-      if (h == NULL)
-        break;
-
-      rc = RPMRC_OK;
-      sigSize = headerSizeof (h, HEADER_MAGIC_YES);
-
-      /* XXX Legacy headers have a HEADER_IMAGE tag added. */
-      if (headerIsEntry (h, RPMTAG_HEADERIMAGE))
-        sigSize -= (16 + 16);
-
-      pad = (8 - (sigSize % 8)) % 8;    /* 8-byte pad */
-      if (sig_type == RPMSIGTYPE_HEADERSIG)
-        {
-          if (!headerGetEntry (h, RPMSIGTAG_SIZE, &type,
-                               (void **) &archSize, &count))
-            break;
-          rc = checkSize (fd, sigSize, pad, *archSize);
-        }
-      if (pad && timedRead (fd, buf, pad) != pad)
-        rc = RPMRC_SHORTREAD;
-      break;
-    default:
-      break;
-    }
-
-  if (rc == 0 && headerp)
-    /address@hidden@ */
-    *headerp = h;
-  /address@hidden@ */
-  else if (h)
-    h = headerFree (h);
-
-  return rc;
-}
-
-
-static int
-readLead (FD_t fd, struct rpmlead *lead)
-{
-  memset (lead, 0, sizeof (*lead));
-  /address@hidden@ *//* FIX: remove timed read */
-  if (timedRead (fd, (char *) lead, sizeof (*lead)) != sizeof (*lead))
-    {
-      return 1;
-    }
-  /address@hidden@ */
-
-  lead->type = ntohs (lead->type);
-  lead->archnum = ntohs (lead->archnum);
-  lead->osnum = ntohs (lead->osnum);
-
-  if (lead->major >= 2)
-    lead->signature_type = ntohs (lead->signature_type);
-
-  return 0;
-}
-
-/** \ingroup header
- * Retrieve tag value using header internal array.
- * Get an entry using as little extra RAM as possible to return the tag value.
- * This is only an issue for RPM_STRING_ARRAY_TYPE.
- *
- * @param h            header
- * @param tag          tag
- * @retval type                address of tag value data type (or NULL)
- * @retval p           address of pointer to tag value(s) (or NULL)
- * @retval c           address of number of values (or NULL)
- * @return             1 on success, 0 on failure
- */
-static int
-headerGetEntryMinMemory (Header h, int_32 tag,
-                         /address@hidden@ *//address@hidden@ */ hTYP_t type,
-                         /address@hidden@ *//address@hidden@ */ hPTR_t * p,
-                         /address@hidden@ *//address@hidden@ */ hCNT_t c)
-        /address@hidden *type, *p, *c @ */
-{
-  return intGetEntry (h, tag, type, p, c, 1);
-}
-
-/** \ingroup header
- * Delete tag in header.
- * Removes all entries of type tag from the header, returns 1 if none were
- * found.
- *
- * @param h            header
- * @param tag          tag
- * @return             0 on success, 1 on failure (INCONSISTENT)
- */
-static int
-headerRemoveEntry (Header h, int_32 tag)
-        /address@hidden h @ */
-{
-  indexEntry last = h->index + h->indexUsed;
-  indexEntry entry, first;
-  int ne;
-
-  entry = findEntry (h, tag, RPM_NULL_TYPE);
-  if (!entry)
-    return 1;
-
-  /* Make sure entry points to the first occurence of this tag. */
-  while (entry > h->index && (entry - 1)->info.tag == tag)
-    entry--;
-
-  /* Free data for tags being removed. */
-  for (first = entry; first < last; first++)
-    {
-      void *data;
-      if (first->info.tag != tag)
-        break;
-      data = first->data;
-      first->data = NULL;
-      first->length = 0;
-      if (ENTRY_IN_REGION (first))
-        continue;
-      data = _free (data);
-    }
-
-  ne = (first - entry);
-  if (ne > 0)
-    {
-      h->indexUsed -= ne;
-      ne = last - first;
-      if (ne > 0)
-        memmove (entry, first, (ne * sizeof (*entry)));
-    }
-
-  return 0;
-}
-
-static int
-dncmp (const void *a, const void *b)
-{
-  const char *const *first = a;
-  const char *const *second = b;
-  return strcmp (*first, *second);
-}
-
 static void
-compressFilelist (Header h)
+sigalrmHandler (int sig)
 {
-  HGE_t hge = (HGE_t) headerGetEntryMinMemory;
-  HAE_t hae = (HAE_t) headerAddEntry;
-  HRE_t hre = (HRE_t) headerRemoveEntry;
-  HFD_t hfd = headerFreeData;
-  char **fileNames;
-  const char **dirNames;
-  const char **baseNames;
-  int_32 *dirIndexes;
-  rpmTagType fnt;
-  int count;
-  int i;
-  int dirIndex = -1;
-
-  /*
-   * This assumes the file list is already sorted, and begins with a
-   * single '/'. That assumption isn't critical, but it makes things go
-   * a bit faster.
-   */
-
-  if (headerIsEntry (h, RPMTAG_DIRNAMES))
-    {
-      (void) hre (h, RPMTAG_OLDFILENAMES);
-      return;                   /* Already converted. */
-    }
-
-  if (!hge (h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
-    return;                     /* no file list */
-  if (fileNames == NULL || count <= 0)
-    return;
-
-  dirNames = alloca (sizeof (*dirNames) * count);       /* worst case */
-  baseNames = alloca (sizeof (*dirNames) * count);
-  dirIndexes = alloca (sizeof (*dirIndexes) * count);
-
-  if (fileNames[0][0] != '/')
-    {
-      /* HACK. Source RPM, so just do things differently */
-      dirIndex = 0;
-      dirNames[dirIndex] = "";
-      for (i = 0; i < count; i++)
-        {
-          dirIndexes[i] = dirIndex;
-          baseNames[i] = fileNames[i];
-        }
-      goto exit;
-    }
-
-  for (i = 0; i < count; i++)
-    {
-      const char **needle;
-      char savechar;
-      char *baseName;
-      int len;
-
-      if (fileNames[i] == NULL) /* XXX can't happen */
-        continue;
-      baseName = strrchr (fileNames[i], '/') + 1;
-      len = baseName - fileNames[i];
-      needle = dirNames;
-      savechar = *baseName;
-      *baseName = '\0';
-      if (dirIndex < 0 ||
-          (needle =
-           bsearch (&fileNames[i], dirNames, dirIndex + 1,
-                    sizeof (dirNames[0]), dncmp)) == NULL)
-        {
-          char *s = alloca (len + 1);
-          memcpy (s, fileNames[i], len + 1);
-          s[len] = '\0';
-          dirIndexes[i] = ++dirIndex;
-          dirNames[dirIndex] = s;
-        }
-      else
-        dirIndexes[i] = needle - dirNames;
-
-      *baseName = savechar;
-      baseNames[i] = baseName;
-    }
-
-exit:
-  if (count > 0)
-    {
-      (void) hae (h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
-      (void) hae (h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
-                  baseNames, count);
-      (void) hae (h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
-                  dirNames, dirIndex + 1);
-    }
-
-  fileNames = hfd (fileNames, fnt);
-
-  (void) hre (h, RPMTAG_OLDFILENAMES);
+  /* do nothing */
 }
 
-static int
-headerNVR (Header h, const char **np, const char **vp, const char **rp)
-{
-  int type;
-  int count;
 
-  if (np)
-    {
-      if (!(headerGetEntry (h, RPMTAG_NAME, &type, (void **) np, &count)
-            && type == RPM_STRING_TYPE && count == 1))
-        *np = NULL;
-    }
-  if (vp)
-    {
-      if (!(headerGetEntry (h, RPMTAG_VERSION, &type, (void **) vp, &count)
-            && type == RPM_STRING_TYPE && count == 1))
-        *vp = NULL;
-    }
-  if (rp)
-    {
-      if (!(headerGetEntry (h, RPMTAG_RELEASE, &type, (void **) rp, &count)
-            && type == RPM_STRING_TYPE && count == 1))
-        *rp = NULL;
-    }
-  return 0;
-}
+/* *************** real libextractor stuff ***************** */
 
-/*
- * Up to rpm 3.0.4, packages implicitly provided their own 
name-version-release.
- * Retrofit an explicit "Provides: name = epoch:version-release.
- */
-static void
-providePackageNVR (Header h)
-{
-  HGE_t hge = (HGE_t) headerGetEntryMinMemory;
-  HFD_t hfd = headerFreeData;
-  const char *name, *version, *release;
-  int_32 *epoch;
-  const char *pEVR;
-  char *p;
-  int_32 pFlags = RPMSENSE_EQUAL;
-  const char **provides = NULL;
-  const char **providesEVR = NULL;
-  rpmTagType pnt, pvt = RPM_NULL_TYPE;
-  int_32 *provideFlags = NULL;
-  int providesCount;
-  int i;
-  int bingo = 1;
-
-  /* Generate provides for this package name-version-release. */
-  (void) headerNVR (h, &name, &version, &release);
-  if (!(name && version && release))
-    return;
-  pEVR = p = alloca (21 + strlen (version) + 1 + strlen (release) + 1);
-  *p = '\0';
-  if (hge (h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL))
-    {
-      sprintf (p, "%d:", *epoch);
-      while (*p != '\0')
-        p++;
-    }
-  (void) my_stpcpy (my_stpcpy (my_stpcpy (p, version), "-"), release);
-
-  /*
-   * Rpm prior to 3.0.3 does not have versioned provides.
-   * If no provides at all are available, we can just add.
-   */
-  if (!hge (h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
-    goto exit;
-
-  /*
-   * Otherwise, fill in entries on legacy packages.
-   */
-  if (!hge (h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL))
-    {
-      for (i = 0; i < providesCount; i++)
-        {
-          char *vdummy = "";
-          int_32 fdummy = RPMSENSE_ANY;
-          (void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEVERSION,
-                                         RPM_STRING_ARRAY_TYPE, &vdummy, 1);
-          (void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEFLAGS,
-                                         RPM_INT32_TYPE, &fdummy, 1);
-        }
-      goto exit;
-    }
-
-  (void) hge (h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
-
-  if (provides && providesEVR && provideFlags)
-    for (i = 0; i < providesCount; i++)
-      {
-        if (!(provides[i] && providesEVR[i]))
-          continue;
-        if (!(provideFlags[i] == RPMSENSE_EQUAL &&
-              !strcmp (name, provides[i]) && !strcmp (pEVR, providesEVR[i])))
-          continue;
-        bingo = 0;
-        break;
-      }
-
-exit:
-  provides = hfd (provides, pnt);
-  providesEVR = hfd (providesEVR, pvt);
-
-  if (bingo)
-    {
-      (void) headerAddOrAppendEntry (h, RPMTAG_PROVIDENAME,
-                                     RPM_STRING_ARRAY_TYPE, &name, 1);
-      (void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
-                                     &pFlags, 1);
-      (void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEVERSION,
-                                     RPM_STRING_ARRAY_TYPE, &pEVR, 1);
-    }
-}
-
-static Header rpmFreeSignature (Header h);
-
-/**
- * Retrieve package components from file handle.
- * @param fd           file handle
- * @param leadPtr      address of lead (or NULL)
- * @param sigs         address of signatures (or NULL)
- * @param hdrPtr       address of header (or NULL)
- * @return             rpmRC return code
- */
-static rpmRC
-readPackageHeaders (FD_t fd,
-                    /address@hidden@ *//address@hidden@ */ struct rpmlead 
*leadPtr,
-                    /address@hidden@ *//address@hidden@ */ Header * sigs,
-                    /address@hidden@ *//address@hidden@ */ Header * hdrPtr)
-        /address@hidden fd, *leadPtr, *sigs, *hdrPtr @ */
-{
-  Header hdrBlock;
-  struct rpmlead leadBlock;
-  Header *hdr = NULL;
-  struct rpmlead *lead;
-  char *defaultPrefix;
-  rpmRC rc;
-
-  hdr = hdrPtr ? hdrPtr : &hdrBlock;
-  lead = leadPtr ? leadPtr : &leadBlock;
-
-  if (readLead (fd, lead))
-    return RPMRC_FAIL;
-
-  if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
-      lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3)
-    {
-      return RPMRC_BADMAGIC;
-    }
-
-  switch (lead->major)
-    {
-    case 1:
-      return RPMRC_FAIL;
-      /address@hidden@ */ break;
-    case 2:
-    case 3:
-    case 4:
-      rc = rpmReadSignature (fd, sigs, lead->signature_type);
-      if (rc == RPMRC_FAIL)
-        return rc;
-      *hdr = headerRead (fd, (lead->major >= 3)
-                         ? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
-      if (*hdr == NULL)
-        {
-          if (sigs != NULL)
-            *sigs = rpmFreeSignature (*sigs);
-          return RPMRC_FAIL;
-        }
-
-      /*
-       * We don't use these entries (and rpm >= 2 never has) and they are
-       * pretty misleading. Let's just get rid of them so they don't confuse
-       * anyone.
-       */
-      if (headerIsEntry (*hdr, RPMTAG_FILEUSERNAME))
-        (void) headerRemoveEntry (*hdr, RPMTAG_FILEUIDS);
-      if (headerIsEntry (*hdr, RPMTAG_FILEGROUPNAME))
-        (void) headerRemoveEntry (*hdr, RPMTAG_FILEGIDS);
-
-      /*
-       * We switched the way we do relocateable packages. We fix some of
-       * it up here, though the install code still has to be a bit
-       * careful. This fixup makes queries give the new values though,
-       * which is quite handy.
-       */
-      if (headerGetEntry (*hdr, RPMTAG_DEFAULTPREFIX, NULL,
-                          (void **) &defaultPrefix, NULL))
-        {
-          defaultPrefix =
-            stripTrailingChar (alloca_strdup (defaultPrefix), '/');
-          (void) headerAddEntry (*hdr, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
-                                 &defaultPrefix, 1);
-        }
-
-      /*
-       * The file list was moved to a more compressed format which not
-       * only saves memory (nice), but gives fingerprinting a nice, fat
-       * speed boost (very nice). Go ahead and convert old headers to
-       * the new style (this is a noop for new headers).
-       */
-      if (lead->major < 4)
-        compressFilelist (*hdr);
-
-      /* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
-      if (lead->type == RPMLEAD_SOURCE)
-        {
-          int_32 one = 1;
-          if (!headerIsEntry (*hdr, RPMTAG_SOURCEPACKAGE))
-            (void) headerAddEntry (*hdr, RPMTAG_SOURCEPACKAGE, RPM_INT32_TYPE,
-                                   &one, 1);
-        }
-      else if (lead->major < 4)
-        {
-          /* Retrofit "Provide: name = EVR" for binary packages. */
-          providePackageNVR (*hdr);
-        }
-      break;
-
-    default:
-      return RPMRC_FAIL;
-      /address@hidden@ */ break;
-    }
-
-  if (hdrPtr == NULL)
-    *hdr = headerFree (*hdr);
-
-  return RPMRC_OK;
-}
-
-static void
-headerMergeLegacySigs (Header h, const Header sig)
-{
-  HFD_t hfd = (HFD_t) headerFreeData;
-  HAE_t hae = (HAE_t) headerAddEntry;
-  HeaderIterator hi;
-  int_32 tag, type, count;
-  const void *ptr;
-
-  /address@hidden@ *//* FIX: undocumented modification of sig */
-  for (hi = headerInitIterator (sig);
-       /address@hidden@ */
-       headerNextIterator (hi, &tag, &type, &ptr, &count, 0);
-       ptr = hfd (ptr, type))
-    {
-      switch (tag)
-        {
-        case RPMSIGTAG_SIZE:
-          tag = RPMTAG_SIGSIZE;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_LEMD5_1:
-          tag = RPMTAG_SIGLEMD5_1;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_PGP:
-          tag = RPMTAG_SIGPGP;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_LEMD5_2:
-          tag = RPMTAG_SIGLEMD5_2;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_MD5:
-          tag = RPMTAG_SIGMD5;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_GPG:
-          tag = RPMTAG_SIGGPG;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_PGP5:
-          tag = RPMTAG_SIGPGP5;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_PAYLOADSIZE:
-          tag = RPMTAG_ARCHIVESIZE;
-          /address@hidden@ */ break;
-        case RPMSIGTAG_SHA1:
-        case RPMSIGTAG_DSA:
-        case RPMSIGTAG_RSA:
-        default:
-          if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
-            continue;
-          /address@hidden@ */ break;
-        }
-      if (ptr == NULL)
-        continue;               /* XXX can't happen */
-      if (!headerIsEntry (h, tag))
-        hae (h, tag, type, ptr, count);
-    }
-  hi = headerFreeIterator (hi);
-}
-
-static Header
-rpmFreeSignature (Header h)
-{
-  return headerFree (h);
-}
-
-static rpmRC
-rpmReadPackageHeader (FD_t fd, Header * hdrp, int *isSource, int *major,
-                      int *minor)
-{
-  struct rpmlead lead;
-  Header sig = NULL;
-  rpmRC rc = readPackageHeaders (fd, &lead, &sig, hdrp);
-
-  if (rc != RPMRC_OK)
-    goto exit;
-
-  if (hdrp && *hdrp && sig)
-    {
-      headerMergeLegacySigs (*hdrp, sig);
-      sig = rpmFreeSignature (sig);
-    }
-
-  if (isSource)
-    *isSource = lead.type == RPMLEAD_SOURCE;
-  /address@hidden@ */
-  if (major)
-    *major = lead.major;
-  if (minor)
-    *minor = lead.minor;
-  /address@hidden@ */
-
-exit:
-  return rc;
-}
-
-
-/* ******************** real libextractor stuff ************************ */
-
 static struct EXTRACTOR_Keywords *
 addKeyword (EXTRACTOR_KeywordType type,
-            char *keyword, struct EXTRACTOR_Keywords *next)
+            const char *keyword, struct EXTRACTOR_Keywords *next)
 {
   EXTRACTOR_KeywordList *result;
 
@@ -3168,8 +80,6 @@
   EXTRACTOR_KeywordType type;
 } Matches;
 
-/* SEE:
-   http://rikers.org/rpmbook/node119.html#SECTION031425200000000000000 */
 static Matches tests[] = {
   {RPMTAG_NAME, EXTRACTOR_TITLE},
   {RPMTAG_VERSION, EXTRACTOR_VERSIONNUMBER},
@@ -3190,42 +100,67 @@
   {0, 0},
 };
 
-/* mimetype = application/rpm */
+static void discardCB() {
+  /* do nothing! */
+}
+
+/* mimetype = application/x-rpm */
 struct EXTRACTOR_Keywords *
-libextractor_rpm_extract (char *filename,
-                          char *data,
+libextractor_rpm_extract (const char *filename,
+                          const char *data,
                           size_t size, struct EXTRACTOR_Keywords *prev)
 {
-  fdStruct handle;
+  struct PipeArgs parg;
+  pthread_t pthr;
+  void * unused;
   Header hdr;
   HeaderIterator hi;
   int_32 tag;
   int_32 type;
   int_32 c;
   hPTR_t p;
-  int isSource;
-  int major;
-  int minor;
   int i;
-  char verb[40];
+  FD_t fdi;
+  rpmRC rc;
+  rpmts ts;
+  struct sigaction sig;
+  struct sigaction old;
 
-  handle.data = data;
-  handle.pos = 0;
-  handle.len = size;
-  if (0 != rpmReadPackageHeader (&handle, &hdr, &isSource, &major, &minor))
+  if (0 != pipe(parg.pi))
+    return prev;
+  fdi = NULL;
+  parg.data = data;
+  parg.pos = 0;
+  parg.size = size;
+  parg.shutdown = 0;
+  if (0 != pthread_create(&pthr,
+                         NULL,
+                         &pipe_feeder,
+                         &parg))
     {
+      CLOSE(parg.pi[0]);
+      CLOSE(parg.pi[1]);
       return prev;
     }
+  rpmlogSetCallback(&discardCB);
+  fdi = fdDup(parg.pi[0]);
+  ts = rpmtsCreate();
+  rc = rpmReadPackageFile (ts, fdi, "GNU libextractor", &hdr);
+  switch (rc)
+    {
+    case RPMRC_OK:
+    case RPMRC_NOKEY:
+    case RPMRC_NOTTRUSTED:
+      break;
+    case RPMRC_NOTFOUND:
+    case RPMRC_FAIL:
+    default:
+      goto END;
+    }
   prev = addKeyword (EXTRACTOR_MIMETYPE,
-                     "application/x-redhat-package-manager", prev);
-  /* FIXME: add platform! */
-  if (isSource)
-    sprintf (verb, _("Source RPM %d.%d"), major, minor);
-  else
-    sprintf (verb, _("Binary RPM %d.%d"), major, minor);
-  prev = addKeyword (EXTRACTOR_UNKNOWN, verb, prev);
+                     "application/x-rpm", prev);
   hi = headerInitIterator (hdr);
-  while (1 == headerNextIterator (hi, &tag, &type, &p, &c, 0))
+  while (1 == headerNextIterator (hi, &tag, &type, &p, &c))
     {
       i = 0;
       while (tests[i].rtype != 0)
@@ -3330,10 +265,22 @@
     }
   headerFreeIterator (hi);
   headerFree (hdr);
+  rpmtsFree(ts);
+ END:                                          
+  /* make sure SIGALRM does not kill us */
+  memset (&sig, 0, sizeof (struct sigaction));
+  memset (&old, 0, sizeof (struct sigaction));
+  sig.sa_flags = SA_NODEFER;
+  sig.sa_handler = &sigalrmHandler;
+  sigaction (SIGALRM, &sig, &old);
+  parg.shutdown = 1;
+  CLOSE(parg.pi[1]);
+  pthread_kill(pthr, SIGALRM);
+  pthread_join(pthr, &unused);
+  sigaction (SIGALRM, &old, &sig);
+  Fclose(fdi);
+  CLOSE(parg.pi[0]);
   return prev;
 }
 
-
-
-
 /* end of rpmextractor.c */

Modified: Extractor/src/plugins/thumbnailextractorqt.cc
===================================================================
--- Extractor/src/plugins/thumbnailextractorqt.cc       2008-07-22 06:26:37 UTC 
(rev 7506)
+++ Extractor/src/plugins/thumbnailextractorqt.cc       2008-07-22 08:56:49 UTC 
(rev 7507)
@@ -42,6 +42,8 @@
 extern "C"
 {
 
+
+#if 0
 QApplication *app;
 char *argv;
 
@@ -59,6 +61,7 @@
     delete app;
   free(argv);
 }
+#endif
 
 static EXTRACTOR_KeywordList * addKeyword(EXTRACTOR_KeywordType type,
                                          char * keyword,
@@ -98,12 +101,11 @@
   NULL
 };
 
-struct EXTRACTOR_Keywords * 
-libextractor_thumbnailqt_extract(const char * filename,
-                                const unsigned char * data,
-                                size_t size,
-                                struct EXTRACTOR_Keywords * prev,
-                                const char * options) {
+static struct EXTRACTOR_Keywords * 
+extract(const unsigned char * data,
+       size_t size,
+       struct EXTRACTOR_Keywords * prev,
+       const char * options) {
   QImage *img;
   QByteArray bytes;
   QBuffer buffer;
@@ -237,7 +239,43 @@
                    prev);
 }
 
+/* create new thread for C++ code (see Mantis #905) */
+
+struct X {
+  const unsigned char * data;
+  size_t size;
+  struct EXTRACTOR_Keywords * prev;
+  const char * options;
+};
+
+static void * run(void * arg) {
+  struct X * x = (struct X*) arg;
+  return extract(x->data, x->size, x->prev,
+                x->options);
+}
+
 struct EXTRACTOR_Keywords * 
+libextractor_thumbnailqt_extract(const char * filename,
+                                const unsigned char * data,
+                                size_t size,
+                                struct EXTRACTOR_Keywords * prev,
+                                const char * options) {
+  pthread_t pt;
+  struct X cls;
+
+  void * ret;
+  cls.data = data;
+  cls.size = size;
+  cls.prev = prev;
+  cls.options = options;
+  if (0 == pthread_create(&pt, NULL, &run, &cls))
+    if (0 == pthread_join(pt, &ret))
+      return (struct EXTRACTOR_Keywords*) ret;
+  return prev; 
+}
+
+
+struct EXTRACTOR_Keywords * 
 libextractor_thumbnail_extract(const char * filename,
                               const unsigned char * data,
                               size_t size,

Modified: Extractor/src/test/fuzz_default.sh
===================================================================
--- Extractor/src/test/fuzz_default.sh  2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/src/test/fuzz_default.sh  2008-07-22 08:56:49 UTC (rev 7507)
@@ -24,7 +24,7 @@
     trap "echo $tmpfile caused SIGSEGV ; exit 1" SEGV
     while [ $seed -lt $ZZSTOPSEED ]
     do
-      echo "file $file seed $seed"
+#      echo "file $file seed $seed"
       zzuf -c -s $seed cat "$file" > "$tmpfile"
       if ! "$bindir/extract" "$tmpfile" > /dev/null
       then

Modified: Extractor/src/test/fuzz_thumbnail.sh
===================================================================
--- Extractor/src/test/fuzz_thumbnail.sh        2008-07-22 06:26:37 UTC (rev 
7506)
+++ Extractor/src/test/fuzz_thumbnail.sh        2008-07-22 08:56:49 UTC (rev 
7507)
@@ -24,7 +24,7 @@
     trap "echo $tmpfile caused SIGSEGV ; exit 1" SEGV
     while [ $seed -lt $ZZSTOPSEED ]
     do
-      echo "file $file seed $seed"
+#      echo "file $file seed $seed"
       zzuf -c -s $seed cat "$file" > "$tmpfile"
       if ! "$bindir/extract" -n -l libextractor_thumbnail:libextractor_mime 
"$tmpfile" > /dev/null
       then

Modified: Extractor/src/test/mt_plugintest2.c
===================================================================
--- Extractor/src/test/mt_plugintest2.c 2008-07-22 06:26:37 UTC (rev 7506)
+++ Extractor/src/test/mt_plugintest2.c 2008-07-22 08:56:49 UTC (rev 7507)
@@ -14,6 +14,7 @@
 };
 
 static volatile int done = 0;
+
 static volatile int failed = 0;
 
 static void *
@@ -52,34 +53,39 @@
 
 #define TEST_SECS 10
 
+#define NUM_TASKS 10
+
 int
 main (int argc, char *argv[])
 {
-  int num_tasks = 10;
-  pthread_t task_list[num_tasks];
-  struct TaskData td[num_tasks];
+  pthread_t task_list[NUM_TASKS];
+  struct TaskData td[NUM_TASKS];
   int ret = 0;
   int i;
+  int max = NUM_TASKS;
+  void * unused;
 
   printf("testing for %d seconds\n", TEST_SECS);
-  for (i = 0; i < num_tasks; i++)
+  for (i = 0; i < NUM_TASKS; i++)
     {
       td[i].id = i;
-      ret = pthread_create (&task_list[i], NULL, test_plugins, &td[i]);
+      ret = pthread_create (&task_list[i], NULL, &test_plugins, &td[i]);
       if (ret != 0)
         {
           printf ("ERROR: pthread_create failed for thread %d\n", i);
-          num_tasks = i;
+          max = i;
           done = 1;
           break;
         }
     }
+  printf("Threads running!\n");
   if (!done)
     sleep (TEST_SECS);
+  printf("Shutting down...\n");
   done = 1;
-  for (i = 0; i < num_tasks; i++)
+  for (i = 0; i < max; i++)
     {
-      if (pthread_join (task_list[i], NULL) != 0)
+      if (pthread_join (task_list[i], &unused) != 0)
         printf ("WARNING: pthread_join failed for thread %d\n", i);
     }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]