- add region marker as RPM_BIN_TYPE in packages and database.
authorjbj <devnull@localhost>
Wed, 8 Nov 2000 17:07:01 +0000 (17:07 +0000)
committerjbj <devnull@localhost>
Wed, 8 Nov 2000 17:07:01 +0000 (17:07 +0000)
- fix: don't headerCopy() relocateable packages if not relocating.

CVS patchset: 4246
CVS date: 2000/11/08 17:07:01

CHANGES
build/pack.c
lib/header.c
lib/transaction.c
po/rpm.pot

diff --git a/CHANGES b/CHANGES
index 7d5e56c..5aeb713 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -27,6 +27,8 @@
                (Pawel A. Gajda<mis@k2.net.pl>).
        - add support for unzip <rodrigob@conectiva.com.br>
        - load headers as single contiguous region.
+       - add region marker as RPM_BIN_TYPE in packages and database.
+       - fix: don't headerCopy() relocateable packages if not relocating.
 
 3.0.6 -> 4.0
        - use DIRNAMES/BASENAMES/DIRINDICES not FILENAMES in packages and db.
index e53d5c1..7a031df 100644 (file)
@@ -351,7 +351,13 @@ int writeRPM(Header *hdrp, const char *fileName, int type,
        headerAddEntry(h, RPMTAG_COOKIE, RPM_STRING_TYPE, *cookie, 1);
     }
     
-    /* Write the header */
+    /* Reallocate the header into one contiguous region. */
+    *hdrp = h = headerReload(h);
+
+    /*
+     * Write the header+archive into a temp file so that the size of
+     * archive (after compression) can be added to the header.
+     */
     if (makeTempFile(NULL, &sigtarget, &fd)) {
        rpmError(RPMERR_CREATE, _("Unable to open temp file."));
        return RPMERR_CREATE;
@@ -374,14 +380,20 @@ int writeRPM(Header *hdrp, const char *fileName, int type,
     if (rc)
        goto exit;
 
-    /* Now set the real archive size in the Header */
+    /*
+     * Set the actual archive size, and rewrite the header.
+     * This used to be done using headerModifyEntry(), but now that headers
+     * have regions, the value is scribbled directly into the header data
+     * area. Some new scheme for adding the final archive size will have
+     * to be devised if headerGetEntry() ever changes to return a pointer
+     * to memory not in the region. <shrug>
+     */
     if (Fileno(csa->cpioFdIn) < 0) {
-       headerModifyEntry(h, RPMTAG_ARCHIVESIZE,
-               RPM_INT32_TYPE, &csa->cpioArchiveSize, 1);
+       int_32 * archiveSize;
+       headerGetEntry(h, RPMTAG_ARCHIVESIZE, NULL, &archiveSize, NULL);
+       *archiveSize = csa->cpioArchiveSize;
     }
 
-    *hdrp = h = headerReload(h);
-
     (void)Fseek(fd, 0,  SEEK_SET);
 
     if (headerWrite(fd, h, HEADER_MAGIC_YES))
index 9cfc287..a6b0959 100644 (file)
@@ -61,13 +61,20 @@ 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)
+
 /**
  * A single tag from a Header.
  */
 struct indexEntry {
     struct entryInfo info;     /*!< Description of tag data. */
     void * data;               /*!< Location of tag data. */
-    int length;                        /*!< Computable, but why bother? */
+    int length;                        /*!< No. bytes of data. */
 };
 
 /**
@@ -410,7 +417,7 @@ 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), "",
+       i, (3*(entry->info.offset & 0xf)), "",
        entry, entry->data, entry->length);
 
     switch (entry->info.type) {
@@ -460,6 +467,7 @@ Header headerLoad(void *pv)
     struct entryInfo * pe;
     struct indexEntry * entry; 
     int prevtag = 0;
+    int rid = 0;
     int i;
 
     h->nregions = 1;
@@ -479,11 +487,11 @@ Header headerLoad(void *pv)
 
     entry = h->index;
     i = 0;
-    if (htonl(pe->tag) != HEADER_IMAGE) {
-       entry->info.type = RPM_BIN_TYPE;
+    if (!(htonl(pe->tag) < HEADER_I18NTABLE)) {
+       entry->info.type = REGION_TAG_TYPE;
        prevtag = entry->info.tag = HEADER_IMAGE;
-       entry->info.count = 1;
-       entry->info.offset = h->nregions - 1;
+       entry->info.count = REGION_TAG_COUNT;
+       entry->info.offset = rid;
        entry->data = h->regions[0].data;
        entry->length = h->regions[0].len;
        entry++;
@@ -510,23 +518,30 @@ Header headerLoad(void *pv)
        entry->info.count = htonl(pe->count);
        entry->info.offset = htonl(pe->offset);
 
-       if (entry->info.offset < 0) {
+       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;
-           h->regions[h->nregions].len = 0;    /* XXX WRONG */
-           h->regions[h->nregions].data = dataStart + entry->info.offset;
+           rid = REGION_ID(h->nregions, 0);
            h->nregions++;
 
-           entry->info.offset = h->nregions - 1;
-           entry->data = h->regions[entry->info.offset].data;
-           entry->length = h->regions[entry->info.offset].len;
+           entry->info.offset = rid;
+           entry->data = h->regions[h->nregions - 1].data;
+           entry->length = h->regions[h->nregions - 1].len;
            continue;
        }
 
        entry->data = t = dataStart + entry->info.offset;
        entry->length = dataLength(entry->info.type, t, entry->info.count, 1);
