00001
00005
00006
00007
00008
00009
00010
00011 #include "system.h"
00012
00013 #define __HEADER_PROTOTYPES__
00014
00015 #include <rpmio_internal.h>
00016 #include <header_internal.h>
00017
00018 #include "debug.h"
00019
00020
00021 int _hdr_debug = 0;
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define PARSER_BEGIN 0
00032 #define PARSER_IN_ARRAY 1
00033 #define PARSER_IN_EXPR 2
00034
00037
00038 static unsigned char header_magic[8] = {
00039 0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
00040 };
00041
00045
00046 static int typeAlign[16] = {
00047 1,
00048 1,
00049 1,
00050 2,
00051 4,
00052 8,
00053 1,
00054 1,
00055 1,
00056 1,
00057 1,
00058 1,
00059 0,
00060 0,
00061 0,
00062 0
00063 };
00064
00068
00069 static int typeSizes[16] = {
00070 0,
00071 1,
00072 1,
00073 2,
00074 4,
00075 8,
00076 -1,
00077 1,
00078 -1,
00079 -1,
00080 1,
00081 1,
00082 0,
00083 0,
00084 0,
00085 0
00086 };
00087
00091
00092 static size_t headerMaxbytes = (32*1024*1024);
00093
00098 #define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
00099
00103 #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE)
00104
00109 #define hdrchkData(_nbytes) ((_nbytes) & 0xff000000)
00110
00114 #define hdrchkAlign(_type, _off) ((_off) & (typeAlign[_type]-1))
00115
00119 #define hdrchkRange(_dl, _off) ((_off) < 0 || (_off) > (_dl))
00120
00121
00122 HV_t hdrVec;
00123
00129 static inline void *
00130 _free( const void * p)
00131 {
00132 if (p != NULL) free((void *)p);
00133 return NULL;
00134 }
00135
00141 static
00142 Header headerLink(Header h)
00143
00144 {
00145
00146 if (h == NULL) return NULL;
00147
00148
00149 h->nrefs++;
00150
00151 if (_hdr_debug)
00152 fprintf(stderr, "--> h %p ++ %d at %s:%u\n", h, h->nrefs, __FILE__, __LINE__);
00153
00154
00155
00156 return h;
00157
00158 }
00159
00165 static
00166 Header headerUnlink( Header h)
00167
00168 {
00169 if (h == NULL) return NULL;
00170
00171 if (_hdr_debug)
00172 fprintf(stderr, "--> h %p -- %d at %s:%u\n", h, h->nrefs, __FILE__, __LINE__);
00173
00174 h->nrefs--;
00175 return NULL;
00176 }
00177
00183 static
00184 Header headerFree( Header h)
00185
00186 {
00187 (void) headerUnlink(h);
00188
00189
00190 if (h == NULL || h->nrefs > 0)
00191 return NULL;
00192
00193 if (h->index) {
00194 indexEntry entry = h->index;
00195 int i;
00196 for (i = 0; i < h->indexUsed; i++, entry++) {
00197 if ((h->flags & HEADERFLAG_ALLOCATED) && ENTRY_IS_REGION(entry)) {
00198 if (entry->length > 0) {
00199 int_32 * ei = entry->data;
00200 if ((ei - 2) == h->blob) h->blob = _free(h->blob);
00201 entry->data = NULL;
00202 }
00203 } else if (!ENTRY_IN_REGION(entry)) {
00204 entry->data = _free(entry->data);
00205 }
00206 entry->data = NULL;
00207 }
00208 h->index = _free(h->index);
00209 }
00210 h->origin = _free(h->origin);
00211
00212 h = _free(h);
00213 return h;
00214
00215 }
00216
00221 static
00222 Header headerNew(void)
00223
00224 {
00225 Header h = xcalloc(1, sizeof(*h));
00226
00227
00228
00229 h->hv = *hdrVec;
00230
00231
00232 h->blob = NULL;
00233 h->origin = NULL;
00234 h->instance = 0;
00235 h->indexAlloced = INDEX_MALLOC_SIZE;
00236 h->indexUsed = 0;
00237 h->flags |= HEADERFLAG_SORTED;
00238
00239 h->index = (h->indexAlloced
00240 ? xcalloc(h->indexAlloced, sizeof(*h->index))
00241 : NULL);
00242
00243 h->nrefs = 0;
00244
00245 return headerLink(h);
00246
00247 }
00248
00251 static int indexCmp(const void * avp, const void * bvp)
00252
00253 {
00254
00255 indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
00256
00257 return (ap->info.tag - bp->info.tag);
00258 }
00259
00264 static
00265 void headerSort(Header h)
00266
00267 {
00268 if (!(h->flags & HEADERFLAG_SORTED)) {
00269
00270 qsort(h->index, h->indexUsed, sizeof(*h->index), indexCmp);
00271
00272 h->flags |= HEADERFLAG_SORTED;
00273 }
00274 }
00275
00278 static int offsetCmp(const void * avp, const void * bvp)
00279 {
00280
00281 indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
00282
00283 int rc = (ap->info.offset - bp->info.offset);
00284
00285 if (rc == 0) {
00286
00287 if (ap->info.offset < 0)
00288 rc = (((char *)ap->data) - ((char *)bp->data));
00289 else
00290 rc = (ap->info.tag - bp->info.tag);
00291 }
00292 return rc;
00293 }
00294
00299 static
00300 void headerUnsort(Header h)
00301
00302 {
00303
00304 qsort(h->index, h->indexUsed, sizeof(*h->index), offsetCmp);
00305
00306 }
00307
00314 static
00315 unsigned int headerSizeof( Header h, enum hMagic magicp)
00316
00317 {
00318 indexEntry entry;
00319 unsigned int size = 0;
00320 unsigned int pad = 0;
00321 int i;
00322
00323 if (h == NULL)
00324 return size;
00325
00326 headerSort(h);
00327
00328 switch (magicp) {
00329 case HEADER_MAGIC_YES:
00330 size += sizeof(header_magic);
00331 break;
00332 case HEADER_MAGIC_NO:
00333 break;
00334 }
00335
00336
00337 size += 2 * sizeof(int_32);
00338
00339
00340 for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) {
00341 unsigned diff;
00342 int_32 type;
00343
00344
00345 if (ENTRY_IS_REGION(entry)) {
00346 size += entry->length;
00347
00348
00349 if (i == 0 && (h->flags & HEADERFLAG_LEGACY))
00350 size += sizeof(struct entryInfo_s) + entry->info.count;
00351
00352 continue;
00353 }
00354
00355
00356 if (entry->info.offset < 0)
00357 continue;
00358
00359
00360 type = entry->info.type;
00361
00362 if (typeSizes[type] > 1) {
00363 diff = typeSizes[type] - (size % typeSizes[type]);
00364 if (diff != typeSizes[type]) {
00365 size += diff;
00366 pad += diff;
00367 }
00368 }
00369
00370
00371
00372 size += sizeof(struct entryInfo_s) + entry->length;
00373
00374 }
00375
00376 return size;
00377 }
00378
00388 static int dataLength(int_32 type, hPTR_t p, int_32 count, int onDisk,
00389 hPTR_t pend)
00390
00391 {
00392 const unsigned char * s = p;
00393 const unsigned char * se = pend;
00394 int length = 0;
00395
00396 switch (type) {
00397 case RPM_STRING_TYPE:
00398 if (count != 1)
00399 return -1;
00400
00401 while (*s++) {
00402 if (se && s > se)
00403 return -1;
00404 length++;
00405 }
00406
00407 length++;
00408 break;
00409
00410 case RPM_STRING_ARRAY_TYPE:
00411 case RPM_I18NSTRING_TYPE:
00412
00413
00414
00415 if (onDisk) {
00416 while (count--) {
00417 length++;
00418
00419 while (*s++) {
00420 if (se && s > se)
00421 return -1;
00422 length++;
00423 }
00424
00425 }
00426 } else {
00427 const char ** av = (const char **)p;
00428
00429 while (count--) {
00430
00431 length += strlen(*av++) + 1;
00432 }
00433
00434 }
00435 break;
00436
00437 default:
00438
00439 if (typeSizes[type] == -1)
00440 return -1;
00441 length = typeSizes[(type & 0xf)] * count;
00442
00443 if (length < 0 || (se && (s + length) > se))
00444 return -1;
00445 break;
00446 }
00447
00448 return length;
00449 }
00450
00477 static int regionSwab( indexEntry entry, int il, int dl,
00478 entryInfo pe,
00479 unsigned char * dataStart,
00480 const unsigned char * dataEnd,
00481 int regionid)
00482
00483 {
00484 unsigned char * tprev = NULL;
00485 unsigned char * t = NULL;
00486 int tdel = 0;
00487 int tl = dl;
00488 struct indexEntry_s ieprev;
00489
00490
00491 memset(&ieprev, 0, sizeof(ieprev));
00492
00493 for (; il > 0; il--, pe++) {
00494 struct indexEntry_s ie;
00495 int_32 type;
00496
00497 ie.info.tag = ntohl(pe->tag);
00498 ie.info.type = ntohl(pe->type);
00499 ie.info.count = ntohl(pe->count);
00500 ie.info.offset = ntohl(pe->offset);
00501
00502 if (hdrchkType(ie.info.type))
00503 return -1;
00504 if (hdrchkData(ie.info.count))
00505 return -1;
00506 if (hdrchkData(ie.info.offset))
00507 return -1;
00508
00509 if (hdrchkAlign(ie.info.type, ie.info.offset))
00510 return -1;
00511
00512
00513 ie.data = t = dataStart + ie.info.offset;
00514 if (dataEnd && t >= dataEnd)
00515 return -1;
00516
00517 ie.length = dataLength(ie.info.type, ie.data, ie.info.count, 1, dataEnd);
00518 if (ie.length < 0 || hdrchkData(ie.length))
00519 return -1;
00520
00521 ie.rdlen = 0;
00522
00523 if (entry) {
00524 ie.info.offset = regionid;
00525
00526 *entry = ie;
00527
00528 entry++;
00529 }
00530
00531
00532 type = ie.info.type;
00533
00534 if (typeSizes[type] > 1) {
00535 unsigned diff;
00536 diff = typeSizes[type] - (dl % typeSizes[type]);
00537 if (diff != typeSizes[type]) {
00538 dl += diff;
00539 if (ieprev.info.type == RPM_I18NSTRING_TYPE)
00540 ieprev.length += diff;
00541 }
00542 }
00543
00544 tdel = (tprev ? (t - tprev) : 0);
00545 if (ieprev.info.type == RPM_I18NSTRING_TYPE)
00546 tdel = ieprev.length;
00547
00548 if (ie.info.tag >= HEADER_I18NTABLE) {
00549 tprev = t;
00550 } else {
00551 tprev = dataStart;
00552
00553
00554 if (ie.info.tag == HEADER_IMAGE)
00555 tprev -= REGION_TAG_COUNT;
00556
00557 }
00558
00559
00560 switch (ntohl(pe->type)) {
00561
00562 case RPM_INT64_TYPE:
00563 { int_64 * it = (int_64 *)t;
00564 int_32 b[2];
00565 for (; ie.info.count > 0; ie.info.count--, it += 1) {
00566 if (dataEnd && ((unsigned char *)it) >= dataEnd)
00567 return -1;
00568 b[1] = htonl(((int_32 *)it)[0]);
00569 b[0] = htonl(((int_32 *)it)[1]);
00570 if (b[1] != ((int_32 *)it)[0])
00571 memcpy(it, b, sizeof(b));
00572 }
00573 t = (char *) it;
00574 } break;
00575 case RPM_INT32_TYPE:
00576 { int_32 * it = (int_32 *)t;
00577 for (; ie.info.count > 0; ie.info.count--, it += 1) {
00578 if (dataEnd && ((unsigned char *)it) >= dataEnd)
00579 return -1;
00580 *it = htonl(*it);
00581 }
00582 t = (char *) it;
00583 } break;
00584 case RPM_INT16_TYPE:
00585 { int_16 * it = (int_16 *) t;
00586 for (; ie.info.count > 0; ie.info.count--, it += 1) {
00587 if (dataEnd && ((unsigned char *)it) >= dataEnd)
00588 return -1;
00589 *it = htons(*it);
00590 }
00591 t = (char *) it;
00592 } break;
00593
00594 default:
00595 t += ie.length;
00596 break;
00597 }
00598
00599 dl += ie.length;
00600 if (dataEnd && dataStart + dl > dataEnd) return -1;
00601 tl += tdel;
00602 ieprev = ie;
00603
00604 }
00605 tdel = (tprev ? (t - tprev) : 0);
00606 tl += tdel;
00607
00608
00609
00610
00611
00612
00613
00614 if (tl+REGION_TAG_COUNT == dl)
00615 tl += REGION_TAG_COUNT;
00616
00617
00618 return dl;
00619 }
00620
00626 static void * doHeaderUnload(Header h,
00627 int * lengthPtr)
00628
00629
00630
00631 {
00632 int_32 * ei = NULL;
00633 entryInfo pe;
00634 char * dataStart;
00635 char * te;
00636 unsigned pad;
00637 unsigned len;
00638 int_32 il = 0;
00639 int_32 dl = 0;
00640 indexEntry entry;
00641 int_32 type;
00642 int i;
00643 int drlen, ndribbles;
00644 int driplen, ndrips;
00645 int legacy = 0;
00646
00647
00648 headerUnsort(h);
00649
00650
00651 pad = 0;
00652 drlen = ndribbles = driplen = ndrips = 0;
00653 for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) {
00654 if (ENTRY_IS_REGION(entry)) {
00655 int_32 rdl = -entry->info.offset;
00656 int_32 ril = rdl/sizeof(*pe);
00657 int rid = entry->info.offset;
00658
00659 il += ril;
00660 dl += entry->rdlen + entry->info.count;
00661
00662 if (i == 0 && (h->flags & HEADERFLAG_LEGACY))
00663 il += 1;
00664
00665
00666 for (; i < h->indexUsed && entry->info.offset <= rid+1; i++, entry++) {
00667 if (entry->info.offset <= rid)
00668 continue;
00669
00670
00671 type = entry->info.type;
00672 if (typeSizes[type] > 1) {
00673 unsigned diff;
00674 diff = typeSizes[type] - (dl % typeSizes[type]);
00675 if (diff != typeSizes[type]) {
00676 drlen += diff;
00677 pad += diff;
00678 dl += diff;
00679 }
00680 }
00681
00682 ndribbles++;
00683 il++;
00684 drlen += entry->length;
00685 dl += entry->length;
00686 }
00687 i--;
00688 entry--;
00689 continue;
00690 }
00691
00692
00693 if (entry->data == NULL || entry->length <= 0)
00694 continue;
00695
00696
00697 type = entry->info.type;
00698 if (typeSizes[type] > 1) {
00699 unsigned diff;
00700 diff = typeSizes[type] - (dl % typeSizes[type]);
00701 if (diff != typeSizes[type]) {
00702 driplen += diff;
00703 pad += diff;
00704 dl += diff;
00705 } else
00706 diff = 0;
00707 }
00708
00709 ndrips++;
00710 il++;
00711 driplen += entry->length;
00712 dl += entry->length;
00713 }
00714
00715
00716 if (hdrchkTags(il) || hdrchkData(dl))
00717 goto errxit;
00718
00719 len = sizeof(il) + sizeof(dl) + (il * sizeof(*pe)) + dl;
00720
00721
00722 ei = xmalloc(len);
00723 ei[0] = htonl(il);
00724 ei[1] = htonl(dl);
00725
00726
00727 pe = (entryInfo) &ei[2];
00728 dataStart = te = (char *) (pe + il);
00729
00730 pad = 0;
00731 for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) {
00732 const char * src;
00733 char *t;
00734 int count;
00735 int rdlen;
00736
00737 if (entry->data == NULL || entry->length <= 0)
00738 continue;
00739
00740 t = te;
00741 pe->tag = htonl(entry->info.tag);
00742 pe->type = htonl(entry->info.type);
00743 pe->count = htonl(entry->info.count);
00744
00745 if (ENTRY_IS_REGION(entry)) {
00746 int_32 rdl = -entry->info.offset;
00747 int_32 ril = rdl/sizeof(*pe) + ndribbles;
00748 int rid = entry->info.offset;
00749
00750 src = (char *)entry->data;
00751 rdlen = entry->rdlen;
00752
00753
00754 if (i == 0 && (h->flags & HEADERFLAG_LEGACY)) {
00755 int_32 stei[4];
00756
00757 legacy = 1;
00758
00759 memcpy(pe+1, src, rdl);
00760 memcpy(te, src + rdl, rdlen);
00761
00762 te += rdlen;
00763
00764 pe->offset = htonl(te - dataStart);
00765 stei[0] = pe->tag;
00766 stei[1] = pe->type;
00767 stei[2] = htonl(-rdl-entry->info.count);
00768 stei[3] = pe->count;
00769
00770 memcpy(te, stei, entry->info.count);
00771
00772 te += entry->info.count;
00773 ril++;
00774 rdlen += entry->info.count;
00775
00776 count = regionSwab(NULL, ril, 0, pe, t, NULL, 0);
00777 if (count != rdlen)
00778 goto errxit;
00779
00780 } else {
00781
00782
00783 memcpy(pe+1, src + sizeof(*pe), ((ril-1) * sizeof(*pe)));
00784 memcpy(te, src + (ril * sizeof(*pe)), rdlen+entry->info.count+drlen);
00785
00786 te += rdlen;
00787 {
00788 entryInfo se = (entryInfo)src;
00789
00790 int off = ntohl(se->offset);
00791 pe->offset = (off) ? htonl(te - dataStart) : htonl(off);
00792 }
00793 te += entry->info.count + drlen;
00794
00795 count = regionSwab(NULL, ril, 0, pe, t, NULL, 0);
00796 if (count != (rdlen + entry->info.count + drlen))
00797 goto errxit;
00798 }
00799
00800
00801 while (i < h->indexUsed && entry->info.offset <= rid+1) {
00802 i++;
00803 entry++;
00804 }
00805 i--;
00806 entry--;
00807 pe += ril;
00808 continue;
00809 }
00810
00811
00812 if (entry->data == NULL || entry->length <= 0)
00813 continue;
00814
00815
00816 type = entry->info.type;
00817 if (typeSizes[type] > 1) {
00818 unsigned diff;
00819 diff = typeSizes[type] - ((te - dataStart) % typeSizes[type]);
00820 if (diff != typeSizes[type]) {
00821
00822 memset(te, 0, diff);
00823
00824 te += diff;
00825 pad += diff;
00826 }
00827 }
00828
00829 pe->offset = htonl(te - dataStart);
00830
00831
00832
00833 switch (entry->info.type) {
00834 case RPM_INT64_TYPE:
00835 { int_32 b[2];
00836 count = entry->info.count;
00837 src = entry->data;
00838 while (count--) {
00839 b[1] = htonl(((int_32 *)src)[0]);
00840 b[0] = htonl(((int_32 *)src)[1]);
00841 if (b[1] == ((int_32 *)src)[0])
00842 memcpy(te, src, sizeof(b));
00843 else
00844 memcpy(te, b, sizeof(b));
00845 te += sizeof(b);
00846 src += sizeof(b);
00847 }
00848 } break;
00849
00850 case RPM_INT32_TYPE:
00851 count = entry->info.count;
00852 src = entry->data;
00853 while (count--) {
00854 *((int_32 *)te) = htonl(*((int_32 *)src));
00855
00856 te += sizeof(int_32);
00857 src += sizeof(int_32);
00858
00859 }
00860 break;
00861
00862 case RPM_INT16_TYPE:
00863 count = entry->info.count;
00864 src = entry->data;
00865 while (count--) {
00866 *((int_16 *)te) = htons(*((int_16 *)src));
00867
00868 te += sizeof(int_16);
00869 src += sizeof(int_16);
00870
00871 }
00872 break;
00873
00874 default:
00875 memcpy(te, entry->data, entry->length);
00876 te += entry->length;
00877 break;
00878 }
00879
00880 pe++;
00881 }
00882
00883
00884 if (((char *)pe) != dataStart)
00885 goto errxit;
00886 if ((((char *)ei)+len) != te)
00887 goto errxit;
00888
00889 if (lengthPtr)
00890 *lengthPtr = len;
00891
00892 h->flags &= ~HEADERFLAG_SORTED;
00893 headerSort(h);
00894
00895 return (void *) ei;
00896
00897 errxit:
00898
00899 ei = _free(ei);
00900
00901 return (void *) ei;
00902 }
00903
00909 static
00910 void * headerUnload(Header h)
00911
00912 {
00913 int length;
00914
00915 void * uh = doHeaderUnload(h, &length);
00916
00917 return uh;
00918 }
00919
00927 static
00928 indexEntry findEntry( Header h, int_32 tag, int_32 type)
00929
00930 {
00931 indexEntry entry, entry2, last;
00932 struct indexEntry_s key;
00933
00934 if (h == NULL) return NULL;
00935 if (!(h->flags & HEADERFLAG_SORTED)) headerSort(h);
00936
00937 key.info.tag = tag;
00938
00939
00940 entry2 = entry =
00941 bsearch(&key, h->index, h->indexUsed, sizeof(*h->index), indexCmp);
00942
00943 if (entry == NULL)
00944 return NULL;
00945
00946 if (type == RPM_NULL_TYPE)
00947 return entry;
00948
00949
00950 while (entry->info.tag == tag && entry->info.type != type &&
00951 entry > h->index) entry--;
00952
00953 if (entry->info.tag == tag && entry->info.type == type)
00954 return entry;
00955
00956 last = h->index + h->indexUsed;
00957
00958 while (entry2->info.tag == tag && entry2->info.type != type &&
00959 entry2 < last) entry2++;
00960
00961
00962 if (entry->info.tag == tag && entry->info.type == type)
00963 return entry;
00964
00965 return NULL;
00966 }
00967
00977 static
00978 int headerRemoveEntry(Header h, int_32 tag)
00979
00980 {
00981 indexEntry last = h->index + h->indexUsed;
00982 indexEntry entry, first;
00983 int ne;
00984
00985 entry = findEntry(h, tag, RPM_NULL_TYPE);
00986 if (!entry) return 1;
00987
00988
00989 while (entry > h->index && (entry - 1)->info.tag == tag)
00990 entry--;
00991
00992
00993 for (first = entry; first < last; first++) {
00994 void * data;
00995 if (first->info.tag != tag)
00996 break;
00997 data = first->data;
00998 first->data = NULL;
00999 first->length = 0;
01000 if (ENTRY_IN_REGION(first))
01001 continue;
01002 data = _free(data);
01003 }
01004
01005 ne = (first - entry);
01006 if (ne > 0) {
01007 h->indexUsed -= ne;
01008 ne = last - first;
01009
01010 if (ne > 0)
01011 memmove(entry, first, (ne * sizeof(*entry)));
01012
01013 }
01014
01015 return 0;
01016 }
01017
01023 static
01024 Header headerLoad( void * uh)
01025
01026 {
01027 int_32 * ei = (int_32 *) uh;
01028 int_32 il = ntohl(ei[0]);
01029 int_32 dl = ntohl(ei[1]);
01030
01031 size_t pvlen = sizeof(il) + sizeof(dl) +
01032 (il * sizeof(struct entryInfo_s)) + dl;
01033
01034 void * pv = uh;
01035 Header h = NULL;
01036 entryInfo pe;
01037 unsigned char * dataStart;
01038 unsigned char * dataEnd;
01039 indexEntry entry;
01040 int rdlen;
01041 int i;
01042
01043
01044 if (hdrchkTags(il) || hdrchkData(dl))
01045 goto errxit;
01046
01047 ei = (int_32 *) pv;
01048
01049 pe = (entryInfo) &ei[2];
01050
01051 dataStart = (unsigned char *) (pe + il);
01052 dataEnd = dataStart + dl;
01053
01054 h = xcalloc(1, sizeof(*h));
01055
01056 h->hv = *hdrVec;
01057
01058
01059 h->blob = uh;
01060
01061 h->indexAlloced = il + 1;
01062 h->indexUsed = il;
01063 h->index = xcalloc(h->indexAlloced, sizeof(*h->index));
01064 h->flags |= HEADERFLAG_SORTED;
01065 h->nrefs = 0;
01066 h = headerLink(h);
01067
01068
01069
01070
01071
01072 if (ntohl(pe->tag) == 15 &&
01073 ntohl(pe->type) == RPM_STRING_TYPE &&
01074 ntohl(pe->count) == 1)
01075 {
01076 pe->tag = htonl(1079);
01077 }
01078
01079 entry = h->index;
01080 i = 0;
01081 if (!(htonl(pe->tag) < HEADER_I18NTABLE)) {
01082 h->flags |= HEADERFLAG_LEGACY;
01083 entry->info.type = REGION_TAG_TYPE;
01084 entry->info.tag = HEADER_IMAGE;
01085
01086 entry->info.count = REGION_TAG_COUNT;
01087
01088 entry->info.offset = ((unsigned char *)pe - dataStart);
01089
01090
01091 entry->data = pe;
01092
01093 entry->length = pvlen - sizeof(il) - sizeof(dl);
01094 rdlen = regionSwab(entry+1, il, 0, pe, dataStart, dataEnd, entry->info.offset);
01095 #if 0
01096 if (rdlen != dl)
01097 goto errxit;
01098 #endif
01099 entry->rdlen = rdlen;
01100 entry++;
01101 h->indexUsed++;
01102 } else {
01103 int_32 rdl;
01104 int_32 ril;
01105
01106 h->flags &= ~HEADERFLAG_LEGACY;
01107
01108 entry->info.type = htonl(pe->type);
01109 entry->info.count = htonl(pe->count);
01110
01111 if (hdrchkType(entry->info.type))
01112 goto errxit;
01113 if (hdrchkTags(entry->info.count))
01114 goto errxit;
01115
01116 { int off = ntohl(pe->offset);
01117
01118 if (hdrchkData(off))
01119 goto errxit;
01120 if (off) {
01121
01122 size_t nb = REGION_TAG_COUNT;
01123
01124 int_32 * stei = memcpy(alloca(nb), dataStart + off, nb);
01125 rdl = -ntohl(stei[2]);
01126 ril = rdl/sizeof(*pe);
01127 if (hdrchkTags(ril) || hdrchkData(rdl))
01128 goto errxit;
01129 entry->info.tag = htonl(pe->tag);
01130 } else {
01131 ril = il;
01132
01133 rdl = (ril * sizeof(struct entryInfo_s));
01134
01135 entry->info.tag = HEADER_IMAGE;
01136 }
01137 }
01138 entry->info.offset = -rdl;
01139
01140
01141 entry->data = pe;
01142
01143 entry->length = pvlen - sizeof(il) - sizeof(dl);
01144 rdlen = regionSwab(entry+1, ril-1, 0, pe+1, dataStart, dataEnd, entry->info.offset);
01145 if (rdlen < 0)
01146 goto errxit;
01147 entry->rdlen = rdlen;
01148
01149 if (ril < h->indexUsed) {
01150 indexEntry newEntry = entry + ril;
01151 int ne = (h->indexUsed - ril);
01152 int rid = entry->info.offset+1;
01153 int rc;
01154
01155
01156 rc = regionSwab(newEntry, ne, 0, pe+ril, dataStart, dataEnd, rid);
01157 if (rc < 0)
01158 goto errxit;
01159 rdlen += rc;
01160
01161 { indexEntry firstEntry = newEntry;
01162 int save = h->indexUsed;
01163 int j;
01164
01165
01166 h->indexUsed -= ne;
01167 for (j = 0; j < ne; j++, newEntry++) {
01168 (void) headerRemoveEntry(h, newEntry->info.tag);
01169 if (newEntry->info.tag == HEADER_BASENAMES)
01170 (void) headerRemoveEntry(h, HEADER_OLDFILENAMES);
01171 }
01172
01173
01174
01175 if (h->indexUsed < (save - ne)) {
01176 memmove(h->index + h->indexUsed, firstEntry,
01177 (ne * sizeof(*entry)));
01178 }
01179
01180 h->indexUsed += ne;
01181 }
01182 }
01183 }
01184
01185 h->flags &= ~HEADERFLAG_SORTED;
01186 headerSort(h);
01187
01188
01189 return h;
01190
01191
01192 errxit:
01193
01194 if (h) {
01195 h->index = _free(h->index);
01196
01197 h = _free(h);
01198
01199 }
01200
01201
01202 return h;
01203
01204 }
01205
01211 static
01212 const char * headerGetOrigin( Header h)
01213
01214 {
01215 return (h != NULL ? h->origin : NULL);
01216 }
01217
01224 static
01225 int headerSetOrigin( Header h, const char * origin)
01226
01227 {
01228 if (h != NULL) {
01229 h->origin = _free(h->origin);
01230 h->origin = xstrdup(origin);
01231 }
01232 return 0;
01233 }
01234
01240 static
01241 int headerGetInstance( Header h)
01242
01243 {
01244 return (h != NULL ? h->instance : 0);
01245 }
01246
01253 static
01254 int headerSetInstance( Header h, int instance)
01255
01256 {
01257 if (h != NULL)
01258 h->