diff --git a/CHANGES b/CHANGES
index 31638cd0a..457bf1b44 100644
--- a/CHANGES
+++ b/CHANGES
@@ -118,6 +118,7 @@
- fix: fsm reads/writes now return error on partial I/O.
- fix: Ferror returned spurious error for gzdio/bzdio.
- check for API/ABI creep, diddle up some compatibility.
+ - preliminary abstraction to support per-header methods.
4.0 -> 4.0.[12]
- add doxygen and lclint annotations most everywhere.
diff --git a/Doxyfile.in b/Doxyfile.in
index 380ed09e1..1322653ca 100644
--- a/Doxyfile.in
+++ b/Doxyfile.in
@@ -359,6 +359,9 @@ INPUT = \
@top_srcdir@/lib/fs.c \
@top_srcdir@/lib/fsm.c \
@top_srcdir@/lib/fsm.h \
+ @top_srcdir@/lib/hdrinline.c \
+ @top_srcdir@/lib/hdrinline.h \
+ @top_srcdir@/lib/hdrproto.h \
@top_srcdir@/lib/header.c \
@top_srcdir@/lib/header.h \
@top_srcdir@/lib/header_internal.c \
diff --git a/build/names.c b/build/names.c
index 4b9e4acaf..84470f705 100644
--- a/build/names.c
+++ b/build/names.c
@@ -112,9 +112,9 @@ const char *getGnameS(const char *gname)
}
/*@=nullderef@*/
-time_t *const getBuildTime(void)
+int_32 *const getBuildTime(void)
{
- static time_t buildTime[1];
+ static int_32 buildTime[1];
if (buildTime[0] == 0)
buildTime[0] = time(NULL);
diff --git a/build/parsePreamble.c b/build/parsePreamble.c
index efb5a4f58..161843e63 100644
--- a/build/parsePreamble.c
+++ b/build/parsePreamble.c
@@ -253,7 +253,7 @@ static int checkForValidArchitectures(Spec spec)
* @return 0 if OK
*/
static int checkForRequired(Header h, const char * NVR)
- /*@*/
+ /* LCL: parse error here with modifies */
{
int res = 0;
rpmTag * p;
diff --git a/build/rpmbuild.h b/build/rpmbuild.h
index 640180fa8..9b55c6458 100644
--- a/build/rpmbuild.h
+++ b/build/rpmbuild.h
@@ -126,7 +126,7 @@ void freeNames(void)
* Return build time stamp.
* @return build time stamp
*/
-/*@observer@*/ time_t * const getBuildTime(void) /*@*/;
+/*@observer@*/ int_32 * const getBuildTime(void) /*@*/;
/** \ingroup rpmbuild
* Read next line from spec file.
diff --git a/configure.in b/configure.in
index f5babb619..9f15f4ecc 100644
--- a/configure.in
+++ b/configure.in
@@ -1014,7 +1014,7 @@ mint) RPMCANONARCH=m68kmint ;;
esac
RPMCANONVENDOR="$build_vendor"
case "${build_vendor}" in
-unknown|pc|redhat|pld|mandrake|conectiva)
+unknown|pc|ibm|redhat|pld|mandrake|conectiva)
test -f /etc/redhat-release && RPMCANONVENDOR=redhat
test -f /etc/pld-release && RPMCANONVENDOR=pld
test -f /etc/mandrake-release && RPMCANONVENDOR=mandrake
diff --git a/doc/rpmbuild.8 b/doc/rpmbuild.8
new file mode 100644
index 000000000..555392910
--- /dev/null
+++ b/doc/rpmbuild.8
@@ -0,0 +1,245 @@
+.\" This manpage has been automatically generated by docbook2man
+.\" from a DocBook document. This tool can be found at:
+.\"
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng .
+.TH "RPMBUILD" "8" "06 June 2001" "Red Hat, Inc." "Red Hat Linux"
+.SH NAME
+rpmbuild \- Build RPM Package(s)
+.SH SYNOPSIS
+.SS "BUILDING PACKAGES:"
+.PP
+
+\fBrpmbuild\fR {\fB-ba|-bb|-bp|-bc|-bi|-bl|-bs\fR} [\fBrpmbuild-options\fR] \fB\fISPECFILE\fB\fR\fI ...\fR
+
+\fBrpmbuild\fR {\fB-ta|-tb|-tp|-tc|-ti|-tl|-ts\fR} [\fBrpmbuild-options\fR] \fB\fITARBALL\fB\fR\fI ...\fR
+
+\fBrpmbuild\fR {\fB--rebuild|--recompile\fR} \fB\fISOURCEPKG\fB\fR\fI ...\fR
+
+\fBrpmbuild\fR \fB--tarbuild\fR \fB\fITARBALL\fB\fR\fI ...\fR
+.SS "MISCELLANEOUS:"
+.PP
+
+\fBrpmbuild\fR {\fB--showrc\fR}
+.SS "RPMBUILD-OPTIONS"
+.PP
+
+\fB[--buildroot \fIDIRECTORY\fB] [--clean] [--nobuild] [--rmsource] [--rmspec]
+[--short-circuit] [--sign] [--target \fIPLATFORM\fB]\fR
+.SH "DESCRIPTION"
+.PP
+\fBrpmbuild\fR is used to build both binary and source software packages.
+A \fBpackage\fR consists of an archive of files and
+meta-data used to install and erase the archive files. The meta-data
+includes helper scripts, file attributes, and descriptive information
+about the package.
+\fBPackages\fR come in two varieties: binary packages,
+used to encapsulate software to be installed, and source packages,
+containing the source code and recipe necessary to produce binary
+packages.
+.PP
+One of the following basic modes must be selected:
+\fBBuild Package\fR,
+\fBBuild Package from Tarball\fR,
+\fBRecompile Package\fR,
+\fBShow Configuration\fR.
+.SS "GENERAL OPTIONS"
+.PP
+These options can be used in all the different modes.
+.TP
+\fB-?, --help\fR
+Print a longer usage message then normal.
+.TP
+\fB--version\fR
+Print a single line containing the version number of \fBrpm\fR
+being used.
+.TP
+\fB--quiet\fR
+Print as little as possible - normally only error messages will
+be displayed.
+.TP
+\fB-v\fR
+Print verbose information - normally routine progress messages will be
+displayed.
+.TP
+\fB-vv\fR
+Print lots of ugly debugging information.
+.TP
+\fB--rcfile \fIFILELIST\fB\fR
+Each of the files in the colon separated
+\fIFILELIST\fR
+is read sequentially by \fBrpm\fR for configuration
+information.
+Only the first file in the list must exist, and tildes will be
+expanded to the value of \fB$HOME\fR.
+The default \fIFILELIST\fR is
+\fI/usr/lib/rpm/rpmrc\fR:\fI/etc/rpmrc\fR:\fI~/.rpmrc\fR.
+.TP
+\fB--pipe \fICMD\fB\fR
+Pipes the output of \fBrpm\fR to the command \fICMD\fR.
+.TP
+\fB--dbpath \fIDIRECTORY\fB\fR
+Use the database in \fIDIRECTORY\fR rathen
+than the default path \fI/var/lib/rpm\fR
+.TP
+\fB--root \fIDIRECTORY\fB\fR
+Use the system rooted at \fIDIRECTORY\fR for all operations.
+Note that this means the database will be read or modified under
+\fIDIRECTORY\fR and any
+\fB%pre\fR or
+\fB%post\fR
+scriptlet(s) are run after a chroot(2) to
+\fIDIRECTORY\fR.
+.SS "BUILD OPTIONS"
+.PP
+The general form of an rpm build command is
+.PP
+\fBrpmbuild\fR {\fB-b\fISTAGE\fB|-t\fISTAGE\fB\fR} [\fBrpmbuild-options\fR] \fB\fIFILE\fB\fR\fI ...\fR
+.PP
+The argument used is \fB-b\fR if a spec file is being
+used to build the package and \fB-t\fR if \fBrpmbuild\fR
+should look inside of a (possibly compressed) tar file for
+the spec file to use. After the first argument, the next
+character (\fISTAGE\fR) specifies the stages
+of building and packaging to be done and is one of:
+.TP
+\fB-ba\fR
+Build binary and source packages (after doing the %prep, %build, and
+%install stages).
+.TP
+\fB-bb\fR
+Build a binary package (after doing the %prep, %build, and %install
+stages).
+.TP
+\fB-bp\fR
+Executes the "%prep" stage from the spec file. Normally this
+involves unpacking the sources and applying any patches.
+.TP
+\fB-bc\fR
+Do the "%build" stage from the spec file (after doing the %prep stage).
+This generally involves the equivalent of a "make".
+.TP
+\fB-bi\fR
+Do the "%install" stage from the spec file (after doing the %prep and
+%build stages). This generally involves the equivalent of a
+"make install".
+.TP
+\fB-bl\fR
+Do a "list check". The "%files" section from the spec file is
+macro expanded, and checks are made to verify that each file
+exists.
+.TP
+\fB-bs\fR
+Build just the source package.
+.PP
+The following options may also be used:
+.TP
+\fB--buildroot \fIDIRECTORY\fB\fR
+When building a package, override the BuildRoot tag with directory
+\fIDIRECTORY\fR.
+.TP
+\fB--clean\fR
+Remove the build tree after the packages are made.
+.TP
+\fB--nobuild\fR
+Do not execute any build stages. Useful for testing out spec files.
+.TP
+\fB--rmsource\fR
+Remove the sources after the build (may also be
+used standalone, e.g. "\fBrpmbuild\fR \fB--rmsource foo.spec\fR").
+.TP
+\fB--rmspec\fR
+Remove the spec file after the build (may also be
+used standalone, eg. "\fBrpmbuild\fR \fB--rmspec foo.spec\fR").
+.TP
+\fB--short-circuit\fR
+Skip straight to specified stage (i.e., skip all stages leading
+up to the specified stage). Only valid with \fB-bc\fR
+and \fB-bi\fR.
+.TP
+\fB--sign\fR
+Embed a GPG signature in the package. This signature can be used
+to verify the integrity and the origin of the package. See the
+section on GPG SIGNATURES for configuration details.
+.TP
+\fB--target \fIPLATFORM\fB\fR
+When building the package, interpret \fIPLATFORM\fR
+as \fBarch-vendor-os\fR and set the macros
+\fB%_target\fR,
+\fB%_target_arch\fR, and
+\fB%_target_os\fR
+accordingly.
+.SS "REBUILD AND RECOMPILE OPTIONS"
+.PP
+There are two other ways to invoke building with rpm:
+.PP
+\fBrpmbuild\fR {\fB--rebuild|--recompile\fR} \fB\fISOURCEPKG\fB\fR\fI ...\fR
+.PP
+When invoked this way, \fBrpmbuild\fR installs the named source
+package, and does a prep, compile and install. In addition,
+\fB--rebuild\fR builds a new binary package. When the build
+has completed, the build directory is removed (as in
+\fB--clean\fR) and the the sources and spec file for
+the package are removed.
+.SS "SHOWRC"
+.PP
+The command
+.PP
+\fBrpmbuild\fR \fB--showrc\fR
+.PP
+shows the values \fBrpmbuild\fR will use for all of the
+options are currently set in
+\fIrpmrc\fR and
+\fImacros\fR
+configuration file(s).
+.SH "FILES"
+.PP
+
+\fI/usr/lib/rpm/rpmrc\fR
+
+\fI/etc/rpmrc\fR
+
+\fI~/.rpmrc\fR
+
+\fI/usr/lib/rpm/macros\fR
+
+\fI/etc/rpm/macros\fR
+
+\fI~/.rpmmacros\fR
+
+\fI/var/lib/rpm/Conflictname\fR
+
+\fI/var/lib/rpm/Basenames\fR
+
+\fI/var/lib/rpm/Group\fR
+
+\fI/var/lib/rpm/Name\fR
+
+\fI/var/lib/rpm/Packages\fR
+
+\fI/var/lib/rpm/Providename\fR
+
+\fI/var/lib/rpm/Requirename\fR
+
+\fI/var/lib/rpm/Triggername\fR
+
+\fI/var/tmp/rpm*\fR
+.SH "SEE ALSO"
+
+\fBpopt\fR(3),
+
+\fBrpm2cpio\fR(8),
+
+\fBgendiff\fR(1),
+
+\fBrpm\fR(8),
+
+\fB http://www.rpm.org/
+\fR
+.SH "AUTHORS"
+
+Marc Ewing
+
+Jeff Johnson
+
+Erik Troan
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 245883c49..f1371b2ec 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -14,7 +14,8 @@ EXTRA_DIST = getdate.y
pkgincdir = $(pkgincludedir)
pkginc_HEADERS = \
- header.h misc.h rpmcli.h rpmlib.h stringbuf.h
+ header.h hdrinline.h hdrproto.h \
+ misc.h rpmcli.h rpmlib.h stringbuf.h
noinst_HEADERS = \
cpio.h depends.h fsm.h header_internal.h \
manifest.h md5.h psm.h \
@@ -32,7 +33,8 @@ LIBS =
lib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
cpio.c depends.c formats.c fs.c fsm.c getdate.c \
- header.c header_internal.c manifest.c md5.c md5sum.c misc.c package.c \
+ header.c hdrinline.c header_internal.c \
+ manifest.c md5.c md5sum.c misc.c package.c \
problems.c poptBT.c poptI.c poptK.c poptQV.c psm.c query.c \
rpmchecksig.c rpminstall.c rpmlead.c rpmlibprov.c rpmrc.c rpmvercmp.c \
signature.c stringbuf.c tagName.c tagtable.c transaction.c \
diff --git a/lib/hdrinline.c b/lib/hdrinline.c
new file mode 100644
index 000000000..ce9392e7a
--- /dev/null
+++ b/lib/hdrinline.c
@@ -0,0 +1,383 @@
+/** \ingroup header
+ * \file lib/hdrinline.c
+ */
+
+#include "system.h"
+
+#include
+
+#include "debug.h"
+
+int _hdrinline_debug = 0;
+
+/*@access Header @*/
+/*@access entryInfo @*/
+/*@access indexEntry @*/
+
+/*@access extensionCache @*/
+/*@access sprintfTag @*/
+/*@access sprintfToken @*/
+
+/**
+ * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
+ * @param p memory to free
+ * @return NULL always
+ */
+/*@unused@*/ static inline /*@null@*/ void *
+_free(/*@only@*/ /*@null@*/ const void * p) /*@modifies *p @*/
+{
+ if (p != NULL) free((void *)p);
+ return NULL;
+}
+
+Header headerNew()
+{
+ Header h = xcalloc(1, sizeof(*h));
+
+ /*@-assignexpose@*/
+ h->hv = hv; /* structure assignment */
+ /*@=assignexpose@*/
+ h->indexAlloced = INDEX_MALLOC_SIZE;
+ h->indexUsed = 0;
+ h->region_allocated = 0;
+ h->sorted = 1;
+ h->legacy = 0;
+ h->nrefs = 1;
+
+ h->index = (h->indexAlloced
+ ? xcalloc(h->indexAlloced, sizeof(*h->index))
+ : NULL);
+
+ /*@-globstate@*/
+ return h;
+ /*@=globstate@*/
+}
+
+Header headerLoad(void * uh)
+{
+ int_32 * ei = (int_32 *) uh;
+ int_32 il = ntohl(ei[0]); /* index length */
+ int_32 dl = ntohl(ei[1]); /* data length */
+ int pvlen = sizeof(il) + sizeof(dl) +
+ (il * sizeof(struct entryInfo)) + dl;
+ void * pv = uh;
+ Header h = xcalloc(1, sizeof(*h));
+ entryInfo pe;
+ char * dataStart;
+ indexEntry entry;
+ int rdlen;
+ int i;
+
+ ei = (int_32 *) pv;
+ /*@-castexpose@*/
+ pe = (entryInfo) &ei[2];
+ /*@=castexpose@*/
+ dataStart = (char *) (pe + il);
+
+ /*@-assignexpose@*/
+ h->hv = hv; /* structure assignment */
+ /*@=assignexpose@*/
+ h->indexAlloced = il + 1;
+ h->indexUsed = il;
+ h->index = xcalloc(h->indexAlloced, sizeof(*h->index));
+ h->sorted = 1;
+ h->region_allocated = 0;
+ h->nrefs = 1;
+
+ /*
+ * 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;
+ i = 0;
+ if (!(htonl(pe->tag) < HEADER_I18NTABLE)) {
+ h->legacy = 1;
+ entry->info.type = REGION_TAG_TYPE;
+ entry->info.tag = HEADER_IMAGE;
+ entry->info.count = REGION_TAG_COUNT;
+ entry->info.offset = ((char *)pe - dataStart); /* negative offset */
+
+ /*@-assignexpose@*/
+ entry->data = pe;
+ /*@=assignexpose@*/
+ entry->length = pvlen - sizeof(il) - sizeof(dl);
+ rdlen = regionSwab(entry+1, il, 0, pe, dataStart, entry->info.offset);
+ if (rdlen != dl) goto errxit;
+ entry->rdlen = rdlen;
+ entry++;
+ h->indexUsed++;
+ } else {
+ int nb = ntohl(pe->count);
+ int_32 rdl;
+ int_32 ril;
+
+ h->legacy = 0;
+ 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);
+
+ { int off = ntohl(pe->offset);
+ if (off) {
+ int_32 * stei = memcpy(alloca(nb), dataStart + off, nb);
+ rdl = -ntohl(stei[2]); /* negative offset */
+ ril = rdl/sizeof(*pe);
+ entry->info.tag = htonl(pe->tag);
+ } else {
+ ril = il;
+ rdl = (ril * sizeof(struct entryInfo));
+ entry->info.tag = HEADER_IMAGE;
+ }
+ }
+ entry->info.offset = -rdl; /* negative offset */
+
+ /*@-assignexpose@*/
+ entry->data = pe;
+ /*@=assignexpose@*/
+ 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->sorted = 0;
+ headerSort(h);
+
+ /*@-globstate@*/
+ return h;
+ /*@=globstate@*/
+
+errxit:
+ /*@-usereleased@*/
+ if (h) {
+ h->index = _free(h->index);
+ /*@-refcounttrans@*/
+ h = _free(h);
+ /*@=refcounttrans@*/
+ }
+ /*@=usereleased@*/
+ /*@-refcounttrans -globstate@*/
+ return h;
+ /*@=refcounttrans =globstate@*/
+}
+
+int headerWrite(FD_t fd, Header h, enum hMagic magicp)
+{
+ ssize_t nb;
+ int length;
+ const void * uh;
+
+ if (h == NULL)
+ return 1;
+ uh = doHeaderUnload(h, &length);
+ if (uh == NULL)
+ return 1;
+ switch (magicp) {
+ case HEADER_MAGIC_YES:
+ nb = Fwrite(header_magic, sizeof(char), sizeof(header_magic), fd);
+ if (nb != sizeof(header_magic))
+ goto exit;
+ break;
+ case HEADER_MAGIC_NO:
+ break;
+ }
+
+ nb = Fwrite(uh, sizeof(char), length, fd);
+
+exit:
+ uh = _free(uh);
+ return (nb == length ? 0 : 1);
+}
+
+Header headerCopyLoad(void * uh)
+{
+ int_32 * ei = (int_32 *) uh;
+ int_32 il = ntohl(ei[0]); /* index length */
+ int_32 dl = ntohl(ei[1]); /* data length */
+ int pvlen = sizeof(il) + sizeof(dl) +
+ (il * sizeof(struct entryInfo)) + dl;
+ void * nuh = memcpy(xmalloc(pvlen), uh, pvlen);
+ Header h;
+
+ h = headerLoad(nuh);
+ if (h == NULL) {
+ nuh = _free(nuh);
+ return h;
+ }
+ h->region_allocated = 1;
+ return h;
+}
+
+Header headerRead(FD_t fd, enum hMagic magicp)
+{
+ int_32 block[4];
+ int_32 reserved;
+ int_32 * ei = NULL;
+ int_32 il;
+ int_32 dl;
+ int_32 magic;
+ Header h = NULL;
+ int len;
+ int i;
+
+ memset(block, 0, sizeof(block));
+ i = 2;
+ if (magicp == HEADER_MAGIC_YES)
+ i += 2;
+
+ if (timedRead(fd, (char *)block, i*sizeof(*block)) != (i * sizeof(*block)))
+ goto exit;
+
+ i = 0;
+
+ if (magicp == HEADER_MAGIC_YES) {
+ magic = block[i++];
+ if (memcmp(&magic, header_magic, sizeof(magic)))
+ goto exit;
+ reserved = block[i++];
+ }
+
+ il = ntohl(block[i++]);
+ dl = ntohl(block[i++]);
+
+ len = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo)) + dl;
+
+ /*
+ * XXX Limit total size of header to 32Mb (~16 times largest known size).
+ */
+ if (len > (32*1024*1024))
+ goto exit;
+
+ ei = xmalloc(len);
+ ei[0] = htonl(il);
+ ei[1] = htonl(dl);
+ len -= sizeof(il) + sizeof(dl);
+
+ if (timedRead(fd, (char *)&ei[2], len) != len)
+ goto exit;
+
+ h = headerLoad(ei);
+
+exit:
+ if (h) {
+ if (h->region_allocated)
+ ei = _free(ei);
+ h->region_allocated = 1;
+ } else if (ei)
+ ei = _free(ei);
+ return h;
+}
+
+void headerCopyTags(Header headerFrom, Header headerTo, hTAG_t tagstocopy)
+{
+ int * p;
+
+ if (headerFrom == headerTo)
+ return;
+
+ for (p = tagstocopy; *p != 0; p++) {
+ char *s;
+ int_32 type;
+ int_32 count;
+ if (headerIsEntry(headerTo, *p))
+ continue;
+ if (!headerGetEntryMinMemory(headerFrom, *p, &type,
+ (hPTR_t *) &s, &count))
+ continue;
+ (void) headerAddEntry(headerTo, *p, type, s, count);
+ s = headerFreeData(s, type);
+ }
+}
+
+/**
+ * Header tag iterator data structure.
+ */
+struct headerIteratorS {
+/*@unused@*/ Header h; /*!< Header being iterated. */
+/*@unused@*/ int next_index; /*!< Next tag index. */
+};
+
+void headerFreeIterator(HeaderIterator hi)
+{
+ hi->h = headerFree(hi->h);
+ hi = _free(hi);
+}
+
+HeaderIterator headerInitIterator(Header h)
+{
+ HeaderIterator hi = xmalloc(sizeof(struct headerIteratorS));
+
+ headerSort(h);
+
+ hi->h = headerLink(h);
+ hi->next_index = 0;
+ return hi;
+}
+
+int headerNextIterator(HeaderIterator hi,
+ hTAG_t tag, hTYP_t type, hPTR_t * p, hCNT_t 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;
+ /*@-noeffect@*/ /* LCL: no clue */
+ hi->next_index++;
+ /*@=noeffect@*/
+
+ if (tag)
+ *tag = entry->info.tag;
+
+ rc = copyEntry(entry, type, p, c, 0);
+
+ /* XXX 1 on success */
+ return ((rc == 1) ? 1 : 0);
+}
diff --git a/lib/hdrinline.h b/lib/hdrinline.h
new file mode 100644
index 000000000..dc17010c4
--- /dev/null
+++ b/lib/hdrinline.h
@@ -0,0 +1,353 @@
+#ifndef H_HDRINLINE
+#define H_HDRINLINE
+
+/** \ingroup header
+ * \file lib/hdrinline.h
+ */
+
+/*@-exportlocal@*/
+extern int _hdrinline_debug;
+/*@=exportlocal@*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*@+voidabstract -nullpass -abstract -mustmod -compdef -shadow -predboolothers @*/
+
+#define HV(_h) ((HV_t *)(_h))
+
+/** \ingroup header
+ * Dereference a header instance.
+ * @param h header
+ * @return NULL always
+ */
+/*@unused@*/ static inline
+/*@null@*/ Header headerFree( /*@null@*/ /*@killref@*/ Header h)
+ /*@modifies h @*/
+{
+ if (h == NULL) return NULL;
+ return (HV(h)->free) (h);
+}
+
+/** \ingroup header
+ * Reference a header instance.
+ * @param h header
+ * @return referenced header instance
+ */
+/*@unused@*/ static inline
+Header headerLink(Header h)
+ /*@modifies h @*/
+{
+ return (HV(h)->link) (h);
+}
+
+/*@-exportlocal@*/
+/** \ingroup header
+ * Sort tags in header.
+ * @param h header
+ */
+/*@unused@*/ static inline
+void headerSort(Header h)
+ /*@modifies h @*/
+{
+ return (HV(h)->sort) (h);
+}
+
+/** \ingroup header
+ * Restore tags in header to original ordering.
+ * @param h header
+ */
+/*@unused@*/ static inline
+void headerUnsort(Header h)
+ /*@modifies h @*/
+{
+ return (HV(h)->unsort) (h);
+}
+/*@=exportlocal@*/
+
+/** \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
+ */
+/*@unused@*/ static inline
+unsigned int headerSizeof(/*@null@*/ Header h, enum hMagic magicp)
+ /*@modifies h @*/
+{
+ if (h == NULL) return 0;
+ return (HV(h)->size) (h, magicp);
+}
+
+/** \ingroup header
+ * Convert header to on-disk representation.
+ * @param h header (with pointers)
+ * @return on-disk header blob (i.e. with offsets)
+ */
+/*@unused@*/ static inline
+/*@only@*/ /*@null@*/ void * headerUnload(Header h)
+ /*@modifies h @*/
+{
+ return (HV(h)->unload) (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)
+ */
+/*@unused@*/ static inline
+/*@null@*/ Header headerReload(/*@only@*/ Header h, int tag)
+ /*@modifies h @*/
+{
+ return (HV(h)->reload) (h, tag);
+}
+
+/** \ingroup header
+ * Duplicate a header.
+ * @param h header
+ * @return new header instance
+ */
+/*@unused@*/ static inline
+/*@null@*/ Header headerCopy(Header h)
+ /*@modifies h @*/
+{
+ return (HV(h)->copy) (h);
+}
+
+/** \ingroup header
+ * Check if tag is in header.
+ * @param h header
+ * @param tag tag
+ * @return 1 on success, 0 on failure
+ */
+/*@unused@*/ static inline
+int headerIsEntry(/*@null@*/Header h, int_32 tag)
+ /*@modifies h @*/
+{
+ if (h == NULL) return 0;
+ return (HV(h)->isentry) (h, tag);
+}
+
+/** \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
+ */
+/*@unused@*/ static inline
+int headerGetEntry(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ void ** p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/
+{
+ return (HV(h)->get) (h, tag, 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
+ */
+/*@unused@*/ static inline
+int headerGetEntryMinMemory(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/
+{
+ return (HV(h)->getmin) (h, tag, type, p, c);
+}
+
+/** \ingroup header
+ * Retrieve tag value with type match.
+ * If *type is RPM_NULL_TYPE any type will match, otherwise only *type will
+ * match.
+ *
+ * @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
+ */
+/*@-exportlocal@*/
+/*@unused@*/ static inline
+int headerGetRawEntry(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/
+{
+ return (HV(h)->getraw) (h, tag, type, p, c);
+}
+/*@=exportlocal@*/
+
+/** \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
+ */
+/*@mayexit@*/
+/*@unused@*/ static inline
+int headerAddEntry(Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies h @*/
+{
+ return (HV(h)->add) (h, tag, type, p, c);
+}
+
+/** \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
+ */
+/*@unused@*/ static inline
+int headerAppendEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies h @*/
+{
+ return (HV(h)->append) (h, tag, type, p, c);
+}
+
+/** \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
+ */
+/*@unused@*/ static inline
+int headerAddOrAppendEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies h @*/
+{
+ return (HV(h)->addorappend) (h, tag, type, p, c);
+}
+
+/** \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
+ */
+/*@unused@*/ static inline
+int headerAddI18NString(Header h, int_32 tag, const char * string,
+ const char * lang)
+ /*@modifies h @*/
+{
+ return (HV(h)->addi18n) (h, tag, string, lang);
+}
+
+/** \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
+ */
+/*@unused@*/ static inline
+int headerModifyEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies h @*/
+{
+ return (HV(h)->modify) (h, tag, type, p, c);
+}
+
+/** \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)
+ */
+/*@unused@*/ static inline
+int headerRemoveEntry(Header h, int_32 tag)
+ /*@modifies h @*/
+{
+ return (HV(h)->remove) (h, tag);
+}
+
+/** \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)
+ */
+/*@unused@*/ static inline
+/*@only@*/ char * headerSprintf(Header h, const char * fmt,
+ const struct headerTagTableEntry * tags,
+ const struct headerSprintfExtension * extensions,
+ /*@null@*/ /*@out@*/ errmsg_t * errmsg)
+ /*@modifies *errmsg @*/
+{
+ return (HV(h)->sprintf) (h, fmt, tags, extensions, errmsg);
+}
+/*@=voidabstract =nullpass =abstract =mustmod =compdef =shadow =predboolothers @*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_HDRINLINE */
diff --git a/lib/hdrproto.h b/lib/hdrproto.h
new file mode 100644
index 000000000..96735ffaf
--- /dev/null
+++ b/lib/hdrproto.h
@@ -0,0 +1,266 @@
+#ifndef H_HDRPROTO
+#define H_HDRPROTO
+
+/** \ingroup header
+ * \file lib/hdrproto.h
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \ingroup header
+ * Dereference a header instance.
+ * @param h header
+ * @return NULL always
+ */
+/*@null@*/ Header headerFree( /*@null@*/ /*@killref@*/ Header h)
+ /*@modifies h @*/;
+
+/** \ingroup header
+ * Reference a header instance.
+ * @param h header
+ * @return referenced header instance
+ */
+Header headerLink(Header h)
+ /*@modifies h @*/;
+
+/*@-exportlocal@*/
+/** \ingroup header
+ * Sort tags in header.
+ * @param h header
+ */
+void headerSort(Header h)
+ /*@modifies h @*/;
+
+/** \ingroup header
+ * Restore tags in header to original ordering.
+ * @param h header
+ */
+void headerUnsort(Header h)
+ /*@modifies h @*/;
+/*@=exportlocal@*/
+
+/** \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
+ */
+unsigned int headerSizeof(/*@null@*/ Header h, enum hMagic magicp)
+ /*@modifies h @*/;
+
+/** \ingroup header
+ * Convert header to on-disk representation.
+ * @param h header (with pointers)
+ * @return on-disk header blob (i.e. with offsets)
+ */
+/*@only@*/ /*@null@*/ void * headerUnload(Header h)
+ /*@modifies 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)
+ */
+/*@null@*/ Header headerReload(/*@only@*/ Header h, int tag)
+ /*@modifies h @*/;
+
+/** \ingroup header
+ * Duplicate a header.
+ * @param h header
+ * @return new header instance
+ */
+/*@null@*/ Header headerCopy(Header h)
+ /*@modifies h @*/;
+
+/** \ingroup header
+ * Check if tag is in header.
+ * @param h header
+ * @param tag tag
+ * @return 1 on success, 0 on failure
+ */
+int headerIsEntry(/*@null@*/Header h, int_32 tag)
+ /*@*/;
+
+/** \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
+ */
+int headerGetEntry(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ void ** p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *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
+ */
+int headerGetEntryMinMemory(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/;
+
+/** \ingroup header
+ * Retrieve tag value with type match.
+ * If *type is RPM_NULL_TYPE any type will match, otherwise only *type will
+ * match.
+ *
+ * @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
+ */
+/*@-exportlocal@*/
+int headerGetRawEntry(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/;
+/*@=exportlocal@*/
+
+/** \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
+ */
+/*@mayexit@*/
+int headerAddEntry(Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies 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
+ */
+int headerAppendEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies 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
+ */
+int headerAddOrAppendEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies 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
+ */
+int headerAddI18NString(Header h, int_32 tag, const char * string,
+ const char * lang)
+ /*@modifies 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
+ */
+int headerModifyEntry(Header h, int_32 tag, int_32 type,
+ const void * p, int_32 c)
+ /*@modifies 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)
+ */
+int headerRemoveEntry(Header h, int_32 tag)
+ /*@modifies h @*/;
+
+/** \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)
+ */
+/*@only@*/ char * headerSprintf(Header h, const char * fmt,
+ const struct headerTagTableEntry * tags,
+ const struct headerSprintfExtension * extensions,
+ /*@null@*/ /*@out@*/ errmsg_t * errmsg)
+ /*@modifies *errmsg @*/;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_HDRPROTO */
diff --git a/lib/header.c b/lib/header.c
index 3237a9d4e..65df111f2 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -2,10 +2,6 @@
* \file lib/header.c
*/
-#undef REMALLOC_HEADER_REGION
-#define _DEBUG_SWAB 1
-#define _DEBUG_INDEX 1
-
/* RPM - Copyright (C) 1995-2000 Red Hat Software */
/* Data written to file descriptors is in network byte order. */
@@ -14,6 +10,8 @@
#include "system.h"
+#define __HEADER_PROTOTYPES__
+
#include
#include "debug.h"
@@ -22,19 +20,18 @@
/*@observer@*/ const char *const tagName(int tag) /*@*/;
/*@=redecl@*/
-/*
- * Teach header.c about legacy tags.
- */
-#define HEADER_OLDFILENAMES 1027
-#define HEADER_BASENAMES 1117
+/*@access entryInfo @*/
+/*@access indexEntry @*/
-#define INDEX_MALLOC_SIZE 8
+/*@access extensionCache @*/
+/*@access sprintfTag @*/
+/*@access sprintfToken @*/
#define PARSER_BEGIN 0
#define PARSER_IN_ARRAY 1
#define PARSER_IN_EXPR 2
-static unsigned char header_magic[8] = {
+unsigned char header_magic[8] = {
0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
};
@@ -66,6 +63,131 @@ _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies *p @*/
return NULL;
}
+Header headerFree(Header h)
+{
+ 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->region_allocated && ENTRY_IS_REGION(entry)) {
+ if (entry->length > 0) {
+ int_32 * ei = entry->data;
+ ei -= 2; /* XXX HACK: adjust to beginning of header. */
+ ei = _free(ei);
+ }
+ } else if (!ENTRY_IN_REGION(entry)) {
+ entry->data = _free(entry->data);
+ }
+ entry->data = NULL;
+ }
+ h->index = _free(h->index);
+ }
+
+ /*@-refcounttrans@*/ h = _free(h); /*@=refcounttrans@*/
+ return h;
+}
+
+Header headerLink(Header h)
+{
+ h->nrefs++;
+ /*@-refcounttrans@*/ return h; /*@=refcounttrans@*/
+}
+
+/**
+ */
+static int indexCmp(const void * avp, const void * bvp) /*@*/
+{
+ /*@-castexpose@*/
+ indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
+ /*@=castexpose@*/
+ return (ap->info.tag - bp->info.tag);
+}
+
+void headerSort(Header h)
+{
+ if (!h->sorted) {
+ qsort(h->index, h->indexUsed, sizeof(*h->index), indexCmp);
+ h->sorted = 1;
+ }
+}
+
+/**
+ */
+static int offsetCmp(const void * avp, const void * bvp) /*@*/
+{
+ /*@-castexpose@*/
+ indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
+ /*@=castexpose@*/
+ int rc = (ap->info.offset - bp->info.offset);
+
+ if (rc == 0)
+ rc = (ap->info.tag - bp->info.tag);
+ return rc;
+}
+
+void headerUnsort(Header h)
+{
+ qsort(h->index, h->indexUsed, sizeof(*h->index), offsetCmp);
+}
+
+unsigned int headerSizeof(Header h, enum hMagic magicp)
+{
+ indexEntry entry;
+ unsigned int size = 0;
+ unsigned int pad = 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;
+ }
+
+ size += 2 * sizeof(int_32); /* count of index entries */
+
+ 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. */
+ if (i == 0 && h->legacy)
+ size += sizeof(struct entryInfo) + entry->info.count;
+ 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;
+ pad += diff;
+ }
+ }
+
+ size += sizeof(struct entryInfo) + entry->length;
+ }
+
+ return size;
+}
+
/**
* Return length of entry data.
* @param type entry data type
@@ -75,7 +197,7 @@ _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies *p @*/
* @return no. bytes in data
*/
/*@mayexit@*/
-static int dataLength(int_32 type, const void * p, int_32 count, int onDisk)
+static int dataLength(int_32 type, hPTR_t p, int_32 count, int onDisk)
/*@modifies fileSystem @*/
{
int length = 0;
@@ -130,33 +252,8 @@ static int dataLength(int_32 type, const void * p, int_32 count, int onDisk)
return length;
}
-/**
- * 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(/*@null@*/ struct indexEntry * entry, int il, int dl,
- const struct entryInfo * pe, char * dataStart, int regionid)
+int regionSwab(/*@null@*/ indexEntry entry, int il, int dl,
+ entryInfo pe, char * dataStart, int regionid)
/*@modifies *entry, *dataStart @*/
{
char * tprev = NULL;
@@ -224,369 +321,10 @@ static int regionSwab(/*@null@*/ struct indexEntry * entry, int il, int dl,
return dl;
}
-/**
- * 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 struct indexEntry * entry,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** p,
- /*@null@*/ /*@out@*/ int_32 * c,
- int minMem)
- /*@modifies *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 HEADER_IMMUTABLE */
- if (ENTRY_IS_REGION(entry)) {
- int_32 * ei = ((int_32 *)entry->data) - 2;
- struct entryInfo * pe = (struct entryInfo *) (ei + 2);
- char * dataStart = (char *) (pe + ntohl(ei[0]));
- int_32 rdl = -entry->info.offset; /* negative offset */
- int_32 ril = rdl/sizeof(*pe);
-
- count = 2 * sizeof(*ei) + (ril * sizeof(*pe)) +
- entry->rdlen + REGION_TAG_COUNT;
- *p = xmalloc(count);
- ei = (int_32 *) *p;
- ei[0] = htonl(ril);
- ei[1] = htonl(entry->rdlen + REGION_TAG_COUNT);
- pe = (struct entryInfo *) memcpy(ei + 2, pe, (ril * sizeof(*pe)));
- dataStart = (char *) memcpy(pe + ril, dataStart,
- (entry->rdlen + REGION_TAG_COUNT));
-
- rc = regionSwab(NULL, ril, 0, pe, dataStart, 0);
- /* XXX 1 on success. */
- rc = (rc < 0) ? 0 : 1;
- } else {
- count = entry->length;
- *p = (!minMem
- ? memcpy(xmalloc(count), entry->data, count)
- : entry->data);
- }
- break;
- case RPM_STRING_TYPE:
- if (count == 1) {
- *p = entry->data;
- break;
- }
- /*@fallthrough@*/
- case RPM_STRING_ARRAY_TYPE:
- case RPM_I18NSTRING_TYPE:
- { const char ** ptrEntry;
- int tableSize = count * sizeof(char *);
- char * t;
- int i;
-
- /*@-mods@*/
- if (minMem) {
- *p = xmalloc(tableSize);
- ptrEntry = (const char **) *p;
- t = entry->data;
- } else {
- t = xmalloc(tableSize + entry->length);
- *p = (void *)t;
- ptrEntry = (const char **) *p;
- t += tableSize;
- memcpy(t, entry->data, entry->length);
- }
- /*@=mods@*/
- 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;
-}
-
-/**
- * Header tag iterator data structure.
- */
-struct headerIteratorS {
- Header h; /*!< Header being iterated. */
- int next_index; /*!< Next tag index. */
-};
-
-HeaderIterator headerInitIterator(Header h)
-{
- HeaderIterator hi = xmalloc(sizeof(struct headerIteratorS));
-
- headerSort(h);
-
- hi->h = headerLink(h);
- hi->next_index = 0;
- return hi;
-}
-
-void headerFreeIterator(HeaderIterator hi)
-{
- hi->h = headerFree(hi->h);
- hi = _free(hi);
-}
-
-int headerNextIterator(HeaderIterator hi,
- int_32 * tag, int_32 * type, const void ** p, int_32 * c)
-{
- Header h = hi->h;
- int slot = hi->next_index;
- struct 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;
- hi->next_index++;
-
- if (tag)
- *tag = entry->info.tag;
-
- rc = copyEntry(entry, type, p, c, 0);
-
- /* XXX 1 on success */
- return ((rc == 1) ? 1 : 0);
-}
-
-/**
- */
-static int indexCmp(const void *avp, const void *bvp) /*@*/
-{
- const struct indexEntry * ap = avp, * bp = bvp;
- return (ap->info.tag - bp->info.tag);
-}
-
-void headerSort(Header h)
-{
- if (!h->sorted) {
- qsort(h->index, h->indexUsed, sizeof(*h->index), indexCmp);
- h->sorted = 1;
- }
-}
-
-/**
- */
-static int offsetCmp(const void *avp, const void *bvp) /*@*/
-{
- const struct indexEntry * ap = avp, * bp = bvp;
- int rc = (ap->info.offset - bp->info.offset);
-
- if (rc == 0)
- rc = (ap->info.tag - bp->info.tag);
- return rc;
-}
-
-void headerUnsort(Header h)
-{
- qsort(h->index, h->indexUsed, sizeof(*h->index), offsetCmp);
-}
-
-Header headerCopy(Header h)
-{
- Header nh = headerNew();
- HeaderIterator hi;
- int_32 tag, type, count;
- const void *ptr;
-
- for (hi = headerInitIterator(h);
- headerNextIterator(hi, &tag, &type, &ptr, &count);
- ptr = headerFreeData((void *)ptr, type))
- {
- if (ptr) (void) headerAddEntry(nh, tag, type, ptr, count);
- }
- headerFreeIterator(hi);
-
- return headerReload(nh, HEADER_IMAGE);
-}
-
-Header headerLoad(void *uh)
-{
- int_32 *ei = (int_32 *) uh;
- int_32 il = ntohl(ei[0]); /* index length */
- int_32 dl = ntohl(ei[1]); /* data length */
- int pvlen = sizeof(il) + sizeof(dl) +
- (il * sizeof(struct entryInfo)) + dl;
-#ifdef REMALLOC_HEADER_REGION
- void * pv = memcpy(xmalloc(pvlen), uh, pvlen);
-#else
- void * pv = uh;
-#endif
- Header h = xcalloc(1, sizeof(*h));
- struct entryInfo * pe;
- char * dataStart;
- struct indexEntry * entry;
- int rdlen;
- int i;
-
- ei = (int_32 *) pv;
- pe = (struct entryInfo *) &ei[2];
- dataStart = (char *) (pe + il);
-
- h->indexAlloced = il + 1;
- h->indexUsed = il;
- h->index = xcalloc(h->indexAlloced, sizeof(*h->index));
- h->sorted = 1;
-#ifdef REMALLOC_HEADER_REGION
- h->region_allocated = 1;
-#else
- h->region_allocated = 0;
-#endif
- h->nrefs = 1;
-
- /*
- * 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;
- i = 0;
- if (!(htonl(pe->tag) < HEADER_I18NTABLE)) {
- h->legacy = 1;
- entry->info.type = REGION_TAG_TYPE;
- entry->info.tag = HEADER_IMAGE;
- entry->info.count = REGION_TAG_COUNT;
- entry->info.offset = ((char *)pe - dataStart); /* negative offset */
-
- entry->data = pe;
- entry->length = pvlen - sizeof(il) - sizeof(dl);
- rdlen = regionSwab(entry+1, il, 0, pe, dataStart, entry->info.offset);
- if (rdlen != dl) goto errxit;
- entry->rdlen = rdlen;
- entry++;
- h->indexUsed++;
- } else {
- int nb = ntohl(pe->count);
- int_32 rdl;
- int_32 ril;
-
- h->legacy = 0;
- entry->info.type = htonl(pe->type);
- if (entry->info.type < RPM_MIN_TYPE || entry->info.type > RPM_MAX_TYPE)
- return NULL;
- entry->info.count = htonl(pe->count);
-
- { int off = ntohl(pe->offset);
- if (off) {
- int_32 * stei = memcpy(alloca(nb), dataStart + off, nb);
- rdl = -ntohl(stei[2]); /* negative offset */
- ril = rdl/sizeof(*pe);
- entry->info.tag = htonl(pe->tag);
- } else {
- ril = il;
- rdl = (ril * sizeof(struct entryInfo));
- entry->info.tag = HEADER_IMAGE;
- }
- }
- entry->info.offset = -rdl; /* negative offset */
-
- entry->data = pe;
- 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) {
- struct 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;
-
- { struct 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->sorted = 0;
- headerSort(h);
-
- return h;
-
-errxit:
- /*@-usereleased@*/
- if (h) {
- h->index = _free(h->index);
- /*@-refcounttrans@*/
- h = _free(h);
- /*@=refcounttrans@*/
- }
- /*@=usereleased@*/
- /*@-refcounttrans@*/
- return h;
- /*@=refcounttrans@*/
-}
-
-Header headerCopyLoad(void *uh)
-{
- int_32 *ei = (int_32 *) uh;
- int_32 il = ntohl(ei[0]); /* index length */
- int_32 dl = ntohl(ei[1]); /* data length */
- int pvlen = sizeof(il) + sizeof(dl) +
- (il * sizeof(struct entryInfo)) + dl;
- void * nuh = memcpy(xmalloc(pvlen), uh, pvlen);
- Header h;
-
- h = headerLoad(nuh);
- if (h == NULL) {
- nuh = _free(nuh);
- return h;
- }
- h->region_allocated = 1;
- return h;
-}
-
#if 0
int headerDrips(const Header h)
{
- struct indexEntry * entry;
+ indexEntry entry;
int i;
for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) {
@@ -610,21 +348,18 @@ int headerDrips(const Header h)
}
#endif
-/**
- */
-static /*@only@*/ /*@null@*/ void * doHeaderUnload(Header h,
- /*@out@*/ int * lengthPtr)
+/*@only@*/ /*@null@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
/*@modifies h, *lengthPtr @*/
{
int_32 * ei = NULL;
- struct entryInfo * pe;
+ entryInfo pe;
char * dataStart;
char * te;
unsigned pad;
unsigned len;
int_32 il = 0;
int_32 dl = 0;
- struct indexEntry * entry;
+ indexEntry entry;
int_32 type;
int i;
int drlen, ndribbles;
@@ -704,7 +439,7 @@ static /*@only@*/ /*@null@*/ void * doHeaderUnload(Header h,
ei[0] = htonl(il);
ei[1] = htonl(dl);
- pe = (struct entryInfo *) &ei[2];
+ pe = (entryInfo) &ei[2];
dataStart = te = (char *) (pe + il);
pad = 0;
@@ -757,7 +492,9 @@ t = te;
memcpy(pe+1, src + sizeof(*pe), ((ril-1) * sizeof(*pe)));
memcpy(te, src + (ril * sizeof(*pe)), rdlen+entry->info.count+drlen);
te += rdlen;
- { struct entryInfo * se = (struct entryInfo *)src;
+ { /*@-castexpose@*/
+ entryInfo se = (entryInfo)src;
+ /*@=castexpose@*/
int off = ntohl(se->offset);
pe->offset = (off) ? htonl(te - dataStart) : htonl(off);
}
@@ -878,92 +615,22 @@ Header headerReload(Header h, int tag)
return nh;
}
-int headerWrite(FD_t fd, Header h, enum hMagic magicp)
+Header headerCopy(Header h)
{
- ssize_t nb;
- int length;
- const void * uh;
-
- if (h == NULL)
- return 1;
- uh = doHeaderUnload(h, &length);
- if (uh == NULL)
- return 1;
- switch (magicp) {
- case HEADER_MAGIC_YES:
- nb = Fwrite(header_magic, sizeof(char), sizeof(header_magic), fd);
- if (nb != sizeof(header_magic))
- goto exit;
- break;
- case HEADER_MAGIC_NO:
- break;
+ Header nh = headerNew();
+ HeaderIterator hi;
+ int_32 tag, type, count;
+ hPTR_t ptr;
+
+ for (hi = headerInitIterator(h);
+ headerNextIterator(hi, &tag, &type, &ptr, &count);
+ ptr = headerFreeData((void *)ptr, type))
+ {
+ if (ptr) (void) headerAddEntry(nh, tag, type, ptr, count);
}
+ headerFreeIterator(hi);
- nb = Fwrite(uh, sizeof(char), length, fd);
-
-exit:
- uh = _free(uh);
- return (nb == length ? 0 : 1);
-}
-
-Header headerRead(FD_t fd, enum hMagic magicp)
-{
- int_32 block[4];
- int_32 reserved;
- int_32 * ei = NULL;
- int_32 il;
- int_32 dl;
- int_32 magic;
- Header h = NULL;
- int len;
- int i;
-
- memset(block, 0, sizeof(block));
- i = 2;
- if (magicp == HEADER_MAGIC_YES)
- i += 2;
-
- if (timedRead(fd, (char *)block, i*sizeof(*block)) != (i * sizeof(*block)))
- goto exit;
-
- i = 0;
-
- if (magicp == HEADER_MAGIC_YES) {
- magic = block[i++];
- if (memcmp(&magic, header_magic, sizeof(magic)))
- goto exit;
- reserved = block[i++];
- }
-
- il = ntohl(block[i++]);
- dl = ntohl(block[i++]);
-
- len = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo)) + dl;
-
- /*
- * XXX Limit total size of header to 32Mb (~16 times largest known size).
- */
- if (len > (32*1024*1024))
- goto exit;
-
- ei = xmalloc(len);
- ei[0] = htonl(il);
- ei[1] = htonl(dl);
- len -= sizeof(il) + sizeof(dl);
-
- if (timedRead(fd, (char *)&ei[2], len) != len)
- goto exit;
-
- h = headerLoad(ei);
-
-exit:
- if (h) {
- if (h->region_allocated)
- ei = _free(ei);
- h->region_allocated = 1;
- } else if (ei)
- ei = _free(ei);
- return h;
+ return headerReload(nh, HEADER_IMAGE);
}
/**
@@ -974,10 +641,10 @@ exit:
* @return header entry
*/
static /*@null@*/
-struct indexEntry * findEntry(/*@null@*/ Header h, int_32 tag, int_32 type)
+indexEntry findEntry(/*@null@*/ Header h, int_32 tag, int_32 type)
/*@modifies h @*/
{
- struct indexEntry * entry, * entry2, * last;
+ indexEntry entry, entry2, last;
struct indexEntry key;
if (h == NULL) return NULL;
@@ -1017,28 +684,91 @@ int headerIsEntry(Header h, int_32 tag)
/*@=mods@*/
}
-int headerGetRawEntry(Header h, int_32 tag, int_32 * type, const void ** p,
- int_32 *c)
+int copyEntry(const indexEntry entry,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c,
+ int minMem)
+ /*@modifies *type, *p, *c @*/
{
- struct indexEntry * entry;
- int rc;
+ int_32 count = entry->info.count;
+ int rc = 1; /* XXX 1 on success. */
- if (p == NULL) return headerIsEntry(h, tag);
+ if (p)
+ switch (entry->info.type) {
+ case RPM_BIN_TYPE:
+ /* XXX this only works for HEADER_IMMUTABLE */
+ if (ENTRY_IS_REGION(entry)) {
+ int_32 * ei = ((int_32 *)entry->data) - 2;
+ /*@-castexpose@*/
+ entryInfo pe = (entryInfo) (ei + 2);
+ /*@=castexpose@*/
+ char * dataStart = (char *) (pe + ntohl(ei[0]));
+ int_32 rdl = -entry->info.offset; /* negative offset */
+ int_32 ril = rdl/sizeof(*pe);
- /* First find the tag */
- /*@-mods@*/ /*@ FIX: h modified by sort. */
- entry = findEntry(h, tag, RPM_NULL_TYPE);
- /*@=mods@*/
- if (!entry) {
- if (p) *p = NULL;
- if (c) *c = 0;
- return 0;
+ count = 2 * sizeof(*ei) + (ril * sizeof(*pe)) +
+ entry->rdlen + REGION_TAG_COUNT;
+ *p = xmalloc(count);
+ ei = (int_32 *) *p;
+ ei[0] = htonl(ril);
+ ei[1] = htonl(entry->rdlen + REGION_TAG_COUNT);
+ /*@-castexpose@*/
+ pe = (entryInfo) memcpy(ei + 2, pe, (ril * sizeof(*pe)));
+ /*@=castexpose@*/
+ dataStart = (char *) memcpy(pe + ril, dataStart,
+ (entry->rdlen + REGION_TAG_COUNT));
+
+ rc = regionSwab(NULL, ril, 0, pe, dataStart, 0);
+ /* XXX 1 on success. */
+ rc = (rc < 0) ? 0 : 1;
+ } else {
+ count = entry->length;
+ *p = (!minMem
+ ? memcpy(xmalloc(count), entry->data, count)
+ : entry->data);
+ }
+ break;
+ case RPM_STRING_TYPE:
+ if (count == 1) {
+ *p = entry->data;
+ break;
+ }
+ /*@fallthrough@*/
+ case RPM_STRING_ARRAY_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ { const char ** ptrEntry;
+ int tableSize = count * sizeof(char *);
+ char * t;
+ int i;
+
+ /*@-mods@*/
+ if (minMem) {
+ *p = xmalloc(tableSize);
+ ptrEntry = (const char **) *p;
+ t = entry->data;
+ } else {
+ t = xmalloc(tableSize + entry->length);
+ *p = (void *)t;
+ ptrEntry = (const char **) *p;
+ t += tableSize;
+ memcpy(t, entry->data, entry->length);
+ }
+ /*@=mods@*/
+ for (i = 0; i < count; i++) {
+ *ptrEntry++ = t;
+ t = strchr(t, 0);
+ t++;
+ }
+ } break;
+
+ default:
+ *p = entry->data;
+ break;
}
-
- rc = copyEntry(entry, type, p, c, 0);
-
- /* XXX 1 on success */
- return ((rc == 1) ? 1 : 0);
+ if (type) *type = entry->info.type;
+ if (c) *c = count;
+ return rc;
}
/**
@@ -1132,20 +862,24 @@ static int headerMatchLocale(const char *td, const char *l, const char *le)
* @return matching i18n string (or 1st string if no match)
*/
/*@dependent@*/ static char *
-headerFindI18NString(Header h, struct indexEntry *entry)
+headerFindI18NString(Header h, indexEntry entry)
{
const char *lang, *l, *le;
- struct indexEntry * table;
+ 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)
- /*@-retalias@*/ return entry->data; /*@=retalias@*/
+ /*@-retalias -retexpose@*/
+ return entry->data;
+ /*@=retalias =retexpose@*/
if ((table = findEntry(h, HEADER_I18NTABLE, RPM_STRING_ARRAY_TYPE)) == NULL)
- /*@-retalias@*/ return entry->data; /*@=retalias@*/
+ /*@-retalias -retexpose@*/
+ return entry->data;
+ /*@=retalias =retexpose@*/
for (l = lang; *l != '\0'; l = le) {
const char *td;
@@ -1170,7 +904,9 @@ headerFindI18NString(Header h, struct indexEntry *entry)
}
}
- /*@-retalias@*/ return entry->data; /*@=retalias@*/
+ /*@-retalias -retexpose@*/
+ return entry->data;
+ /*@=retalias =retexpose@*/
}
/**
@@ -1183,13 +919,14 @@ headerFindI18NString(Header h, struct indexEntry *entry)
* @param minMem string pointers reference header memory?
* @return 1 on success, 0 on not found
*/
-static int intGetEntry(Header h, int_32 tag, /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** p,
- /*@null@*/ /*@out@*/ int_32 *c,
- int minMem)
- /*@modifies *type, *p, *c @*/
+static int intGetEntry(Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTAG_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c,
+ int minMem)
+ /*@modifies *type, *p, *c @*/
{
- struct indexEntry * entry;
+ indexEntry entry;
int rc;
/* First find the tag */
@@ -1221,128 +958,46 @@ static int intGetEntry(Header h, int_32 tag, /*@null@*/ /*@out@*/ int_32 * type,
return ((rc == 1) ? 1 : 0);
}
-int headerGetEntryMinMemory(Header h, int_32 tag, int_32 *type, const void **p,
- int_32 *c)
+int headerGetEntry(Header h, int_32 tag, hTYP_t type, void **p, hCNT_t c)
+{
+ return intGetEntry(h, tag, type, (hPTR_t *)p, c, 0);
+}
+
+int headerGetEntryMinMemory(Header h, int_32 tag, hTYP_t type, hPTR_t * p,
+ hCNT_t c)
{
return intGetEntry(h, tag, type, p, c, 1);
}
-int headerGetEntry(Header h, int_32 tag, int_32 * type, void **p, int_32 * c)
+int headerGetRawEntry(Header h, int_32 tag, int_32 * type, hPTR_t * p,
+ int_32 * c)
{
- return intGetEntry(h, tag, type, (const void **)p, c, 0);
-}
+ indexEntry entry;
+ int rc;
-Header headerNew()
-{
- Header h = xcalloc(1, sizeof(*h));
+ if (p == NULL) return headerIsEntry(h, tag);
- h->indexAlloced = INDEX_MALLOC_SIZE;
- h->indexUsed = 0;
- h->region_allocated = 0;
- h->sorted = 1;
- h->legacy = 0;
- h->nrefs = 1;
-
- h->index = (h->indexAlloced
- ? xcalloc(h->indexAlloced, sizeof(*h->index))
- : NULL);
-
- return h;
-}
-
-Header headerFree(Header h)
-{
- if (h == NULL || --h->nrefs > 0)
- return NULL; /* XXX return previous header? */
-
- if (h->index) {
- struct indexEntry * entry = h->index;
- int i;
- for (i = 0; i < h->indexUsed; i++, entry++) {
- if (h->region_allocated && ENTRY_IS_REGION(entry)) {
- if (entry->length > 0) {
- int_32 * ei = entry->data;
- ei -= 2; /* XXX HACK: adjust to beginning of header. */
- ei = _free(ei);
- }
- } else if (!ENTRY_IN_REGION(entry)) {
- entry->data = _free(entry->data);
- }
- entry->data = NULL;
- }
- h->index = _free(h->index);
+ /* First find the tag */
+ /*@-mods@*/ /*@ FIX: h modified by sort. */
+ entry = findEntry(h, tag, RPM_NULL_TYPE);
+ /*@=mods@*/
+ if (!entry) {
+ if (p) *p = NULL;
+ if (c) *c = 0;
+ return 0;
}
- /*@-refcounttrans@*/ h = _free(h); /*@=refcounttrans@*/
- return h;
-}
+ rc = copyEntry(entry, type, p, c, 0);
-Header headerLink(Header h)
-{
- h->nrefs++;
- /*@-refcounttrans@*/ return h; /*@=refcounttrans@*/
-}
-
-unsigned int headerSizeof(Header h, enum hMagic magicp)
-{
- struct indexEntry * entry;
- unsigned int size = 0;
- unsigned int pad = 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;
- }
-
- size += 2 * sizeof(int_32); /* count of index entries */
-
- 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. */
- if (i == 0 && h->legacy)
- size += sizeof(struct entryInfo) + entry->info.count;
- 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;
- pad += diff;
- }
- }
-
- size += sizeof(struct entryInfo) + entry->length;
- }
-
- return size;
+ /* XXX 1 on success */
+ return ((rc == 1) ? 1 : 0);
}
/**
*/
static void copyData(int_32 type, /*@out@*/ void * dstPtr, const void * srcPtr,
- int_32 c, int dataLength)
- /*@modifies *dstPtr @*/
+ int_32 c, int dataLength)
+ /*@modifies *dstPtr @*/
{
const char ** src;
char * dst;
@@ -1379,9 +1034,9 @@ static void copyData(int_32 type, /*@out@*/ void * dstPtr, const void * srcPtr,
* @retval lengthPtr no. bytes in returned data
* @return (malloc'ed) copy of entry data
*/
-static void * grabData(int_32 type, const void * p, int_32 c,
- /*@out@*/ int * lengthPtr)
- /*@modifies *lengthPtr @*/
+static void * grabData(int_32 type, hPTR_t p, int_32 c,
+ /*@out@*/ int * lengthPtr)
+ /*@modifies *lengthPtr @*/
{
int length = dataLength(type, p, c, 0);
void * data = xmalloc(length);
@@ -1393,9 +1048,9 @@ static void * grabData(int_32 type, const void * p, int_32 c,
return data;
}
-int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
+int headerAddEntry(Header h, int_32 tag, int_32 type, hPTR_t p, int_32 c)
{
- struct indexEntry *entry;
+ indexEntry entry;
/* Count must always be >= 1 for headerAddEntry. */
if (c <= 0)
@@ -1422,9 +1077,52 @@ int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
return 1;
}
+int headerAppendEntry(Header h, int_32 tag, int_32 type,
+ hPTR_t p, int_32 c)
+{
+ 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 = xmalloc(entry->length + length);
+ memcpy(t, entry->data, entry->length);
+ entry->data = t;
+ entry->info.offset = 0;
+ } else
+ entry->data = xrealloc(entry->data, entry->length + length);
+
+ copyData(type, ((char *) entry->data) + entry->length, p, c, length);
+
+ entry->length += length;
+
+ entry->info.count += c;
+
+ return 1;
+}
+
+int headerAddOrAppendEntry(Header h, int_32 tag, int_32 type,
+ hPTR_t p, int_32 c)
+{
+ return (findEntry(h, tag, type)
+ ? headerAppendEntry(h, tag, type, p, c)
+ : headerAddEntry(h, tag, type, p, c));
+}
+
int headerAddI18NString(Header h, int_32 tag, const char * string, const char * lang)
{
- struct indexEntry * table, * entry;
+ indexEntry table, entry;
const char ** strArray;
int length;
int ghosts;
@@ -1550,10 +1248,9 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
return 0;
}
-int headerModifyEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
+int headerModifyEntry(Header h, int_32 tag, int_32 type, hPTR_t p, int_32 c)
{
- struct indexEntry *entry;
+ indexEntry entry;
void * oldData;
/* First find the tag */
@@ -1581,53 +1278,10 @@ int headerModifyEntry(Header h, int_32 tag, int_32 type,
return 1;
}
-int headerAddOrAppendEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
-{
- return (findEntry(h, tag, type)
- ? headerAppendEntry(h, tag, type, p, c)
- : headerAddEntry(h, tag, type, p, c));
-}
-
-int headerAppendEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
-{
- struct 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 = xmalloc(entry->length + length);
- memcpy(t, entry->data, entry->length);
- entry->data = t;
- entry->info.offset = 0;
- } else
- entry->data = xrealloc(entry->data, entry->length + length);
-
- copyData(type, ((char *) entry->data) + entry->length, p, c, length);
-
- entry->length += length;
-
- entry->info.count += c;
-
- return 1;
-}
-
int headerRemoveEntry(Header h, int_32 tag)
{
- struct indexEntry * last = h->index + h->indexUsed;
- struct indexEntry * entry, * first;
+ indexEntry last = h->index + h->indexUsed;
+ indexEntry entry, first;
int ne;
entry = findEntry(h, tag, RPM_NULL_TYPE);
@@ -1678,9 +1332,13 @@ static char escapedChar(const char ch) /*@*/
}
/**
+ * Destroy headerSprintf format array.
+ * @param format sprintf format array
+ * @param num number of elements
+ * @return NULL always
*/
-static /*@null@*/ struct sprintfToken *
-freeFormat( /*@only@*/ /*@null@*/ struct sprintfToken * format, int num)
+static /*@null@*/ sprintfToken
+freeFormat( /*@only@*/ /*@null@*/ sprintfToken format, int num)
/*@modifies *format @*/
{
int i;
@@ -1714,14 +1372,14 @@ freeFormat( /*@only@*/ /*@null@*/ struct sprintfToken * format, int num)
/**
*/
-static void findTag(char * name, const struct headerTagTableEntry * tags,
- const struct headerSprintfExtension * extensions,
- /*@out@*/const struct headerTagTableEntry ** tagMatch,
- /*@out@*/const struct headerSprintfExtension ** extMatch)
+static void findTag(char * name, const headerTagTableEntry tags,
+ const headerSprintfExtension extensions,
+ /*@out@*/ headerTagTableEntry * tagMatch,
+ /*@out@*/ headerSprintfExtension * extMatch)
/*@modifies *tagMatch, *extMatch @*/
{
- const struct headerTagTableEntry * entry;
- const struct headerSprintfExtension * ext;
+ headerTagTableEntry entry;
+ headerSprintfExtension ext;
const char * tagname;
*tagMatch = NULL;
@@ -1765,27 +1423,27 @@ static void findTag(char * name, const struct headerTagTableEntry * tags,
}
/* forward ref */
-static int parseExpression(struct sprintfToken * token, char * str,
- const struct headerTagTableEntry * tags,
- const struct headerSprintfExtension * extensions,
- /*@out@*/char ** endPtr, /*@null@*/ /*@out@*/ errmsg_t * errmsg)
- /*@modifies str, *str, *token, *endPtr, *errmsg @*/;
+static int parseExpression(sprintfToken token, char * str,
+ const headerTagTableEntry tags,
+ const headerSprintfExtension extensions,
+ /*@out@*/char ** endPtr, /*@null@*/ /*@out@*/ errmsg_t * errmsg)
+ /*@modifies str, *str, *token, *endPtr, *errmsg @*/;
/**
*/
-static int parseFormat(char * str, const struct headerTagTableEntry * tags,
- const struct headerSprintfExtension * extensions,
- /*@out@*/struct sprintfToken ** formatPtr, /*@out@*/int * numTokensPtr,
- /*@null@*/ /*@out@*/char ** endPtr, int state,
- /*@null@*/ /*@out@*/errmsg_t * errmsg)
- /*@modifies str, *str, *formatPtr, *numTokensPtr, *endPtr, *errmsg @*/
+static int parseFormat(char * str, const headerTagTableEntry tags,
+ const headerSprintfExtension extensions,
+ /*@out@*/sprintfToken * formatPtr, /*@out@*/int * numTokensPtr,
+ /*@null@*/ /*@out@*/ char ** endPtr, int state,
+ /*@null@*/ /*@out@*/ errmsg_t * errmsg)
+ /*@modifies str, *str, *formatPtr, *numTokensPtr, *endPtr, *errmsg @*/
{
char * chptr, * start, * next, * dst;
- struct sprintfToken * format;
+ sprintfToken format;
int numTokens;
int currToken;
- const struct headerTagTableEntry * tag;
- const struct headerSprintfExtension * ext;
+ headerTagTableEntry tag;
+ headerSprintfExtension ext;
int i;
int done = 0;
@@ -1809,9 +1467,9 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
if (currToken < 0 || format[currToken].type != PTOK_STRING) {
currToken++;
format[currToken].type = PTOK_STRING;
- /*@-temptrans@*/
+ /*@-temptrans -assignexpose@*/
dst = format[currToken].u.string.string = start;
- /*@=temptrans@*/
+ /*@=temptrans =assignexpose@*/
}
start++;
@@ -1830,7 +1488,8 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
start++;
if (parseExpression(format + currToken, start, tags,
- extensions, &newEnd, errmsg)) {
+ extensions, &newEnd, errmsg))
+ {
format = freeFormat(format, numTokens);
return 1;
}
@@ -1838,7 +1497,9 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
break; /* out of switch */
}
+ /*@-assignexpose@*/
format[currToken].u.tag.format = start;
+ /*@=assignexpose@*/
format[currToken].u.tag.pad = 0;
format[currToken].u.tag.justOne = 0;
format[currToken].u.tag.arrayCount = 0;
@@ -1896,7 +1557,9 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
format = freeFormat(format, numTokens);
return 1;
}
+ /*@-assignexpose@*/
format[currToken].u.tag.type = chptr;
+ /*@=assignexpose@*/
} else {
format[currToken].u.tag.type = NULL;
}
@@ -1984,9 +1647,9 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
if (currToken < 0 || format[currToken].type != PTOK_STRING) {
currToken++;
format[currToken].type = PTOK_STRING;
- /*@-temptrans@*/
+ /*@-temptrans -assignexpose@*/
dst = format[currToken].u.string.string = start;
- /*@=temptrans@*/
+ /*@=temptrans =assignexpose@*/
}
if (*start == '\\') {
@@ -2018,13 +1681,14 @@ static int parseFormat(char * str, const struct headerTagTableEntry * tags,
/**
*/
-static int parseExpression(struct sprintfToken * token, char * str,
- const struct headerTagTableEntry * tags,
- const struct headerSprintfExtension * extensions,
- /*@out@*/ char ** endPtr, /*@null@*/ /*@out@*/ errmsg_t * errmsg)
+static int parseExpression(sprintfToken token, char * str,
+ const headerTagTableEntry tags,
+ const headerSprintfExtension extensions,
+ /*@out@*/ char ** endPtr,
+ /*@null@*/ /*@out@*/ errmsg_t * errmsg)
{
- const struct headerTagTableEntry * tag;
- const struct headerSprintfExtension * ext;
+ headerTagTableEntry tag;
+ headerSprintfExtension ext;
char * chptr;
char * end;
@@ -2141,11 +1805,14 @@ static int parseExpression(struct sprintfToken * token, char * str,
}
/**
+ * @return 0 on success, 1 on failure
*/
static int getExtension(Header h, headerTagTagFunction fn,
- /*@out@*/ int_32 * typeptr, /*@out@*/ const void ** data,
- /*@out@*/ int_32 * countptr, struct extensionCache * ext)
- /*@modifies *typeptr, *data, *countptr, ext->avail @*/
+ /*@out@*/ hTYP_t typeptr,
+ /*@out@*/ hPTR_t * data,
+ /*@out@*/ hCNT_t countptr,
+ extensionCache ext)
+ /*@modifies *typeptr, *data, *countptr, ext @*/
{
if (!ext->avail) {
if (fn(h, &ext->type, &ext->data, &ext->count, &ext->freeit))
@@ -2153,41 +1820,42 @@ static int getExtension(Header h, headerTagTagFunction fn,
ext->avail = 1;
}
- *typeptr = ext->type;
- *data = ext->data;
- *countptr = ext->count;
+ if (typeptr) *typeptr = ext->type;
+ if (data) *data = ext->data;
+ if (countptr) *countptr = ext->count;
return 0;
}
/**
*/
-static char * formatValue(struct sprintfTag * tag, Header h,
- const struct headerSprintfExtension * extensions,
- struct extensionCache * extCache, int element)
- /*@modifies extCache->avail @*/
+static char * formatValue(sprintfTag tag, Header h,
+ const headerSprintfExtension extensions,
+ extensionCache extCache, int element)
+ /*@modifies extCache @*/
{
int len;
char buf[20];
int_32 count, type;
- const void * data;
+ hPTR_t data;
unsigned int intVal;
char * val = NULL;
const char ** strarray;
int mayfree = 0;
int countBuf;
headerTagFormatFunction tagtype = NULL;
- const struct headerSprintfExtension * ext;
+ headerSprintfExtension ext;
if (tag->ext) {
if (getExtension(h, tag->ext, &type, &data, &count,
- extCache + tag->extNum)) {
+ extCache + tag->extNum))
+ {
count = 1;
type = RPM_STRING_TYPE;
data = "(none)"; /* XXX i18n? NO!, sez; gafton */
}
} else {
- if (!headerGetEntry(h, tag->tag, &type, (void **)&data, &count)){
+ if (!headerGetEntry(h, tag->tag, &type, (void **)&data, &count)) {
count = 1;
type = RPM_STRING_TYPE;
data = "(none)"; /* XXX i18n? NO!, sez; gafton */
@@ -2293,10 +1961,10 @@ static char * formatValue(struct sprintfTag * tag, Header h,
/**
*/
-static const char * singleSprintf(Header h, struct sprintfToken * token,
- const struct headerSprintfExtension * extensions,
- struct extensionCache * extCache, int element)
- /*@modifies h, extCache->avail @*/
+static const char * singleSprintf(Header h, sprintfToken token,
+ const headerSprintfExtension extensions,
+ extensionCache extCache, int element)
+ /*@modifies h, extCache @*/
{
char * val;
const char * thisItem;
@@ -2305,7 +1973,7 @@ static const char * singleSprintf(Header h, struct sprintfToken * token,
int i, j;
int numElements;
int type;
- struct sprintfToken * condFormat;
+ sprintfToken condFormat;
int condNumFormats;
/* we assume the token and header have been validated already! */
@@ -2410,11 +2078,11 @@ static const char * singleSprintf(Header h, struct sprintfToken * token,
/**
*/
-static struct extensionCache * allocateExtensionCache(
- const struct headerSprintfExtension * extensions)
- /*@*/
+static /*@only@*/ extensionCache
+allocateExtensionCache(const headerSprintfExtension extensions)
+ /*@*/
{
- const struct headerSprintfExtension * ext = extensions;
+ headerSprintfExtension ext = extensions;
int i = 0;
while (ext->type != HEADER_EXT_LAST) {
@@ -2429,11 +2097,14 @@ static struct extensionCache * allocateExtensionCache(
}
/**
+ * @return NULL always
*/
-static void freeExtensionCache(const struct headerSprintfExtension * extensions,
- /*@only@*/struct extensionCache * cache)
+static /*@null@*/ extensionCache
+freeExtensionCache(const headerSprintfExtension extensions,
+ /*@only@*/ extensionCache cache)
+ /*@*/
{
- const struct headerSprintfExtension * ext = extensions;
+ headerSprintfExtension ext = extensions;
int i = 0;
while (ext->type != HEADER_EXT_LAST) {
@@ -2447,32 +2118,37 @@ static void freeExtensionCache(const struct headerSprintfExtension * extensions,
}
cache = _free(cache);
+ return NULL;
}
char * headerSprintf(Header h, const char * fmt,
- const struct headerTagTableEntry * tags,
- const struct headerSprintfExtension * extensions,
- errmsg_t * errmsg)
+ const struct headerTagTableEntry * tabletags,
+ const struct headerSprintfExtension * extensions,
+ errmsg_t * errmsg)
{
+ /*@-castexpose@*/ /* FIX: legacy API shouldn't change. */
+ headerSprintfExtension exts = (headerSprintfExtension) extensions;
+ headerTagTableEntry tags = (headerTagTableEntry) tabletags;
+ /*@=castexpose@*/
char * fmtString;
- struct sprintfToken * format;
+ sprintfToken format;
int numTokens;
char * answer;
int answerLength;
int answerAlloced;
int i;
- struct extensionCache * extCache;
+ extensionCache extCache;
/*fmtString = escapeString(fmt);*/
fmtString = xstrdup(fmt);
- if (parseFormat(fmtString, tags, extensions, &format, &numTokens,
+ if (parseFormat(fmtString, tags, exts, &format, &numTokens,
NULL, PARSER_BEGIN, errmsg)) {
fmtString = _free(fmtString);
return NULL;
}
- extCache = allocateExtensionCache(extensions);
+ extCache = allocateExtensionCache(exts);
answerAlloced = 1024;
answerLength = 0;
@@ -2484,7 +2160,7 @@ char * headerSprintf(Header h, const char * fmt,
int pieceLength;
/*@-mods@*/
- piece = singleSprintf(h, format + i, extensions, extCache, 0);
+ piece = singleSprintf(h, format + i, exts, extCache, 0);
/*@=mods@*/
if (piece) {
pieceLength = strlen(piece);
@@ -2501,7 +2177,7 @@ char * headerSprintf(Header h, const char * fmt,
}
fmtString = _free(fmtString);
- freeExtensionCache(extensions, extCache);
+ extCache = freeExtensionCache(exts, extCache);
format = _free(format);
return answer;
@@ -2509,9 +2185,9 @@ char * headerSprintf(Header h, const char * fmt,
/**
*/
-static char * octalFormat(int_32 type, const void * data,
+static char * octalFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, /*@unused@*/int element)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
char * val;
@@ -2528,9 +2204,9 @@ static char * octalFormat(int_32 type, const void * data,
/**
*/
-static char * hexFormat(int_32 type, const void * data,
+static char * hexFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, /*@unused@*/int element)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
char * val;
@@ -2547,10 +2223,10 @@ static char * hexFormat(int_32 type, const void * data,
/**
*/
-static char * realDateFormat(int_32 type, const void * data,
+static char * realDateFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, /*@unused@*/int element,
const char * strftimeFormat)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
char * val;
@@ -2578,18 +2254,18 @@ static char * realDateFormat(int_32 type, const void * data,
/**
*/
-static char * dateFormat(int_32 type, const void * data,
+static char * dateFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, int element)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
return realDateFormat(type, data, formatPrefix, padding, element, "%c");
}
/**
*/
-static char * dayFormat(int_32 type, const void * data,
+static char * dayFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, int element)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
return realDateFormat(type, data, formatPrefix, padding, element,
"%a %b %d %Y");
@@ -2597,9 +2273,9 @@ static char * dayFormat(int_32 type, const void * data,
/**
*/
-static char * shescapeFormat(int_32 type, const void * data,
+static char * shescapeFormat(int_32 type, hPTR_t data,
char * formatPrefix, int padding, /*@unused@*/int element)
- /*@modifies formatPrefix @*/
+ /*@modifies formatPrefix @*/
{
char * result, * dst, * src, * buf;
@@ -2641,23 +2317,24 @@ const struct headerSprintfExtension headerDefaultFormats[] = {
{ HEADER_EXT_LAST, NULL, { NULL } }
};
-void headerCopyTags(Header headerFrom, Header headerTo, int_32 * tagstocopy)
-{
- int * p;
-
- if (headerFrom == headerTo)
- return;
-
- for (p = tagstocopy; *p != 0; p++) {
- char *s;
- int_32 type;
- int_32 count;
- if (headerIsEntry(headerTo, *p))
- continue;
- if (!headerGetEntryMinMemory(headerFrom, *p, &type,
- (const void **) &s, &count))
- continue;
- (void) headerAddEntry(headerTo, *p, type, s, count);
- s = headerFreeData(s, type);
- }
-}
+HV_t hv = {
+ headerFree,
+ headerLink,
+ headerSort,
+ headerUnsort,
+ headerSizeof,
+ headerUnload,
+ headerReload,
+ headerCopy,
+ headerIsEntry,
+ headerGetEntry,
+ headerGetEntryMinMemory,
+ headerGetRawEntry,
+ headerAddEntry,
+ headerAppendEntry,
+ headerAddOrAppendEntry,
+ headerAddI18NString,
+ headerModifyEntry,
+ headerRemoveEntry,
+ headerSprintf,
+};
diff --git a/lib/header.h b/lib/header.h
index 1bb5b3c1d..2dedb0e0f 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -17,16 +17,16 @@
* - Support for version 1 headers was removed in rpm-4.0.
*
* - version 2
- * - (Before my time, sorry.)
+ * - @todo Document version2 headers.
*
* - version 3 (added in rpm-3.0)
- * - added RPM_I18NSTRING_TYPE as an associative array reference
+ * - Added RPM_I18NSTRING_TYPE as an associative array reference
* for i18n locale dependent single element tags (i.e Group).
- * - added an 8 byte magic string to headers in packages on-disk. The
+ * - Added an 8 byte magic string to headers in packages on-disk. The
* magic string was not added to headers in the database.
*
* - version 4 (added in rpm-4.0)
- * - represent file names as a (dirname/basename/dirindex) triple
+ * - Represent file names as a (dirname/basename/dirindex) triple
* rather than as an absolute path name. Legacy package headers are
* converted when the header is read. Legacy database headers are
* converted when the database is rebuilt.
@@ -35,7 +35,17 @@
* on package provides. Legacy package headers are converted
* when the header is read. Legacy database headers are
* converted when the database is rebuilt.
- *
+ * - (rpm-4.0.2) The original package header (and all original
+ * metadata) is preserved in what's called an "immutable header region".
+ * The original header can be retrieved as an RPM_BIN_TYPE, just
+ * like any other tag, and the original header reconstituted using
+ * headerLoad().
+ * - (rpm-4.0.2) The signature tags are added (and renumbered to avoid
+ * tag value collisions) to the package header during package
+ * installation.
+ * - (rpm-4.0.3) A SHA1 digest of the original header is appended
+ * (i.e. detached digest) to the immutable header region to verify
+ * changes to the original header.
* .
*
* \par Development Issues
@@ -43,27 +53,26 @@
* Here's a brief description of future features/incompatibilities that
* will be added to headers.
*
- * - Signature tags
- * - Signatures are stored in A header, but not THE header
- * of a package. That means that signatures are discarded
- * when a package is installed, preventing verification
- * of header contents after install. All signature tags
- * will be added to THE package header so that they are
- * saved in the rpm database for later retrieval and verification.
- * Adding signatures to THE header will also permit signatures to
- * be accessed by Red Hat Network, i.e. retrieval by existing
- * Python bindings.
- * - Signature tag values collide with existing rpm tags, and will
- * have to be renumbered. Part of this renumbering was accomplished
- * in rpm-4.0, but more remains to be done.
- * - Signatures, because they involve MD5 and other 1-way hashes on
- * immutable data, will cause the header to be reconstituted as a
- * immutable section and a mutable section.
+ * - Private header methods.
+ * - Private methods (e.g. headerLoad(), headerUnload(), etc.) to
+ * permit header data to be manipulated opaquely. Initially
+ * the transaction element file info TFI_t will be used as
+ * proof-of-concept, binary XML will probably be implemented
+ * soon thereafter.
+ * - DSA signature for header metadata.
+ * - The manner in which rpm packages are signed is going to change.
+ * The SHA1 digest in the header will be signed, equivalent to a DSA
+ * digital signature on the original header metadata. As the original
+ * header will contain "trusted" (i.e. because the header is signed
+ * with DSA) file MD5 digests, there will be little or no reason
+ * to sign the payload, but that may happen as well. Note that cpio
+ * headers in the payload are not used to install package metadata,
+ * only the name field in the cpio header is used to associate an
+ * archive file member with the corresponding entry for the file
+ * in header metadata.
*/
-/* RPM - Copyright (C) 1995-2000 Red Hat Software */
-
-/* WARNING: 1 means success, 0 means failure (yes, this is backwards) */
+/* RPM - Copyright (C) 1995-2001 Red Hat Software */
#include
#include
@@ -94,17 +103,30 @@ typedef unsigned int uint_32;
typedef unsigned short uint_16;
#endif
+/*@-redef@*/ /* LCL: no clue */
/** \ingroup header
*/
-typedef /*@abstract@*/ /*@refcounted@*/ struct headerToken *Header;
+typedef const char * errmsg_t;
/** \ingroup header
*/
-typedef /*@abstract@*/ struct headerIteratorS *HeaderIterator;
+typedef int_32 * hTAG_t;
+typedef int_32 * hTYP_t;
+typedef const void * hPTR_t;
+typedef int_32 * hCNT_t;
+
+/** \ingroup header
+ */
+typedef /*@abstract@*/ /*@refcounted@*/ struct headerToken * Header;
+
+/** \ingroup header
+ */
+typedef /*@abstract@*/ struct headerIteratorS * HeaderIterator;
/** \ingroup header
* Associate tag names with numeric values.
*/
+typedef /*@abstract@*/ struct headerTagTableEntry * headerTagTableEntry;
struct headerTagTableEntry {
/*@observer@*/ /*@null@*/ const char * name; /*!< Tag name. */
int val; /*!< Tag numeric value. */
@@ -146,14 +168,15 @@ typedef /*only@*/ char * (*headerTagFormatFunction)(int_32 type,
* @return 0 on success
*/
typedef int (*headerTagTagFunction) (Header h,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** data,
- /*@null@*/ /*@out@*/ int_32 * count,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * data,
+ /*@null@*/ /*@out@*/ hCNT_t count,
/*@null@*/ /*@out@*/ int * freeData);
/** \ingroup header
* Define header tag output formats.
*/
+typedef /*@abstract@*/ struct headerSprintfExtension * headerSprintfExtension;
struct headerSprintfExtension {
enum headerSprintfExtenstionType type; /*!< Type of extension. */
/*@observer@*/ /*@null@*/ const char * name; /*!< Name of extension. */
@@ -180,341 +203,145 @@ enum hMagic {
HEADER_MAGIC_YES = 1
};
-/** \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)
+/**
*/
-/*@null@*/ Header headerRead(FD_t fd, enum hMagic magicp)
- /*@modifies fd, fileSystem @*/;
+/*@-typeuse -fielduse@*/
+typedef union hRET_s {
+ const void * ptr;
+ const char ** argv;
+ const char * str;
+ uint_32 * ui32p;
+ uint_16 * ui16p;
+ int_32 * i32p;
+ int_16 * i16p;
+ int_8 * i8p;
+} * hRET_t;
+/*@=typeuse =fielduse@*/
-/** \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
+/**
*/
-int headerWrite(FD_t fd, /*@null@*/ Header h, enum hMagic magicp)
- /*@modifies fd, h, fileSystem @*/;
+/*@-typeuse -fielduse@*/
+typedef struct HE_s {
+ int_32 tag;
+/*@null@*/ hTYP_t typ;
+ union {
+/*@null@*/ hPTR_t * ptr;
+/*@null@*/ hRET_t * ret;
+ } u;
+/*@null@*/ hCNT_t cnt;
+} * HE_t;
+/*@=typeuse =fielduse@*/
-/** \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
- */
-unsigned int headerSizeof(/*@null@*/ Header h, enum hMagic magicp)
- /*@modifies h @*/;
+typedef
+/*@null@*/ Header (*HVfree) (/*@null@*/ /*@killref@*/ Header h)
+ /*@modifies h @*/;
-/** \ingroup header
- * Convert header to in-memory representation.
- * @param uh on-disk header blob (i.e. with offsets)
- * @return header
- */
-/*@-exportlocal@*/
-/*@null@*/ Header headerLoad(/*@kept@*/ void * uh)
- /*@modifies uh @*/;
-/*@=exportlocal@*/
+typedef
+Header (*HVlink) (Header h)
+ /*@modifies h @*/;
-/** \ingroup header
- * Make a copy and convert header to in-memory representation.
- * @param uh on-disk header blob (i.e. with offsets)
- * @return header
- */
-/*@null@*/ Header headerCopyLoad(void * uh)
- /*@modifies uh @*/;
+typedef
+void (*HVsort) (Header h)
+ /*@modifies h @*/;
-/** \ingroup header
- * Convert header to on-disk representation.
- * @param h header (with pointers)
- * @return on-disk header blob (i.e. with offsets)
- */
-/*@only@*/ /*@null@*/ void * headerUnload(Header h)
- /*@modifies h @*/;
+typedef
+void (*HVunsort) (Header h)
+ /*@modifies 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)
- */
-/*@null@*/ Header headerReload(/*@only@*/ Header h, int tag)
- /*@modifies h @*/;
+typedef
+unsigned int (*HVsize) (/*@null@*/ Header h, enum hMagic magicp)
+ /*@modifies h @*/;
-/** \ingroup header
- * Create new (empty) header instance.
- * @return header
- */
-Header headerNew(void) /*@*/;
+typedef
+/*@only@*/ /*@null@*/ void * (*HVunload) (Header h)
+ /*@modifies h @*/;
-/** \ingroup header
- * Reference a header instance.
- * @param h header
- * @return referenced header instance
- */
-Header headerLink(Header h)
- /*@modifies h @*/;
+typedef
+/*@null@*/ Header (*HVreload) (/*@only@*/ Header h, int tag)
+ /*@modifies h @*/;
-/** \ingroup header
- * Dereference a header instance.
- * @param h header
- * @return NULL always
- */
-/*@null@*/ Header headerFree( /*@null@*/ /*@killref@*/ Header h)
- /*@modifies h @*/;
+typedef
+Header (*HVcopy) (Header h)
+ /*@modifies h @*/;
-/*@-redef@*/ /* LCL: no clue */
-typedef const char * errmsg_t;
-/*@=redef@*/
+typedef
+int (*HVisentry) (/*@null@*/Header h, int_32 tag)
+ /*@*/;
-/** \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)
- */
-/*@only@*/ char * headerSprintf(Header h, const char * fmt,
+typedef
+int (*HVget) (Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ void ** p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/;
+
+typedef
+int (*HVgetmin) (Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/;
+
+typedef
+int (*HVgetraw) (Header h, int_32 tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies *type, *p, *c @*/;
+
+typedef
+int (*HVadd) (Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies h @*/;
+
+typedef
+int (*HVappend) (Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies h @*/;
+
+typedef
+int (*HVaddorappend) (Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies h @*/;
+
+typedef
+int (*HVaddi18n) (Header h, int_32 tag, const char * string,
+ const char * lang)
+ /*@modifies h @*/;
+
+typedef
+int (*HVmodify) (Header h, int_32 tag, int_32 type, const void * p, int_32 c)
+ /*@modifies h @*/;
+
+typedef
+int (*HVremove) (Header h, int_32 tag)
+ /*@modifies h @*/;
+
+typedef
+/*@only@*/ char * (*HVsprintf) (Header h, const char * fmt,
const struct headerTagTableEntry * tags,
const struct headerSprintfExtension * extensions,
/*@null@*/ /*@out@*/ errmsg_t * errmsg)
/*@modifies *errmsg @*/;
-/** \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
- */
-/*@mayexit@*/
-int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
- /*@modifies 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
- */
-int headerModifyEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
- /*@modifies 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
- */
-int headerAddI18NString(Header h, int_32 tag, const char * string,
- const char * lang)
- /*@modifies 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
- */
-int headerAppendEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
- /*@modifies 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
- */
-int headerAddOrAppendEntry(Header h, int_32 tag, int_32 type,
- const void * p, int_32 c)
- /*@modifies h @*/;
-
-/** \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
- */
-int headerGetEntry(Header h, int_32 tag,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ void ** p,
- /*@null@*/ /*@out@*/int_32 *c)
- /*@modifies *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
- */
-int headerGetEntryMinMemory(Header h, int_32 tag,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** p,
- /*@null@*/ /*@out@*/ int_32 * c)
- /*@modifies *type, *p, *c @*/;
-
-/** \ingroup header
- * Retrieve tag value with type match.
- * If *type is RPM_NULL_TYPE any type will match, otherwise only *type will
- * match.
- *
- * @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
- */
-/*@-exportlocal@*/
-int headerGetRawEntry(Header h, int_32 tag,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** p,
- /*@null@*/ /*@out@*/ int_32 * c)
- /*@modifies *type, *p, *c @*/;
-/*@=exportlocal@*/
-
-/** \ingroup header
- * Check if tag is in header.
- * @param h header
- * @param tag tag
- * @return 1 on success, 0 on failure
- */
-int headerIsEntry(/*@null@*/Header h, int_32 tag) /*@*/;
-
-/** \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)
- */
-int headerRemoveEntry(Header h, int_32 tag)
- /*@modifies h @*/;
-
-/** \ingroup header
- * Create header tag iterator.
- * @param h header
- * @return header tag iterator
- */
-HeaderIterator headerInitIterator(Header h)
- /*@modifies 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
- */
-int headerNextIterator(HeaderIterator hi,
- /*@null@*/ /*@out@*/ int_32 * tag,
- /*@null@*/ /*@out@*/ int_32 * type,
- /*@null@*/ /*@out@*/ const void ** p,
- /*@null@*/ /*@out@*/ int_32 * c)
- /*@modifies hi, *tag, *type, *p, *c @*/;
-
-/** \ingroup header
- * Destroy header tag iterator.
- * @param hi header tag iterator
- */
-void headerFreeIterator(/*@only@*/ HeaderIterator hi)
- /*@modifies hi @*/;
-
-/** \ingroup header
- * Duplicate a header.
- * @param h header
- * @return new header instance
- */
-/*@null@*/ Header headerCopy(Header h)
- /*@modifies h @*/;
-
-/** \ingroup header
- * Sort tags in header.
- * @param h header
- */
-/*@-exportlocal@*/
-void headerSort(Header h)
- /*@modifies h @*/;
-
-/** \ingroup header
- * Restore tags in header to original ordering.
- * @param h header
- */
-void headerUnsort(Header h)
- /*@modifies h @*/;
-/*@=exportlocal@*/
-
-/** \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
- */
-void headerCopyTags(Header headerFrom, Header headerTo, int_32 * tagstocopy)
- /*@modifies headerFrom, headerTo @*/;
+typedef struct HV_s {
+ HVfree free;
+ HVlink link;
+ HVsort sort;
+ HVunsort unsort;
+ HVsize size;
+ HVunload unload;
+ HVreload reload;
+ HVcopy copy;
+ HVisentry isentry;
+ HVget get;
+ HVgetmin getmin;
+ HVgetraw getraw;
+ HVadd add;
+ HVappend append;
+ HVaddorappend addorappend;
+ HVaddi18n addi18n;
+ HVmodify modify;
+ HVremove remove;
+ HVsprintf sprintf;
+} HV_t;
/** \ingroup header
* The basic types of data in tags from headers.
@@ -534,28 +361,6 @@ typedef enum rpmTagType_e {
#define RPM_MAX_TYPE 9
} rpmTagType;
-/** \ingroup header
- * Free data allocated when retrieved from header.
- * @param data address of data (or NULL)
- * @param type type of data (or -1 to force free)
- * @return NULL always
- */
-/*@unused@*/ static inline /*@null@*/
-void * headerFreeData( /*@only@*/ /*@null@*/ const void * data, rpmTagType type)
- /*@modifies data @*/
-{
- if (data) {
- /*@-branchstate@*/
- if (type == -1 ||
- type == RPM_STRING_ARRAY_TYPE ||
- type == RPM_I18NSTRING_TYPE ||
- type == RPM_BIN_TYPE)
- free((void *)data);
- /*@=branchstate@*/
- }
- return NULL;
-}
-
/** \ingroup header
* New rpm data types under consideration/development.
* These data types may (or may not) be added to rpm at some point. In order
@@ -588,6 +393,117 @@ typedef enum rpmSubTagType_e {
#define HEADER_SIGBASE 256
#define HEADER_TAGBASE 1000
+/** \ingroup header
+ * Free data allocated when retrieved from header.
+ * @param data address of data (or NULL)
+ * @param type type of data (or -1 to force free)
+ * @return NULL always
+ */
+/*@unused@*/ static inline /*@null@*/
+void * headerFreeData( /*@only@*/ /*@null@*/ const void * data, rpmTagType type)
+ /*@modifies data @*/
+{
+ if (data) {
+ /*@-branchstate@*/
+ if (type == -1 ||
+ type == RPM_STRING_ARRAY_TYPE ||
+ type == RPM_I18NSTRING_TYPE ||
+ type == RPM_BIN_TYPE)
+ free((void *)data);
+ /*@=branchstate@*/
+ }
+ return NULL;
+}
+
+/** \ingroup header
+ * Create new (empty) header instance.
+ * @return header
+ */
+Header headerNew(void) /*@*/;
+
+/** \ingroup header
+ * Convert header to in-memory representation.
+ * @param uh on-disk header blob (i.e. with offsets)
+ * @return header
+ */
+/*@-exportlocal@*/
+/*@null@*/ Header headerLoad(/*@kept@*/ void * uh)
+ /*@modifies uh @*/;
+/*@=exportlocal@*/
+
+/** \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
+ */
+int headerWrite(FD_t fd, /*@null@*/ Header h, enum hMagic magicp)
+ /*@modifies fd, h, fileSystem @*/;
+
+/** \ingroup header
+ * Make a copy and convert header to in-memory representation.
+ * @param uh on-disk header blob (i.e. with offsets)
+ * @return header
+ */
+/*@null@*/ Header headerCopyLoad(void * uh)
+ /*@modifies 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)
+ */
+/*@null@*/ Header headerRead(FD_t fd, enum hMagic magicp)
+ /*@modifies fd, fileSystem @*/;
+
+/** \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
+ */
+void headerCopyTags(Header headerFrom, Header headerTo, hTAG_t tagstocopy)
+ /*@modifies headerFrom, headerTo @*/;
+
+/** \ingroup header
+ * Destroy header tag iterator.
+ * @param hi header tag iterator
+ */
+void headerFreeIterator(/*@only@*/ HeaderIterator hi)
+ /*@modifies hi @*/;
+
+/** \ingroup header
+ * Create header tag iterator.
+ * @param h header
+ * @return header tag iterator
+ */
+HeaderIterator headerInitIterator(Header h)
+ /*@modifies 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
+ */
+int headerNextIterator(HeaderIterator hi,
+ /*@null@*/ /*@out@*/ hTAG_t tag,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c)
+ /*@modifies hi, *tag, *type, *p, *c @*/;
+
+#if defined(__HEADER_PROTOTYPES__)
+#include
+#else
+#include
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/header_internal.c b/lib/header_internal.c
index 3e77222c5..6ecfce3ab 100644
--- a/lib/header_internal.c
+++ b/lib/header_internal.c
@@ -8,14 +8,33 @@
#include "debug.h"
-void headerDump(Header h, FILE *f, int flags,
- const struct headerTagTableEntry * tags)
+char ** headerGetLangs(Header h)
+{
+ char **s, *e, **table;
+ int i, type, count;
+
+ if (!headerGetRawEntry(h, HEADER_I18NTABLE, &type, (const void **)&s, &count))
+ return NULL;
+
+ /* XXX xcalloc never returns NULL. */
+ if ((table = (char **)xcalloc((count+1), sizeof(char *))) == NULL)
+ return NULL;
+
+ for (i = 0, e = *s; i < count > 0; i++, e += strlen(e)+1)
+ table[i] = e;
+ table[count] = NULL;
+
+ /*@-nullret@*/ return table; /*@=nullret@*/ /* LCL: double indirection? */
+}
+
+void headerDump(Header h, FILE *f, int flags,
+ const struct headerTagTableEntry * tags)
{
int i;
- struct indexEntry *p;
+ indexEntry p;
const struct headerTagTableEntry * tage;
- const char *tag;
- char *type;
+ const char * tag;
+ char * type;
/* First write out the length of the index (count of index entries) */
fprintf(f, "Entry count: %d\n", h->indexUsed);
diff --git a/lib/header_internal.h b/lib/header_internal.h
index db87fdbab..1087214f9 100644
--- a/lib/header_internal.h
+++ b/lib/header_internal.h
@@ -11,10 +11,18 @@
#include
#endif /* __LCLINT__ */
+#define INDEX_MALLOC_SIZE 8
-/**
+/*
+ * Teach header.c about legacy tags.
+ */
+#define HEADER_OLDFILENAMES 1027
+#define HEADER_BASENAMES 1117
+
+/** \ingroup header
* Description of tag data.
*/
+typedef /*@abstract@*/ struct entryInfo * entryInfo;
struct entryInfo {
int_32 tag; /*!< Tag identifier. */
int_32 type; /*!< Tag data type. */
@@ -28,9 +36,10 @@ struct entryInfo {
#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE)
#define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0)
-/**
+/** \ingroup header
* A single tag from a Header.
*/
+typedef /*@abstract@*/ struct indexEntry * indexEntry;
struct indexEntry {
struct entryInfo info; /*!< Description of tag data. */
/*@owned@*/ void * data; /*!< Location of tag data. */
@@ -38,11 +47,12 @@ struct indexEntry {
int rdlen; /*!< No. bytes of data in region. */
};
-/**
+/** \ingroup header
* The Header data structure.
*/
struct headerToken {
-/*@owned@*/ struct indexEntry * index; /*!< Array of tags. */
+/*@unused@*/ HV_t hv; /*!< Header public methods. */
+/*@owned@*/ indexEntry index; /*!< Array of tags. */
int indexUsed; /*!< Current size of tag array. */
int indexAlloced; /*!< Allocated size of tag array. */
int region_allocated; /*!< Is 1st header region allocated? */
@@ -51,8 +61,9 @@ struct headerToken {
/*@refs@*/ int nrefs; /*!< Reference count. */
};
-/**
+/** \ingroup header
*/
+typedef /*@abstract@*/ struct sprintfTag * sprintfTag;
struct sprintfTag {
/*@null@*/ headerTagTagFunction ext; /*!< if NULL tag element is invalid */
int extNum;
@@ -64,8 +75,9 @@ struct sprintfTag {
int pad;
};
-/**
+/** \ingroup header
*/
+typedef /*@abstract@*/ struct extensionCache * extensionCache;
struct extensionCache {
int_32 type;
int_32 count;
@@ -74,8 +86,10 @@ struct extensionCache {
/*@owned@*/ const void * data;
};
-/**
+/** \ingroup header
*/
+/*@-fielduse@*/
+typedef /*@abstract@*/ struct sprintfToken * sprintfToken;
struct sprintfToken {
enum {
PTOK_NONE = 0,
@@ -86,28 +100,106 @@ struct sprintfToken {
} type;
union {
struct {
- /*@only@*/ struct sprintfToken * format;
+ /*@only@*/ sprintfToken format;
int numTokens;
} array;
struct sprintfTag tag;
struct {
- /*@dependent@*/ char * string;
+ /*@dependent@*/ char * string;
int len;
} string;
struct {
- /*@only@*/ /*@null@*/ struct sprintfToken * ifFormat;
+ /*@only@*/ /*@null@*/ sprintfToken ifFormat;
int numIfTokens;
- /*@only@*/ /*@null@*/ struct sprintfToken * elseFormat;
+ /*@only@*/ /*@null@*/ sprintfToken elseFormat;
int numElseTokens;
struct sprintfTag tag;
} cond;
} u;
};
+/*@=fielduse@*/
#ifdef __cplusplus
extern "C" {
#endif
+/** \ingroup header
+ */
+extern unsigned char header_magic[8];
+
+/** \ingroup header
+ */
+extern HV_t hv;
+
+/** \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
+ */
+int regionSwab(/*@null@*/ indexEntry entry, int il, int dl,
+ entryInfo pe, char * dataStart, int regionid)
+ /*@modifies entry, *dataStart @*/;
+
+/** \ingroup header
+ */
+/*@only@*/ /*@null@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
+ /*@modifies h, *lengthPtr @*/;
+
+/** \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.
+ */
+int copyEntry(const indexEntry entry,
+ /*@null@*/ /*@out@*/ hTYP_t type,
+ /*@null@*/ /*@out@*/ hPTR_t * p,
+ /*@null@*/ /*@out@*/ hCNT_t c,
+ int minMem)
+ /*@modifies *type, *p, *c @*/;
+
+/** \ingroup header
+ * Return array of locales found in header.
+ * The array is terminated with a NULL sentinel.
+ * @param h header
+ * @return array of locales (or NULL on error)
+ */
+/*@unused@*/
+/*@only@*/ /*@null@*/ char ** headerGetLangs(Header h)
+ /*@*/;
+
+/** \ingroup header
+ * Return header reference count.
+ * @param h header
+ * @return no. of references
+ */
+/*@unused@*/ static inline int headerUsageCount(Header h) /*@*/ {
+ return h->nrefs;
+}
/** \ingroup header
* Dump a header in human readable format (for debugging).
@@ -117,7 +209,8 @@ extern "C" {
*/
/*@unused@*/
void headerDump(Header h, FILE *f, int flags,
- const struct headerTagTableEntry * tags);
+ const struct headerTagTableEntry * tags)
+ /*@modifies f, fileSystem @*/;
#define HEADER_DUMP_INLINE 1
#ifdef __cplusplus
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index 1c82d7850..e7700fd02 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -154,7 +154,7 @@ int rpmHeaderGetEntry(Header h, int_32 tag, /*@out@*/ int_32 *type,
/*@unused@*/
int rpmPackageGetEntry(void *leadp, Header sigs, Header h,
int_32 tag, int_32 *type, void **p, int_32 *c)
- /*@modifies *type, *p, *c @*/;
+ /*@modifies h, *type, *p, *c @*/;
/**
* Automatically generated table of tag name/value pairs.
diff --git a/lib/rpmvercmp.c b/lib/rpmvercmp.c
index ec09447dd..881955855 100644
--- a/lib/rpmvercmp.c
+++ b/lib/rpmvercmp.c
@@ -4,7 +4,7 @@
#include "system.h"
-#include
+#include
#include "debug.h"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e0d9ce847..8af440dca 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -29,6 +29,7 @@ lib/depends.c
lib/formats.c
lib/fs.c
lib/fsm.c
+lib/hdrinline.c
lib/header.c
lib/header_internal.c
lib/manifest.c
diff --git a/po/rpm.pot b/po/rpm.pot
index a3116cf31..2c9703eb6 100644
--- a/po/rpm.pot
+++ b/po/rpm.pot
@@ -6,1088 +6,1091 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-05-07 15:57-0400\n"
+"POT-Creation-Date: 2001-06-19 07:31-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: ENCODING\n"
+"Content-Transfer-Encoding: 8bit\n"
-#: build.c:35
+#: build.c:36
#, c-format
msgid "cannot open rpm database in %s\n"
msgstr ""
-#: build.c:45
+#: build.c:46
msgid "failed build dependencies:\n"
msgstr ""
-#: build.c:76
+#: build.c:78
#, c-format
msgid "Unable to open spec file %s: %s\n"
msgstr ""
-#: build.c:147 build.c:159
+#: build.c:151 build.c:163
#, c-format
msgid "Failed to open tar pipe: %m\n"
msgstr ""
#. Give up
-#: build.c:166
+#: build.c:170
#, c-format
msgid "Failed to read spec file from %s\n"
msgstr ""
-#: build.c:194
+#: build.c:198
#, c-format
msgid "Failed to rename %s to %s: %m\n"
msgstr ""
-#: build.c:233
+#: build.c:237
#, c-format
msgid "failed to stat %s: %m\n"
msgstr ""
-#: build.c:238
+#: build.c:242
#, c-format
msgid "File %s is not a regular file.\n"
msgstr ""
-#: build.c:247
+#: build.c:251
#, c-format
msgid "File %s does not appear to be a specfile.\n"
msgstr ""
#. parse up the build operators
-#: build.c:303
+#: build.c:307
#, c-format
msgid "Building target platforms: %s\n"
msgstr ""
-#: build.c:318
+#: build.c:322
#, c-format
msgid "Building for target %s\n"
msgstr ""
-#: rpm.c:224 rpmqv.c:394
+#: rpm.c:227
#, c-format
msgid "rpm: %s\n"
msgstr ""
-#: rpm.c:235 rpmqv.c:399
+#: rpm.c:238 rpmqv.c:215
#, c-format
msgid "RPM version %s\n"
msgstr ""
-#: rpm.c:239 rpmqv.c:403
+#: rpm.c:242 rpmqv.c:221
msgid "Copyright (C) 1998-2000 - Red Hat, Inc."
msgstr ""
-#: rpm.c:240 rpmqv.c:404
+#: rpm.c:243 rpmqv.c:222
msgid "This program may be freely redistributed under the terms of the GNU GPL"
msgstr ""
-#: rpm.c:248
+#: rpm.c:251
msgid "Usage: rpm {--help}"
msgstr ""
-#: rpm.c:249
+#: rpm.c:252
msgid " rpm {--version}"
msgstr ""
-#: rpm.c:250
-msgid " rpm {--initdb} [--dbpath ]"
-msgstr ""
-
-#: rpm.c:251
-msgid ""
-" rpm {--install -i} [-v] [--hash -h] [--percent] [--force] [--test]"
-msgstr ""
-
-#: rpm.c:252
-msgid " [--replacepkgs] [--replacefiles] [--root ]"
-msgstr ""
-
#: rpm.c:253
-msgid " [--excludedocs] [--includedocs] [--noscripts]"
+msgid " rpm {--initdb} [--dbpath ]"
msgstr ""
#: rpm.c:254
msgid ""
-" [--rcfile ] [--ignorearch] [--dbpath ]"
+" rpm {--install -i} [-v] [--hash -h] [--percent] [--force] [--test]"
msgstr ""
#: rpm.c:255
+msgid " [--replacepkgs] [--replacefiles] [--root ]"
+msgstr ""
+
+#: rpm.c:256
+msgid " [--excludedocs] [--includedocs] [--noscripts]"
+msgstr ""
+
+#: rpm.c:257
msgid ""
-" [--prefix ] [--ignoreos] [--nodeps] [--allfiles]"
-msgstr ""
-
-#: rpm.c:256 rpm.c:265 rpm.c:275
-msgid " [--ftpproxy ] [--ftpport ]"
-msgstr ""
-
-#: rpm.c:257 rpm.c:276
-msgid " [--httpproxy ] [--httpport ]"
+" [--rcfile ] [--ignorearch] [--dbpath ]"
msgstr ""
#: rpm.c:258
msgid ""
-" [--justdb] [--noorder] [--relocate oldpath=newpath]"
+" [--prefix ] [--ignoreos] [--nodeps] [--allfiles]"
msgstr ""
-#: rpm.c:259
-msgid ""
-" [--badreloc] [--notriggers] [--excludepath ]"
+#: rpm.c:259 rpm.c:268 rpm.c:278
+msgid " [--ftpproxy ] [--ftpport ]"
msgstr ""
-#: rpm.c:260
-msgid " [--ignoresize] file1.rpm ... fileN.rpm"
+#: rpm.c:260 rpm.c:279
+msgid " [--httpproxy ] [--httpport ]"
msgstr ""
#: rpm.c:261
msgid ""
-" rpm {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test]"
+" [--justdb] [--noorder] [--relocate oldpath=newpath]"
msgstr ""
#: rpm.c:262
-msgid " [--oldpackage] [--root ] [--noscripts]"
+msgid ""
+" [--badreloc] [--notriggers] [--excludepath ]"
msgstr ""
#: rpm.c:263
-msgid ""
-" [--excludedocs] [--includedocs] [--rcfile ]"
+msgid " [--ignoresize] file1.rpm ... fileN.rpm"
msgstr ""
#: rpm.c:264
msgid ""
-" [--ignorearch] [--dbpath ] [--prefix ] "
+" rpm {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test]"
+msgstr ""
+
+#: rpm.c:265
+msgid " [--oldpackage] [--root ] [--noscripts]"
msgstr ""
#: rpm.c:266
-msgid " [--httpproxy ] [--httpport ] "
+msgid ""
+" [--excludedocs] [--includedocs] [--rcfile ]"
msgstr ""
#: rpm.c:267
-msgid " [--ignoreos] [--nodeps] [--allfiles] [--justdb]"
-msgstr ""
-
-#: rpm.c:268
-msgid " [--noorder] [--relocate oldpath=newpath]"
+msgid ""
+" [--ignorearch] [--dbpath ] [--prefix ] "
msgstr ""
#: rpm.c:269
+msgid " [--httpproxy ] [--httpport ] "
+msgstr ""
+
+#: rpm.c:270
+msgid " [--ignoreos] [--nodeps] [--allfiles] [--justdb]"
+msgstr ""
+
+#: rpm.c:271
+msgid " [--noorder] [--relocate oldpath=newpath]"
+msgstr ""
+
+#: rpm.c:272
msgid ""
" [--badreloc] [--excludepath ] [--ignoresize]"
msgstr ""
-#: rpm.c:270
+#: rpm.c:273
msgid " file1.rpm ... fileN.rpm"
msgstr ""
-#: rpm.c:271
+#: rpm.c:274
msgid " rpm {--query -q} [-afpg] [-i] [-l] [-s] [-d] [-c] [-v] [-R]"
msgstr ""
-#: rpm.c:272
+#: rpm.c:275
msgid " [--scripts] [--root ] [--rcfile ]"
msgstr ""
-#: rpm.c:273
+#: rpm.c:276
msgid " [--whatprovides] [--whatrequires] [--requires]"
msgstr ""
-#: rpm.c:274
+#: rpm.c:277
msgid " [--triggeredby]"
msgstr ""
-#: rpm.c:277
+#: rpm.c:280
msgid " [--provides] [--triggers] [--dump]"
msgstr ""
-#: rpm.c:278
+#: rpm.c:281
msgid " [--changelog] [--dbpath ] [targets]"
msgstr ""
-#: rpm.c:279
+#: rpm.c:282
msgid " rpm {--verify -V -y} [-afpg] [--root ] [--rcfile ]"
msgstr ""
-#: rpm.c:280
+#: rpm.c:283
msgid ""
" [--dbpath ] [--nodeps] [--nofiles] [--noscripts]"
msgstr ""
-#: rpm.c:281
+#: rpm.c:284
msgid " [--nomd5] [targets]"
msgstr ""
-#: rpm.c:282
+#: rpm.c:285
msgid " rpm {--setperms} [-afpg] [target]"
msgstr ""
-#: rpm.c:283
+#: rpm.c:286
msgid " rpm {--setugids} [-afpg] [target]"
msgstr ""
-#: rpm.c:284
+#: rpm.c:287
msgid " rpm {--freshen -F} file1.rpm ... fileN.rpm"
msgstr ""
-#: rpm.c:285
+#: rpm.c:288
msgid " rpm {--erase -e} [--root ] [--noscripts] [--rcfile ]"
msgstr ""
-#: rpm.c:286
+#: rpm.c:289
msgid " [--dbpath ] [--nodeps] [--allmatches]"
msgstr ""
-#: rpm.c:287
+#: rpm.c:290
msgid " [--justdb] [--notriggers] package1 ... packageN"
msgstr ""
-#: rpm.c:288
+#: rpm.c:291
msgid " rpm {--resign} [--rcfile ] package1 package2 ... packageN"
msgstr ""
-#: rpm.c:289
+#: rpm.c:292
msgid " rpm {--addsign} [--rcfile ] package1 package2 ... packageN"
msgstr ""
-#: rpm.c:290
+#: rpm.c:293
msgid ""
" rpm {--checksig -K} [--nopgp] [--nogpg] [--nomd5] [--rcfile ]"
msgstr ""
-#: rpm.c:291
+#: rpm.c:294
msgid " package1 ... packageN"
msgstr ""
-#: rpm.c:292
+#: rpm.c:295
msgid " rpm {--rebuilddb} [--rcfile ] [--dbpath ]"
msgstr ""
-#: rpm.c:293
+#: rpm.c:296
+msgid " rpm {--verifydb} [--rcfile ] [--dbpath ]"
+msgstr ""
+
+#: rpm.c:297
msgid " rpm {--querytags}"
msgstr ""
-#: rpm.c:327 rpmqv.c:479
+#: rpm.c:331
msgid "Usage:"
msgstr ""
-#: rpm.c:329 rpmqv.c:481
+#: rpm.c:333
msgid "print this message"
msgstr ""
-#: rpm.c:331 rpmqv.c:130 rpmqv.c:483
+#: rpm.c:335 rpmqv.c:100
msgid "print the version of rpm being used"
msgstr ""
-#: rpm.c:334
+#: rpm.c:338
msgid " All modes support the following arguments:"
msgstr ""
-#: rpm.c:335
+#: rpm.c:339
msgid " --define ' '"
msgstr ""
-#: rpm.c:336 rpmqv.c:137 rpmqv.c:488
+#: rpm.c:340 rpmqv.c:107
msgid "define macro with value "
msgstr ""
-#: rpm.c:337
+#: rpm.c:341
msgid " --eval '+' "
msgstr ""
-#: rpm.c:338
+#: rpm.c:342
msgid "print the expansion of macro to stdout"
msgstr ""
-#: rpm.c:339
+#: rpm.c:343
msgid " --pipe "
msgstr ""
-#: rpm.c:340 rpmqv.c:143 rpmqv.c:492
+#: rpm.c:344 rpmqv.c:113
msgid "send stdout to "
msgstr ""
-#: rpm.c:341
+#: rpm.c:345
msgid " --rcfile "
msgstr ""
-#: rpm.c:342
+#: rpm.c:346
msgid "use instead of /etc/rpmrc and $HOME/.rpmrc"
msgstr ""
-#: rpm.c:344 rpmqv.c:161 rpmqv.c:496
+#: rpm.c:348 rpmqv.c:131
msgid "display final rpmrc and macro configuration"
msgstr ""
-#: rpm.c:346 rpmqv.c:504
+#: rpm.c:350
msgid "be a little more verbose"
msgstr ""
-#: rpm.c:348 rpmqv.c:506
+#: rpm.c:352
msgid "be incredibly verbose (for debugging)"
msgstr ""
-#: rpm.c:351
+#: rpm.c:355
msgid " Install, upgrade and query (with -p) allow URL's to be used in place"
msgstr ""
-#: rpm.c:352
+#: rpm.c:356
msgid " of file names as well as the following options:"
msgstr ""
-#: rpm.c:353
+#: rpm.c:357
msgid " --ftpproxy "
msgstr ""
-#: rpm.c:354 rpmqv.c:513
+#: rpm.c:358
msgid "hostname or IP of ftp proxy"
msgstr ""
-#: rpm.c:355
+#: rpm.c:359
msgid " --ftpport "
msgstr ""
-#: rpm.c:356 rpmqv.c:515
+#: rpm.c:360
msgid "port number of ftp server (or proxy)"
msgstr ""
-#: rpm.c:357
+#: rpm.c:361
msgid " --httpproxy "
msgstr ""
-#: rpm.c:358 rpmqv.c:517
+#: rpm.c:362
msgid "hostname or IP of http proxy"
msgstr ""
-#: rpm.c:359
+#: rpm.c:363
msgid " --httpport "
msgstr ""
-#: rpm.c:360 rpmqv.c:519
+#: rpm.c:364
msgid "port number of http server (or proxy)"
msgstr ""
-#: rpm.c:364 rpmqv.c:539
+#: rpm.c:368
msgid "query mode"
msgstr ""
-#: rpm.c:365 rpm.c:411 rpm.c:436 rpm.c:488 rpm.c:560
+#: rpm.c:369 rpm.c:415 rpm.c:440 rpm.c:492 rpm.c:566
msgid " --dbpath "
msgstr ""
-#: rpm.c:366 rpm.c:412 rpm.c:437 rpm.c:489 rpm.c:561 rpmqv.c:499
+#: rpm.c:370 rpm.c:416 rpm.c:441 rpm.c:493 rpm.c:567
msgid "use as the directory for the database"
msgstr ""
-#: rpm.c:367
+#: rpm.c:371
msgid " --queryformat "
msgstr ""
-#: rpm.c:368 rpmqv.c:541
+#: rpm.c:372
msgid "use as the header format (implies --info)"
msgstr ""
-#: rpm.c:369 rpm.c:413 rpm.c:471 rpm.c:500
+#: rpm.c:373 rpm.c:417 rpm.c:475 rpm.c:504
msgid " --root "
msgstr ""
-#: rpm.c:370 rpm.c:414 rpm.c:472 rpm.c:501 rpm.c:563 rpmqv.c:146 rpmqv.c:501
+#: rpm.c:374 rpm.c:418 rpm.c:476 rpm.c:505 rpm.c:569 rpmqv.c:116
msgid "use as the top level directory"
msgstr ""
-#: rpm.c:371
+#: rpm.c:375
msgid " Package specification options:"
msgstr ""
-#: rpm.c:373
+#: rpm.c:377
msgid "query all packages"
msgstr ""
-#: rpm.c:374
+#: rpm.c:378
msgid " -f + "
msgstr ""
-#: rpm.c:375
+#: rpm.c:379
msgid "query package owning "
msgstr ""
-#: rpm.c:376
+#: rpm.c:380
msgid " -p + "
msgstr ""
-#: rpm.c:377
+#: rpm.c:381
msgid "query (uninstalled) package "
msgstr ""
-#: rpm.c:378
+#: rpm.c:382
msgid " --triggeredby "
msgstr ""
-#: rpm.c:379
+#: rpm.c:383
msgid "query packages triggered by "
msgstr ""
-#: rpm.c:380
+#: rpm.c:384
msgid " --whatprovides "
msgstr ""
-#: rpm.c:381
+#: rpm.c:385
msgid "query packages which provide capability"
msgstr ""
-#: rpm.c:382
+#: rpm.c:386
msgid " --whatrequires "
msgstr ""
-#: rpm.c:383
+#: rpm.c:387
msgid "query packages which require capability"
msgstr ""
-#: rpm.c:384
+#: rpm.c:388
msgid " Information selection options:"
msgstr ""
-#: rpm.c:386 rpmqv.c:545
+#: rpm.c:390
msgid "display package information"
msgstr ""
-#: rpm.c:388 rpmqv.c:547
+#: rpm.c:392
msgid "display the package's change log"
msgstr ""
-#: rpm.c:390 rpmqv.c:549
+#: rpm.c:394
msgid "display package file list"
msgstr ""
-#: rpm.c:392 rpmqv.c:551
+#: rpm.c:396
msgid "show file states (implies -l)"
msgstr ""
-#: rpm.c:394 rpmqv.c:553
+#: rpm.c:398
msgid "list only documentation files (implies -l)"
msgstr ""
-#: rpm.c:396 rpmqv.c:555
+#: rpm.c:400
msgid "list only configuration files (implies -l)"
msgstr ""
-#: rpm.c:398 rpmqv.c:557
-msgid ""
-"show all verifiable information for each file (must be used with -l, -c, or "
-"-d)"
-msgstr ""
-
-#: rpm.c:400
-msgid "list capabilities package provides"
-msgstr ""
-
#: rpm.c:402
-msgid "list package dependencies"
+msgid ""
+"show all verifiable information for each file (must be used with -l, -c, or -"
+"d)"
msgstr ""
#: rpm.c:404
-msgid "print the various [un]install scripts"
+msgid "list capabilities package provides"
msgstr ""
#: rpm.c:406
+msgid "list package dependencies"
+msgstr ""
+
+#: rpm.c:408
+msgid "print the various [un]install scripts"
+msgstr ""
+
+#: rpm.c:410
msgid "show the trigger scripts contained in the package"
msgstr ""
-#: rpm.c:410 rpmqv.c:568
+#: rpm.c:414
msgid ""
"verify a package installation using the same same package specification "
"options as -q"
msgstr ""
-#: lib/poptBT.c:187 lib/verify.c:60 rpm.c:416 rpm.c:458 rpm.c:493 rpmqv.c:270
-#: rpmqv.c:570 rpmqv.c:618 rpmqv.c:652
+#: lib/poptBT.c:189 lib/poptI.c:128 rpm.c:420 rpm.c:462 rpm.c:497
msgid "do not verify package dependencies"
msgstr ""
-#: lib/verify.c:66 rpm.c:418 rpmqv.c:210 rpmqv.c:574
+#: lib/poptK.c:67 rpm.c:422
msgid "do not verify file md5 checksums"
msgstr ""
-#: rpm.c:420 rpmqv.c:572
+#: rpm.c:424
msgid "do not verify file attributes"
msgstr ""
-#: rpm.c:422 rpmqv.c:579
+#: rpm.c:426
msgid "list the tags that can be used in a query format"
msgstr ""
-#: rpm.c:425
+#: rpm.c:429
msgid " --install "
msgstr ""
-#: rpm.c:426
+#: rpm.c:430
msgid " -i "
msgstr ""
-#: rpm.c:427 rpmqv.c:266 rpmqv.c:593
+#: lib/poptI.c:124 rpm.c:431
msgid "install package"
msgstr ""
-#: rpm.c:428
+#: rpm.c:432
msgid " --excludepath "
msgstr ""
-#: rpm.c:429
+#: rpm.c:433
msgid "skip files in path "
msgstr ""
-#: rpm.c:430
+#: rpm.c:434
msgid " --relocate ="
msgstr ""
-#: rpm.c:431 rpmqv.c:630
+#: rpm.c:435
msgid "relocate files from to "
msgstr ""
-#: rpm.c:433 rpmqv.c:238 rpmqv.c:598
+#: lib/poptI.c:90 rpm.c:437
msgid "relocate files in non-relocateable package"
msgstr ""
-#: rpm.c:434
+#: rpm.c:438
msgid " --prefix "
msgstr ""
-#: rpm.c:435 rpmqv.c:313 rpmqv.c:628
+#: lib/poptI.c:174 rpm.c:439
msgid "relocate the package to , if relocatable"
msgstr ""
-#: rpm.c:439 rpmqv.c:244 rpmqv.c:600
+#: lib/poptI.c:98 rpm.c:443
msgid "do not install documentation"
msgstr ""
-#: rpm.c:441 rpmqv.c:249 rpmqv.c:604
+#: lib/poptI.c:104 rpm.c:445
msgid "short hand for --replacepkgs --replacefiles"
msgstr ""
-#: rpm.c:443 rpmqv.c:255 rpmqv.c:606
+#: lib/poptI.c:110 rpm.c:447
msgid "print hash marks as package installs (good with -v)"
msgstr ""
-#: rpm.c:445 rpmqv.c:226 rpmqv.c:595
+#: lib/poptI.c:76 rpm.c:449
msgid "install all files, even configurations which might otherwise be skipped"
msgstr ""
-#: rpm.c:448 rpmqv.c:257 rpmqv.c:608
+#: lib/poptI.c:113 rpm.c:452
msgid "don't verify package architecture"
msgstr ""
-#: rpm.c:450 rpmqv.c:262 rpmqv.c:610
+#: lib/poptI.c:119 rpm.c:454
msgid "don't check disk space before installing"
msgstr ""
-#: rpm.c:452 rpmqv.c:259 rpmqv.c:612
+#: lib/poptI.c:116 rpm.c:456
msgid "don't verify package operating system"
msgstr ""
-#: rpm.c:454 rpmqv.c:264 rpmqv.c:614
+#: lib/poptI.c:121 rpm.c:458
msgid "install documentation"
msgstr ""
-#: rpm.c:456 rpm.c:491 rpmqv.c:268 rpmqv.c:616 rpmqv.c:650
+#: lib/poptI.c:126 rpm.c:460 rpm.c:495
msgid "update the database, but do not modify the filesystem"
msgstr ""
-#: rpm.c:460 rpm.c:495 rpmqv.c:272 rpmqv.c:620 rpmqv.c:654
+#: lib/poptI.c:131 rpm.c:464 rpm.c:499
msgid "do not reorder package installation to satisfy dependencies"
msgstr ""
-#: rpm.c:462
+#: rpm.c:466
msgid "don't execute any installation scripts"
msgstr ""
-#: rpm.c:464 rpm.c:499 rpmqv.c:658
+#: rpm.c:468 rpm.c:503
msgid "don't execute any scripts triggered by this package"
msgstr ""
-#: rpm.c:466 rpmqv.c:311 rpmqv.c:626
+#: lib/poptI.c:172 rpm.c:470
msgid "print percentages as package installs"
msgstr ""
-#: rpm.c:468 rpmqv.c:322 rpmqv.c:632
+#: lib/poptI.c:184 rpm.c:472
msgid "install even if the package replaces installed files"
msgstr ""
-#: rpm.c:470 rpmqv.c:324 rpmqv.c:634
+#: lib/poptI.c:187 rpm.c:474
msgid "reinstall if the package is already present"
msgstr ""
-#: rpm.c:474 rpmqv.c:326 rpmqv.c:636
+#: lib/poptI.c:189 rpm.c:478
msgid "don't install, but tell if it would work or not"
msgstr ""
-#: rpm.c:477
+#: rpm.c:481
msgid " --upgrade "
msgstr ""
-#: rpm.c:478
+#: rpm.c:482
msgid " -U "
msgstr ""
-#: rpm.c:479 rpmqv.c:640
+#: rpm.c:483
msgid "upgrade package (same options as --install, plus)"
msgstr ""
-#: rpm.c:481 rpmqv.c:308 rpmqv.c:642
+#: lib/poptI.c:168 rpm.c:485
msgid ""
"upgrade to an old version of the package (--force on upgrades does this "
"automatically)"
msgstr ""
-#: rpm.c:483
+#: rpm.c:487
msgid " --erase "
msgstr ""
-#: rpm.c:484
+#: rpm.c:488
msgid " -e "
msgstr ""
-#: rpm.c:485 rpmqv.c:242 rpmqv.c:646
+#: lib/poptI.c:95 rpm.c:489
msgid "erase (uninstall) package"
msgstr ""
-#: rpm.c:487 rpmqv.c:229 rpmqv.c:648
+#: lib/poptI.c:80 rpm.c:491
msgid ""
"remove all packages which match (normally an error is generated if "
" specified multiple packages)"
msgstr ""
-#: rpm.c:497 rpmqv.c:656
+#: rpm.c:501
msgid "do not execute any package specific scripts"
msgstr ""
-#: rpm.c:503
+#: rpm.c:507
msgid " -b "
msgstr ""
-#: rpm.c:504
+#: rpm.c:508
msgid " -t "
msgstr ""
-#: rpm.c:505
+#: rpm.c:509
msgid "build package, where is one of:"
msgstr ""
-#: rpm.c:507
+#: rpm.c:511
msgid "prep (unpack sources and apply patches)"
msgstr ""
-#: rpm.c:509
+#: rpm.c:513
#, c-format
msgid "list check (do some cursory checks on %files)"
msgstr ""
-#: rpm.c:511
+#: rpm.c:515
msgid "compile (prep and compile)"
msgstr ""
-#: rpm.c:513
+#: rpm.c:517
msgid "install (prep, compile, install)"
msgstr ""
-#: rpm.c:515
+#: rpm.c:519
msgid "binary package (prep, compile, install, package)"
msgstr ""
-#: rpm.c:517
+#: rpm.c:521
msgid "bin/src package (prep, compile, install, package)"
msgstr ""
-#: lib/poptBT.c:198 rpm.c:519
+#: lib/poptBT.c:200 rpm.c:523
msgid "skip straight to specified stage (only for c,i)"
msgstr ""
-#: lib/poptBT.c:177 rpm.c:521
+#: lib/poptBT.c:179 rpm.c:525
msgid "remove build tree when done"
msgstr ""
-#: lib/poptBT.c:194 rpm.c:523
+#: lib/poptBT.c:196 rpm.c:527
msgid "remove sources when done"
msgstr ""
-#: rpm.c:525
+#: rpm.c:529
msgid "remove spec file when done"
msgstr ""
-#: lib/poptBT.c:200 rpm.c:527 rpmqv.c:202
+#: lib/poptBT.c:202 rpm.c:531
msgid "generate PGP/GPG signature"
msgstr ""
-#: rpm.c:528
+#: rpm.c:532
msgid " --buildroot "
msgstr ""
-#: rpm.c:529
+#: rpm.c:533
msgid "use as the build root"
msgstr ""
-#: rpm.c:530
+#: rpm.c:534
msgid " --target=+"
msgstr ""
-#: rpm.c:531
+#: rpm.c:535
msgid "build the packages for the build targets platform1...platformN."
msgstr ""
-#: rpm.c:533
+#: rpm.c:537
msgid "do not execute any stages"
msgstr ""
-#: rpm.c:535
+#: rpm.c:539
msgid " --rebuild "
msgstr ""
-#: rpm.c:536
+#: rpm.c:540
msgid ""
"install source package, build binary package and remove spec file, sources, "
"patches, and icons."
msgstr ""
-#: rpm.c:537
+#: rpm.c:541
msgid " --recompile "
msgstr ""
-#: rpm.c:538
+#: rpm.c:542
msgid "like --rebuild, but don't build any package"
msgstr ""
-#: rpm.c:541
+#: rpm.c:545
msgid " --resign + "
msgstr ""
-#: rpm.c:542 rpmqv.c:200 rpmqv.c:664
+#: lib/poptK.c:54 rpm.c:546
msgid "sign a package (discard current signature)"
msgstr ""
-#: rpm.c:543
+#: rpm.c:547
msgid " --addsign + "
msgstr ""
-#: rpm.c:544 rpmqv.c:198 rpmqv.c:666
+#: lib/poptK.c:52 rpm.c:548
msgid "add a signature to a package"
msgstr ""
-#: rpm.c:545
+#: rpm.c:549
msgid " --checksig +"
msgstr ""
-#: rpm.c:546
+#: rpm.c:550
msgid " -K + "
msgstr ""
-#: rpm.c:547 rpmqv.c:204 rpmqv.c:670
+#: lib/poptK.c:58 rpm.c:551
msgid "verify package signature"
msgstr ""
-#: rpm.c:549 rpmqv.c:206 rpmqv.c:672
+#: lib/poptK.c:64 rpm.c:553
msgid "skip any PGP signatures"
msgstr ""
-#: rpm.c:551 rpmqv.c:208 rpmqv.c:674
+#: lib/poptK.c:61 rpm.c:555
msgid "skip any GPG signatures"
msgstr ""
-#: rpm.c:553 rpmqv.c:676
+#: rpm.c:557
msgid "skip any MD5 signatures"
msgstr ""
-#: rpm.c:557
+#: rpm.c:561
msgid "make sure a valid database exists"
msgstr ""
-#: rpm.c:559
+#: rpm.c:563
msgid "rebuild database from existing database"
msgstr ""
-#: rpm.c:567 rpmqv.c:581
+#: rpm.c:565 rpmdb/poptDB.c:27
+msgid "verify database files"
+msgstr ""
+
+#: rpm.c:573
msgid ""
"set the file permissions to those in the package database using the same "
"package specification options as -q"
msgstr ""
-#: rpm.c:570 rpmqv.c:584
+#: rpm.c:576
msgid ""
"set the file owner and group to those in the package database using the same "
"package specification options as -q"
msgstr ""
-#: rpm.c:722 rpm.c:728 rpm.c:737 rpm.c:759 rpm.c:765 rpm.c:772 rpm.c:780
-#: rpm.c:788 rpm.c:809 rpm.c:872 rpmqv.c:877 rpmqv.c:883 rpmqv.c:890
-#: rpmqv.c:896 rpmqv.c:938 rpmqv.c:946 rpmqv.c:952 rpmqv.c:960 rpmqv.c:1033
+#: rpm.c:728 rpm.c:734 rpm.c:743 rpm.c:765 rpm.c:771 rpm.c:778 rpm.c:786
+#: rpm.c:794 rpm.c:815 rpm.c:821 rpm.c:884 rpmqv.c:528 rpmqv.c:534 rpmqv.c:540
+#: rpmqv.c:574
msgid "only one major mode may be specified"
msgstr ""
-#: rpm.c:730
+#: rpm.c:736
msgid "-u and --uninstall are deprecated and no longer work.\n"
msgstr ""
-#: rpm.c:732
+#: rpm.c:738
msgid "Use -e or --erase instead.\n"
msgstr ""
-#: rpm.c:815 rpmqv.c:919
+#: lib/poptI.c:49 rpm.c:827
msgid "relocations must begin with a /"
msgstr ""
-#: rpm.c:817 rpmqv.c:921
+#: lib/poptI.c:51 rpm.c:829
msgid "relocations must contain a ="
msgstr ""
-#: rpm.c:820 rpmqv.c:925
+#: lib/poptI.c:54 rpm.c:832
msgid "relocations must have a / following the ="
msgstr ""
-#: rpm.c:829 rpmqv.c:904
+#: lib/poptI.c:37 rpm.c:841
msgid "exclude paths must begin with a /"
msgstr ""
-#: rpm.c:838 rpmqv.c:986
+#: rpm.c:850 rpmqv.c:481
msgid "The --rcfile option has been eliminated.\n"
msgstr ""
-#: rpm.c:839
+#: rpm.c:851
msgid "Use --macros with a colon separated list of macro files to read.\n"
msgstr ""
-#: rpm.c:844 rpmqv.c:993
+#: rpm.c:856 rpmqv.c:488
#, c-format
msgid "Internal error in argument processing (%d) :-(\n"
msgstr ""
-#: rpm.c:879 rpmqv.c:1048
+#: rpm.c:891 rpmqv.c:555
msgid "one type of query/verify may be performed at a time"
msgstr ""
-#: rpm.c:884 rpmqv.c:1052
+#: rpm.c:896 rpmqv.c:559
msgid "unexpected query flags"
msgstr ""
-#: rpm.c:887 rpmqv.c:1055
+#: rpm.c:899 rpmqv.c:562
msgid "unexpected query format"
msgstr ""
-#: rpm.c:890 rpmqv.c:1058
+#: rpm.c:902 rpmqv.c:565
msgid "unexpected query source"
msgstr ""
-#: rpm.c:893 rpmqv.c:1068
+#: rpm.c:905 rpmqv.c:590
msgid "only installation, upgrading, rmsource and rmspec may be forced"
msgstr ""
-#: rpm.c:896 rpmqv.c:1073
+#: rpm.c:908 rpmqv.c:592
msgid "files may only be relocated during package installation"
msgstr ""
-#: rpm.c:899 rpmqv.c:1076
+#: rpm.c:911 rpmqv.c:595
msgid "only one of --prefix or --relocate may be used"
msgstr ""
-#: rpm.c:902 rpmqv.c:1079
+#: rpm.c:914 rpmqv.c:598
msgid ""
"--relocate and --excludepath may only be used when installing new packages"
msgstr ""
-#: rpm.c:905 rpmqv.c:1082
+#: rpm.c:917 rpmqv.c:601
msgid "--prefix may only be used when installing new packages"
msgstr ""
-#: rpm.c:908 rpmqv.c:1085
+#: rpm.c:920 rpmqv.c:604
msgid "arguments to --prefix must begin with a /"
msgstr ""
-#: rpm.c:911 rpmqv.c:1088
+#: rpm.c:923 rpmqv.c:607
msgid "--hash (-h) may only be specified during package installation"
msgstr ""
-#: rpm.c:915 rpmqv.c:1092
+#: rpm.c:927 rpmqv.c:611
msgid "--percent may only be specified during package installation"
msgstr ""
-#: rpm.c:919 rpmqv.c:1097
+#: rpm.c:931 rpmqv.c:616
msgid "--replacefiles may only be specified during package installation"
msgstr ""
-#: rpm.c:923 rpmqv.c:1101
+#: rpm.c:935 rpmqv.c:620
msgid "--replacepkgs may only be specified during package installation"
msgstr ""
-#: rpm.c:927 rpmqv.c:1105
+#: rpm.c:939 rpmqv.c:624
msgid "--excludedocs may only be specified during package installation"
msgstr ""
-#: rpm.c:931 rpmqv.c:1109
+#: rpm.c:943 rpmqv.c:628
msgid "--includedocs may only be specified during package installation"
msgstr ""
-#: rpm.c:935 rpmqv.c:1113
+#: rpm.c:947 rpmqv.c:632
msgid "only one of --excludedocs and --includedocs may be specified"
msgstr ""
-#: rpm.c:939 rpmqv.c:1117
+#: rpm.c:951 rpmqv.c:636
msgid "--ignorearch may only be specified during package installation"
msgstr ""
-#: rpm.c:943 rpmqv.c:1121
+#: rpm.c:955 rpmqv.c:640
msgid "--ignoreos may only be specified during package installation"
msgstr ""
-#: rpm.c:947 rpmqv.c:1126
+#: rpm.c:959 rpmqv.c:645
msgid "--ignoresize may only be specified during package installation"
msgstr ""
-#: rpm.c:951 rpmqv.c:1130
+#: rpm.c:963 rpmqv.c:649
msgid "--allmatches may only be specified during package erasure"
msgstr ""
-#: rpm.c:955 rpmqv.c:1134
+#: rpm.c:967 rpmqv.c:653
msgid "--allfiles may only be specified during package installation"
msgstr ""
-#: rpm.c:959 rpmqv.c:1139
+#: rpm.c:971 rpmqv.c:658
msgid "--justdb may only be specified during package installation and erasure"
msgstr ""
-#: rpm.c:966
+#: rpm.c:978
msgid ""
"script disabling options may only be specified during package installation, "
"erasure, and verification"
msgstr ""
-#: rpm.c:970
+#: rpm.c:982
msgid "--apply may only be specified during package installation"
msgstr ""
-#: rpm.c:975 rpmqv.c:1151
+#: rpm.c:987 rpmqv.c:668
msgid ""
"trigger disabling options may only be specified during package installation "
"and erasure"
msgstr ""
-#: rpm.c:979 rpmqv.c:1155
+#: rpm.c:991 rpmqv.c:672
msgid ""
"--nodeps may only be specified during package building, rebuilding, "
"recompilation, installation,erasure, and verification"
msgstr ""
-#: rpm.c:984 rpmqv.c:1160
+#: rpm.c:996 rpmqv.c:677
msgid ""
"--test may only be specified during package installation, erasure, and "
"building"
msgstr ""
-#: rpm.c:988 rpmqv.c:1165
+#: rpm.c:1000 rpmqv.c:682
msgid ""
"--root (-r) may only be specified during installation, erasure, querying, "
"and database rebuilds"
msgstr ""
-#: rpm.c:1000 rpmqv.c:1177
+#: rpm.c:1012 rpmqv.c:694
msgid "arguments to --root (-r) must begin with a /"
msgstr ""
-#: rpm.c:1006
+#: rpm.c:1018
msgid "--oldpackage may only be used during upgrades"
msgstr ""
-#: rpm.c:1009 rpmqv.c:1184
+#: rpm.c:1021
msgid "--nopgp may only be used during signature checking"
msgstr ""
-#: rpm.c:1012 rpmqv.c:1187
+#: rpm.c:1024
msgid "--nogpg may only be used during signature checking"
msgstr ""
-#: rpm.c:1015 rpmqv.c:1192
+#: rpm.c:1027
msgid ""
"--nomd5 may only be used during signature checking and package verification"
msgstr ""
-#: rpm.c:1026 rpmqv.c:1208
+#: rpm.c:1038 rpmqv.c:715
msgid "no files to sign\n"
msgstr ""
-#: rpm.c:1031 rpmqv.c:1213
+#: rpm.c:1043 rpmqv.c:720
#, c-format
msgid "cannot access file %s\n"
msgstr ""
-#: rpm.c:1046 rpmqv.c:1232
+#: rpm.c:1058 rpmqv.c:739
msgid "pgp not found: "
msgstr ""
-#: rpm.c:1050 rpmqv.c:1237
+#: rpm.c:1062 rpmqv.c:744
msgid "Enter pass phrase: "
msgstr ""
-#: rpm.c:1052 rpmqv.c:1239
+#: rpm.c:1064 rpmqv.c:746
msgid "Pass phrase check failed\n"
msgstr ""
-#: rpm.c:1055 rpmqv.c:1243
+#: rpm.c:1067 rpmqv.c:750
msgid "Pass phrase is good.\n"
msgstr ""
-#: rpm.c:1060 rpmqv.c:1248
+#: rpm.c:1072 rpmqv.c:755
+#, c-format
msgid "Invalid %%_signature spec in macro file.\n"
msgstr ""
-#: rpm.c:1066 rpmqv.c:1255
+#: rpm.c:1078 rpmqv.c:762
msgid "--sign may only be used during package building"
msgstr ""
-#: rpm.c:1081 rpmqv.c:1271
+#: rpm.c:1093 rpmqv.c:778
msgid "exec failed\n"
msgstr ""
-#: rpm.c:1100 rpmqv.c:1521
+#: rpm.c:1116 rpmqv.c:985
msgid "unexpected arguments to --querytags "
msgstr ""
-#: rpm.c:1111 rpmqv.c:1545
+#: rpm.c:1127 rpmqv.c:994
msgid "no packages given for signature check"
msgstr ""
-#: rpm.c:1122 rpmqv.c:1556
+#: rpm.c:1138 rpmqv.c:1003
msgid "no packages given for signing"
msgstr ""
-#: rpm.c:1138 rpmqv.c:1415
+#: rpm.c:1154 rpmqv.c:896
msgid "no packages given for uninstall"
msgstr ""
-#: rpm.c:1227 rpmqv.c:1444
+#: rpm.c:1243 rpmqv.c:919
msgid "no packages given for install"
msgstr ""
-#: rpm.c:1251 rpmqv.c:1487
+#: rpm.c:1267 rpmqv.c:948
msgid "extra arguments given for query of all packages"
msgstr ""
-#: rpm.c:1256 rpmqv.c:1492
+#: rpm.c:1272 rpmqv.c:957
msgid "no arguments given for query"
msgstr ""
-#: rpm.c:1273 rpmqv.c:1509
+#: rpm.c:1289 rpmqv.c:973
msgid "extra arguments given for verify of all packages"
msgstr ""
-#: rpm.c:1277 rpmqv.c:1513
+#: rpm.c:1293 rpmqv.c:977
msgid "no arguments given for verify"
msgstr ""
-#: rpm2cpio.c:24
-#, c-format
-msgid "cannot open package: %s\n"
-msgstr ""
-
#: rpm2cpio.c:34
msgid "argument is not an RPM package\n"
msgstr ""
@@ -1101,423 +1104,127 @@ msgstr ""
msgid "cannot re-open payload: %s\n"
msgstr ""
-#: rpmqv.c:133
+#: rpmqv.c:103
msgid "provide less detailed output"
msgstr ""
-#: rpmqv.c:135
+#: rpmqv.c:105
msgid "provide more detailed output"
msgstr ""
-#: rpmqv.c:138
+#: rpmqv.c:108
msgid "' '"
msgstr ""
-#: rpmqv.c:140
+#: rpmqv.c:110
msgid "print macro expansion of +"
msgstr ""
-#: rpmqv.c:141
+#: rpmqv.c:111
msgid "+"
msgstr ""
-#: rpmqv.c:144
+#: rpmqv.c:114
msgid ""
msgstr ""
-#: rpmqv.c:147 rpmqv.c:314
+#: lib/poptI.c:175 rpmqv.c:117
msgid ""
msgstr ""
-#: rpmqv.c:149
+#: rpmqv.c:119
msgid "read instead of default macro file(s)"
msgstr ""
-#: rpmqv.c:150 rpmqv.c:154 rpmqv.c:158
+#: rpmqv.c:120 rpmqv.c:124 rpmqv.c:128
msgid ""
msgstr ""
-#: rpmqv.c:153 rpmqv.c:157
+#: rpmqv.c:123 rpmqv.c:127
msgid "read instead of default rpmrc file(s)"
msgstr ""
-#: rpmqv.c:166
+#: rpmqv.c:136
msgid "disable use of libio(3) API"
msgstr ""
-#: rpmqv.c:169
+#: rpmqv.c:139
msgid "debug protocol data stream"
msgstr ""
-#: rpmqv.c:171
+#: rpmqv.c:141
msgid "debug rpmio I/O"
msgstr ""
-#: rpmqv.c:173
+#: rpmqv.c:143
msgid "debug URL cache handling"
msgstr ""
-#: rpmqv.c:181
-msgid "initialize database"
-msgstr ""
-
-#: rpmqv.c:183
-msgid "rebuild database inverted lists from installed package headers"
-msgstr ""
-
-#: rpmqv.c:186
-msgid "generate headers compatible with (legacy) rpm[23] packaging"
-msgstr ""
-
-#: lib/poptBT.c:179 rpmqv.c:189
-msgid "generate headers compatible with rpm4 packaging"
-msgstr ""
-
-#: rpmqv.c:235 rpmqv.c:277
-msgid "do not execute package scriptlet(s)"
-msgstr ""
-
-#: rpmqv.c:240
-msgid "save erased package files by renaming into sub-directory"
-msgstr ""
-
-#: rpmqv.c:242
-msgid "+"
-msgstr ""
-
-#: rpmqv.c:246 rpmqv.c:602
-msgid "skip files with leading component "
-msgstr ""
-
-#: rpmqv.c:247
-msgid ""
-msgstr ""
-
-#: rpmqv.c:252
-msgid "upgrade package(s) if already installed"
-msgstr ""
-
-#: rpmqv.c:253 rpmqv.c:266 rpmqv.c:329
-msgid "+"
-msgstr ""
-
-#: rpmqv.c:280
-msgid "do not execute %%pre scriptlet (if any)"
-msgstr ""
-
-#: rpmqv.c:283
-msgid "do not execute %%post scriptlet (if any)"
-msgstr ""
-
-#: rpmqv.c:286
-msgid "do not execute %%preun scriptlet (if any)"
-msgstr ""
-
-#: rpmqv.c:289
-msgid "do not execute %%postun scriptlet (if any)"
-msgstr ""
-
-#: rpmqv.c:293
-msgid "do not execute any scriptlet(s) triggered by this package"
-msgstr ""
-
-#: rpmqv.c:296
-msgid "do not execute any %%triggerprein scriptlet(s)"
-msgstr ""
-
-#: rpmqv.c:299
-msgid "do not execute any %%triggerin scriptlet(s)"
-msgstr ""
-
-#: rpmqv.c:302
-msgid "do not execute any %%triggerun scriptlet(s)"
-msgstr ""
-
-#: rpmqv.c:305
-msgid "do not execute any %%triggerpostun scriptlet(s)"
-msgstr ""
-
-#: rpmqv.c:316
-msgid "relocate files from path to "
-msgstr ""
-
-#: rpmqv.c:317
-msgid "="
-msgstr ""
-
-#: rpmqv.c:319
-msgid "save erased package files by repackaging"
-msgstr ""
-
-#: rpmqv.c:328
-msgid "upgrade package(s)"
-msgstr ""
-
-#: rpmqv.c:348
+#: rpmqv.c:161
msgid "Query options (with -q or --query):"
msgstr ""
-#: rpmqv.c:351
+#: rpmqv.c:164
msgid "Verify options (with -V or --verify):"
msgstr ""
-#: rpmqv.c:357
+#: rpmqv.c:170
msgid "Signature options:"
msgstr ""
-#: rpmqv.c:363
+#: rpmqv.c:176
msgid "Database options:"
msgstr ""
-#: rpmqv.c:369
+#: rpmqv.c:182
msgid "Build options with [ | |