summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorjbj <devnull@localhost>2000-12-02 21:53:44 +0000
committerjbj <devnull@localhost>2000-12-02 21:53:44 +0000
commit2885f536b6e314734c0c04245d77b9f7bdc76d42 (patch)
tree1ab8d5ab1cbc20bd1b1da69ba475b80816db2da9 /lib
parentd7a40e754dc6b0ac07d2185bb5723384065feab5 (diff)
downloadlibrpm-tizen-2885f536b6e314734c0c04245d77b9f7bdc76d42.tar.gz
librpm-tizen-2885f536b6e314734c0c04245d77b9f7bdc76d42.tar.bz2
librpm-tizen-2885f536b6e314734c0c04245d77b9f7bdc76d42.zip
Bring header reggions mods back to top of stack.
CVS patchset: 4305 CVS date: 2000/12/02 21:53:44
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am16
-rw-r--r--lib/cpio.c6
-rw-r--r--lib/db1.c32
-rw-r--r--lib/depends.c13
-rw-r--r--lib/fprint.c12
-rw-r--r--lib/header.c730
-rw-r--r--lib/header.h32
-rw-r--r--lib/install.c197
-rw-r--r--lib/md5sum.c43
-rw-r--r--lib/misc.c4
-rw-r--r--lib/package.c58
-rw-r--r--lib/rpmchecksig.c36
-rw-r--r--lib/rpmdb.c39
-rw-r--r--lib/rpmlib.h70
-rw-r--r--lib/signature.c8
-rw-r--r--lib/transaction.c28
-rw-r--r--lib/verify.c13
17 files changed, 745 insertions, 592 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7257d23ac..6ac2ae907 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,7 +12,8 @@ pkginc_HEADERS = \
header.h misc.h rpmlib.h stringbuf.h
noinst_HEADERS = \
cpio.h depends.h falloc.h fprint.h hash.h install.h \
- md5.h rpmdb.h rpmlead.h signature.h
+ md5.h \
+ rpmdb.h rpmlead.h signature.h
mylibpaths = -L$(top_builddir)/lib/.libs -L$(top_builddir)/rpmio/.libs \
-L$(top_builddir)/popt/.libs
@@ -21,14 +22,15 @@ LIBS =
lib_LTLIBRARIES = librpm.la
librpm_la_SOURCES = \
- cpio.c $(DBLIBOBJS) depends.c \
+ cpio.c $(DBLIBSRCS) depends.c \
formats.c fprint.c fs.c hash.c header.c install.c \
md5.c md5sum.c misc.c package.c problems.c \
poptBT.c poptQV.c query.c rpmchecksig.c rpmdb.c rpminstall.c \
rpmlead.c rpmlibprov.c rpmrc.c signature.c stringbuf.c stubs.c \
tagName.c tagtable.c transaction.c uninstall.c verify.c
librpm_la_LDFLAGS = @libdb3@ @libdb2@ @libdb1@
-librpm_la_LIBADD = $(subst .c,.lo,$(DBLIBOBJS))
+librpm_la_LIBADD = $(DBLIBOBJS)
+librpm_la_DEPENDENCIES = $(DBLIBOBJS)
# XXX Add internal libtool dependence
install-data-local:
@@ -57,11 +59,5 @@ BUILT_SOURCES = tagtable.c
lclint:
lclint $(DEFS) $(INCLUDES) $(librpm_la_SOURCES)
-tmacro: macro.c
- $(CC) $(CFLAGS) $(DEFS) -DDEBUG_MACROS $(INCLUDES) -o $@ $<
-
-rpmeval: macro.c
- $(CC) $(CFLAGS) $(DEFS) -DDEBUG_MACROS -DEVAL_MACROS $(INCLUDES) -o $@ $<
-
-tufdio: tufdio.c
+th: th.c librpm.la
$(CC) $(CFLAGS) $(DEFS) $(INCLUDES) -o $@ $< $(mylibpaths) $(mylibs) $(LIBS)
diff --git a/lib/cpio.c b/lib/cpio.c
index 7fab884ab..687135dc0 100644
--- a/lib/cpio.c
+++ b/lib/cpio.c
@@ -416,6 +416,7 @@ static int inline checkDirectory(const char * filename) /*@*/
/**
* Create file from payload stream.
+ * @todo Legacy: support brokenEndian MD5 checks?
* @param cfd payload file handle
* @param hdr file name and stat info
* @param filemd5 file md5 sum
@@ -459,8 +460,9 @@ static int expandRegular(FD_t cfd, const struct cpioHeader * hdr,
if (ofd == NULL || Ferror(ofd))
return CPIOERR_OPEN_FAILED;
+ /* XXX This doesn't support brokenEndian checks. */
if (filemd5)
- fdInitMD5(ofd);
+ fdInitMD5(ofd, 0);
cbInfo.file = hdr->path;
cbInfo.fileSize = st->st_size;
@@ -735,7 +737,7 @@ int cpioInstallArchive(FD_t cfd, const struct cpioFileMapping * mappings,
#ifdef NOTYET
char * md5sum = NULL;
- fdInitMD5(cfd);
+ fdInitMD5(cfd, 0);
#endif
fdSetCpioPos(cfd, 0);
diff --git a/lib/db1.c b/lib/db1.c
index 8344773b7..fc4ccd81c 100644
--- a/lib/db1.c
+++ b/lib/db1.c
@@ -6,7 +6,15 @@
static int _debug = 1; /* XXX if < 0 debugging, > 0 unusual error returns */
+#ifdef HAVE_DB1_DB_H
#include <db1/db.h>
+#else
+#ifdef HAVE_DB_185_H
+#include <db_185.h> /* XXX there are too mant compat API's for this to work */
+#else
+#include <db.h>
+#endif
+#endif
#define DB_VERSION_MAJOR 0
#define DB_VERSION_MINOR 0
@@ -41,28 +49,6 @@ static inline DBTYPE db3_to_dbtype(int dbitype)
/*@notreached@*/ return DB_HASH;
}
-/** \ingroup db1
- */
-char * db1basename (int rpmtag) {
- char * base = NULL;
- switch (rpmtag) {
- case 0: base = "packages.rpm"; break;
- case RPMTAG_NAME: base = "nameindex.rpm"; break;
- case RPMTAG_BASENAMES: base = "fileindex.rpm"; break;
- case RPMTAG_GROUP: base = "groupindex.rpm"; break;
- case RPMTAG_REQUIRENAME: base = "requiredby.rpm"; break;
- case RPMTAG_PROVIDENAME: base = "providesindex.rpm"; break;
- case RPMTAG_CONFLICTNAME: base = "conflictsindex.rpm"; break;
- case RPMTAG_TRIGGERNAME: base = "triggerindex.rpm"; break;
- default:
- { const char * tn = tagName(rpmtag);
- base = alloca( strlen(tn) + sizeof(".idx") + 1 );
- (void) stpcpy( stpcpy(base, tn), ".idx");
- } break;
- }
- return xstrdup(base);
-}
-
static /*@observer@*/ const char * db_strerror(int error)
{
if (error == 0)
@@ -161,7 +147,7 @@ static void * doGetRecord(FD_t pkgs, unsigned int offset)
* list.
*/
if (!headerGetEntryMinMemory(h, RPMTAG_OLDFILENAMES, NULL,
- (void **) &fileNames, &fileCount)) goto exit;
+ (const void **) &fileNames, &fileCount)) goto exit;
for (i = 0; i < fileCount; i++)
if (*fileNames[i] != '/') break;
diff --git a/lib/depends.c b/lib/depends.c
index 78f39f691..60dc46bdd 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -300,15 +300,16 @@ static /*@exposed@*/ struct availablePackage * alAddPackage(struct availableList
p->requireFlags = NULL;
}
- if (!headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL, (void **)
- &p->baseNames, &p->filesCount)) {
+ if (!headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL,
+ (const void **) &p->baseNames, &p->filesCount))
+ {
p->filesCount = 0;
p->baseNames = NULL;
} else {
- headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, (void **)
- &dirNames, &numDirs);
- headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL, (void **)
- &dirIndexes, NULL);
+ headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL,
+ (const void **) &dirNames, &numDirs);
+ headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL,
+ (const void **) &dirIndexes, NULL);
headerGetEntry(h, RPMTAG_FILEFLAGS, NULL, (void **) &fileFlags, NULL);
/* XXX FIXME: We ought to relocate the directory list here */
diff --git a/lib/fprint.c b/lib/fprint.c
index 65f705907..866af714b 100644
--- a/lib/fprint.c
+++ b/lib/fprint.c
@@ -230,13 +230,13 @@ void fpLookupHeader(fingerPrintCache cache, Header h, fingerPrint * fpList)
int_32 * dirIndexes;
if (!headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL,
- (void **) &baseNames, &fileCount)) return;
- headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, (void **) &dirNames,
- NULL);
- headerGetEntry(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
-
- fpLookupList(cache, dirNames, baseNames, dirIndexes, fileCount, fpList);
+ (const void **) &baseNames, &fileCount)) return;
+ headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL,
+ (const void **) &dirNames, NULL);
+ headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL,
+ (const void **) &dirIndexes, NULL);
+ fpLookupList(cache, dirNames, baseNames, dirIndexes, fileCount, fpList);
free(dirNames);
free(baseNames);
}
diff --git a/lib/header.c b/lib/header.c
index a6b0959fe..fcfe8328d 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -22,7 +22,7 @@
#include <rpmio.h>
#include <header.h>
-
+#include <assert.h>
/* XXX avoid rpmlib.h for debugging. */
/*@observer@*/ const char *const tagName(int tag) /*@*/;
@@ -33,13 +33,15 @@
#define PARSER_IN_ARRAY 1
#define PARSER_IN_EXPR 2
-static unsigned char header_magic[4] = { 0x8e, 0xad, 0xe8, 0x01 };
+static unsigned char header_magic[8] = {
+ 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
+};
/** \ingroup header
* Alignment needs (and sizeof scalars types) for internal rpm data types.
*/
static int typeSizes[] = {
- -1, /*!< RPM_NULL_TYPE */
+ 0, /*!< RPM_NULL_TYPE */
1, /*!< RPM_CHAR_TYPE */
1, /*!< RPM_INT8_TYPE */
2, /*!< RPM_INT16_TYPE */
@@ -61,12 +63,11 @@ struct entryInfo {
int_32 count; /*!< Number of tag elements. */
};
-#define REGION_ID(_x, _y) (((_x) << 4) + ((_y) & 0xf))
#define REGION_TAG_TYPE RPM_BIN_TYPE
#define REGION_TAG_COUNT sizeof(struct entryInfo)
-#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE)
-#define ENTRY_IN_REGION(_e) (((_e)->info.offset & 0xf) > 0)
+#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE)
+#define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0)
/**
* A single tag from a Header.
@@ -78,32 +79,22 @@ struct indexEntry {
};
/**
- * A single contiguous region from a Header.
- */
-typedef struct {
- int allocated; /*!< Should region be freed? */
- int len; /*!< No. bytes in region. */
-/*@shared@*/ void * data; /*!< Region data. */
-} * headerRegion;
-
-/**
* The Header data structure.
*/
struct headerToken {
-/*@owned@*/ headerRegion regions;/*!< Data regions. */
struct indexEntry *index; /*!< Array of tags. */
- int nregions; /*!< No. of data regions. */
int indexUsed; /*!< Current size of tag array. */
int indexAlloced; /*!< Allocated size of tag array. */
- int sorted; /*!< Are header entries sorted? */
-/*@refs@*/ int nrefs; /*!< Reference count. */
+ int region_allocated; /*!< Is 1st header region allocated? */
+ int sorted; /*!< Are header entries sorted? */
+ int reloaded; /*!< Append region data? */
+/*@refs@*/ int nrefs; /*!< Reference count. */
};
/**
*/
struct sprintfTag {
- /* if NULL tag element is invalid */
- headerTagTagFunction ext;
+ headerTagTagFunction ext; /*!< if NULL tag element is invalid */
int extNum;
int_32 tag;
int justOne;
@@ -201,115 +192,177 @@ static void headerProbe(Header h, const char *msg)
#define HEADERPROBE(_h, _msg)
#endif /* HAVE_MCHECK_H */
-static void copyEntry(const struct indexEntry * entry, /*@out@*/ int_32 * type,
- /*@out@*/ const void ** p, /*@out@*/ int_32 * c, int minimizeMemory)
- /*@modifies *type, *p, *c @*/
-{
- if (type)
- *type = entry->info.type;
- if (c)
- *c = entry->info.count;
- if (p == NULL)
- return;
-
- /* Now look it up */
- switch (entry->info.type) {
- case RPM_STRING_TYPE:
- if (entry->info.count == 1) {
- *p = entry->data;
- break;
- }
- /*@fallthrough@*/
- case RPM_STRING_ARRAY_TYPE:
- case RPM_I18NSTRING_TYPE:
- { const char ** ptrEntry;
- char * chptr;
- int i = entry->info.count;
- int tableSize = i * sizeof(char *);
-
- if (minimizeMemory) {
- ptrEntry = *p = xmalloc(tableSize);
- chptr = entry->data;
- } else {
- chptr = xmalloc(tableSize + entry->length); /* XXX memory leak */
- ptrEntry = *p = (void *)chptr;
- chptr += tableSize;
- memcpy(chptr, entry->data, entry->length);
- }
- while (i--) {
- *ptrEntry++ = chptr;
- chptr = strchr(chptr, 0);
- chptr++;
- }
- } break;
-
- default:
- *p = entry->data;
- break;
- }
-}
-
+/**
+ * Return length of entry data.
+ * @param type entry data type
+ * @param p entry data
+ * @param count entry item count
+ * @param onDisk data is concatenated strings (with NUL's))?
+ * @return no. bytes in data
+ */
static int dataLength(int_32 type, const void * p, int_32 count, int onDisk)
/*@*/
{
- int thisLen, length, i;
- char ** src, * chptr;
+ int length = 0;
- length = 0;
switch (type) {
case RPM_STRING_TYPE:
- if (count == 1) {
- /* Special case -- p is just the string */
+ if (count == 1) { /* Special case -- p is just the string */
length = strlen(p) + 1;
break;
}
/* This should not be allowed */
- fprintf(stderr, _("grabData() RPM_STRING_TYPE count must be 1.\n"));
+ fprintf(stderr, _("dataLength() RPM_STRING_TYPE count must be 1.\n"));
exit(EXIT_FAILURE);
/*@notreached@*/ break;
case RPM_STRING_ARRAY_TYPE:
case RPM_I18NSTRING_TYPE:
+ { int i;
+
/* This is like RPM_STRING_TYPE, except it's *always* an array */
/* Compute sum of length of all strings, including null terminators */
i = count;
- length = 0;
if (onDisk) {
- chptr = (char *) p;
+ const char * chptr = p;
+ int thisLen;
+
while (i--) {
thisLen = strlen(chptr) + 1;
length += thisLen;
chptr += thisLen;
}
} else {
- src = (char **) p;
+ const char ** src = (const char **)p;
while (i--) {
/* add one for null termination */
length += strlen(*src++) + 1;
}
}
- break;
+ } break;
default:
- if (typeSizes[type] != -1)
+ if (typeSizes[type] != -1) {
length = typeSizes[type] * count;
- else {
- fprintf(stderr, _("Data type %d not supported\n"), (int) type);
- exit(EXIT_FAILURE);
- /*@notreached@*/
+ break;
}
- break;
+ fprintf(stderr, _("Data type %d not supported\n"), (int) type);
+ exit(EXIT_FAILURE);
+ /*@notreached@*/ break;
}
return length;
}
-/********************************************************************/
-/* */
-/* Header iteration and copying */
-/* */
-/********************************************************************/
+/**
+ * Swap int_32 and int_16 arrays within header region.
+ * @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 myoffset translate start of data (must be 0 now)
+ * @return no. bytes of data in region
+ */
+static int regionSwab(struct indexEntry * entry, int il, int dl,
+ const struct entryInfo * pe, char * dataStart, int myoff)
+{
+ for (; il > 0; il--, pe++) {
+ struct indexEntry ie;
+ void * t;
+
+ ie.info.tag = ntohl(pe->tag);
+ ie.info.type = ntohl(pe->type);
+assert(ie.info.type >= RPM_MIN_TYPE && ie.info.type <= RPM_MAX_TYPE);
+ ie.info.count = ntohl(pe->count);
+ ie.info.offset = ntohl(pe->offset);
+ ie.data = t = dataStart + ie.info.offset + myoff;
+ ie.length = dataLength(ie.info.type, ie.data, ie.info.count, 1);
+
+ if (entry) {
+ ie.info.offset = ((char *)pe - dataStart); /* negative offset */
+ *entry = ie; /* structure assignment */
+ entry++;
+ }
+
+ dl += ie.length;
+
+ /* Perform endian conversions */
+ switch (ntohl(pe->type)) {
+ case RPM_INT32_TYPE:
+ for (; ie.info.count > 0; ie.info.count--, ((int_32 *)t) += 1)
+ *((int_32 *)t) = htonl(*((int_32 *)t));
+ break;
+ case RPM_INT16_TYPE:
+ for (; ie.info.count > 0; ie.info.count--, ((int_16 *)t) += 1)
+ *((int_16 *)t) = htons(*((int_16 *)t));
+ break;
+ }
+ }
+ return dl;
+}
+
+/**
+ * Retrieve data from header entry.
+ * @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?
+ */
+static void copyEntry(const struct indexEntry * entry, /*@out@*/ int_32 * type,
+ /*@out@*/ const void ** p, /*@out@*/ int_32 * c, int minMem)
+ /*@modifies *type, *p, *c @*/
+{
+ if (type)
+ *type = entry->info.type;
+ if (c)
+ *c = entry->info.count;
+ if (p == NULL)
+ return;
+
+ /* Now look it up */
+ switch (entry->info.type) {
+ case RPM_BIN_TYPE:
+ *p = (!minMem
+ ? memcpy(xmalloc(entry->length), entry->data, entry->length)
+ : entry->data);
+ break;
+ case RPM_STRING_TYPE:
+ if (entry->info.count == 1) {
+ *p = entry->data;
+ break;
+ }
+ /*@fallthrough@*/
+ case RPM_STRING_ARRAY_TYPE:
+ case RPM_I18NSTRING_TYPE:
+ { const char ** ptrEntry;
+ char * t;
+ int i = entry->info.count;
+ int tableSize = i * sizeof(char *);
+
+ if (minMem) {
+ ptrEntry = *p = xmalloc(tableSize);
+ t = entry->data;
+ } else {
+ t = xmalloc(tableSize + entry->length);
+ ptrEntry = *p = (void *)t;
+ t += tableSize;
+ memcpy(t, entry->data, entry->length);
+ }
+ while (i--) {
+ *ptrEntry++ = t;
+ t = strchr(t, 0);
+ t++;
+ }
+ } break;
+
+ default:
+ *p = entry->data;
+ break;
+ }
+}
/**
* Header tag iterator data structure.
@@ -336,28 +389,29 @@ void headerFreeIterator(HeaderIterator iter)
free(iter);
}
-int headerNextIterator(HeaderIterator iter,
+int headerNextIterator(HeaderIterator hi,
int_32 * tag, int_32 * type, const void ** p, int_32 * c)
{
- Header h = iter->h;
- int slot = iter->next_index;
+ Header h = hi->h;
+ int slot = hi->next_index;
+ struct indexEntry * entry;
- if (slot == h->indexUsed)
+ if (slot >= h->indexUsed)
return 0;
- iter->next_index++;
+ hi->next_index++;
+ entry = h->index + slot;
if (tag)
- *tag = h->index[slot].info.tag;
+ *tag = entry->info.tag;
- copyEntry(h->index + slot, type, p, c, 0);
+ copyEntry(entry, type, p, c, 0);
return 1;
}
static int indexCmp(const void *avp, const void *bvp) /*@*/
{
- const struct indexEntry * ap = avp;
- const struct indexEntry * bp = bvp;
+ const struct indexEntry * ap = avp, * bp = bvp;
return (ap->info.tag - bp->info.tag);
}
@@ -369,10 +423,9 @@ void headerSort(Header h)
}
}
-static int offsetCmp(const void *avp, const void *bvp) /*@*/
+static int offsetCmp(const void *avp, const void *bvp) /*@*/
{
- const struct indexEntry * ap = avp;
- const struct indexEntry * bp = bvp;
+ const struct indexEntry * ap = avp, * bp = bvp;
int rc = (ap->info.offset - bp->info.offset);
if (rc == 0)
@@ -387,176 +440,88 @@ void headerUnsort(Header h)
Header headerCopy(Header h)
{
+ Header res = headerNew();
+ HeaderIterator hi;
int_32 tag, type, count;
const void *ptr;
- HeaderIterator headerIter;
- Header res = headerNew();
+ int prevtag = 0;
- headerIter = headerInitIterator(h);
-
- while (headerNextIterator(headerIter, &tag, &type, &ptr, &count)) {
+ for (hi = headerInitIterator(h);
+ headerNextIterator(hi, &tag, &type, &ptr, &count);
+ ptr = headerFreeData((void *)ptr, type))
+ {
+ if (prevtag && prevtag > tag)
+ res->sorted = 0;
+ prevtag = tag;
headerAddEntry(res, tag, type, ptr, count);
- if (type == RPM_STRING_ARRAY_TYPE ||
- type == RPM_I18NSTRING_TYPE) free((void *)ptr);
}
-
- res->sorted = 1;
-
- headerFreeIterator(headerIter);
+ headerFreeIterator(hi);
return res;
}
-/********************************************************************/
-/* */
-/* Header loading and unloading */
-/* */
-/********************************************************************/
-#if 0
-static void fprIndexEntry(const char *msg, struct indexEntry *entry, int i)
-{
- const char * val;
- fprintf(stderr, "%6d %*s %p: %p[%d]",
- i, (3*(entry->info.offset & 0xf)), "",
- entry, entry->data, entry->length);
-
- switch (entry->info.type) {
- case RPM_STRING_TYPE:
- case RPM_STRING_ARRAY_TYPE:
- case RPM_I18NSTRING_TYPE:
- val = (const char *) entry->data;
- break;
- case RPM_CHAR_TYPE:
- val = "CHAR";
- break;
- case RPM_INT8_TYPE:
- val = "INT8";
- break;
- case RPM_INT16_TYPE:
- val = "INT16";
- break;
- case RPM_INT32_TYPE:
- val = "INT32";
- break;
- case RPM_BIN_TYPE:
- val = "BIN";
- break;
- default:
- val = "";
- break;
- }
-
- fprintf(stderr, "\t%-8.8s %s(%d) %s\n",
- val,
- tagName(entry->info.tag), entry->info.tag,
- (msg ? msg : ""));
-}
-#endif
-
Header headerLoad(void *pv)
{
int_32 *ei = (int_32 *) pv;
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;
- char *p = (char *) &ei[2];
- Header h = xmalloc(sizeof(*h));
+ (il * sizeof(struct entryInfo)) + dl;
+ Header h = xcalloc(1, sizeof(*h));
- const char * dataStart;
- struct entryInfo * pe;
+ struct entryInfo * pe = (struct entryInfo *) &ei[2];
+ char * dataStart = (char *) (pe + il);
struct indexEntry * entry;
- int prevtag = 0;
- int rid = 0;
int i;
- h->nregions = 1;
- h->regions = xcalloc(h->nregions, sizeof(*h->regions));
- h->regions[0].allocated = 0;
- h->regions[0].len = pvlen;
- h->regions[0].data = pv;
-
h->indexAlloced = il + 1;
h->indexUsed = il;
- h->index = xcalloc(h->indexAlloced, sizeof(struct indexEntry));
+ h->index = xcalloc(h->indexAlloced, sizeof(*h->index));
h->sorted = 1;
+ h->reloaded = 0;
h->nrefs = 1;
- pe = (struct entryInfo *) p;
- dataStart = (char *) (pe + il);
-
entry = h->index;
i = 0;
if (!(htonl(pe->tag) < HEADER_I18NTABLE)) {
entry->info.type = REGION_TAG_TYPE;
- prevtag = entry->info.tag = HEADER_IMAGE;
+ entry->info.tag = HEADER_IMAGE;
entry->info.count = REGION_TAG_COUNT;
- entry->info.offset = rid;
- entry->data = h->regions[0].data;
- entry->length = h->regions[0].len;
+ entry->info.offset = ((char *)(pe-1) - dataStart); /* negative offset */
+ entry->data = pe;
+ entry->length = pvlen - sizeof(il) - sizeof(dl);
entry++;
+ regionSwab(entry, il, 0, pe, dataStart, 0);
i++;
il++;
h->indexUsed++;
- }
-
- for (; i < h->indexUsed; i++, entry++, pe++) {
- char * t;
- int j;
+ } else {
+ int_32 * stei = memcpy(alloca(REGION_TAG_COUNT), dataStart + ntohl(pe->offset), REGION_TAG_COUNT);
+ int_32 rdl = -ntohl(stei[2]); /* negative offset */
+ int_32 ril = rdl/sizeof(*pe);
+ int dlen;
+ int j = 0;
entry->info.type = htonl(pe->type);
if (entry->info.type < RPM_MIN_TYPE || entry->info.type > RPM_MAX_TYPE)
return NULL;
-
entry->info.tag = htonl(pe->tag);
-
- /* Check that header entries are sorted. */
- if (entry->info.tag < prevtag)
- h->sorted = 0;
- prevtag = entry->info.tag;
-
entry->info.count = htonl(pe->count);
- entry->info.offset = htonl(pe->offset);
+ entry->info.offset = -rdl; /* negative offset */
- if (ENTRY_IS_REGION(entry)) {
- int doff;
- h->regions = xrealloc(h->regions,
- (h->nregions + 1) * sizeof(*h->regions));
-
- { int_32 * stei = (int_32 *) (dataStart + entry->info.offset);
- doff = ntohl(stei[2]);
- h->regions[h->nregions].data = dataStart + doff;
- h->regions[h->nregions].len = ntohl(stei[3]);
- }
-
- h->regions[h->nregions].allocated = 0;
- rid = REGION_ID(h->nregions, 0);
- h->nregions++;
-
- entry->info.offset = rid;
- entry->data = h->regions[h->nregions - 1].data;
- entry->length = h->regions[h->nregions - 1].len;
- continue;
- }
+ entry->length = pvlen - sizeof(il) - sizeof(dl);
+ dlen = regionSwab(entry+1, ril-1, 0, pe+1, dataStart, 0);
+ entry->data = dataStart + entry->info.offset;
- entry->data = t = dataStart + entry->info.offset;
- entry->length = dataLength(entry->info.type, t, entry->info.count, 1);
- entry->info.offset = rid + 1;
+ j += ril;
- /* Perform endian conversions. */
- switch (entry->info.type) {
- case RPM_INT32_TYPE:
- for (j = entry->info.count; j > 0; j--, t += sizeof(int_32))
- *((int_32 *)t) = htonl(*((int_32 *)t));
- break;
- case RPM_INT16_TYPE:
- for (j = entry->info.count; j > 0; j--, t += sizeof(int_16))
- *((int_16 *)t) = htons(*((int_16 *)t));
- break;
+ if (j < h->indexUsed) {
+ dlen = regionSwab(entry+ril, h->indexUsed-ril, dlen, pe+ril, dataStart, 0);
}
}
- if (!h->sorted) headerSort(h);
+ h->sorted = 0;
+ headerSort(h);
return h;
}
@@ -566,17 +531,19 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
{
int_32 * ei;
struct entryInfo * pe;
- const char * dataStart;
+ char * dataStart;
char * te;
unsigned pad = 0;
unsigned len;
int_32 il;
int_32 dl;
- struct indexEntry * entry;
+ struct indexEntry * entry;
int i;
/* Sort entries by (region,tag) */
headerUnsort(h);
+
+ /* XXX Hack to avoid the headerSort() undoing headerUnsort. */
i = h->sorted;
h->sorted = 1;
len = headerSizeof(h, HEADER_MAGIC_NO);
@@ -595,34 +562,57 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
dataStart = te = (char *) (pe + il);
for (; i < h->indexUsed; i++, entry++, pe++) {
+const char *t;
const char * src;
- unsigned diff;
int_32 type;
int count;
+ int dlen;
- pe->type = htonl(entry->info.type);
- pe->tag = htonl(entry->info.tag);
-
+t = te;
if (ENTRY_IS_REGION(entry)) {
-
- pe->count = htonl(REGION_TAG_COUNT);
- pe->offset = htonl(te - dataStart);
-
- { int_32 * stei = (int_32 *) te;
- int_32 doff = ((char *)entry->data) - dataStart;
- stei[0] = htonl(0);
- stei[1] = htonl(0);
- stei[2] = htonl(doff);
- stei[3] = htonl(entry->length);
- te = (char *) &stei[4];
+ int_32 rdl = -entry->info.offset; /* negative offset */
+ int_32 ril = rdl/sizeof(*pe);
+
+src = (char *)entry->data;
+dlen = (entry->length - rdl + sizeof(*pe));
+
+ if (!(h->reloaded || entry->info.tag == HEADER_IMAGE)) {
+ src += sizeof(*pe);
+ dlen -= REGION_TAG_COUNT;
}
-
+
+ memcpy(pe+1, src, (rdl - sizeof(*pe)));
+ memcpy(te, src + rdl - sizeof(*pe), dlen);
+ count = regionSwab(NULL, ril-1, 0, pe+1, te, 0);
+ te += dlen;
+
+ pe->tag = htonl(entry->info.tag);
+ pe->type = htonl(entry->info.type);
+ pe->count = htonl(entry->info.count);
+
+ if (!(h->reloaded || entry->info.tag == HEADER_IMAGE)) {
+ pe->offset = htonl(te - dataStart - REGION_TAG_COUNT);
+ } else {
+ int_32 * stei = memcpy(alloca(REGION_TAG_COUNT), te, REGION_TAG_COUNT);
+ stei[0] = pe->tag;
+ stei[1] = pe->type;
+ stei[2] = htonl(-rdl); /* YYY +REGION_TAG_COUNT */
+ stei[3] = pe->count;
+ memcpy(te, stei, REGION_TAG_COUNT);
+ pe->offset = htonl(te - dataStart);
+ te += REGION_TAG_COUNT;
+ }
+
+ i += (ril-1);
+ entry += (ril-1);
+ pe += (ril-1);
continue;
}
/* Alignment */
type = entry->info.type;
if (typeSizes[type] > 1) {
+ unsigned diff;
diff = typeSizes[type] - ((te - dataStart) % typeSizes[type]);
if (diff != typeSizes[type]) {
memset(te, 0, diff);
@@ -631,6 +621,8 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
}
}
+ pe->tag = htonl(entry->info.tag);
+ pe->type = htonl(entry->info.type);
pe->count = htonl(entry->info.count);
pe->offset = htonl(te - dataStart);
@@ -663,9 +655,14 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
}
}
+ /* Insure that there are no memcpy dribbles. */
+ assert(((char *)pe) == dataStart);
+ assert((((char *)ei)+len) == te);
+
if (lengthPtr)
*lengthPtr = len;
+ h->sorted = 0;
headerSort(h);
return (void *)ei;
@@ -678,39 +675,36 @@ void *headerUnload(Header h)
return uh;
}
-Header headerReload(Header h)
+Header headerReload(Header h, int tag)
{
+ Header nh;
int length;
void * uh = doHeaderUnload(h, &length);
+
headerFree(h);
- h = headerLoad(uh);
- h->regions[0].allocated = 1;
- return h;
+ nh = headerLoad(uh);
+ nh->region_allocated = 1;
+ nh->reloaded = 1;
+ if (ENTRY_IS_REGION(nh->index)) {
+ if (tag == HEADER_SIGNATURES || tag == HEADER_IMMUTABLE)
+ nh->index[0].info.tag = tag;
+ }
+ return nh;
}
-/********************************************************************/
-/* */
-/* Reading and writing headers */
-/* */
-/********************************************************************/
-
int headerWrite(FD_t fd, Header h, enum hMagic magicp)
{
int length;
- void * uh = doHeaderUnload(h, &length);
+ const void * uh;
ssize_t nb;
+ uh = doHeaderUnload(h, &length);
switch (magicp) {
case HEADER_MAGIC_YES:
- { int_32 l = htonl(0);
-
nb = Fwrite(header_magic, sizeof(char), sizeof(header_magic), fd);
if (nb != sizeof(header_magic))
goto exit;
- nb = Fwrite(&l, sizeof(char), sizeof(l), fd);
- if (nb != sizeof(l))
- goto exit;
- } break;
+ break;
case HEADER_MAGIC_NO:
break;
}
@@ -718,7 +712,7 @@ int headerWrite(FD_t fd, Header h, enum hMagic magicp)
nb = Fwrite(uh, sizeof(char), length, fd);
exit:
- free(uh);
+ free((void *)uh);
return (nb == length ? 0 : 1);
}
@@ -730,7 +724,7 @@ Header headerRead(FD_t fd, enum hMagic magicp)
int_32 il;
int_32 dl;
int_32 magic;
- Header h;
+ Header h = NULL;
int len;
int i;
@@ -740,14 +734,14 @@ Header headerRead(FD_t fd, enum hMagic magicp)
i += 2;
if (timedRead(fd, (char *)block, i*sizeof(*block)) != (i * sizeof(*block)))
- return NULL;
+ goto exit;
i = 0;
if (magicp == HEADER_MAGIC_YES) {
magic = block[i++];
if (memcmp(&magic, header_magic, sizeof(magic)))
- return NULL;
+ goto exit;
reserved = block[i++];
}
@@ -760,7 +754,7 @@ Header headerRead(FD_t fd, enum hMagic magicp)
* XXX Limit total size of header to 32Mb (~16 times largest known size).
*/
if (len > (32*1024*1024))
- return NULL;
+ goto exit;
ei = xmalloc(len);
ei[0] = htonl(il);
@@ -769,22 +763,16 @@ Header headerRead(FD_t fd, enum hMagic magicp)
if (timedRead(fd, (char *)&ei[2], len) != len) {
free(ei);
- return NULL;
+ goto exit;
}
- h = headerLoad(ei);
-
- h->regions[0].allocated = 1;
+ if ((h = headerLoad(ei)) != NULL)
+ h->region_allocated = 1;
+exit:
return h;
}
-/********************************************************************/
-/* */
-/* Header dumping */
-/* */
-/********************************************************************/
-
void headerDump(Header h, FILE *f, int flags,
const struct headerTagTableEntry * tags)
{
@@ -904,12 +892,13 @@ void headerDump(Header h, FILE *f, int flags,
}
}
-/********************************************************************/
-/* */
-/* Entry lookup */
-/* */
-/********************************************************************/
-
+/**
+ * Find matching (tag,type) entry in header.
+ * @param h header
+ * @param tag entry tag
+ * @param type entry type
+ * @return header entry
+ */
static struct indexEntry *findEntry(Header h, int_32 tag, int_32 type)
{
struct indexEntry * entry, * entry2, * last;
@@ -920,7 +909,7 @@ static struct indexEntry *findEntry(Header h, int_32 tag, int_32 type)
key.info.tag = tag;
entry2 = entry =
- bsearch(&key, h->index, h->indexUsed, sizeof(*entry), indexCmp);
+ bsearch(&key, h->index, h->indexUsed, sizeof(*h->index), indexCmp);
if (entry == NULL)
return NULL;
@@ -969,20 +958,29 @@ int headerGetRawEntry(Header h, int_32 tag, int_32 * type, const void ** p,
return 1;
}
+/**
+ * Does locale match entry in header i18n table?
+ *
+ * \verbatim
+ * The range [l,le) contains the next locale to match:
+ * ll[_CC][.EEEEE][@dddd]
+ * where
+ * ll ISO language code (in lowercase).
+ * CC (optional) ISO coutnry code (in uppercase).
+ * EEEEE (optional) encoding (not really standardized).
+ * dddd (optional) dialect.
+ * \endverbatim
+ *
+ * @param td header i18n table data, NUL terminated
+ * @param l start of locale to match
+ * @param le end of locale to match
+ * @return 1 on match, 0 on no match
+ */
static int headerMatchLocale(const char *td, const char *l, const char *le)
/*@*/
{
const char *fe;
- /*
- * The range [l,le) contains the next locale to match:
- * ll[_CC][.EEEEE][@dddd]
- * where
- * ll ISO language code (in lowercase).
- * CC (optional) ISO coutnry code (in uppercase).
- * EEEEE (optional) encoding (not really standardized).
- * dddd (optional) dialect.
- */
#if 0
{ const char *s, *ll, *CC, *EE, *dd;
@@ -1044,6 +1042,12 @@ static int headerMatchLocale(const char *td, const char *l, const char *le)
return 0;
}
+/**
+ * Return i18n string from header that matches locale.
+ * @param h header
+ * @param entry i18n string data
+ * @return matching i18n string (or 1st string if no match)
+ */
/*@dependent@*/ static char *
headerFindI18NString(Header h, struct indexEntry *entry)
{
@@ -1086,40 +1090,52 @@ headerFindI18NString(Header h, struct indexEntry *entry)
return entry->data;
}
+/**
+ * Retrieve tag data from header.
+ * @param h header
+ * @param tag tag to retrieve
+ * @retval type address of type (or NULL)
+ * @retval p address of data (or NULL)
+ * @retval c address of count (or NULL)
+ * @param minMem string pointers reference header memory?
+ * @return 1 on success, 0 on not found
+ */
static int intGetEntry(Header h, int_32 tag, /*@out@*/ int_32 *type,
/*@out@*/ const void **p, /*@out@*/ int_32 *c, int minMem)
/*@modifies *type, *p, *c @*/
{
struct indexEntry * entry;
- char * chptr;
HEADERPROBE(h, "intGetEntry");
/* First find the tag */
entry = findEntry(h, tag, RPM_NULL_TYPE);
- if (!entry) {
+ if (entry == NULL) {
+ if (type) type = 0;
if (p) *p = NULL;
if (c) *c = 0;
return 0;
}
- if (entry->info.type == RPM_I18NSTRING_TYPE) {
- chptr = headerFindI18NString(h, entry);
-
+ switch (entry->info.type) {
+ case RPM_I18NSTRING_TYPE:
if (type) *type = RPM_STRING_TYPE;
if (c) *c = 1;
-
- /*@-dependenttrans@*/ *p = chptr; /*@=dependenttrans@*/
- } else {
+ /*@-dependenttrans@*/
+ if (p) *p = headerFindI18NString(h, entry);
+ /*@=dependenttrans@*/
+ break;
+ default:
copyEntry(entry, type, p, c, minMem);
+ break;
}
return 1;
}
-int headerGetEntryMinMemory(Header h, int_32 tag, int_32 *type, void **p,
+int headerGetEntryMinMemory(Header h, int_32 tag, int_32 *type, const void **p,
int_32 *c)
{
- return intGetEntry(h, tag, type, (const void **)p, c, 1);
+ return intGetEntry(h, tag, type, p, c, 1);
}
int headerGetEntry(Header h, int_32 tag, int_32 * type, void **p, int_32 * c)
@@ -1127,61 +1143,49 @@ int headerGetEntry(Header h, int_32 tag, int_32 * type, void **p, int_32 * c)
return intGetEntry(h, tag, type, (const void **)p, c, 0);
}
-/********************************************************************/
-/* */
-/* Header creation and deletion */
-/* */
-/********************************************************************/
-
Header headerNew()
{
Header h = xcalloc(1, sizeof(*h));
- h->nregions = 0;
h->indexAlloced = INDEX_MALLOC_SIZE;
h->indexUsed = 0;
+ h->region_allocated = 1;
h->sorted = 1;
+ h->reloaded = 0;
h->nrefs = 1;
h->index = (h->indexAlloced
? xcalloc(h->indexAlloced, sizeof(*h->index))
: NULL);
- h->regions = (h->nregions
- ? xcalloc(h->nregions, sizeof(*h->regions))
- : NULL);
return h;
}
void headerFree(Header h)
{
- if (--h->nrefs)
+
+ if (h == NULL || --h->nrefs > 0)
return;
if (h->index) {
struct indexEntry * entry = h->index;
int i;
for (i = 0; i < h->indexUsed; i++, entry++) {
- if (ENTRY_IS_REGION(entry))
- continue;
- if (ENTRY_IN_REGION(entry))
- continue;
- free(entry->data);
+ 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. */
+ free(ei);
+ }
+ } else if (!ENTRY_IN_REGION(entry)) {
+ free(entry->data);
+ }
entry->data = NULL;
}
free(h->index);
h->index = NULL;
}
- if (h->regions) {
- /* XXX only region[0] needs to be free'ed if regions are nested. */
- if (h->regions[0].allocated) {
- free(h->regions[0].data);
- h->regions[0].data = NULL;
- }
- free(h->regions);
- h->regions = NULL;
- }
/*@-refcounttrans@*/ free(h); /*@=refcounttrans@*/
}
@@ -1200,21 +1204,32 @@ int headerUsageCount(Header h)
unsigned int headerSizeof(Header h, enum hMagic magicp)
{
struct indexEntry * entry;
- unsigned int size = 0, pad = 0;
+ unsigned int size = 0, rsize = 0, pad = 0;
int i;
headerSort(h);
+ size += sizeof(int_32); /* count of index entries */
+ size += sizeof(int_32); /* length of data */
+ size += sizeof(struct entryInfo) * h->indexUsed;
+ switch (magicp) {
+ case HEADER_MAGIC_YES:
+ size += sizeof(header_magic);
+ break;
+ case HEADER_MAGIC_NO:
+ break;
+ }
+
entry = h->index;
for (i = 0; i < h->indexUsed; i++, entry++) {
unsigned diff;
int_32 type;
- if (ENTRY_IS_REGION(entry)) {
- if (entry->info.count > 0)
- size += entry->info.count;
- continue;
- }
+ if (ENTRY_IS_REGION(entry)) {
+ if (entry->info.count > 0)
+ rsize += entry->info.count;
+ continue;
+ }
/* Alignment */
type = entry->info.type;
@@ -1228,13 +1243,9 @@ unsigned int headerSizeof(Header h, enum hMagic magicp)
size += entry->length;
}
-
- size += sizeof(struct entryInfo) * h->indexUsed;
- size += sizeof(int_32); /* count of index entries */
- size += sizeof(int_32); /* length of data */
- if (magicp)
- size += 2*sizeof(int_32);
+ size += rsize;
+
return size;
}
@@ -1267,6 +1278,14 @@ static void copyData(int_32 type, /*@out@*/ void * dstPtr, const void * srcPtr,
}
}
+/**
+ * Return (malloc'ed) copy of entry data.
+ * @param type entry data type
+ * @param p entry data
+ * @param c entry item count
+ * @retval lengthPtr no. bytes in returned data
+ * @return (malloc'ed) copy of entry data
+ */
static void * grabData(int_32 type, const void * p, int_32 c,
/*@out@*/ int * lengthPtr)
/*@modifies *lengthPtr @*/
@@ -1281,12 +1300,6 @@ static void * grabData(int_32 type, const void * p, int_32 c,
return data;
}
-/********************************************************************/
-/* */
-/* Adding and modifying entries */
-/* */
-/********************************************************************/
-
int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
{
struct indexEntry *entry;
@@ -1355,7 +1368,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
return 0; /* this shouldn't ever happen!! */
if (!table && !entry) {
- errmsg_t charArray[2];
+ const char * charArray[2];
int count = 0;
if (!lang || (lang[0] == 'C' && lang[1] == '\0')) {
/*@-observertrans@*/
@@ -1451,6 +1464,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
/* Replace I18N string array */
entry->length -= strlen(be) + 1;
entry->length += sn;
+
if (ENTRY_IN_REGION(entry)) {
entry->info.offset = 0;
} else
@@ -1524,6 +1538,7 @@ int headerAppendEntry(Header h, int_32 tag, int_32 type, void * p, int_32 c)
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;
@@ -1563,7 +1578,7 @@ int headerRemoveEntry(Header h, int_32 tag)
if (ne > 0)
memmove(entry, first, (ne * sizeof(*entry)));
}
-
+
return 0;
}
@@ -1658,13 +1673,13 @@ static void findTag(char * name, const struct headerTagTableEntry * tags,
static int parseExpression(struct sprintfToken * token, char * str,
const struct headerTagTableEntry * tags,
const struct headerSprintfExtension * extensions,
- /*@out@*/char ** endPtr, /*@out@*/ errmsg_t * errmsg)
+ /*@out@*/char ** endPtr, /*@out@*/const char ** 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,
- /*@out@*/char ** endPtr, int state, /*@out@*/ errmsg_t * errmsg)
+ /*@out@*/char ** endPtr, int state, /*@out@*/const char ** errmsg)
/*@modifies str, *str, *formatPtr, *numTokensPtr, *endPtr, *errmsg @*/
{
char * chptr, * start, * next, * dst;
@@ -1901,7 +1916,7 @@ 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, /*@out@*/ errmsg_t * errmsg)
+ /*@out@*/ char ** endPtr, /*@out@*/ const char ** errmsg)
{
const struct headerTagTableEntry * tag;
const struct headerSprintfExtension * ext;
@@ -2073,7 +2088,7 @@ static char * formatValue(struct sprintfTag * tag, Header h,
if (tag->arrayCount) {
/*@-observertrans -modobserver@*/
- if (type == RPM_STRING_ARRAY_TYPE) free((void *)data);
+ headerFreeData(data, type);
/*@=observertrans =modobserver@*/
countBuf = count;
@@ -2244,7 +2259,7 @@ static const char * singleSprintf(Header h, struct sprintfToken * token,
if (!headerGetEntry(h, token->u.array.format[i].u.tag.tag,
&type, (void **) &val, &numElements))
continue;
- if (type == RPM_STRING_ARRAY_TYPE) free(val);
+ headerFreeData(val, type);
}
break;
}
@@ -2319,7 +2334,7 @@ static void freeExtensionCache(const struct headerSprintfExtension * extensions,
char * headerSprintf(Header h, const char * origFmt,
const struct headerTagTableEntry * tags,
const struct headerSprintfExtension * extensions,
- errmsg_t * errmsg)
+ const char ** errmsg)
{
char * fmtString;
struct sprintfToken * format;
@@ -2503,11 +2518,10 @@ void headerCopyTags(Header headerFrom, Header headerTo, int *tagstocopy)
int type, count;
if (headerIsEntry(headerTo, *p))
continue;
- if (!headerGetEntry(headerFrom, *p, &type, (void **) &s, &count))
+ if (!headerGetEntryMinMemory(headerFrom, *p, &type,
+ (const void **) &s, &count))
continue;
headerAddEntry(headerTo, *p, type, s, count);
- if (s != NULL &&
- (type == RPM_STRING_ARRAY_TYPE || type == RPM_I18NSTRING_TYPE))
- free(s);
+ headerFreeData(s, type);
}
}
diff --git a/lib/header.h b/lib/header.h
index ab78b128b..f293d40cc 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -219,9 +219,10 @@ void *headerUnload(Header h) /*@*/;
* 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)
*/
-Header headerReload(/*@only@*/ Header h) /*@*/;
+Header headerReload(/*@only@*/ Header h, int tag) /*@*/;
/** \ingroup header
* Create new (empty) header instance.
@@ -241,7 +242,7 @@ Header headerLink(Header h)
* Dereference a header instance.
* @param h header
*/
-void headerFree( /*@killref@*/ Header h);
+void headerFree( /*@only@*/ /*@null@*/ /*@killref@*/ Header h);
/** \ingroup header
* Return header reference count.
@@ -400,7 +401,7 @@ int headerGetEntry(Header h, int_32 tag, /*@out@*/ int_32 *type,
* @return 1 on success, 0 on failure
*/
int headerGetEntryMinMemory(Header h, int_32 tag, int_32 *type,
- /*@out@*/ void **p, /*@out@*/ int_32 *c)
+ /*@out@*/ const void **p, /*@out@*/ int_32 *c)
/*@modifies *type, *p, *c @*/;
/** \ingroup header
@@ -491,9 +492,9 @@ void headerUnsort(Header h)
/** \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
+ * @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 @*/;
@@ -517,6 +518,23 @@ typedef enum rpmTagType_e {
} rpmTagType;
/** \ingroup header
+ * Free data allocated when retrieved from header.
+ * @param data address of data
+ * @param type type of data
+ * @return NULL always
+ */
+/*@unused@*/ static inline /*@null@*/ void * headerFreeData(
+ /*@only@*/ const void * data, rpmTagType type)
+{
+ if (type == RPM_STRING_ARRAY_TYPE ||
+ type == RPM_I18NSTRING_TYPE ||
+ type == RPM_BIN_TYPE) {
+ if (data) free((void *)data);
+ }
+ 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
* to avoid incompatibility with legacy versions of rpm, these data (sub-)types
@@ -543,6 +561,8 @@ typedef enum rpmSubTagType_e {
#define HEADER_IMMUTABLE 63
#define HEADER_REGIONS 64
#define HEADER_I18NTABLE 100
+#define HEADER_SIGBASE 256
+#define HEADER_TAGBASE 1000
#ifdef __cplusplus
}
diff --git a/lib/install.c b/lib/install.c
index ce77bca39..da0521c68 100644
--- a/lib/install.c
+++ b/lib/install.c
@@ -231,6 +231,7 @@ static void setFileOwners(Header h, struct fileInfo * files, int fileCount)
free(fileGroups);
}
+#ifdef DYING
/**
* Truncate header changelog tag to configurable limit before installing.
* @param h header
@@ -285,6 +286,7 @@ static void trimChangelog(Header h)
free(names);
free(texts);
}
+#endif /* DYING */
/**
* Copy file data from h to newH.
@@ -334,60 +336,58 @@ static int mergeFiles(Header h, Header newH, enum fileActions * actions)
fileSize += fileSizes[i];
}
headerModifyEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE, &fileSize, 1);
- for (i = 0; mergeTags[i]; i++)
- if (headerGetEntryMinMemory(newH, mergeTags[i], &type,
- (void **) &data, &count)) {
- switch (type) {
- case RPM_CHAR_TYPE:
- case RPM_INT8_TYPE:
- newdata = xmalloc(fileCount * sizeof(int_8));
- for (j = 0, k = 0; j < count; j++)
- if (actions[j] != FA_SKIPMULTILIB)
+ for (i = 0; mergeTags[i]; i++) {
+ if (!headerGetEntryMinMemory(newH, mergeTags[i], &type,
+ (const void **) &data, &count))
+ continue;
+ switch (type) {
+ case RPM_CHAR_TYPE:
+ case RPM_INT8_TYPE:
+ newdata = xmalloc(fileCount * sizeof(int_8));
+ for (j = 0, k = 0; j < count; j++)
+ if (actions[j] != FA_SKIPMULTILIB)
((int_8 *) newdata)[k++] = ((int_8 *) data)[j];
- headerAddOrAppendEntry(h, mergeTags[i], type, newdata,
- fileCount);
- free (newdata);
- break;
- case RPM_INT16_TYPE:
- newdata = xmalloc(fileCount * sizeof(int_16));
- for (j = 0, k = 0; j < count; j++)
- if (actions[j] != FA_SKIPMULTILIB)
- ((int_16 *) newdata)[k++] = ((int_16 *) data)[j];
- headerAddOrAppendEntry(h, mergeTags[i], type, newdata,
- fileCount);
- free (newdata);
- break;
- case RPM_INT32_TYPE:
- newdata = xmalloc(fileCount * sizeof(int_32));
- for (j = 0, k = 0; j < count; j++)
- if (actions[j] != FA_SKIPMULTILIB)
- ((int_32 *) newdata)[k++] = ((int_32 *) data)[j];
- headerAddOrAppendEntry(h, mergeTags[i], type, newdata,
- fileCount);
- free (newdata);
- break;
- case RPM_STRING_ARRAY_TYPE:
- newdata = xmalloc(fileCount * sizeof(char *));
- for (j = 0, k = 0; j < count; j++)
- if (actions[j] != FA_SKIPMULTILIB)
- ((char **) newdata)[k++] = ((char **) data)[j];
- headerAddOrAppendEntry(h, mergeTags[i], type, newdata,
+ headerAddOrAppendEntry(h, mergeTags[i], type, newdata,
fileCount);
- free (newdata);
- free (data);
- break;
- default:
- fprintf(stderr, _("Data type %d not supported\n"), (int) type);
- exit(EXIT_FAILURE);
- /*@notreached@*/
- }
- }
+ free (newdata);
+ break;
+ case RPM_INT16_TYPE:
+ newdata = xmalloc(fileCount * sizeof(int_16));
+ for (j = 0, k = 0; j < count; j++)
+ if (actions[j] != FA_SKIPMULTILIB)
+ ((int_16 *) newdata)[k++] = ((int_16 *) data)[j];
+ headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fileCount);
+ free (newdata);
+ break;
+ case RPM_INT32_TYPE:
+ newdata = xmalloc(fileCount * sizeof(int_32));
+ for (j = 0, k = 0; j < count; j++)
+ if (actions[j] != FA_SKIPMULTILIB)
+ ((int_32 *) newdata)[k++] = ((int_32 *) data)[j];
+ headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fileCount);
+ free (newdata);
+ break;
+ case RPM_STRING_ARRAY_TYPE:
+ newdata = xmalloc(fileCount * sizeof(char *));
+ for (j = 0, k = 0; j < count; j++)
+ if (actions[j] != FA_SKIPMULTILIB)
+ ((char **) newdata)[k++] = ((char **) data)[j];
+ headerAddOrAppendEntry(h, mergeTags[i], type, newdata, fileCount);
+ free (newdata);
+ free (data);
+ break;
+ default:
+ fprintf(stderr, _("Data type %d not supported\n"), (int) type);
+ exit(EXIT_FAILURE);
+ /*@notreached@*/
+ }
+ }
headerGetEntry(newH, RPMTAG_DIRINDEXES, NULL, (void **) &newDirIndexes,
&count);
headerGetEntryMinMemory(newH, RPMTAG_DIRNAMES, NULL,
- (void **) &newDirNames, NULL);
+ (const void **) &newDirNames, NULL);
headerGetEntry(h, RPMTAG_DIRINDEXES, NULL, (void **) &dirIndexes, NULL);
- headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, (void **) &data,
+ headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL, (const void **) &data,
&dirNamesCount);
dirNames = xcalloc(dirNamesCount + fileCount, sizeof(char *));
@@ -395,15 +395,16 @@ static int mergeFiles(Header h, Header newH, enum fileActions * actions)
dirNames[i] = ((char **) data)[i];
dirCount = dirNamesCount;
newdata = xmalloc(fileCount * sizeof(int_32));
- for (i = 0, k = 0; i < count; i++)
- if (actions[i] != FA_SKIPMULTILIB) {
- for (j = 0; j < dirCount; j++)
- if (!strcmp(dirNames[j], newDirNames[newDirIndexes[i]]))
- break;
- if (j == dirCount)
- dirNames[dirCount++] = newDirNames[newDirIndexes[i]];
- ((int_32 *) newdata)[k++] = j;
- }
+ for (i = 0, k = 0; i < count; i++) {
+ if (actions[i] == FA_SKIPMULTILIB)
+ continue;
+ for (j = 0; j < dirCount; j++)
+ if (!strcmp(dirNames[j], newDirNames[newDirIndexes[i]]))
+ break;
+ if (j == dirCount)
+ dirNames[dirCount++] = newDirNames[newDirIndexes[i]];
+ ((int_32 *) newdata)[k++] = j;
+ }
headerAddOrAppendEntry(h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, newdata,
fileCount);
if (dirCount > dirNamesCount)
@@ -420,46 +421,47 @@ static int mergeFiles(Header h, Header newH, enum fileActions * actions)
uint_32 *Flags, *newFlags;
int Count = 0, newCount = 0;
- if (headerGetEntryMinMemory(newH, requireTags[i], NULL,
- (void **) &newNames, &newCount)) {
- headerGetEntryMinMemory(newH, requireTags[i+1], NULL,
- (void **) &newEVR, NULL);
- headerGetEntry(newH, requireTags[i+2], NULL, (void **) &newFlags,
- NULL);
- if (headerGetEntryMinMemory(h, requireTags[i], NULL,
- (void **) &Names, &Count)) {
- headerGetEntryMinMemory(h, requireTags[i+1], NULL,
- (void **) &EVR, NULL);
- headerGetEntry(h, requireTags[i+2], NULL, (void **) &Flags,
- NULL);
- for (j = 0; j < newCount; j++)
- for (k = 0; k < Count; k++)
- if (!strcmp (newNames[j], Names[k])
- && !strcmp (newEVR[j], EVR[k])
- && (newFlags[j] & RPMSENSE_SENSEMASK) ==
- (Flags[k] & RPMSENSE_SENSEMASK)) {
- newNames[j] = NULL;
- break;
- }
- }
- for (j = 0, k = 0; j < newCount; j++) {
- if (!newNames[j] || !isDependsMULTILIB(newFlags[j]))
- continue;
- if (j != k) {
- newNames[k] = newNames[j];
- newEVR[k] = newEVR[j];
- newFlags[k] = newFlags[j];
- }
- k++;
+ if (!headerGetEntryMinMemory(newH, requireTags[i], NULL,
+ (const void **) &newNames, &newCount))
+ continue;
+
+ headerGetEntryMinMemory(newH, requireTags[i+1], NULL,
+ (const void **) &newEVR, NULL);
+ headerGetEntry(newH, requireTags[i+2], NULL, (void **) &newFlags, NULL);
+ if (headerGetEntryMinMemory(h, requireTags[i], NULL,
+ (const void **) &Names, &Count))
+ {
+ headerGetEntryMinMemory(h, requireTags[i+1], NULL,
+ (const void **) &EVR, NULL);
+ headerGetEntry(h, requireTags[i+2], NULL, (void **) &Flags, NULL);
+ for (j = 0; j < newCount; j++)
+ for (k = 0; k < Count; k++)
+ if (!strcmp (newNames[j], Names[k])
+ && !strcmp (newEVR[j], EVR[k])
+ && (newFlags[j] & RPMSENSE_SENSEMASK) ==
+ (Flags[k] & RPMSENSE_SENSEMASK))
+ {
+ newNames[j] = NULL;
+ break;
+ }
+ }
+ for (j = 0, k = 0; j < newCount; j++) {
+ if (!newNames[j] || !isDependsMULTILIB(newFlags[j]))
+ continue;
+ if (j != k) {
+ newNames[k] = newNames[j];
+ newEVR[k] = newEVR[j];
+ newFlags[k] = newFlags[j];
}
- if (k) {
- headerAddOrAppendEntry(h, requireTags[i],
+ k++;
+ }
+ if (k) {
+ headerAddOrAppendEntry(h, requireTags[i],
RPM_STRING_ARRAY_TYPE, newNames, k);
- headerAddOrAppendEntry(h, requireTags[i+1],
+ headerAddOrAppendEntry(h, requireTags[i+1],
RPM_STRING_ARRAY_TYPE, newEVR, k);
- headerAddOrAppendEntry(h, requireTags[i+2], RPM_INT32_TYPE,
+ headerAddOrAppendEntry(h, requireTags[i+2], RPM_INT32_TYPE,
newFlags, k);
- }
}
}
return 0;
@@ -613,13 +615,10 @@ static int installArchive(FD_t fd, struct fileInfo * files, int fileCount,
#else
urltype = urlPath(files[i].relativePath, &map[mappedFiles].fsPath);
#endif
- /* XXX Can't do src rpm MD5 sum verification yet. */
- map[mappedFiles].md5sum =
- specFile == NULL ? files[i].md5sum : NULL;
/* XXX Can't do src rpm MD5 sum verification (yet). */
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
map[mappedFiles].md5sum = headerIsEntry(h, RPMTAG_SOURCERPM)
- ? files[i].md5sum : NULL;
+ ? files[i].md5sum : NULL;
map[mappedFiles].finalMode = files[i].mode;
map[mappedFiles].finalUid = files[i].uid;
map[mappedFiles].finalGid = files[i].gid;
@@ -824,7 +823,7 @@ static int installSources(Header h, const char * rootDir, FD_t fd,
Chdir(realSourceDir);
if (installArchive(fd, fileCount > 0 ? files : NULL,
fileCount, notify, notifyData, NULL, h,
- specFileIndex >=0 ? NULL : &specFile,
+ specFileIndex >= 0 ? NULL : &specFile,
archiveSizePtr ? *archiveSizePtr : 0)) {
rc = 2;
goto exit;
@@ -1183,7 +1182,9 @@ int installBinaryPackage(const rpmTransactionSet ts, FD_t fd, Header h,
currDir = NULL;
}
+#ifdef DYING
trimChangelog(h);
+#endif
/* if this package has already been installed, remove it from the database
before adding the new one */
diff --git a/lib/md5sum.c b/lib/md5sum.c
index 7ae359ef5..0bd07dde7 100644
--- a/lib/md5sum.c
+++ b/lib/md5sum.c
@@ -13,6 +13,7 @@
#include "system.h"
#include "md5.h"
+#include "rpmio_internal.h"
/**
* Calculate MD5 sum for file.
@@ -23,12 +24,15 @@
* @return 0 on success, 1 on error
*/
static int domd5(const char * fn, unsigned char * digest, int asAscii,
- int brokenEndian) {
+ int brokenEndian)
+{
+ int rc;
+
+#ifndef DYING
unsigned char buf[1024];
unsigned char bindigest[16];
FILE * fp;
MD5_CTX ctx;
- int n;
memset(bindigest, 0, sizeof(bindigest));
fp = fopen(fn, "r");
@@ -37,8 +41,8 @@ static int domd5(const char * fn, unsigned char * digest, int asAscii,
}
rpmMD5Init(&ctx, brokenEndian);
- while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
- rpmMD5Update(&ctx, buf, n);
+ while ((rc = fread(buf, sizeof(buf[0]), sizeof(buf), fp)) > 0)
+ rpmMD5Update(&ctx, buf, rc);
rpmMD5Final(bindigest, &ctx);
if (ferror(fp)) {
fclose(fp);
@@ -69,8 +73,37 @@ static int domd5(const char * fn, unsigned char * digest, int asAscii,
}
fclose(fp);
+ rc = 0;
+#else
+ FD_t fd = Fopen(fn, "r.ufdio");
+ unsigned char buf[BUFSIZ];
+ unsigned char * md5sum = NULL;
+ size_t md5len;
+
+ if (fd == NULL || Ferror(fd)) {
+ if (fd)
+ Fclose(fd);
+ return 1;
+ }
+
+ /* Preserve legacy "brokenEndian" behavior. */
+ fdInitMD5(fd, (brokenEndian ? RPMDIGEST_NATIVE : 0) );
+
+ while ((rc = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
+ ;
+ fdFiniMD5(fd, (void **)&md5sum, &md5len, 1);
+
+ if (Ferror(fd))
+ rc = 1;
+ Fclose(fd);
+
+ if (!rc)
+ memcpy(digest, md5sum, md5len);
+ if (md5sum)
+ free(md5sum);
+#endif
- return 0;
+ return rc;
}
int mdbinfile(const char *fn, unsigned char *bindigest) {
diff --git a/lib/misc.c b/lib/misc.c
index 76a6cae9e..b10f2b0c6 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -701,13 +701,15 @@ int rpmPackageGetEntry( /*@unused@*/ void *leadp, Header sigs, Header h,
/*@notreached@*/ break;
}
+ if (headerIsEntry(h, tag))
+ return rpmHeaderGetEntry(h, tag, type, p, c);
+
if (sigs == NULL) {
if (c) *c = 0;
return 0;
}
return headerGetEntry(sigs, sigtag, type, p, c);
-
}
/*
diff --git a/lib/package.c b/lib/package.c
index d9400146b..0d1779af5 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -21,6 +21,34 @@
/*@access Header@*/ /* XXX compared with NULL */
+void headerMergeLegacySigs(Header h, const Header sig)
+{
+ HeaderIterator hi;
+ int_32 tag, type, count;
+ const void * ptr;
+
+ for (hi = headerInitIterator(sig);
+ headerNextIterator(hi, &tag, &type, &ptr, &count);
+ ptr = headerFreeData(ptr, type))
+ {
+ if (tag < RPMSIGTAG_SIZE)
+ continue;
+ switch (tag) {
+ case RPMSIGTAG_SIZE: tag = RPMTAG_SIGSIZE; break;
+ case RPMSIGTAG_LEMD5_1: tag = RPMTAG_SIGLEMD5_1;break;
+ case RPMSIGTAG_PGP: tag = RPMTAG_SIGPGP; break;
+ case RPMSIGTAG_LEMD5_2: tag = RPMTAG_SIGLEMD5_2;break;
+ case RPMSIGTAG_MD5: tag = RPMTAG_SIGMD5; break;
+ case RPMSIGTAG_GPG: tag = RPMTAG_SIGGPG; break;
+ case RPMSIGTAG_PGP5: tag = RPMTAG_SIGPGP5; break;
+ default: break;
+ }
+ if (!headerIsEntry(h, tag))
+ headerAddEntry(h, tag, type, ptr, count);
+ }
+ headerFreeIterator(hi);
+}
+
/**
* Retrieve package components from file handle.
* @param fd file handle
@@ -100,9 +128,8 @@ static int readPackageHeaders(FD_t fd, /*@out@*/ struct rpmlead * leadPtr,
only saves memory (nice), but gives fingerprinting a nice, fat
speed boost (very nice). Go ahead and convert old headers to
the new style (this is a noop for new headers) */
- if (lead->major < 4) {
+ if (lead->major < 4)
compressFilelist(*hdr);
- }
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
if (lead->type == RPMLEAD_SOURCE) {
@@ -122,30 +149,39 @@ static int readPackageHeaders(FD_t fd, /*@out@*/ struct rpmlead * leadPtr,
/*@notreached@*/ break;
}
- if (hdrPtr == NULL) {
+ if (hdrPtr == NULL)
headerFree(*hdr);
- }
return 0;
}
-int rpmReadPackageInfo(FD_t fd, Header * signatures, Header * hdr)
+int rpmReadPackageInfo(FD_t fd, Header * sigp, Header * hdrp)
{
- return readPackageHeaders(fd, NULL, signatures, hdr);
+ int rc = readPackageHeaders(fd, NULL, sigp, hdrp);
+ if (hdrp && *hdrp && sigp && *sigp)
+ headerMergeLegacySigs(*hdrp, *sigp);
+ return rc;
}
-int rpmReadPackageHeader(FD_t fd, Header * hdr, int * isSource, int * major,
+int rpmReadPackageHeader(FD_t fd, Header * hdrp, int * isSource, int * major,
int * minor)
{
- int rc;
struct rpmlead lead;
+ Header sig = NULL;
+ int rc = readPackageHeaders(fd, &lead, &sig, hdrp);
+
+ if (rc)
+ goto exit;
- rc = readPackageHeaders(fd, &lead, NULL, hdr);
- if (rc) return rc;
+ if (hdrp && *hdrp && sig) {
+ headerMergeLegacySigs(*hdrp, sig);
+ headerFree(sig);
+ }
if (isSource) *isSource = lead.type == RPMLEAD_SOURCE;
if (major) *major = lead.major;
if (minor) *minor = lead.minor;
- return 0;
+exit:
+ return rc;
}
diff --git a/lib/rpmchecksig.c b/lib/rpmchecksig.c
index 660d40a53..7f2bb78ac 100644
--- a/lib/rpmchecksig.c
+++ b/lib/rpmchecksig.c
@@ -95,18 +95,29 @@ exit:
return rc;
}
+/*
+ * XXX gcc-2.96-60 on alpha (at least) needs ALPHA_LOSSAGE defined.
+ *
+ * Otherwise, the (mis-compilation?!) symptom is the inability to pass sig_type- * correctly to rpmReadSignature(FD_t *fd, Header *header, short sig_type)
+ * (Note: the short in both struct rpmlead and in the prototype).
+ */
+#define ALPHA_LOSSAGE
+
int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
{
FD_t fd = NULL;
FD_t ofd = NULL;
- struct rpmlead lead;
- unsigned short sigtype;
+ struct rpmlead lead, *l = &lead;
+ int sigtype;
const char *rpm, *trpm;
const char *sigtarget = NULL;
char tmprpm[1024+1];
Header sig = NULL;
int rc = EXIT_FAILURE;
+#ifdef ALPHA_LOSSAGE
+l = malloc(sizeof(*l));
+#endif
tmprpm[0] = '\0';
while ((rpm = *argv++) != NULL) {
@@ -115,11 +126,11 @@ int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
if (manageFile(&fd, &rpm, O_RDONLY, 0))
goto exit;
- if (readLead(fd, &lead)) {
+ if (readLead(fd, l)) {
fprintf(stderr, _("%s: readLead failed\n"), rpm);
goto exit;
}
- switch (lead.major) {
+ switch (l->major) {
case 1:
fprintf(stderr, _("%s: Can't sign v1.0 RPM\n"), rpm);
goto exit;
@@ -132,7 +143,7 @@ int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
break;
}
- if (rpmReadSignature(fd, &sig, lead.signature_type)) {
+ if (rpmReadSignature(fd, &sig, l->signature_type)) {
fprintf(stderr, _("%s: rpmReadSignature failed\n"), rpm);
goto exit;
}
@@ -168,8 +179,8 @@ int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
goto exit;
- lead.signature_type = RPMSIG_HEADERSIG;
- if (writeLead(ofd, &lead)) {
+ l->signature_type = RPMSIG_HEADERSIG;
+ if (writeLead(ofd, l)) {
fprintf(stderr, _("%s: writeLead failed: %s\n"), trpm,
Fstrerror(ofd));
goto exit;
@@ -200,6 +211,7 @@ int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
rc = 0;
exit:
+if (l != &lead) free(l);
if (fd) manageFile(&fd, NULL, 0, rc);
if (ofd) manageFile(&ofd, NULL, 0, rc);
@@ -225,7 +237,7 @@ int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
FD_t fd = NULL;
FD_t ofd = NULL;
int res2, res3;
- struct rpmlead lead;
+ struct rpmlead lead, *l = &lead;
const char *rpm = NULL;
char result[1024];
const char * sigtarget = NULL;
@@ -238,6 +250,9 @@ int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
const void * ptr;
int res = 0;
+#ifdef ALPHA_LOSSAGE
+l = malloc(sizeof(*l));
+#endif
while ((rpm = *argv++) != NULL) {
if (manageFile(&fd, &rpm, O_RDONLY, 0)) {
@@ -250,7 +265,7 @@ int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
res++;
goto bottom;
}
- switch (lead.major) {
+ switch (l->major) {
case 1:
fprintf(stderr, _("%s: No signature available (v1.0 RPM)\n"), rpm);
res++;
@@ -259,7 +274,7 @@ int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
default:
break;
}
- if (rpmReadSignature(fd, &sig, lead.signature_type)) {
+ if (rpmReadSignature(fd, &sig, l->signature_type)) {
fprintf(stderr, _("%s: rpmReadSignature failed\n"), rpm);
res++;
goto bottom;
@@ -447,6 +462,7 @@ int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
xfree(sigtarget); sigtarget = NULL;
}
}
+if (l != &lead) free(l);
return res;
}
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index ef0e8973c..93c2ef2cf 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -104,7 +104,7 @@ static void dbiTagsInit(void)
if (dbiTagToDbix(rpmtag) >= 0)
continue;
- dbiTags = xrealloc(dbiTags, (dbiTagsMax + 1) * sizeof(*dbiTags));
+ dbiTags = xrealloc(dbiTags, (dbiTagsMax + 1) * sizeof(*dbiTags)); /* XXX memory leak */
dbiTags[dbiTagsMax++] = rpmtag;
}
@@ -906,6 +906,7 @@ int rpmdbInit (const char * prefix, int perms)
rc = openDatabase(prefix, NULL, _dbapi, &rpmdb, (O_CREAT | O_RDWR), perms, RPMDB_FLAG_JUSTCHECK);
if (rpmdb) {
+ rpmdbOpenAll(rpmdb);
rpmdbClose(rpmdb);
rpmdb = NULL;
}
@@ -1011,11 +1012,11 @@ static int rpmdbFindByFile(rpmdb rpmdb, const char * filespec,
}
headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL,
- (void **) &baseNames, NULL);
- headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL,
- (void **) &dirIndexes, NULL);
+ (const void **) &baseNames, NULL);
headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL,
- (void **) &dirNames, NULL);
+ (const void **) &dirNames, NULL);
+ headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL,
+ (const void **) &dirIndexes, NULL);
do {
fingerPrint fp2;
@@ -2096,12 +2097,12 @@ int rpmdbFindFpList(rpmdb rpmdb, fingerPrint * fpList, dbiIndexSet * matchList,
num = end - start;
/* Compute fingerprints for this header's matches */
- headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL,
- (void **) &dirNames, NULL);
headerGetEntryMinMemory(h, RPMTAG_BASENAMES, NULL,
- (void **) &fullBaseNames, NULL);
+ (const void **) &fullBaseNames, NULL);
+ headerGetEntryMinMemory(h, RPMTAG_DIRNAMES, NULL,
+ (const void **) &dirNames, NULL);
headerGetEntryMinMemory(h, RPMTAG_DIRINDEXES, NULL,
- (void **) &fullDirIndexes, NULL);
+ (const void **) &fullDirIndexes, NULL);
baseNames = xcalloc(num, sizeof(*baseNames));
dirIndexes = xcalloc(num, sizeof(*dirIndexes));
@@ -2136,6 +2137,26 @@ int rpmdbFindFpList(rpmdb rpmdb, fingerPrint * fpList, dbiIndexSet * matchList,
}
+char * db1basename (int rpmtag) {
+ char * base = NULL;
+ switch (rpmtag) {
+ case RPMDBI_PACKAGES: base = "packages.rpm"; break;
+ case RPMTAG_NAME: base = "nameindex.rpm"; break;
+ case RPMTAG_BASENAMES: base = "fileindex.rpm"; break;
+ case RPMTAG_GROUP: base = "groupindex.rpm"; break;
+ case RPMTAG_REQUIRENAME: base = "requiredby.rpm"; break;
+ case RPMTAG_PROVIDENAME: base = "providesindex.rpm"; break;
+ case RPMTAG_CONFLICTNAME: base = "conflictsindex.rpm"; break;
+ case RPMTAG_TRIGGERNAME: base = "triggerindex.rpm"; break;
+ default:
+ { const char * tn = tagName(rpmtag);
+ base = alloca( strlen(tn) + sizeof(".idx") + 1 );
+ (void) stpcpy( stpcpy(base, tn), ".idx");
+ } break;
+ }
+ return xstrdup(base);
+}
+
static int rpmdbRemoveDatabase(const char * rootdir,
const char * dbpath, int _dbapi)
{
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index e416aba97..be9f0b9d7 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -44,7 +44,7 @@ int rpmReadPackageHeader(FD_t fd, /*@out@*/ Header * hdr,
/*@out@*/ int * minor)
/*@modifies fd, *hdr, *isSource, *major, *minor @*/;
-/**
+/** \ingroup header
* Return name, version, release strings from header.
* @param h header
* @retval np address of name pointer (or NULL)
@@ -55,6 +55,14 @@ int rpmReadPackageHeader(FD_t fd, /*@out@*/ Header * hdr,
int headerNVR(Header h, /*@out@*/ const char **np, /*@out@*/ const char **vp,
/*@out@*/ const char **rp) /*@modifies *np, *vp, *rp @*/;
+/** \ingroup header
+ * Translate and merge legacy signature tags into header.
+ * @param h header
+ * @param sig signature header
+ */
+void headerMergeLegacySigs(Header h, const Header sig)
+ /*@modifies h @*/;
+
/**
* Retrieve file names from header.
* The representation of file names in package headers changed in rpm-4.0.
@@ -122,14 +130,15 @@ extern const int rpmTagTableSize;
*/
extern const struct headerSprintfExtension rpmHeaderFormats[];
-/* these pseudo-tags are used by the dbi iterator interface */
-#define RPMDBI_PACKAGES 0
-#define RPMDBI_DEPENDS 1
-#define RPMDBI_LABEL 2 /* XXX remove rpmdbFindByLabel from API */
-#define RPMDBI_ADDED 3
-#define RPMDBI_REMOVED 4
-#define RPMDBI_AVAILABLE 5
-
+/**
+ * Pseudo-tags used by the rpmdb iterator API.
+ */
+#define RPMDBI_PACKAGES 0 /*!< Installed package headers. */
+#define RPMDBI_DEPENDS 1 /*!< Dependency resolution cache. */
+#define RPMDBI_LABEL 2 /*!< Fingerprint search marker. */
+#define RPMDBI_ADDED 3 /*!< Added package headers. */
+#define RPMDBI_REMOVED 4 /*!< Removed package headers. */
+#define RPMDBI_AVAILABLE 5 /*!< Available package headers. */
/**
* Tags identify data in package headers.
@@ -147,7 +156,7 @@ typedef enum rpmTag_e {
/* Retrofit (and uniqify) signature tags for use by tagName() and rpmQuery. */
/* the md5 sum was broken *twice* on big endian machines */
/* XXX 2nd underscore prevents tagTable generation */
- RPMTAG_SIG_BASE = 256,
+ RPMTAG_SIG_BASE = HEADER_SIGBASE,
RPMTAG_SIGSIZE = RPMTAG_SIG_BASE+1,
RPMTAG_SIGLEMD5_1 = RPMTAG_SIG_BASE+2,
RPMTAG_SIGPGP = RPMTAG_SIG_BASE+3,
@@ -397,21 +406,23 @@ typedef enum rpmsenseFlags_e {
#define RPMVAR_NUM 55 /* number of RPMVAR entries */
/** \ingroup rpmrc
- * Return value of rpmrc variable.
+ * Return value of an rpmrc variable.
* @deprecated Use rpmExpand() with appropriate macro expression.
* @todo Eliminate from API.
*/
const char * rpmGetVar(int var);
/** \ingroup rpmrc
- * Set value of rpmrc variable.
+ * Set value of an rpmrc variable.
* @deprecated Use rpmDefineMacro() to change appropriate macro instead.
* @todo Eliminate from API.
*/
void rpmSetVar(int var, const char *val);
/** \ingroup rpmrc
- * List of macro files to read for configuring rpm.
+ * List of macro files to read when configuring rpm.
+ * This is a colon separated list of files. URI's are permitted as well,
+ * identified by the token '://', so file paths must not begin with '//'.
*/
const char * macrofiles;
@@ -420,12 +431,12 @@ const char * macrofiles;
* @todo Eliminate from API.
*/
enum rpm_machtable_e {
- RPM_MACHTABLE_INSTARCH = 0,
- RPM_MACHTABLE_INSTOS = 1,
- RPM_MACHTABLE_BUILDARCH = 2,
- RPM_MACHTABLE_BUILDOS = 3
+ RPM_MACHTABLE_INSTARCH = 0, /*!< Install platform architecture. */
+ RPM_MACHTABLE_INSTOS = 1, /*!< Install platform operating system. */
+ RPM_MACHTABLE_BUILDARCH = 2, /*!< Build platform architecture. */
+ RPM_MACHTABLE_BUILDOS = 3 /*!< Build platform operating system. */
};
-#define RPM_MACHTABLE_COUNT 4 /* number of arch/os tables */
+#define RPM_MACHTABLE_COUNT 4 /*!< No. of arch/os tables. */
/** \ingroup rpmrc
* Read macro configuration file(s) for a target.
@@ -460,16 +471,16 @@ void rpmGetOsInfo( /*@out@*/ const char ** name, /*@out@*/ int * num);
/** \ingroup rpmrc
* Return arch/os score of a name.
- * An arch score measures the nearness of an arch name to the currently
- * running (or defined) platform arch. For example, the score of "i586"
- * on an i686 platform is (usually) 1. The arch score is used to select
- * one of several otherwise identical packages based on the arch/os hints
- * in the header of the intended platform.
+ * An arch/os score measures the "nearness" of a name to the currently
+ * running (or defined) platform arch/os. For example, the score of arch
+ * "i586" on an i686 platform is (usually) 2. The arch/os score is used
+ * to select one of several otherwise identical packages using the arch/os
+ * tags from the header as hints of the intended platform for the package.
* @todo Rewrite to use RE's against config.guess target platform output.
*
* @param type any of the RPM_MACHTABLE_* constants
* @param name name
- * @return arch score
+ * @return arch score (0 is no match, lower is preferred)
*/
int rpmMachineScore(int type, const char * name);
@@ -1163,6 +1174,17 @@ enum rpmVerifyAttrs_e {
int rpmVerifyFile(const char * root, Header h, int filenum,
/*@out@*/ int * result, int omitMask);
+/**
+ * Return exit code from running verify script in header.
+ * @todo kpackage prevents static, should be using VERIFY_SCRIPT flag.
+ * @param rootDir path to top of install tree
+ * @param rpmdb rpm database
+ * @param h header
+ * @param scriptFd file handle to use for stderr
+ * @return 0 on success
+ */
+int rpmVerifyScript(const char * rootDir, rpmdb rpmdb, Header h, FD_t scriptFd);
+
/** \ingroup rpmcli
* The command line argument will be used to retrieve header(s) ...
*/
diff --git a/lib/signature.c b/lib/signature.c
index 1bf662851..b33d04fef 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -162,6 +162,11 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sig_type)
if (h == NULL)
break;
sigSize = headerSizeof(h, HEADER_MAGIC_YES);
+
+ /* XXX Legacy headers have a HEADER_IMAGE tag added. */
+ if (headerIsEntry(h, RPMTAG_HEADERIMAGE))
+ sigSize -= (16 + 16);
+
pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
rpmMessage(RPMMESS_DEBUG, _("Signature size: %d\n"), sigSize);
rpmMessage(RPMMESS_DEBUG, _("Signature pad : %d\n"), pad);
@@ -190,7 +195,7 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sig_type)
int rpmWriteSignature(FD_t fd, Header header)
{
int sigSize, pad;
- byte buf[8];
+ static byte buf[8] = "\000\000\000\000\000\000\000\000";
int rc = 0;
rc = headerWrite(fd, header, HEADER_MAGIC_YES);
@@ -202,7 +207,6 @@ int rpmWriteSignature(FD_t fd, Header header)
if (pad) {
rpmMessage(RPMMESS_DEBUG, _("Signature size: %d\n"), sigSize);
rpmMessage(RPMMESS_DEBUG, _("Signature pad : %d\n"), pad);
- memset(buf, 0, pad);
if (Fwrite(buf, sizeof(buf[0]), pad, fd) != pad)
rc = 1;
}
diff --git a/lib/transaction.c b/lib/transaction.c
index 3bbead367..b99bb2bc6 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -104,9 +104,6 @@ static void freeFi(TFI_t *fi)
if (fi->bnl) {
free(fi->bnl); fi->bnl = NULL;
free(fi->dnl); fi->dnl = NULL;
-#ifdef DOUBLE_FREE
- xfree(fi->dil); fi->dil = NULL;
-#endif
}
if (fi->flinks) {
free(fi->flinks); fi->flinks = NULL;
@@ -129,6 +126,9 @@ static void freeFi(TFI_t *fi)
if (fi->fstates) {
free(fi->fstates); fi->fstates = NULL;
}
+ if (fi->dil) {
+ xfree(fi->dil); fi->dil = NULL;
+ }
break;
case TR_ADDED:
break;
@@ -803,17 +803,17 @@ static int handleInstInstalledFiles(TFI_t * fi, rpmdb db,
}
headerGetEntryMinMemory(h, RPMTAG_FILEMD5S, NULL,
- (void **) &otherMd5s, NULL);
+ (const void **) &otherMd5s, NULL);
headerGetEntryMinMemory(h, RPMTAG_FILELINKTOS, NULL,
- (void **) &otherLinks, NULL);
+ (const void **) &otherLinks, NULL);
headerGetEntryMinMemory(h, RPMTAG_FILESTATES, NULL,
- (void **) &otherStates, NULL);
+ (const void **) &otherStates, NULL);
headerGetEntryMinMemory(h, RPMTAG_FILEMODES, NULL,
- (void **) &otherModes, NULL);
+ (const void **) &otherModes, NULL);
headerGetEntryMinMemory(h, RPMTAG_FILEFLAGS, NULL,
- (void **) &otherFlags, NULL);
+ (const void **) &otherFlags, NULL);
headerGetEntryMinMemory(h, RPMTAG_FILESIZES, NULL,
- (void **) &otherSizes, NULL);
+ (const void **) &otherSizes, NULL);
fi->replaced = xmalloc(sizeof(*fi->replaced) * sharedCount);
@@ -892,7 +892,7 @@ static int handleRmvdInstalledFiles(TFI_t * fi, rpmdb db,
}
headerGetEntryMinMemory(h, RPMTAG_FILESTATES, NULL,
- (void **) &otherStates, NULL);
+ (const void **) &otherStates, NULL);
for (i = 0; i < sharedCount; i++, shared++) {
int otherFileNum, fileNum;
@@ -1484,9 +1484,9 @@ int rpmRunTransactions( rpmTransactionSet ts,
break;
case TR_ADDED:
headerGetEntryMinMemory(fi->h, RPMTAG_FILEMD5S, NULL,
- (void **) &fi->fmd5s, NULL);
+ (const void **) &fi->fmd5s, NULL);
headerGetEntryMinMemory(fi->h, RPMTAG_FILELINKTOS, NULL,
- (void **) &fi->flinks, NULL);
+ (const void **) &fi->flinks, NULL);
/* 0 makes for noops */
fi->replacedSizes = xcalloc(fi->fc, sizeof(*fi->replacedSizes));
@@ -1659,9 +1659,6 @@ int rpmRunTransactions( rpmTransactionSet ts,
continue;
free(fi->bnl); fi->bnl = NULL;
free(fi->dnl); fi->dnl = NULL;
-#ifdef DOUBLE_FREE
- xfree(fi->dil); fi->dil = NULL;
-#endif
switch (fi->type) {
case TR_ADDED:
free(fi->fmd5s); fi->fmd5s = NULL;
@@ -1669,6 +1666,7 @@ int rpmRunTransactions( rpmTransactionSet ts,
free(fi->fps); fi->fps = NULL;
break;
case TR_REMOVED:
+ xfree(fi->dil); fi->dil = NULL;
free(fi->fps); fi->fps = NULL;
break;
}
diff --git a/lib/verify.c b/lib/verify.c
index 0d8e55fae..6bb063e8e 100644
--- a/lib/verify.c
+++ b/lib/verify.c
@@ -244,13 +244,14 @@ int rpmVerifyFile(const char * prefix, Header h, int filenum, int * result,
/**
* Return exit code from running verify script in header.
- * @param rootDir path to top of install tree
- * @param rpmdb rpm database
- * @param h header
- * @param scriptFd file handle to use for stderr
- * @return 0 on success
+ * @todo kpackage prevents static, should be using VERIFY_SCRIPT flag.
+ * @param rootDir path to top of install tree
+ * @param rpmdb rpm database
+ * @param h header
+ * @param scriptFd file handle to use for stderr
+ * @return 0 on success
*/
-static int rpmVerifyScript(const char * rootDir, rpmdb rpmdb, Header h, FD_t scriptFd)
+int rpmVerifyScript(const char * rootDir, rpmdb rpmdb, Header h, FD_t scriptFd)
{
rpmTransactionSet ts = rpmtransCreateSet(rpmdb, rootDir);
int rc;