-       entry->info.offset = h->nregions;
+       entry->info.offset = rid + 1;
 
        /* Perform endian conversions. */
        switch (entry->info.type) {
@@ -572,13 +587,6 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
     entry = h->index;
     i = 0;
 
-    if (entry->info.tag == HEADER_IMAGE) {
-       entry++;
-       i++;
-       il--;
-       dl += sizeof(struct entryInfo);
-    }
-
     ei = xmalloc(len);
     ei[0] = htonl(il);
     ei[1] = htonl(dl);
@@ -594,7 +602,23 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
 
        pe->type = htonl(entry->info.type);
        pe->tag = htonl(entry->info.tag);
-       pe->count = htonl(entry->info.count);
+
+       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];
+           }
+           
+           continue;
+       }
 
        /* Alignment */
        type = entry->info.type;
@@ -607,6 +631,7 @@ static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
            }
        }
 
+       pe->count = htonl(entry->info.count);
        pe->offset = htonl(te - dataStart);
 
        /* copy data w/ endian conversions */
@@ -1132,13 +1157,14 @@ void headerFree(Header h)
 {
     if (--h->nrefs)
        return;
+
     if (h->index) {
        struct indexEntry * entry = h->index;
        int i;
        for (i = 0; i < h->indexUsed; i++, entry++) {
-           if (entry->info.tag < HEADER_I18NTABLE)
+           if (ENTRY_IS_REGION(entry))
                continue;
-           if (entry->info.offset > 0)
+           if (ENTRY_IN_REGION(entry))
                continue;
            free(entry->data);
            entry->data = NULL;
@@ -1184,8 +1210,9 @@ unsigned int headerSizeof(Header h, enum hMagic magicp)
        unsigned diff;
        int_32 type;
 
-       if (entry->info.tag < HEADER_I18NTABLE) {
-           size -= sizeof(struct entryInfo);
+       if (ENTRY_IS_REGION(entry)) {
+           if (entry->info.count > 0)
+               size += entry->info.count;
            continue;
        }
 
@@ -1289,10 +1316,6 @@ int headerAddEntry(Header h, int_32 tag, int_32 type, const void *p, int_32 c)
        h->sorted = 0;
     h->indexUsed++;
 
-#ifdef DYING
-    headerSort(h);
-#endif
-
     return 1;
 }
 
@@ -1360,7 +1383,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
 
     if (langNum >= table->info.count) {
        length = strlen(lang) + 1;
-       if (table->info.offset > 0) {
+       if (ENTRY_IN_REGION(table)) {
            char * t = xmalloc(table->length + length);
            memcpy(t, table->data, table->length);
            table->data = t;
@@ -1383,7 +1406,7 @@ int headerAddI18NString(Header h, int_32 tag, const char * string, const char *
        ghosts = langNum - entry->info.count;
        
        length = strlen(string) + 1 + ghosts;
-       if (entry->info.offset > 0) {
+       if (ENTRY_IN_REGION(entry)) {
            char * t = xmalloc(entry->length + length);
            memcpy(t, entry->data, entry->length);
            entry->data = t;
@@ -1428,7 +1451,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->info.offset > 0) {
+       if (ENTRY_IN_REGION(entry)) {
            entry->info.offset = 0;
        } else
            free(entry->data);
@@ -1461,7 +1484,7 @@ int headerModifyEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c)
     entry->info.type = type;
     entry->data = grabData(type, p, c, &entry->length);
 
-    if (entry->info.offset > 0) {
+    if (ENTRY_IN_REGION(entry)) {
        entry->info.offset = 0;
     } else
        free(oldData);
@@ -1494,7 +1517,7 @@ int headerAppendEntry(Header h, int_32 tag, int_32 type, void * p, int_32 c)
 
     length = dataLength(type, p, c, 0);
 
-    if (entry->info.offset > 0) {
+    if (ENTRY_IN_REGION(entry)) {
        char * t = xmalloc(entry->length + length);
        memcpy(t, entry->data, entry->length);
        entry->data = t;
@@ -1527,7 +1550,7 @@ int headerRemoveEntry(Header h, int_32 tag)
     for (first = entry; first < last; first++) {
        if (first->info.tag != tag)
            break;
-       if (first->info.offset > 0)
+       if (ENTRY_IN_REGION(first))
            continue;
        free(first->data);
        first->data = NULL;
@@ -1541,32 +1564,6 @@ int headerRemoveEntry(Header h, int_32 tag)
            memmove(entry, first, (ne * sizeof(*entry)));
     }
     
-#if 0
-    /* We might be better off just counting the number of items off the
-       end and issuing one big memcpy, but memcpy() doesn't have to work
-       on overlapping regions thanks to ANSI <sigh>. A alloca() and two
-       memcpy() would probably still be a win (as our moving from the
-       end to the middle isn't very nice to the qsort() we'll have to
-       do to make up for this!), but I'm too lazy to implement it. Just
-       remember that this repeating this is basically nlogn thanks to this
-       dumb implementation (but n is the best we'd do anyway) */
-
-    if (entry->info.offset > 0) {
-       char * t = xmalloc(entry->length);
-       memcpy(t, entry->data, entry->length);
-       entry->data = t;
-       entry->info.offset = 0;
-    }
-
-    while (entry->info.tag == tag && entry < last) {
-       free(entry->data);
-       *(entry++) = *(--last);
-    }
-    h->indexUsed = last - h->index;
-
-    headerSort(h);
-#endif
-
     return 0;
 }
 
index efb830c..3bbead3 100644 (file)
@@ -262,6 +262,7 @@ void rpmProblemSetFree(rpmProblemSet probs)
     free(probs);
 }
 
+/** @todo multilib file action assignment need to be checked. */
 static Header relocateFileList(struct availablePackage * alp,
                               rpmProblemSet probs, Header origH,
                               enum fileActions * actions,
@@ -290,16 +291,29 @@ static Header relocateFileList(struct availablePackage * alp,
                        (void **) &validRelocations, &numValid))
        numValid = 0;
 
-    if (!rawRelocations && !numValid && !alp->multiLib) {
-       Header oH =  headerLink(origH);
-       return oH;
+    /*
+     * If no relocations are specified (usually the case), then return the
+     * original header. If there are prefixes, however, then INSTPREFIXES
+     * should be added, but, since relocateFileList() can be called more
+     * than once for the same header, don't bother if already present.
+     */
+    if (rawRelocations == NULL) {
+
+       if (numValid && !headerIsEntry(origH, RPMTAG_INSTPREFIXES)) {
+           if (!headerIsEntry(origH, RPMTAG_INSTPREFIXES))
+               headerAddEntry(origH, RPMTAG_INSTPREFIXES,
+                       RPM_STRING_ARRAY_TYPE, validRelocations, numValid);
+           xfree(validRelocations);
+       }
+       /* XXX FIXME multilib file actions need to be checked. */
+       return headerLink(origH);
     }
 
     h = headerCopy(origH);
 
     if (rawRelocations) {
-       for (i = 0; rawRelocations[i].newPath || rawRelocations[i].oldPath;
-               i++) ;
+       for (i = 0; rawRelocations[i].newPath || rawRelocations[i].oldPath; i++)
+           ;
        numRelocations = i;
     } else {
        numRelocations = 0;
index 13bcac9..38683fe 100644 (file)
@@ -6,7 +6,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2000-11-07 07:55-0500\n"
+"POT-Creation-Date: 2000-11-08 11:51-0500\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1495,7 +1495,7 @@ msgstr ""
 msgid "no tar files given for build"
 msgstr ""
 
-#: build/build.c:111 build/pack.c:356
+#: build/build.c:111 build/pack.c:362
 msgid "Unable to open temp file."
 msgstr ""
 
@@ -1822,51 +1822,51 @@ msgstr ""
 msgid "readRPM: reading header from %s\n"
 msgstr ""
 
-#: build/pack.c:368
+#: build/pack.c:374
 msgid "Bad CSA data"
 msgstr ""
 
-#: build/pack.c:400
+#: build/pack.c:412
 #, c-format
 msgid "Could not open %s: %s\n"
 msgstr ""
 
-#: build/pack.c:433
+#: build/pack.c:445
 #, c-format
 msgid "Unable to write package: %s"
 msgstr ""
 
-#: build/pack.c:445
+#: build/pack.c:457
 #, c-format
 msgid "Generating signature: %d\n"
 msgstr ""
 
-#: build/pack.c:458
+#: build/pack.c:470
 #, c-format
 msgid "Unable to open sigtarget %s: %s"
 msgstr ""
 
-#: build/pack.c:465
+#: build/pack.c:477
 #, c-format
 msgid "Unable to read sigtarget %s: %s"
 msgstr ""
 
-#: build/pack.c:471
+#: build/pack.c:483
 #, c-format
 msgid "Unable to write package %s: %s"
 msgstr ""
 
-#: build/pack.c:494
+#: build/pack.c:506
 #, c-format
 msgid "Wrote: %s\n"
 msgstr ""
 
-#: build/pack.c:560
+#: build/pack.c:572
 #, c-format
 msgid "Could not generate output filename for package %s: %s\n"
 msgstr ""
 
-#: build/pack.c:577
+#: build/pack.c:589
 #, c-format
 msgid "cannot create %s: %s\n"
 msgstr ""
@@ -2485,7 +2485,7 @@ msgid ""
 msgstr ""
 
 #: lib/formats.c:86 lib/formats.c:112 lib/formats.c:141 lib/formats.c:182
-#: lib/header.c:2385 lib/header.c:2402 lib/header.c:2422
+#: lib/header.c:2382 lib/header.c:2399 lib/header.c:2419
 msgid "(not a number)"
 msgstr ""
 
@@ -2514,92 +2514,92 @@ msgid "file %s is on an unknown device"
 msgstr ""
 
 #. This should not be allowed
-#: lib/header.c:260
+#: lib/header.c:267
 msgid "grabData() RPM_STRING_TYPE count must be 1.\n"
 msgstr ""
 
-#: lib/header.c:291 lib/header.c:872 lib/install.c:380
+#: lib/header.c:298 lib/header.c:897 lib/install.c:380
 #, c-format
 msgid "Data type %d not supported\n"
 msgstr ""
 
-#: lib/header.c:1268
+#: lib/header.c:1295
 #, c-format
 msgid "Bad count for headerAddEntry(): %d\n"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1738
+#: lib/header.c:1735
 #, c-format
 msgid "missing { after %"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1768
+#: lib/header.c:1765
 msgid "missing } after %{"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1782
+#: lib/header.c:1779
 msgid "empty tag format"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1794
+#: lib/header.c:1791
 msgid "empty tag name"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1811
+#: lib/header.c:1808
 msgid "unknown tag"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1838
+#: lib/header.c:1835
 msgid "] expected at end of array"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1856
+#: lib/header.c:1853
 msgid "unexpected ]"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1860
+#: lib/header.c:1857
 msgid "unexpected }"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1920
+#: lib/header.c:1917
 msgid "? expected in expression"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1929
+#: lib/header.c:1926
 msgid "{ expected after ? in expression"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1942 lib/header.c:1983
+#: lib/header.c:1939 lib/header.c:1980
 msgid "} expected in expression"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1952
+#: lib/header.c:1949
 msgid ": expected following ? subexpression"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1968
+#: lib/header.c:1965
 msgid "{ expected after : in expression"
 msgstr ""
 
 #. @-observertrans@
-#: lib/header.c:1993
+#: lib/header.c:1990
 msgid "| expected at end of expression"
 msgstr ""
 
-#: lib/header.c:2164
+#: lib/header.c:2161
 msgid "(unknown type)"
 msgstr ""
 
@@ -3697,27 +3697,27 @@ msgstr ""
 msgid "You must set \"%%_pgp_name\" in your macro file"
 msgstr ""
 
-#: lib/transaction.c:423
+#: lib/transaction.c:437
 #, c-format
 msgid "excluding file %s%s\n"
 msgstr ""
 
-#: lib/transaction.c:449 lib/transaction.c:532
+#: lib/transaction.c:463 lib/transaction.c:546
 #, c-format
 msgid "excluding directory %s\n"
 msgstr ""
 
-#: lib/transaction.c:454
+#: lib/transaction.c:468
 #, c-format
 msgid "relocating %s to %s\n"
 msgstr ""
 
-#: lib/transaction.c:525
+#: lib/transaction.c:539
 #, c-format
 msgid "relocating directory %s to %s\n"
 msgstr ""
 
-#: lib/transaction.c:677
+#: lib/transaction.c:691
 #, c-format
 msgid "%s skipped due to missingok flag\n"
 msgstr ""