21
21
#include "platform.h"
22
22
#include "extractor.h"
24
/* someone was using this non-portable function. Mac OS X
25
* doesn't have it so rpmextractor wouldn't load. I rewrite
26
* the function so that it will now work. below is the
27
* original FIXME notice. -- Filip Pizlo 2003 */
28
/* FIXME: replace use of stpcpy to increase portability */
30
my_stpcpy (char *dest, const char *src)
33
return dest + strlen (src);
36
/* **************** buffer-based IO ************** */
23
#include <rpm/rpmlib.h>
24
#include <rpm/rpmts.h>
26
#include <sys/types.h>
29
/* ******************** pipe feeder ************************ */
45
typedef fdStruct *FD_t;
48
timedRead (FD_t f, void *dst, size_t n)
52
if (f->len - f->pos >= n)
55
min = f->len - f->pos;
56
memcpy (dst, &f->data[f->pos], min);
61
/* *************** RPM types ************************ */
64
typedef unsigned int uint_32;
68
* Header private tags.
69
* @note General use tags should start at 1000 (RPM's tag space starts there).
71
#define HEADER_IMAGE 61
72
#define HEADER_SIGNATURES 62
73
#define HEADER_IMMUTABLE 63
74
#define HEADER_REGIONS 64
75
#define HEADER_I18NTABLE 100
76
#define HEADER_SIGBASE 256
77
#define HEADER_TAGBASE 1000
80
* Tags identify data in package headers.
81
* @note tags should not have value 0!
86
RPMTAG_HEADERIMAGE = HEADER_IMAGE, /*!< Current image. */
87
RPMTAG_HEADERSIGNATURES = HEADER_SIGNATURES, /*!< Signatures. */
88
RPMTAG_HEADERIMMUTABLE = HEADER_IMMUTABLE, /*!< Original image. */
90
RPMTAG_HEADERREGIONS = HEADER_REGIONS, /*!< Regions. */
92
RPMTAG_HEADERI18NTABLE = HEADER_I18NTABLE, /*!< I18N string locales. */
95
/* Retrofit (and uniqify) signature tags for use by tagName() and rpmQuery. */
96
/* the md5 sum was broken *twice* on big endian machines */
97
/* XXX 2nd underscore prevents tagTable generation */
98
RPMTAG_SIG_BASE = HEADER_SIGBASE,
99
RPMTAG_SIGSIZE = RPMTAG_SIG_BASE + 1,
100
RPMTAG_SIGLEMD5_1 = RPMTAG_SIG_BASE + 2, /*!< internal - obsolate */
101
RPMTAG_SIGPGP = RPMTAG_SIG_BASE + 3,
102
RPMTAG_SIGLEMD5_2 = RPMTAG_SIG_BASE + 4, /*!< internal - obsolate */
103
RPMTAG_SIGMD5 = RPMTAG_SIG_BASE + 5,
104
RPMTAG_SIGGPG = RPMTAG_SIG_BASE + 6,
105
RPMTAG_SIGPGP5 = RPMTAG_SIG_BASE + 7, /*!< internal - obsolate */
107
RPMTAG_BADSHA1_1 = RPMTAG_SIG_BASE + 8, /*!< internal - obsolate */
108
RPMTAG_BADSHA1_2 = RPMTAG_SIG_BASE + 9, /*!< internal - obsolate */
110
RPMTAG_PUBKEYS = RPMTAG_SIG_BASE + 10,
111
RPMTAG_DSAHEADER = RPMTAG_SIG_BASE + 11,
112
RPMTAG_RSAHEADER = RPMTAG_SIG_BASE + 12,
113
RPMTAG_SHA1HEADER = RPMTAG_SIG_BASE + 13,
116
RPMTAG_VERSION = 1001,
117
RPMTAG_RELEASE = 1002,
119
#define RPMTAG_SERIAL RPMTAG_EPOCH /* backward comaptibility */
120
RPMTAG_SUMMARY = 1004,
121
RPMTAG_DESCRIPTION = 1005,
122
RPMTAG_BUILDTIME = 1006,
123
RPMTAG_BUILDHOST = 1007,
124
RPMTAG_INSTALLTIME = 1008,
126
RPMTAG_DISTRIBUTION = 1010,
127
RPMTAG_VENDOR = 1011,
130
RPMTAG_LICENSE = 1014,
131
#define RPMTAG_COPYRIGHT RPMTAG_LICENSE /* backward comaptibility */
132
RPMTAG_PACKAGER = 1015,
135
RPMTAG_CHANGELOG = 1017, /*!< internal */
137
RPMTAG_SOURCE = 1018,
143
RPMTAG_POSTIN = 1024,
145
RPMTAG_POSTUN = 1026,
146
RPMTAG_OLDFILENAMES = 1027, /* obsolete */
147
RPMTAG_FILESIZES = 1028,
148
RPMTAG_FILESTATES = 1029,
149
RPMTAG_FILEMODES = 1030,
150
RPMTAG_FILEUIDS = 1031, /*!< internal */
151
RPMTAG_FILEGIDS = 1032, /*!< internal */
152
RPMTAG_FILERDEVS = 1033,
153
RPMTAG_FILEMTIMES = 1034,
154
RPMTAG_FILEMD5S = 1035,
155
RPMTAG_FILELINKTOS = 1036,
156
RPMTAG_FILEFLAGS = 1037,
158
RPMTAG_ROOT = 1038, /*!< internal - obsolete */
160
RPMTAG_FILEUSERNAME = 1039,
161
RPMTAG_FILEGROUPNAME = 1040,
163
RPMTAG_EXCLUDE = 1041, /*!< internal - obsolete */
164
RPMTAG_EXCLUSIVE = 1042, /*!< internal - obsolete */
167
RPMTAG_SOURCERPM = 1044,
168
RPMTAG_FILEVERIFYFLAGS = 1045,
169
RPMTAG_ARCHIVESIZE = 1046,
170
RPMTAG_PROVIDENAME = 1047,
171
#define RPMTAG_PROVIDES RPMTAG_PROVIDENAME /* backward comaptibility */
172
RPMTAG_REQUIREFLAGS = 1048,
173
RPMTAG_REQUIRENAME = 1049,
174
RPMTAG_REQUIREVERSION = 1050,
175
RPMTAG_NOSOURCE = 1051, /*!< internal */
176
RPMTAG_NOPATCH = 1052, /*!< internal */
177
RPMTAG_CONFLICTFLAGS = 1053,
178
RPMTAG_CONFLICTNAME = 1054,
179
RPMTAG_CONFLICTVERSION = 1055,
180
RPMTAG_DEFAULTPREFIX = 1056, /*!< internal - deprecated */
181
RPMTAG_BUILDROOT = 1057, /*!< internal */
182
RPMTAG_INSTALLPREFIX = 1058, /*!< internal - deprecated */
183
RPMTAG_EXCLUDEARCH = 1059,
184
RPMTAG_EXCLUDEOS = 1060,
185
RPMTAG_EXCLUSIVEARCH = 1061,
186
RPMTAG_EXCLUSIVEOS = 1062,
187
RPMTAG_AUTOREQPROV = 1063, /*!< internal */
188
RPMTAG_RPMVERSION = 1064,
189
RPMTAG_TRIGGERSCRIPTS = 1065,
190
RPMTAG_TRIGGERNAME = 1066,
191
RPMTAG_TRIGGERVERSION = 1067,
192
RPMTAG_TRIGGERFLAGS = 1068,
193
RPMTAG_TRIGGERINDEX = 1069,
194
RPMTAG_VERIFYSCRIPT = 1079,
195
RPMTAG_CHANGELOGTIME = 1080,
196
RPMTAG_CHANGELOGNAME = 1081,
197
RPMTAG_CHANGELOGTEXT = 1082,
199
RPMTAG_BROKENMD5 = 1083, /*!< internal */
201
RPMTAG_PREREQ = 1084, /*!< internal */
202
RPMTAG_PREINPROG = 1085,
203
RPMTAG_POSTINPROG = 1086,
204
RPMTAG_PREUNPROG = 1087,
205
RPMTAG_POSTUNPROG = 1088,
206
RPMTAG_BUILDARCHS = 1089,
207
RPMTAG_OBSOLETENAME = 1090,
208
#define RPMTAG_OBSOLETES RPMTAG_OBSOLETENAME /* backward comaptibility */
209
RPMTAG_VERIFYSCRIPTPROG = 1091,
210
RPMTAG_TRIGGERSCRIPTPROG = 1092,
211
RPMTAG_DOCDIR = 1093, /*!< internal */
212
RPMTAG_COOKIE = 1094,
213
RPMTAG_FILEDEVICES = 1095,
214
RPMTAG_FILEINODES = 1096,
215
RPMTAG_FILELANGS = 1097,
216
RPMTAG_PREFIXES = 1098,
217
RPMTAG_INSTPREFIXES = 1099,
218
RPMTAG_TRIGGERIN = 1100, /*!< internal */
219
RPMTAG_TRIGGERUN = 1101, /*!< internal */
220
RPMTAG_TRIGGERPOSTUN = 1102, /*!< internal */
221
RPMTAG_AUTOREQ = 1103, /*!< internal */
222
RPMTAG_AUTOPROV = 1104, /*!< internal */
224
RPMTAG_CAPABILITY = 1105, /*!< internal - obsolete */
226
RPMTAG_SOURCEPACKAGE = 1106, /*!< internal */
228
RPMTAG_OLDORIGFILENAMES = 1107, /*!< internal - obsolete */
230
RPMTAG_BUILDPREREQ = 1108, /*!< internal */
231
RPMTAG_BUILDREQUIRES = 1109, /*!< internal */
232
RPMTAG_BUILDCONFLICTS = 1110, /*!< internal */
234
RPMTAG_BUILDMACROS = 1111, /*!< internal */
236
RPMTAG_PROVIDEFLAGS = 1112,
237
RPMTAG_PROVIDEVERSION = 1113,
238
RPMTAG_OBSOLETEFLAGS = 1114,
239
RPMTAG_OBSOLETEVERSION = 1115,
240
RPMTAG_DIRINDEXES = 1116,
241
RPMTAG_BASENAMES = 1117,
242
RPMTAG_DIRNAMES = 1118,
243
RPMTAG_ORIGDIRINDEXES = 1119, /*!< internal */
244
RPMTAG_ORIGBASENAMES = 1120, /*!< internal */
245
RPMTAG_ORIGDIRNAMES = 1121, /*!< internal */
246
RPMTAG_OPTFLAGS = 1122,
247
RPMTAG_DISTURL = 1123,
248
RPMTAG_PAYLOADFORMAT = 1124,
249
RPMTAG_PAYLOADCOMPRESSOR = 1125,
250
RPMTAG_PAYLOADFLAGS = 1126,
251
RPMTAG_MULTILIBS = 1127,
252
RPMTAG_INSTALLTID = 1128,
253
RPMTAG_REMOVETID = 1129,
254
RPMTAG_SHA1RHN = 1130, /*!< internal */
255
RPMTAG_RHNPLATFORM = 1131,
256
RPMTAG_PLATFORM = 1132,
258
RPMTAG_FIRSTFREE_TAG /*!< internal */
262
#define RPMTAG_EXTERNAL_TAG 1000000
264
/** \ingroup signature
265
* Tags found in signature header from package.
269
RPMSIGTAG_SIZE = 1000, /*!< Header+Payload size in bytes. */
270
/* the md5 sum was broken *twice* on big endian machines */
271
RPMSIGTAG_LEMD5_1 = 1001, /*!< Broken MD5, take 1 */
272
RPMSIGTAG_PGP = 1002, /*!< PGP 2.6.3 signature. */
273
RPMSIGTAG_LEMD5_2 = 1003, /*!< Broken MD5, take 2 */
274
RPMSIGTAG_MD5 = 1004, /*!< MD5 signature. */
275
RPMSIGTAG_GPG = 1005, /*!< GnuPG signature. */
276
RPMSIGTAG_PGP5 = 1006, /*!< PGP5 signature @deprecated legacy. */
277
RPMSIGTAG_PAYLOADSIZE = 1007,
278
/*!< uncompressed payload size in bytes. */
279
RPMSIGTAG_BADSHA1_1 = RPMTAG_BADSHA1_1, /*!< Broken SHA1, take 1. */
280
RPMSIGTAG_BADSHA1_2 = RPMTAG_BADSHA1_2, /*!< Broken SHA1, take 2. */
281
RPMSIGTAG_SHA1 = RPMTAG_SHA1HEADER, /*!< sha1 header digest. */
282
RPMSIGTAG_DSA = RPMTAG_DSAHEADER, /*!< DSA header signature. */
283
RPMSIGTAG_RSA = RPMTAG_RSAHEADER /*!< RSA header signature. */
287
* Dependency Attributes.
289
typedef enum rpmsenseFlags_e
293
RPMSENSE_SERIAL = (1 << 0), /*!< @todo Legacy. */
295
RPMSENSE_LESS = (1 << 1),
296
RPMSENSE_GREATER = (1 << 2),
297
RPMSENSE_EQUAL = (1 << 3),
298
RPMSENSE_PROVIDES = (1 << 4), /* only used internally by builds */
299
RPMSENSE_CONFLICTS = (1 << 5), /* only used internally by builds */
300
RPMSENSE_PREREQ = (1 << 6), /*!< @todo Legacy. */
301
RPMSENSE_OBSOLETES = (1 << 7), /* only used internally by builds */
302
RPMSENSE_INTERP = (1 << 8), /*!< Interpreter used by scriptlet. */
303
RPMSENSE_SCRIPT_PRE = ((1 << 9) | RPMSENSE_PREREQ), /*!< %pre dependency. */
304
RPMSENSE_SCRIPT_POST = ((1 << 10) | RPMSENSE_PREREQ), /*!< %post dependency. */
305
RPMSENSE_SCRIPT_PREUN = ((1 << 11) | RPMSENSE_PREREQ), /*!< %preun dependency. */
306
RPMSENSE_SCRIPT_POSTUN = ((1 << 12) | RPMSENSE_PREREQ), /*!< %postun dependency. */
307
RPMSENSE_SCRIPT_VERIFY = (1 << 13), /*!< %verify dependency. */
308
RPMSENSE_FIND_REQUIRES = (1 << 14), /*!< find-requires generated dependency. */
309
RPMSENSE_FIND_PROVIDES = (1 << 15), /*!< find-provides generated dependency. */
311
RPMSENSE_TRIGGERIN = (1 << 16), /*!< %triggerin dependency. */
312
RPMSENSE_TRIGGERUN = (1 << 17), /*!< %triggerun dependency. */
313
RPMSENSE_TRIGGERPOSTUN = (1 << 18), /*!< %triggerpostun dependency. */
314
RPMSENSE_MULTILIB = (1 << 19),
315
RPMSENSE_SCRIPT_PREP = (1 << 20), /*!< %prep build dependency. */
316
RPMSENSE_SCRIPT_BUILD = (1 << 21), /*!< %build build dependency. */
317
RPMSENSE_SCRIPT_INSTALL = (1 << 22), /*!< %install build dependency. */
318
RPMSENSE_SCRIPT_CLEAN = (1 << 23), /*!< %clean build dependency. */
319
RPMSENSE_RPMLIB = ((1 << 24) | RPMSENSE_PREREQ), /*!< rpmlib(feature) dependency. */
321
RPMSENSE_TRIGGERPREIN = (1 << 25), /*!< @todo Implement %triggerprein. */
325
RPMSENSE_KEYRING = (1 << 26)
330
* Include calculation for 8 bytes of (magic, 0)?
339
* Package read return codes.
351
* The basic types of data in tags from headers.
353
typedef enum rpmTagType_e
355
#define RPM_MIN_TYPE 0
361
/* RPM_INT64_TYPE = 5, ---- These aren't supported (yet) */
364
RPM_STRING_ARRAY_TYPE = 8,
365
RPM_I18NSTRING_TYPE = 9
366
#define RPM_MAX_TYPE 9
370
* Teach header.c about legacy tags.
372
#define HEADER_OLDFILENAMES 1027
373
#define HEADER_BASENAMES 1117
375
#define REGION_TAG_TYPE RPM_BIN_TYPE
376
#define REGION_TAG_COUNT sizeof(struct entryInfo)
378
#define RPMLEAD_BINARY 0
379
#define RPMLEAD_SOURCE 1
381
#define RPMLEAD_MAGIC0 0xed
382
#define RPMLEAD_MAGIC1 0xab
383
#define RPMLEAD_MAGIC2 0xee
384
#define RPMLEAD_MAGIC3 0xdb
386
#define RPMLEAD_SIZE 96 /*!< Don't rely on sizeof(struct) */
389
* Maximum no. of bytes permitted in a header.
392
static size_t headerMaxbytes = (32 * 1024 * 1024);
395
* The lead data structure.
396
* The lead needs to be 8 byte aligned.
397
* @deprecated The lead (except for signature_type) is legacy.
398
* @todo Don't use any information from lead.
402
unsigned char magic[4];
403
unsigned char major, minor;
408
short signature_type; /*!< Signature header type (RPMSIG_HEADERSIG) */
409
/*@unused@*/ char reserved[16];
410
/*!< Pad to 96 bytes -- 8 byte aligned */
414
* Alignment needs (and sizeof scalars types) for internal rpm data types.
416
/*@observer@*//*@unchecked@ */
417
static int typeSizes[] = {
418
0, /*!< RPM_NULL_TYPE */
419
1, /*!< RPM_CHAR_TYPE */
420
1, /*!< RPM_INT8_TYPE */
421
2, /*!< RPM_INT16_TYPE */
422
4, /*!< RPM_INT32_TYPE */
423
-1, /*!< RPM_INT64_TYPE */
424
-1, /*!< RPM_STRING_TYPE */
425
1, /*!< RPM_BIN_TYPE */
426
-1, /*!< RPM_STRING_ARRAY_TYPE */
427
-1 /*!< RPM_I18NSTRING_TYPE */
432
enum headerSprintfExtenstionType
434
HEADER_EXT_LAST = 0, /*!< End of extension chain. */
435
HEADER_EXT_FORMAT, /*!< headerTagFormatFunction() extension */
436
HEADER_EXT_MORE, /*!< Chain to next table. */
437
HEADER_EXT_TAG /*!< headerTagTagFunction() extension */
440
/** \ingroup signature
441
* Signature types stored in rpm lead.
443
typedef enum sigType_e
445
RPMSIGTYPE_NONE = 0, /*!< unused, legacy. */
446
RPMSIGTYPE_PGP262_1024 = 1, /*!< unused, legacy. */
448
RPMSIGTYPE_BAD = 2, /*!< Unknown signature type. */
450
RPMSIGTYPE_MD5 = 3, /*!< unused, legacy. */
451
RPMSIGTYPE_MD5_PGP = 4, /*!< unused, legacy. */
452
RPMSIGTYPE_HEADERSIG = 5, /*!< Header style signature */
453
RPMSIGTYPE_DISABLE = 6 /*!< Disable verification (debugging only) */
457
* HEADER_EXT_TAG format function prototype.
458
* This will only ever be passed RPM_INT32_TYPE or RPM_STRING_TYPE to
459
* help keep things simple.
461
* @param type tag type
462
* @param data tag value
463
* @param formatPrefix
466
* @return formatted string
468
typedef /*only@ */ char *(*headerTagFormatFunction) (int_32 type,
476
* Associate tag names with numeric values.
478
typedef /*@abstract@ */ struct headerTagTableEntry_s *headerTagTableEntry;
479
struct headerTagTableEntry_s
481
/*@observer@*//*@null@ */ const char *name;
483
int val; /*!< Tag numeric value. */
488
typedef /*@abstract@ */ struct headerIteratorS *HeaderIterator;
492
typedef /*@abstract@ *//*@refcounted@ */ struct headerToken *Header;
495
typedef int_32 *hTYP_t;
496
typedef const void *hPTR_t;
497
typedef int_32 *hCNT_t;
500
* HEADER_EXT_FORMAT format function prototype.
501
* This is allowed to fail, which indicates the tag doesn't exist.
504
* @retval type address of tag type
505
* @retval data address of tag value pointer
506
* @retval count address of no. of data items
507
* @retval freedata address of data-was-malloc'ed indicator
508
* @return 0 on success
510
typedef int (*headerTagTagFunction) (Header h,
511
/*@null@ *//*@out@ */ hTYP_t type,
512
/*@null@ *//*@out@ */ hPTR_t * data,
513
/*@null@ *//*@out@ */ hCNT_t count,
514
/*@null@ *//*@out@ */ int *freeData);
517
* Define header tag output formats.
519
typedef /*@abstract@ */ struct headerSprintfExtension_s
520
*headerSprintfExtension;
521
struct headerSprintfExtension_s
523
enum headerSprintfExtenstionType type; /*!< Type of extension. */
524
/*@observer@*//*@null@ */
525
const char *name; /*!< Name of extension. */
528
/*@observer@*//*@null@ */
529
void *generic; /*!< Private extension. */
530
headerTagFormatFunction formatFunction; /*!< HEADER_EXT_TAG extension. */
531
headerTagTagFunction tagFunction; /*!< HEADER_EXT_FORMAT extension. */
532
struct headerSprintfExtension_s *more; /*!< Chained table extension. */
537
* Create new (empty) header instance.
540
typedef Header (*HDRnew) (void)
544
* Dereference a header instance.
546
* @return NULL always
549
/*@null@*/ Header (*HDRfree) ( /*@null@ *//*@killref@ */ Header h)
553
* Reference a header instance.
555
* @return referenced header instance
557
typedef Header (*HDRlink) (Header h)
561
* Dereference a header instance.
563
* @return NULL always
565
typedef Header (*HDRunlink) ( /*@killref@ *//*@null@ */ Header h)
569
* Sort tags in header.
570
* @todo Eliminate from API.
573
typedef void (*HDRsort) (Header h)
577
* Restore tags in header to original ordering.
578
* @todo Eliminate from API.
581
typedef void (*HDRunsort) (Header h)
585
* Return size of on-disk header representation in bytes.
587
* @param magicp include size of 8 bytes for (magic, 0)?
588
* @return size of on-disk header
590
typedef unsigned int (*HDRsizeof) ( /*@null@ */ Header h, enum hMagic magicp)
594
* Convert header to on-disk representation.
595
* @param h header (with pointers)
596
* @return on-disk header blob (i.e. with offsets)
599
/*@only@*//*@null@ */ void *(*HDRunload) (Header h)
603
* Convert header to on-disk representation, and then reload.
604
* This is used to insure that all header data is in one chunk.
605
* @param h header (with pointers)
606
* @param tag region tag
607
* @return on-disk header (with offsets)
610
/*@null@*/ Header (*HDRreload) ( /*@only@ */ Header h, int tag)
614
* Duplicate a header.
616
* @return new header instance
618
typedef Header (*HDRcopy) (Header h)
622
* Convert header to in-memory representation.
623
* @param uh on-disk header blob (i.e. with offsets)
627
/*@null@*/ Header (*HDRload) ( /*@kept@ */ void *uh)
628
/*@modifies uh @ */ ;
631
* Make a copy and convert header to in-memory representation.
632
* @param uh on-disk header blob (i.e. with offsets)
636
/*@null@*/ Header (*HDRcopyload) (const void *uh)
640
* Read (and load) header from file handle.
641
* @param fd file handle
642
* @param magicp read (and verify) 8 bytes of (magic, 0)?
643
* @return header (or NULL on error)
646
/*@null@*/ Header (*HDRhdrread) (FD_t fd, enum hMagic magicp)
647
/*@modifies fd @ */ ;
650
* Write (with unload) header to file handle.
651
* @param fd file handle
653
* @param magicp prefix write with 8 bytes of (magic, 0)?
654
* @return 0 on success, 1 on error
656
typedef int (*HDRhdrwrite) (FD_t fd, /*@null@ */ Header h, enum hMagic magicp)
657
/*@globals fileSystem @ */
658
/*@modifies fd, h, fileSystem @ */ ;
661
* Check if tag is in header.
664
* @return 1 on success, 0 on failure
666
typedef int (*HDRisentry) ( /*@null@ */ Header h, int_32 tag)
670
* Free data allocated when retrieved from header.
672
* @param data address of data (or NULL)
673
* @param type type of data (or -1 to force free)
674
* @return NULL always
677
/*@null@*/ void *(*HDRfreetag) (Header h,
678
/*@only@ *//*@null@ */ const void *data,
680
/*@modifies data @ */ ;
683
* Retrieve tag value.
684
* Will never return RPM_I18NSTRING_TYPE! RPM_STRING_TYPE elements with
685
* RPM_I18NSTRING_TYPE equivalent entries are translated (if HEADER_I18NTABLE
690
* @retval type address of tag value data type (or NULL)
691
* @retval p address of pointer to tag value(s) (or NULL)
692
* @retval c address of number of values (or NULL)
693
* @return 1 on success, 0 on failure
695
typedef int (*HDRget) (Header h, int_32 tag,
696
/*@null@ *//*@out@ */ hTYP_t type,
697
/*@null@ *//*@out@ */ void **p,
698
/*@null@ *//*@out@ */ hCNT_t c)
699
/*@modifies *type, *p, *c @ */ ;
702
* Retrieve tag value using header internal array.
703
* Get an entry using as little extra RAM as possible to return the tag value.
704
* This is only an issue for RPM_STRING_ARRAY_TYPE.
708
* @retval type address of tag value data type (or NULL)
709
* @retval p address of pointer to tag value(s) (or NULL)
710
* @retval c address of number of values (or NULL)
711
* @return 1 on success, 0 on failure
713
typedef int (*HDRgetmin) (Header h, int_32 tag,
714
/*@null@ *//*@out@ */ hTYP_t type,
715
/*@null@ *//*@out@ */ hPTR_t * p,
716
/*@null@ *//*@out@ */ hCNT_t c)
717
/*@modifies *type, *p, *c @ */ ;
721
* Duplicate tags are okay, but only defined for iteration (with the
722
* exceptions noted below). While you are allowed to add i18n string
723
* arrays through this function, you probably don't mean to. See
724
* headerAddI18NString() instead.
728
* @param type tag value data type
729
* @param p pointer to tag value(s)
730
* @param c number of values
731
* @return 1 on success, 0 on failure
734
int (*HDRadd) (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
738
* Append element to tag array in header.
739
* Appends item p to entry w/ tag and type as passed. Won't work on
740
* RPM_STRING_TYPE. Any pointers into header memory returned from
741
* headerGetEntryMinMemory() for this entry are invalid after this
742
* call has been made!
746
* @param type tag value data type
747
* @param p pointer to tag value(s)
748
* @param c number of values
749
* @return 1 on success, 0 on failure
752
int (*HDRappend) (Header h, int_32 tag, int_32 type, const void *p,
757
* Add or append element to tag array in header.
758
* @todo Arg "p" should have const.
761
* @param type tag value data type
762
* @param p pointer to tag value(s)
763
* @param c number of values
764
* @return 1 on success, 0 on failure
767
int (*HDRaddorappend) (Header h, int_32 tag, int_32 type, const void *p,
772
* Add locale specific tag to header.
773
* A NULL lang is interpreted as the C locale. Here are the rules:
775
* - If the tag isn't in the header, it's added with the passed string
777
* - If the tag occurs multiple times in entry, which tag is affected
778
* by the operation is undefined.
779
* - If the tag is in the header w/ this language, the entry is
780
* *replaced* (like headerModifyEntry()).
782
* This function is intended to just "do the right thing". If you need
783
* more fine grained control use headerAddEntry() and headerModifyEntry().
787
* @param string tag value
789
* @return 1 on success, 0 on failure
792
int (*HDRaddi18n) (Header h, int_32 tag, const char *string,
797
* Modify tag in header.
798
* If there are multiple entries with this tag, the first one gets replaced.
801
* @param type tag value data type
802
* @param p pointer to tag value(s)
803
* @param c number of values
804
* @return 1 on success, 0 on failure
807
int (*HDRmodify) (Header h, int_32 tag, int_32 type, const void *p,
812
* Delete tag in header.
813
* Removes all entries of type tag from the header, returns 1 if none were
818
* @return 0 on success, 1 on failure (INCONSISTENT)
820
typedef int (*HDRremove) (Header h, int_32 tag)
823
/*@-redef@*//* LCL: no clue */
826
typedef const char *errmsg_t;
827
typedef int_32 *hTAG_t;
830
* Return formatted output string from header tags.
831
* The returned string must be free()d.
834
* @param fmt format to use
835
* @param tags array of tag name/value pairs
836
* @param extensions chained table of formatting extensions.
837
* @retval errmsg error message (if any)
838
* @return formatted output string (malloc'ed)
841
/*@only@*/ char *(*HDRhdrsprintf) (Header h, const char *fmt,
842
const struct headerTagTableEntry_s * tags,
843
const struct headerSprintfExtension_s *
845
/*@null@ *//*@out@ */ errmsg_t * errmsg)
846
/*@modifies *errmsg @ */ ;
849
* Duplicate tag values from one header into another.
850
* @param headerFrom source header
851
* @param headerTo destination header
852
* @param tagstocopy array of tags that are copied
855
void (*HDRcopytags) (Header headerFrom, Header headerTo, hTAG_t tagstocopy)
856
/*@modifies headerFrom, headerTo @ */ ;
859
* Destroy header tag iterator.
860
* @param hi header tag iterator
861
* @return NULL always
863
typedef HeaderIterator (*HDRfreeiter) ( /*@only@ */ HeaderIterator hi)
864
/*@modifies hi @ */ ;
867
* Create header tag iterator.
869
* @return header tag iterator
871
typedef HeaderIterator (*HDRinititer) (Header h)
875
* Return next tag from header.
876
* @param hi header tag iterator
877
* @retval tag address of tag
878
* @retval type address of tag value data type
879
* @retval p address of pointer to tag value(s)
880
* @retval c address of number of values
881
* @return 1 on success, 0 on failure
883
typedef int (*HDRnextiter) (HeaderIterator hi,
884
/*@null@ *//*@out@ */ hTAG_t tag,
885
/*@null@ *//*@out@ */ hTYP_t type,
886
/*@null@ *//*@out@ */ hPTR_t * p,
887
/*@null@ *//*@out@ */ hCNT_t c)
888
/*@modifies hi, *tag, *type, *p, *c @ */ ;
891
* Header method vectors.
893
typedef /*@abstract@ */ struct HV_s *HV_t;
906
HDRcopyload hdrcopyload;
908
HDRhdrwrite hdrwrite;
909
HDRisentry hdrisentry;
910
HDRfreetag hdrfreetag;
915
HDRaddorappend hdraddorappend;
916
HDRaddi18n hdraddi18n;
919
HDRhdrsprintf hdrsprintf;
920
HDRcopytags hdrcopytags;
921
HDRfreeiter hdrfreeiter;
922
HDRinititer hdrinititer;
923
HDRnextiter hdrnextiter;
933
* Description of tag data.
935
typedef /*@abstract@ */ struct entryInfo *entryInfo;
938
int_32 tag; /*!< Tag identifier. */
939
int_32 type; /*!< Tag data type. */
940
int_32 offset; /*!< Offset into data segment (ondisk only). */
941
int_32 count; /*!< Number of tag elements. */
945
* A single tag from a Header.
947
typedef /*@abstract@ */ struct indexEntry *indexEntry;
950
struct entryInfo info; /*!< Description of tag data. */
951
/*@owned@*/ void *data;
952
/*!< Location of tag data. */
953
int length; /*!< No. bytes of data. */
954
int rdlen; /*!< No. bytes of data in region. */
958
* The Header data structure.
962
/*@unused@*/ struct HV_s hv;
963
/*!< Header public methods. */
964
void *blob; /*!< Header region blob. */
965
/*@owned@*/ indexEntry index;
966
/*!< Array of tags. */
967
int indexUsed; /*!< Current size of tag array. */
968
int indexAlloced; /*!< Allocated size of tag array. */
970
#define HEADERFLAG_SORTED (1 << 0) /*!< Are header entries sorted? */
971
#define HEADERFLAG_ALLOCATED (1 << 1) /*!< Is 1st header region allocated? */
972
#define HEADERFLAG_LEGACY (1 << 2) /*!< Header came from legacy source? */
973
/*@refs@*/ int nrefs;
974
/*!< Reference count. */
978
* Header tag iterator data structure.
980
struct headerIteratorS
982
/*@unused@*/ Header h;
983
/*!< Header being iterated. */
984
/*@unused@*/ int next_index;
985
/*!< Next tag index. */
989
/* ==================================================================== */
993
* Prototype for headerFreeData() vector.
994
* @param data address of data (or NULL)
995
* @param type type of data (or -1 to force free)
996
* @return NULL always
999
void *(*HFD_t) ( /*@only@ *//*@null@ */ const void *data, rpmTagType type)
1000
/*@modifies data @ */ ;
1003
* Prototype for headerAddEntry() vector.
1004
* Duplicate tags are okay, but only defined for iteration (with the
1005
* exceptions noted below). While you are allowed to add i18n string
1006
* arrays through this function, you probably don't mean to. See
1007
* headerAddI18NString() instead.
1011
* @param type tag value data type
1012
* @param p pointer to tag value(s)
1013
* @param c number of values
1014
* @return 1 on success, 0 on failure
1016
typedef int (*HAE_t) (Header h, rpmTag tag, rpmTagType type,
1017
const void *p, int_32 c)
1018
/*@modifies h @ */ ;
1021
* Prototype for headerGetEntry() vector.
1022
* Will never return RPM_I18NSTRING_TYPE! RPM_STRING_TYPE elements with
1023
* RPM_I18NSTRING_TYPE equivalent entries are translated (if HEADER_I18NTABLE
1024
* entry is present).
1028
* @retval type address of tag value data type (or NULL)
1029
* @retval p address of pointer to tag value(s) (or NULL)
1030
* @retval c address of number of values (or NULL)
1031
* @return 1 on success, 0 on failure
1033
typedef int (*HGE_t) (Header h, rpmTag tag,
1034
/*@null@ *//*@out@ */ rpmTagType * type,
1035
/*@null@ *//*@out@ */ void **p,
1036
/*@null@ *//*@out@ */ int_32 * c)
1037
/*@modifies *type, *p, *c @ */ ;
1040
* Prototype for headerRemoveEntry() vector.
1041
* Delete tag in header.
1042
* Removes all entries of type tag from the header, returns 1 if none were
1047
* @return 0 on success, 1 on failure (INCONSISTENT)
1049
typedef int (*HRE_t) (Header h, int_32 tag)
1050
/*@modifies h @ */ ;
1052
#define ENTRY_IS_REGION(_e) \
1053
(((_e)->info.tag >= HEADER_IMAGE) && ((_e)->info.tag < HEADER_REGIONS))
1056
#define alloca_strdup(_s) strcpy(alloca(strlen(_s)+1), (_s))
1059
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
1060
* @param p memory to free
1061
* @return NULL always
1063
/*@unused@*/ static /*@null@ */ void *
1064
_free ( /*@only@ *//*@null@ *//*@out@ */ const void *p) /*@modifies *p @ */
1074
indexCmp (const void *avp, const void *bvp) /*@ */
1077
indexEntry ap = (indexEntry) avp, bp = (indexEntry) bvp;
1079
return (ap->info.tag - bp->info.tag);
1083
* Sort tags in header.
1087
headerSort (Header h)
1090
if (!(h->flags & HEADERFLAG_SORTED))
1092
qsort (h->index, h->indexUsed, sizeof (*h->index), indexCmp);
1093
h->flags |= HEADERFLAG_SORTED;
1098
* Remove occurences of trailing character from string.
1100
* @param c character to strip
1103
/*@unused@*/ static inline
1105
stripTrailingChar ( /*@only@ */ char *s, char c)
1109
for (t = s + strlen (s) - 1; *t == c && t >= s; t--)
1115
* Free data allocated when retrieved from header.
1116
* @deprecated Use headerFreeTag() instead.
1117
* @todo Remove from API.
1119
* @param data address of data (or NULL)
1120
* @param type type of data (or -1 to force free)
1121
* @return NULL always
1126
headerFreeData ( /*@only@ *//*@null@ */ const void *data, rpmTagType type)
1127
/*@modifies data @ */
1133
type == RPM_STRING_ARRAY_TYPE ||
1134
type == RPM_I18NSTRING_TYPE || type == RPM_BIN_TYPE)
1135
free ((void *) data);
1143
* Return length of entry data.
1144
* @todo Remove sanity check exit's.
1145
* @param type entry data type
1146
* @param p entry data
1147
* @param count entry item count
1148
* @param onDisk data is concatenated strings (with NUL's))?
1149
* @return no. bytes in data
1153
dataLength (int_32 type, hPTR_t p, int_32 count, int onDisk)
1160
case RPM_STRING_TYPE:
1162
{ /* Special case -- p is just the string */
1163
length = strlen (p) + 1;
1166
/* This should not be allowed */
1169
exit (EXIT_FAILURE);
1170
/*@notreached@ */ break;
1172
case RPM_STRING_ARRAY_TYPE:
1173
case RPM_I18NSTRING_TYPE:
1177
/* This is like RPM_STRING_TYPE, except it's *always* an array */
1178
/* Compute sum of length of all strings, including null terminators */
1183
const char *chptr = p;
1188
thisLen = strlen (chptr) + 1;
1195
const char **src = (const char **) p;
1198
/* add one for null termination */
1199
length += strlen (*src++) + 1;
1206
if (typeSizes[type] != -1)
1208
length = typeSizes[type] * count;
1213
exit (EXIT_FAILURE);
1214
/*@notreached@ */ break;
1223
copyData (int_32 type, /*@out@ */ void *dstPtr, const void *srcPtr,
1224
int_32 c, int dataLengtha)
1225
/*@modifies *dstPtr @ */
1233
case RPM_STRING_ARRAY_TYPE:
1234
case RPM_I18NSTRING_TYPE:
1235
/* Otherwise, p is char** */
1237
src = (const char **) srcPtr;
1243
int len = strlen (*src) + 1;
1244
memcpy (dst, *src, len);
1252
memmove (dstPtr, srcPtr, dataLengtha);
1258
* Return (malloc'ed) copy of entry data.
1259
* @param type entry data type
1260
* @param p entry data
1261
* @param c entry item count
1262
* @retval lengthPtr no. bytes in returned data
1263
* @return (malloc'ed) copy of entry data
1266
grabData (int_32 type, hPTR_t p, int_32 c,
1267
/*@out@ */ int *lengthPtr)
1268
/*@modifies *lengthPtr @ */
1270
int length = dataLength (type, p, c, 0);
1271
void *data = malloc (length);
1273
copyData (type, data, p, c, length);
1276
*lengthPtr = length;
1281
#define INDEX_MALLOC_SIZE 8
1284
* Add tag to header.
1285
* Duplicate tags are okay, but only defined for iteration (with the
1286
* exceptions noted below). While you are allowed to add i18n string
1287
* arrays through this function, you probably don't mean to. See
1288
* headerAddI18NString() instead.
1292
* @param type tag value data type
1293
* @param p pointer to tag value(s)
1294
* @param c number of values
1295
* @return 1 on success, 0 on failure
1298
headerAddEntry (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
1303
/* Count must always be >= 1 for headerAddEntry. */
1307
/* Allocate more index space if necessary */
1308
if (h->indexUsed == h->indexAlloced)
1310
h->indexAlloced += INDEX_MALLOC_SIZE;
1311
h->index = realloc (h->index, h->indexAlloced * sizeof (*h->index));
1314
/* Fill in the index */
1315
entry = h->index + h->indexUsed;
1316
entry->info.tag = tag;
1317
entry->info.type = type;
1318
entry->info.count = c;
1319
entry->info.offset = 0;
1320
entry->data = grabData (type, p, c, &entry->length);
1322
if (h->indexUsed > 0 && tag < h->index[h->indexUsed - 1].info.tag)
1323
h->flags &= ~HEADERFLAG_SORTED;
1330
* Dereference a header instance.
1332
* @return NULL always
1335
Header headerFree ( /*@killref@ *//*@null@ */ Header h);
1340
* Destroy header tag iterator.
1341
* @param hi header tag iterator
1342
* @return NULL always
1346
headerFreeIterator ( /*@only@ */ HeaderIterator hi)
1349
hi->h = headerFree (hi->h);
1355
* Find matching (tag,type) entry in header.
1357
* @param tag entry tag
1358
* @param type entry type
1359
* @return header entry
1363
findEntry ( /*@null@ */ Header h, int_32 tag, int_32 type)
1366
indexEntry entry, entry2, last;
1367
struct indexEntry key;
1371
if (!(h->flags & HEADERFLAG_SORTED))
1377
bsearch (&key, h->index, h->indexUsed, sizeof (*h->index), indexCmp);
1381
if (type == RPM_NULL_TYPE)
1384
/* look backwards */
1385
while (entry->info.tag == tag && entry->info.type != type &&
1389
if (entry->info.tag == tag && entry->info.type == type)
1392
last = h->index + h->indexUsed;
1393
/*@-usereleased@ *//* FIX: entry2 = entry. Code looks bogus as well. */
1394
while (entry2->info.tag == tag && entry2->info.type != type &&
1399
if (entry->info.tag == tag && entry->info.type == type)
1405
static int regionSwab ( /*@null@ */ indexEntry entry, int il, int dl,
1406
entryInfo pe, char *dataStart, int regionid);
1407
/*@modifies *entry, *dataStart @ */
1410
* Retrieve data from header entry.
1411
* @todo Permit retrieval of regions other than HEADER_IMUTABLE.
1412
* @param entry header entry
1413
* @retval type address of type (or NULL)
1414
* @retval p address of data (or NULL)
1415
* @retval c address of count (or NULL)
1416
* @param minMem string pointers refer to header memory?
1417
* @return 1 on success, otherwise error.
1420
copyEntry (const indexEntry entry,
1421
/*@null@ *//*@out@ */ hTYP_t type,
1422
/*@null@ *//*@out@ */ hPTR_t * p,
1423
/*@null@ *//*@out@ */ hCNT_t c,
1425
/*@modifies *type, *p, *c @ */
1427
int_32 count = entry->info.count;
1428
int rc = 1; /* XXX 1 on success. */
1431
switch (entry->info.type)
1435
* XXX This only works for
1436
* XXX "sealed" HEADER_IMMUTABLE/HEADER_SIGNATURES/HEADER_IMAGE.
1437
* XXX This will *not* work for unsealed legacy HEADER_IMAGE (i.e.
1438
* XXX a legacy header freshly read, but not yet unloaded to the rpmdb).
1440
if (ENTRY_IS_REGION (entry))
1442
int_32 *ei = ((int_32 *) entry->data) - 2;
1444
entryInfo pe = (entryInfo) (ei + 2);
1446
char *dataStart = (char *) (pe + ntohl (ei[0]));
1447
int_32 rdl = -entry->info.offset; /* negative offset */
1448
int_32 ril = rdl / sizeof (*pe);
1452
count = 2 * sizeof (*ei) + (ril * sizeof (*pe)) + rdl;
1453
if (entry->info.tag == HEADER_IMAGE)
1460
count += REGION_TAG_COUNT;
1461
rdl += REGION_TAG_COUNT;
1464
*p = malloc (count);
1465
ei = (int_32 *) * p;
1466
ei[0] = htonl (ril);
1467
ei[1] = htonl (rdl);
1470
pe = (entryInfo) memcpy (ei + 2, pe, (ril * sizeof (*pe)));
1473
dataStart = (char *) memcpy (pe + ril, dataStart, rdl);
1476
rc = regionSwab (NULL, ril, 0, pe, dataStart, 0);
1477
/* XXX 1 on success. */
1478
rc = (rc < 0) ? 0 : 1;
1482
count = entry->length;
1484
? memcpy (malloc (count), entry->data, count)
1488
case RPM_STRING_TYPE:
1495
case RPM_STRING_ARRAY_TYPE:
1496
case RPM_I18NSTRING_TYPE:
1498
const char **ptrEntry;
1500
int tableSize = count * sizeof (char *);
1508
*p = malloc (tableSize);
1509
ptrEntry = (const char **) *p;
1514
t = malloc (tableSize + entry->length);
1516
ptrEntry = (const char **) *p;
1518
memcpy (t, entry->data, entry->length);
1521
for (i = 0; i < count; i++)
1535
*type = entry->info.type;
1541
#define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0)
1544
* Append element to tag array in header.
1545
* Appends item p to entry w/ tag and type as passed. Won't work on
1546
* RPM_STRING_TYPE. Any pointers into header memory returned from
1547
* headerGetEntryMinMemory() for this entry are invalid after this
1548
* call has been made!
1552
* @param type tag value data type
1553
* @param p pointer to tag value(s)
1554
* @param c number of values
1555
* @return 1 on success, 0 on failure
1558
headerAppendEntry (Header h, int_32 tag, int_32 type, const void *p, int_32 c)
1564
/* First find the tag */
1565
entry = findEntry (h, tag, type);
1569
if (type == RPM_STRING_TYPE || type == RPM_I18NSTRING_TYPE)
1571
/* we can't do this */
1575
length = dataLength (type, p, c, 0);
1577
if (ENTRY_IN_REGION (entry))
1579
char *t = malloc (entry->length + length);
1580
memcpy (t, entry->data, entry->length);
1582
entry->info.offset = 0;
1585
entry->data = realloc (entry->data, entry->length + length);
1587
copyData (type, ((char *) entry->data) + entry->length, p, c, length);
1589
entry->length += length;
1591
entry->info.count += c;
1597
* Add or append element to tag array in header.
1598
* @todo Arg "p" should have const.
1601
* @param type tag value data type
1602
* @param p pointer to tag value(s)
1603
* @param c number of values
1604
* @return 1 on success, 0 on failure
1607
headerAddOrAppendEntry (Header h, int_32 tag, int_32 type,
1608
const void *p, int_32 c)
1611
return (findEntry (h, tag, type)
1612
? headerAppendEntry (h, tag, type, p, c)
1613
: headerAddEntry (h, tag, type, p, c));
1617
* Does locale match entry in header i18n table?
1620
* The range [l,le) contains the next locale to match:
1621
* ll[_CC][.EEEEE][@dddd]
1623
* ll ISO language code (in lowercase).
1624
* CC (optional) ISO coutnry code (in uppercase).
1625
* EEEEE (optional) encoding (not really standardized).
1626
* dddd (optional) dialect.
1629
* @param td header i18n table data, NUL terminated
1630
* @param l start of locale to match
1631
* @param le end of locale to match
1632
* @return 1 on match, 0 on no match
1635
headerMatchLocale (const char *td, const char *l, const char *le)
1643
const char *s, *ll, *CC, *EE, *dd;
1645
/* Copy the buffer and parse out components on the fly. */
1646
lbuf = alloca (le - l + 1);
1647
for (s = l, ll = t = lbuf; *s; s++, t++)
1669
if (ll) /* ISO language should be lower case */
1670
for (t = ll; *t; t++)
1672
if (CC) /* ISO country code should be upper case */
1673
for (t = CC; *t; t++)
1676
/* There are a total of 16 cases to attempt to match. */
1680
/* First try a complete match. */
1681
if (strlen (td) == (le - l) && !strncmp (td, l, (le - l)))
1684
/* Next, try stripping optional dialect and matching. */
1685
for (fe = l; fe < le && *fe != '@'; fe++)
1688
if (fe < le && !strncmp (td, l, (fe - l)))
1691
/* Next, try stripping optional codeset and matching. */
1692
for (fe = l; fe < le && *fe != '.'; fe++)
1695
if (fe < le && !strncmp (td, l, (fe - l)))
1698
/* Finally, try stripping optional country code and matching. */
1699
for (fe = l; fe < le && *fe != '_'; fe++)
1702
if (fe < le && !strncmp (td, l, (fe - l)))
1709
* Return i18n string from header that matches locale.
1711
* @param entry i18n string data
1712
* @return matching i18n string (or 1st string if no match)
1714
/*@dependent@*//*@exposed@ */ static char *
1715
headerFindI18NString (Header h, indexEntry entry)
1718
const char *lang, *l, *le;
1721
/* XXX Drepper sez' this is the order. */
1722
if ((lang = getenv ("LANGUAGE")) == NULL &&
1723
(lang = getenv ("LC_ALL")) == NULL &&
1724
(lang = getenv ("LC_MESSAGES")) == NULL &&
1725
(lang = getenv ("LANG")) == NULL)
1730
findEntry (h, HEADER_I18NTABLE, RPM_STRING_ARRAY_TYPE)) == NULL)
1734
for (l = lang; *l != '\0'; l = le)
1740
while (*l && *l == ':') /* skip leading colons */
1744
for (le = l; *le && *le != ':'; le++) /* find end of this locale */
1748
/* For each entry in the header ... */
1749
for (langNum = 0, td = table->data, ed = entry->data;
1750
langNum < entry->info.count;
1751
langNum++, td += strlen (td) + 1, ed += strlen (ed) + 1)
1754
if (headerMatchLocale (td, l, le))
1764
* Retrieve tag data from header.
1766
* @param tag tag to retrieve
1767
* @retval type address of type (or NULL)
1768
* @retval p address of data (or NULL)
1769
* @retval c address of count (or NULL)
1770
* @param minMem string pointers reference header memory?
1771
* @return 1 on success, 0 on not found
1774
intGetEntry (Header h, int_32 tag,
1775
/*@null@ *//*@out@ */ hTAG_t type,
1776
/*@null@ *//*@out@ */ hPTR_t * p,
1777
/*@null@ *//*@out@ */ hCNT_t c,
1779
/*@modifies *type, *p, *c @ */
1784
/* First find the tag */
1785
/*@-mods@ *//*@ FIX: h modified by sort. */
1786
entry = findEntry (h, tag, RPM_NULL_TYPE);
1799
switch (entry->info.type)
1801
case RPM_I18NSTRING_TYPE:
1804
*type = RPM_STRING_TYPE;
1807
/*@-dependenttrans@ */
1809
*p = headerFindI18NString (h, entry);
1810
/*@=dependenttrans@ */
1813
rc = copyEntry (entry, type, p, c, minMem);
1817
/* XXX 1 on success */
1818
return ((rc == 1) ? 1 : 0);
1822
* Retrieve tag value.
1823
* Will never return RPM_I18NSTRING_TYPE! RPM_STRING_TYPE elements with
1824
* RPM_I18NSTRING_TYPE equivalent entries are translated (if HEADER_I18NTABLE
1825
* entry is present).
1829
* @retval type address of tag value data type (or NULL)
1830
* @retval p address of pointer to tag value(s) (or NULL)
1831
* @retval c address of number of values (or NULL)
1832
* @return 1 on success, 0 on failure
1835
headerGetEntry (Header h, int_32 tag,
1836
/*@null@ *//*@out@ */ hTYP_t type,
1837
/*@null@ *//*@out@ */ void **p,
1838
/*@null@ *//*@out@ */ hCNT_t c)
1839
/*@modifies *type, *p, *c @ */
1841
return intGetEntry (h, tag, type, (hPTR_t *) p, c, 0);
1846
/*@observer@*//*@unchecked@ */
1847
static unsigned char header_magic[8] = {
1848
0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
1852
* Return size of on-disk header representation in bytes.
1854
* @param magicp include size of 8 bytes for (magic, 0)?
1855
* @return size of on-disk header
1858
headerSizeof ( /*@null@ */ Header h, enum hMagic magicp)
1862
unsigned int size = 0;
1872
case HEADER_MAGIC_YES:
1873
size += sizeof (header_magic);
1875
case HEADER_MAGIC_NO:
1880
size += 2 * sizeof (int_32); /* count of index entries */
1883
for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++)
1888
/* Regions go in as is ... */
1889
if (ENTRY_IS_REGION (entry))
1891
size += entry->length;
1892
/* XXX Legacy regions do not include the region tag and data. */
1894
if (i == 0 && (h->flags & HEADERFLAG_LEGACY))
1895
size += sizeof (struct entryInfo) + entry->info.count;
1900
/* ... and region elements are skipped. */
1901
if (entry->info.offset < 0)
1905
type = entry->info.type;
1906
if (typeSizes[type] > 1)
1908
diff = typeSizes[type] - (size % typeSizes[type]);
1909
if (diff != typeSizes[type])
1916
size += sizeof (struct entryInfo) + entry->length;
1924
* Reference a header instance.
1926
* @return referenced header instance
1929
headerLink (Header h)
1934
/*@-refcounttrans -nullret @ */
1936
/*@=refcounttrans =nullret @ */
1940
* Create header tag iterator.
1942
* @return header tag iterator
1944
static HeaderIterator
1945
headerInitIterator (Header h)
1948
HeaderIterator hi = malloc (sizeof (*hi));
1952
hi->h = headerLink (h);
1958
* Check if tag is in header.
1961
* @return 1 on success, 0 on failure
1964
headerIsEntry ( /*@null@ */ Header h, int_32 tag)
1967
/*@-mods@ *//*@ FIX: h modified by sort. */
1968
return (findEntry (h, tag, RPM_NULL_TYPE) ? 1 : 0);
1973
* Return next tag from header.
1974
* @param hi header tag iterator
1975
* @retval tag address of tag
1976
* @retval type address of tag value data type
1977
* @retval p address of pointer to tag value(s)
1978
* @retval c address of number of values
1979
* @return 1 on success, 0 on failure
1982
headerNextIterator (HeaderIterator hi,
1983
/*@null@ *//*@out@ */ hTAG_t tag,
1984
/*@null@ *//*@out@ */ hTYP_t type,
1985
/*@null@ *//*@out@ */ hPTR_t * p,
1986
/*@null@ *//*@out@ */ hCNT_t c,
1988
/*@modifies hi, *tag, *type, *p, *c @ */
1991
int slot = hi->next_index;
1992
indexEntry entry = NULL;
1995
for (slot = hi->next_index; slot < h->indexUsed; slot++)
1997
entry = h->index + slot;
1998
if (!ENTRY_IS_REGION (entry))
2001
hi->next_index = slot;
2002
if (entry == NULL || slot >= h->indexUsed)
2004
/*@-noeffect@ *//* LCL: no clue */
2009
*tag = entry->info.tag;
2011
rc = copyEntry (entry, type, p, c, do_copy);
2013
/* XXX 1 on success */
2014
return ((rc == 1) ? 1 : 0);
2018
* Dereference a header instance.
2020
* @return NULL always
2024
headerUnlink ( /*@killref@ *//*@null@ */ Header h)
2033
* Dereference a header instance.
2035
* @return NULL always
2039
headerFree ( /*@killref@ *//*@null@ */ Header h)
2042
(void) headerUnlink (h);
2045
if (h == NULL || h->nrefs > 0)
2046
return NULL; /* XXX return previous header? */
2050
indexEntry entry = h->index;
2052
for (i = 0; i < h->indexUsed; i++, entry++)
2054
if ((h->flags & HEADERFLAG_ALLOCATED) && ENTRY_IS_REGION (entry))
2056
if (entry->length > 0)
2058
int_32 *ei = entry->data;
2059
if ((ei - 2) == h->blob)
2060
h->blob = _free (h->blob);
2064
else if (!ENTRY_IN_REGION (entry))
2066
entry->data = _free (entry->data);
2070
h->index = _free (h->index);
2073
/*@-refcounttrans@ */ h = _free (h);
2074
/*@=refcounttrans@ */
2080
* Sanity check on no. of tags.
2081
* This check imposes a limit of 65K tags, more than enough.
2083
#define hdrchkTags(_ntags) ((_ntags) & 0xffff0000)
2086
* Sanity check on data size and/or offset.
2087
* This check imposes a limit of 16Mb, more than enough.
2089
#define hdrchkData(_nbytes) ((_nbytes) & 0xff000000)
2094
* Swap int_32 and int_16 arrays within header region.
2096
* This code is way more twisty than I would like.
2098
* A bug with RPM_I18NSTRING_TYPE in rpm-2.5.x (fixed in August 1998)
2099
* causes the offset and length of elements in a header region to disagree
2100
* regarding the total length of the region data.
2102
* The "fix" is to compute the size using both offset and length and
2103
* return the larger of the two numbers as the size of the region.
2104
* Kinda like computing left and right Riemann sums of the data elements
2105
* to determine the size of a data structure, go figger :-).
2107
* There's one other twist if a header region tag is in the set to be swabbed,
2108
* as the data for a header region is located after all other tag data.
2110
* @param entry header entry
2111
* @param il no. of entries
2112
* @param dl start no. bytes of data
2113
* @param pe header physical entry pointer (swapped)
2114
* @param dataStart header data
2115
* @param regionid region offset
2116
* @return no. bytes of data in region, -1 on error
2119
regionSwab ( /*@null@ */ indexEntry entry, int il, int dl,
2120
entryInfo pe, char *dataStart, int regionid)
2121
/*@modifies *entry, *dataStart @ */
2126
struct indexEntry ieprev;
2128
memset (&ieprev, 0, sizeof (ieprev));
2129
for (; il > 0; il--, pe++)
2131
struct indexEntry ie;
2134
ie.info.tag = ntohl (pe->tag);
2135
ie.info.type = ntohl (pe->type);
2136
if (ie.info.type < RPM_MIN_TYPE || ie.info.type > RPM_MAX_TYPE)
2138
ie.info.count = ntohl (pe->count);
2139
ie.info.offset = ntohl (pe->offset);
2140
ie.data = t = dataStart + ie.info.offset;
2141
ie.length = dataLength (ie.info.type, ie.data, ie.info.count, 1);
2146
ie.info.offset = regionid;
2147
*entry = ie; /* structure assignment */
2152
type = ie.info.type;
2153
if (typeSizes[type] > 1)
2156
diff = typeSizes[type] - (dl % typeSizes[type]);
2157
if (diff != typeSizes[type])
2160
if (ieprev.info.type == RPM_I18NSTRING_TYPE)
2161
ieprev.length += diff;
2164
tdel = (tprev ? (t - tprev) : 0);
2165
if (ieprev.info.type == RPM_I18NSTRING_TYPE)
2166
tdel = ieprev.length;
2168
if (ie.info.tag >= HEADER_I18NTABLE)
2175
/* XXX HEADER_IMAGE tags don't include region sub-tag. */
2177
if (ie.info.tag == HEADER_IMAGE)
2178
tprev -= REGION_TAG_COUNT;
2182
/* Perform endian conversions */
2183
switch (ntohl (pe->type))
2185
case RPM_INT32_TYPE:
2187
int_32 *it = (int_32 *) t;
2188
for (; ie.info.count > 0; ie.info.count--, it += 1)
2191
} /*@switchbreak@ */ break;
2192
case RPM_INT16_TYPE:
2194
unsigned short *it = (unsigned short *) t;
2195
for (; ie.info.count > 0; ie.info.count--, it += 1)
2198
} /*@switchbreak@ */ break;
2201
/*@switchbreak@ */ break;
2206
ieprev = ie; /* structure assignment */
2209
tdel = (tprev ? (t - tprev) : 0);
2213
* There are two hacks here:
2214
* 1) tl is 16b (i.e. REGION_TAG_COUNT) short while doing headerReload().
2215
* 2) the 8/98 rpm bug with inserting i18n tags needs to use tl, not dl.
2218
if (tl + REGION_TAG_COUNT == dl)
2219
tl += REGION_TAG_COUNT;
2225
static int headerRemoveEntry (Header h, int_32 tag);
2228
* Convert header to in-memory representation.
2229
* @param uh on-disk header blob (i.e. with offsets)
2234
headerLoad ( /*@kept@ */ void *uh)
2237
int_32 *ei = (int_32 *) uh;
2238
int_32 il = ntohl (ei[0]); /* index length */
2239
int_32 dl = ntohl (ei[1]); /* data length */
2241
size_t pvlen = sizeof (il) + sizeof (dl) +
2242
(il * sizeof (struct entryInfo)) + dl;
2251
/* Sanity checks on header intro. */
2252
if (hdrchkTags (il) || hdrchkData (dl))
2257
pe = (entryInfo) & ei[2];
2259
dataStart = (char *) (pe + il);
2261
h = calloc (1, sizeof (*h));
2262
memset (h, 0, sizeof (*h));
2263
/*@-assignexpose@ */
2264
/*@=assignexpose@ */
2265
/*@-assignexpose -kepttrans@ */
2267
/*@=assignexpose =kepttrans@ */
2268
h->indexAlloced = il + 1;
2270
h->index = calloc (h->indexAlloced, sizeof (*h->index));
2271
h->flags = HEADERFLAG_SORTED;
2276
* XXX XFree86-libs, ash, and pdksh from Red Hat 5.2 have bogus
2277
* %verifyscript tag that needs to be diddled.
2279
if (ntohl (pe->tag) == 15 &&
2280
ntohl (pe->type) == RPM_STRING_TYPE && ntohl (pe->count) == 1)
2282
pe->tag = htonl (1079);
2286
if (!(htonl (pe->tag) < HEADER_I18NTABLE))
2288
h->flags |= HEADERFLAG_LEGACY;
2289
entry->info.type = REGION_TAG_TYPE;
2290
entry->info.tag = HEADER_IMAGE;
2292
entry->info.count = REGION_TAG_COUNT;
2294
entry->info.offset = ((char *) pe - dataStart); /* negative offset */
2296
/*@-assignexpose@ */
2298
/*@=assignexpose@ */
2299
entry->length = pvlen - sizeof (il) - sizeof (dl);
2301
regionSwab (entry + 1, il, 0, pe, dataStart, entry->info.offset);
2302
#if 0 /* XXX don't check, the 8/98 i18n bug fails here. */
2306
entry->rdlen = rdlen;
2312
int nb = ntohl (pe->count);
2316
h->flags &= ~HEADERFLAG_LEGACY;
2318
entry->info.type = htonl (pe->type);
2319
if (entry->info.type < RPM_MIN_TYPE || entry->info.type > RPM_MAX_TYPE)
2321
entry->info.count = htonl (pe->count);
2323
if (hdrchkTags (entry->info.count))
2327
int off = ntohl (pe->offset);
2329
if (hdrchkData (off))
2333
int_32 *stei = memcpy (alloca (nb), dataStart + off, nb);
2334
rdl = -ntohl (stei[2]); /* negative offset */
2335
ril = rdl / sizeof (*pe);
2336
if (hdrchkTags (ril) || hdrchkData (rdl))
2338
entry->info.tag = htonl (pe->tag);
2344
rdl = (ril * sizeof (struct entryInfo));
2346
entry->info.tag = HEADER_IMAGE;
2349
entry->info.offset = -rdl; /* negative offset */
2351
/*@-assignexpose@ */
2353
/*@=assignexpose@ */
2354
entry->length = pvlen - sizeof (il) - sizeof (dl);
2356
regionSwab (entry + 1, ril - 1, 0, pe + 1, dataStart,
2357
entry->info.offset);
2360
entry->rdlen = rdlen;
2362
if (ril < h->indexUsed)
2364
indexEntry newEntry = entry + ril;
2365
int ne = (h->indexUsed - ril);
2366
int rid = entry->info.offset + 1;
2369
/* Load dribble entries from region. */
2370
rc = regionSwab (newEntry, ne, 0, pe + ril, dataStart, rid);
2376
indexEntry firstEntry = newEntry;
2377
int save = h->indexUsed;
2380
/* Dribble entries replace duplicate region entries. */
2382
for (j = 0; j < ne; j++, newEntry++)
2384
(void) headerRemoveEntry (h, newEntry->info.tag);
2385
if (newEntry->info.tag == HEADER_BASENAMES)
2386
(void) headerRemoveEntry (h, HEADER_OLDFILENAMES);
2389
/* If any duplicate entries were replaced, move new entries down. */
2390
if (h->indexUsed < (save - ne))
2392
memmove (h->index + h->indexUsed, firstEntry,
2393
(ne * sizeof (*entry)));
2400
h->flags &= ~HEADERFLAG_SORTED;
2403
/*@-globstate -observertrans @ */
2405
/*@=globstate =observertrans @ */
2411
h->index = _free (h->index);
2412
/*@-refcounttrans@ */
2414
/*@=refcounttrans@ */
2417
/*@-refcounttrans -globstate@ */
2419
/*@=refcounttrans =globstate@ */
2423
* Read (and load) header from file handle.
2424
* @param fd file handle
2425
* @param magicp read (and verify) 8 bytes of (magic, 0)?
2426
* @return header (or NULL on error)
2430
headerRead (FD_t fd, enum hMagic magicp)
2442
memset (block, 0, sizeof (block));
2444
if (magicp == HEADER_MAGIC_YES)
2447
/*@-type@ *//* FIX: cast? */
2448
if (timedRead (fd, (char *) block, i * sizeof (*block)) !=
2449
(i * sizeof (*block)))
2455
if (magicp == HEADER_MAGIC_YES)
2458
if (memcmp (&magic, header_magic, sizeof (magic)))
2463
il = ntohl (block[i]);
2465
dl = ntohl (block[i]);
2469
len = sizeof (il) + sizeof (dl) + (il * sizeof (struct entryInfo)) + dl;
2472
/* Sanity checks on header intro. */
2473
if (hdrchkTags (il) || hdrchkData (dl) || len > headerMaxbytes)
2479
len -= sizeof (il) + sizeof (dl);
2481
/*@-type@ *//* FIX: cast? */
2482
if (timedRead (fd, (char *) &ei[2], len) != len)
2486
h = headerLoad (ei);
2491
if (h->flags & HEADERFLAG_ALLOCATED)
2493
h->flags |= HEADERFLAG_ALLOCATED;
2497
/*@-mustmod@ *//* FIX: timedRead macro obscures annotation */
2503
* Check package size.
2504
* @todo rpmio: use fdSize rather than fstat(2) to get file size.
2505
* @param fd package file handle
2506
* @param siglen signature header size
2507
* @param pad signature padding
2508
* @param datalen length of header+payload
2509
* @return rpmRC return code
2512
checkSize (FD_t fd, int siglen, int pad, int datalen)
2513
/*@globals fileSystem @ */
2514
/*@modifies fileSystem @ */
2518
rc = (((sizeof (struct rpmlead) + siglen + pad + datalen) - fd->len)
2519
? RPMRC_BADSIZE : RPMRC_OK);
2525
* Create new (empty) header instance.
2532
Header h = calloc (1, sizeof (*h));
2534
memset (h, 0, sizeof (*h));
2535
/*@-assignexpose@ */
2536
/*@=assignexpose@ */
2538
h->indexAlloced = INDEX_MALLOC_SIZE;
2540
h->flags = HEADERFLAG_SORTED;
2542
h->index = (h->indexAlloced
2543
? calloc (h->indexAlloced, sizeof (*h->index)) : NULL);
2545
/*@-globstate -observertrans @ */
2547
return headerLink (h);
2548
/*@=globstate =observertrans @ */
2551
typedef unsigned char byte;
2554
rpmReadSignature (FD_t fd, Header * headerp, sigType sig_type)
2561
rpmRC rc = RPMRC_FAIL; /* assume failure */
2569
case RPMSIGTYPE_NONE:
2572
case RPMSIGTYPE_PGP262_1024:
2573
/* These are always 256 bytes */
2574
if (timedRead (fd, buf, 256) != 256)
2577
(void) headerAddEntry (h, RPMSIGTAG_PGP, RPM_BIN_TYPE, buf, 152);
2580
case RPMSIGTYPE_MD5:
2581
case RPMSIGTYPE_MD5_PGP:
2583
case RPMSIGTYPE_HEADERSIG:
2584
case RPMSIGTYPE_DISABLE:
2585
/* This is a new style signature */
2586
h = headerRead (fd, HEADER_MAGIC_YES);
2591
sigSize = headerSizeof (h, HEADER_MAGIC_YES);
2593
/* XXX Legacy headers have a HEADER_IMAGE tag added. */
2594
if (headerIsEntry (h, RPMTAG_HEADERIMAGE))
2595
sigSize -= (16 + 16);
2597
pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
2598
if (sig_type == RPMSIGTYPE_HEADERSIG)
2600
if (!headerGetEntry (h, RPMSIGTAG_SIZE, &type,
2601
(void **) &archSize, &count))
2603
rc = checkSize (fd, sigSize, pad, *archSize);
2605
if (pad && timedRead (fd, buf, pad) != pad)
2606
rc = RPMRC_SHORTREAD;
2612
if (rc == 0 && headerp)
2624
readLead (FD_t fd, struct rpmlead *lead)
2626
memset (lead, 0, sizeof (*lead));
2627
/*@-type@ *//* FIX: remove timed read */
2628
if (timedRead (fd, (char *) lead, sizeof (*lead)) != sizeof (*lead))
2634
lead->type = ntohs (lead->type);
2635
lead->archnum = ntohs (lead->archnum);
2636
lead->osnum = ntohs (lead->osnum);
2638
if (lead->major >= 2)
2639
lead->signature_type = ntohs (lead->signature_type);
2645
* Retrieve tag value using header internal array.
2646
* Get an entry using as little extra RAM as possible to return the tag value.
2647
* This is only an issue for RPM_STRING_ARRAY_TYPE.
2651
* @retval type address of tag value data type (or NULL)
2652
* @retval p address of pointer to tag value(s) (or NULL)
2653
* @retval c address of number of values (or NULL)
2654
* @return 1 on success, 0 on failure
2657
headerGetEntryMinMemory (Header h, int_32 tag,
2658
/*@null@ *//*@out@ */ hTYP_t type,
2659
/*@null@ *//*@out@ */ hPTR_t * p,
2660
/*@null@ *//*@out@ */ hCNT_t c)
2661
/*@modifies *type, *p, *c @ */
2663
return intGetEntry (h, tag, type, p, c, 1);
2667
* Delete tag in header.
2668
* Removes all entries of type tag from the header, returns 1 if none were
2673
* @return 0 on success, 1 on failure (INCONSISTENT)
2676
headerRemoveEntry (Header h, int_32 tag)
2679
indexEntry last = h->index + h->indexUsed;
2680
indexEntry entry, first;
2683
entry = findEntry (h, tag, RPM_NULL_TYPE);
2687
/* Make sure entry points to the first occurence of this tag. */
2688
while (entry > h->index && (entry - 1)->info.tag == tag)
2691
/* Free data for tags being removed. */
2692
for (first = entry; first < last; first++)
2695
if (first->info.tag != tag)
2700
if (ENTRY_IN_REGION (first))
2702
data = _free (data);
2705
ne = (first - entry);
2711
memmove (entry, first, (ne * sizeof (*entry)));
2718
dncmp (const void *a, const void *b)
2720
const char *const *first = a;
2721
const char *const *second = b;
2722
return strcmp (*first, *second);
2726
compressFilelist (Header h)
2728
HGE_t hge = (HGE_t) headerGetEntryMinMemory;
2729
HAE_t hae = (HAE_t) headerAddEntry;
2730
HRE_t hre = (HRE_t) headerRemoveEntry;
2731
HFD_t hfd = headerFreeData;
2733
const char **dirNames;
2734
const char **baseNames;
2742
* This assumes the file list is already sorted, and begins with a
2743
* single '/'. That assumption isn't critical, but it makes things go
2747
if (headerIsEntry (h, RPMTAG_DIRNAMES))
2749
(void) hre (h, RPMTAG_OLDFILENAMES);
2750
return; /* Already converted. */
2753
if (!hge (h, RPMTAG_OLDFILENAMES, &fnt, (void **) &fileNames, &count))
2754
return; /* no file list */
2755
if (fileNames == NULL || count <= 0)
2758
dirNames = alloca (sizeof (*dirNames) * count); /* worst case */
2759
baseNames = alloca (sizeof (*dirNames) * count);
2760
dirIndexes = alloca (sizeof (*dirIndexes) * count);
2762
if (fileNames[0][0] != '/')
2764
/* HACK. Source RPM, so just do things differently */
2766
dirNames[dirIndex] = "";
2767
for (i = 0; i < count; i++)
2769
dirIndexes[i] = dirIndex;
2770
baseNames[i] = fileNames[i];
2775
for (i = 0; i < count; i++)
2777
const char **needle;
2782
if (fileNames[i] == NULL) /* XXX can't happen */
2784
baseName = strrchr (fileNames[i], '/') + 1;
2785
len = baseName - fileNames[i];
2787
savechar = *baseName;
2791
bsearch (&fileNames[i], dirNames, dirIndex + 1,
2792
sizeof (dirNames[0]), dncmp)) == NULL)
2794
char *s = alloca (len + 1);
2795
memcpy (s, fileNames[i], len + 1);
2797
dirIndexes[i] = ++dirIndex;
2798
dirNames[dirIndex] = s;
2801
dirIndexes[i] = needle - dirNames;
2803
*baseName = savechar;
2804
baseNames[i] = baseName;
2810
(void) hae (h, RPMTAG_DIRINDEXES, RPM_INT32_TYPE, dirIndexes, count);
2811
(void) hae (h, RPMTAG_BASENAMES, RPM_STRING_ARRAY_TYPE,
2813
(void) hae (h, RPMTAG_DIRNAMES, RPM_STRING_ARRAY_TYPE,
2814
dirNames, dirIndex + 1);
2817
fileNames = hfd (fileNames, fnt);
2819
(void) hre (h, RPMTAG_OLDFILENAMES);
2823
headerNVR (Header h, const char **np, const char **vp, const char **rp)
2830
if (!(headerGetEntry (h, RPMTAG_NAME, &type, (void **) np, &count)
2831
&& type == RPM_STRING_TYPE && count == 1))
2836
if (!(headerGetEntry (h, RPMTAG_VERSION, &type, (void **) vp, &count)
2837
&& type == RPM_STRING_TYPE && count == 1))
2842
if (!(headerGetEntry (h, RPMTAG_RELEASE, &type, (void **) rp, &count)
2843
&& type == RPM_STRING_TYPE && count == 1))
2850
* Up to rpm 3.0.4, packages implicitly provided their own name-version-release.
2851
* Retrofit an explicit "Provides: name = epoch:version-release.
2854
providePackageNVR (Header h)
2856
HGE_t hge = (HGE_t) headerGetEntryMinMemory;
2857
HFD_t hfd = headerFreeData;
2858
const char *name, *version, *release;
2862
int_32 pFlags = RPMSENSE_EQUAL;
2863
const char **provides = NULL;
2864
const char **providesEVR = NULL;
2865
rpmTagType pnt, pvt = RPM_NULL_TYPE;
2866
int_32 *provideFlags = NULL;
2871
/* Generate provides for this package name-version-release. */
2872
(void) headerNVR (h, &name, &version, &release);
2873
if (!(name && version && release))
2875
pEVR = p = alloca (21 + strlen (version) + 1 + strlen (release) + 1);
2877
if (hge (h, RPMTAG_EPOCH, NULL, (void **) &epoch, NULL))
2879
sprintf (p, "%d:", *epoch);
2883
(void) my_stpcpy (my_stpcpy (my_stpcpy (p, version), "-"), release);
2886
* Rpm prior to 3.0.3 does not have versioned provides.
2887
* If no provides at all are available, we can just add.
2889
if (!hge (h, RPMTAG_PROVIDENAME, &pnt, (void **) &provides, &providesCount))
2893
* Otherwise, fill in entries on legacy packages.
2895
if (!hge (h, RPMTAG_PROVIDEVERSION, &pvt, (void **) &providesEVR, NULL))
2897
for (i = 0; i < providesCount; i++)
2900
int_32 fdummy = RPMSENSE_ANY;
2901
(void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEVERSION,
2902
RPM_STRING_ARRAY_TYPE, &vdummy, 1);
2903
(void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEFLAGS,
2904
RPM_INT32_TYPE, &fdummy, 1);
2909
(void) hge (h, RPMTAG_PROVIDEFLAGS, NULL, (void **) &provideFlags, NULL);
2911
if (provides && providesEVR && provideFlags)
2912
for (i = 0; i < providesCount; i++)
2914
if (!(provides[i] && providesEVR[i]))
2916
if (!(provideFlags[i] == RPMSENSE_EQUAL &&
2917
!strcmp (name, provides[i]) && !strcmp (pEVR, providesEVR[i])))
2924
provides = hfd (provides, pnt);
2925
providesEVR = hfd (providesEVR, pvt);
2929
(void) headerAddOrAppendEntry (h, RPMTAG_PROVIDENAME,
2930
RPM_STRING_ARRAY_TYPE, &name, 1);
2931
(void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEFLAGS, RPM_INT32_TYPE,
2933
(void) headerAddOrAppendEntry (h, RPMTAG_PROVIDEVERSION,
2934
RPM_STRING_ARRAY_TYPE, &pEVR, 1);
2938
static Header rpmFreeSignature (Header h);
2941
* Retrieve package components from file handle.
2942
* @param fd file handle
2943
* @param leadPtr address of lead (or NULL)
2944
* @param sigs address of signatures (or NULL)
2945
* @param hdrPtr address of header (or NULL)
2946
* @return rpmRC return code
2949
readPackageHeaders (FD_t fd,
2950
/*@null@ *//*@out@ */ struct rpmlead *leadPtr,
2951
/*@null@ *//*@out@ */ Header * sigs,
2952
/*@null@ *//*@out@ */ Header * hdrPtr)
2953
/*@modifies fd, *leadPtr, *sigs, *hdrPtr @ */
2956
struct rpmlead leadBlock;
2958
struct rpmlead *lead;
2959
char *defaultPrefix;
2962
hdr = hdrPtr ? hdrPtr : &hdrBlock;
2963
lead = leadPtr ? leadPtr : &leadBlock;
2965
if (readLead (fd, lead))
2968
if (lead->magic[0] != RPMLEAD_MAGIC0 || lead->magic[1] != RPMLEAD_MAGIC1 ||
2969
lead->magic[2] != RPMLEAD_MAGIC2 || lead->magic[3] != RPMLEAD_MAGIC3)
2971
return RPMRC_BADMAGIC;
2974
switch (lead->major)
2978
/*@notreached@ */ break;
2982
rc = rpmReadSignature (fd, sigs, lead->signature_type);
2983
if (rc == RPMRC_FAIL)
2985
*hdr = headerRead (fd, (lead->major >= 3)
2986
? HEADER_MAGIC_YES : HEADER_MAGIC_NO);
2990
*sigs = rpmFreeSignature (*sigs);
2995
* We don't use these entries (and rpm >= 2 never has) and they are
2996
* pretty misleading. Let's just get rid of them so they don't confuse
2999
if (headerIsEntry (*hdr, RPMTAG_FILEUSERNAME))
3000
(void) headerRemoveEntry (*hdr, RPMTAG_FILEUIDS);
3001
if (headerIsEntry (*hdr, RPMTAG_FILEGROUPNAME))
3002
(void) headerRemoveEntry (*hdr, RPMTAG_FILEGIDS);
3005
* We switched the way we do relocateable packages. We fix some of
3006
* it up here, though the install code still has to be a bit
3007
* careful. This fixup makes queries give the new values though,
3008
* which is quite handy.
3010
if (headerGetEntry (*hdr, RPMTAG_DEFAULTPREFIX, NULL,
3011
(void **) &defaultPrefix, NULL))
3014
stripTrailingChar (alloca_strdup (defaultPrefix), '/');
3015
(void) headerAddEntry (*hdr, RPMTAG_PREFIXES, RPM_STRING_ARRAY_TYPE,
3020
* The file list was moved to a more compressed format which not
3021
* only saves memory (nice), but gives fingerprinting a nice, fat
3022
* speed boost (very nice). Go ahead and convert old headers to
3023
* the new style (this is a noop for new headers).
3025
if (lead->major < 4)
3026
compressFilelist (*hdr);
3028
/* XXX binary rpms always have RPMTAG_SOURCERPM, source rpms do not */
3029
if (lead->type == RPMLEAD_SOURCE)
3032
if (!headerIsEntry (*hdr, RPMTAG_SOURCEPACKAGE))
3033
(void) headerAddEntry (*hdr, RPMTAG_SOURCEPACKAGE, RPM_INT32_TYPE,
3036
else if (lead->major < 4)
3038
/* Retrofit "Provide: name = EVR" for binary packages. */
3039
providePackageNVR (*hdr);
3045
/*@notreached@ */ break;
3049
*hdr = headerFree (*hdr);
3055
headerMergeLegacySigs (Header h, const Header sig)
3057
HFD_t hfd = (HFD_t) headerFreeData;
3058
HAE_t hae = (HAE_t) headerAddEntry;
3060
int_32 tag, type, count;
3063
/*@-mods@ *//* FIX: undocumented modification of sig */
3064
for (hi = headerInitIterator (sig);
3066
headerNextIterator (hi, &tag, &type, &ptr, &count, 0);
3067
ptr = hfd (ptr, type))
3071
case RPMSIGTAG_SIZE:
3072
tag = RPMTAG_SIGSIZE;
3073
/*@switchbreak@ */ break;
3074
case RPMSIGTAG_LEMD5_1:
3075
tag = RPMTAG_SIGLEMD5_1;
3076
/*@switchbreak@ */ break;
3078
tag = RPMTAG_SIGPGP;
3079
/*@switchbreak@ */ break;
3080
case RPMSIGTAG_LEMD5_2:
3081
tag = RPMTAG_SIGLEMD5_2;
3082
/*@switchbreak@ */ break;
3084
tag = RPMTAG_SIGMD5;
3085
/*@switchbreak@ */ break;
3087
tag = RPMTAG_SIGGPG;
3088
/*@switchbreak@ */ break;
3089
case RPMSIGTAG_PGP5:
3090
tag = RPMTAG_SIGPGP5;
3091
/*@switchbreak@ */ break;
3092
case RPMSIGTAG_PAYLOADSIZE:
3093
tag = RPMTAG_ARCHIVESIZE;
3094
/*@switchbreak@ */ break;
3095
case RPMSIGTAG_SHA1:
3099
if (!(tag >= HEADER_SIGBASE && tag < HEADER_TAGBASE))
3101
/*@switchbreak@ */ break;
3104
continue; /* XXX can't happen */
3105
if (!headerIsEntry (h, tag))
3106
hae (h, tag, type, ptr, count);
3108
hi = headerFreeIterator (hi);
3112
rpmFreeSignature (Header h)
3114
return headerFree (h);
3118
rpmReadPackageHeader (FD_t fd, Header * hdrp, int *isSource, int *major,
3121
struct rpmlead lead;
3123
rpmRC rc = readPackageHeaders (fd, &lead, &sig, hdrp);
3128
if (hdrp && *hdrp && sig)
3130
headerMergeLegacySigs (*hdrp, sig);
3131
sig = rpmFreeSignature (sig);
3135
*isSource = lead.type == RPMLEAD_SOURCE;
3138
*major = lead.major;
3140
*minor = lead.minor;
3148
/* ******************** real libextractor stuff ************************ */
40
pipe_feeder(void * args)
43
struct PipeArgs * p = args;
45
while ( (p->shutdown == 0) &&
46
(0 < (ret = WRITE(p->pi[1],
55
sigalrmHandler (int sig)
61
/* *************** real libextractor stuff ***************** */
3150
63
static struct EXTRACTOR_Keywords *
3151
64
addKeyword (EXTRACTOR_KeywordType type,
3152
char *keyword, struct EXTRACTOR_Keywords *next)
65
const char *keyword, struct EXTRACTOR_Keywords *next)
3154
67
EXTRACTOR_KeywordList *result;