diff options
author | jbj <devnull@localhost> | 2000-12-02 21:53:44 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2000-12-02 21:53:44 +0000 |
commit | 2885f536b6e314734c0c04245d77b9f7bdc76d42 (patch) | |
tree | 1ab8d5ab1cbc20bd1b1da69ba475b80816db2da9 /lib | |
parent | d7a40e754dc6b0ac07d2185bb5723384065feab5 (diff) | |
download | librpm-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.am | 16 | ||||
-rw-r--r-- | lib/cpio.c | 6 | ||||
-rw-r--r-- | lib/db1.c | 32 | ||||
-rw-r--r-- | lib/depends.c | 13 | ||||
-rw-r--r-- | lib/fprint.c | 12 | ||||
-rw-r--r-- | lib/header.c | 730 | ||||
-rw-r--r-- | lib/header.h | 32 | ||||
-rw-r--r-- | lib/install.c | 197 | ||||
-rw-r--r-- | lib/md5sum.c | 43 | ||||
-rw-r--r-- | lib/misc.c | 4 | ||||
-rw-r--r-- | lib/package.c | 58 | ||||
-rw-r--r-- | lib/rpmchecksig.c | 36 | ||||
-rw-r--r-- | lib/rpmdb.c | 39 | ||||
-rw-r--r-- | lib/rpmlib.h | 70 | ||||
-rw-r--r-- | lib/signature.c | 8 | ||||
-rw-r--r-- | lib/transaction.c | 28 | ||||
-rw-r--r-- | lib/verify.c | 13 |
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); @@ -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; |