Product SiteDocumentation Site

15.3.3. Reading header information

The header information includes the package name, version, pre- and post-installation scripts, and so on. To read in the RPM header, call headerRead. If successful, headerRead returns a Header object. You can then read data values from the Header.
Header headerRead(FD_t fd,
enum hMagic magicp);
Note
When working with the RPM database, you will also use Header objects.
The trickiest thing about calling headerRead is that you must pass a special magic number flag. This value must be HEADER_MAGIC_YES if the header has a set of magic numbers, and HEADER_MAGIC_NO if not. If you guess incorrectly, headerRead will return an error. To get around, this, you can compare the major number in the lead. For example:
Header header = headerRead(fd, (lead.major >= 3) ?
HEADER_MAGIC_YES : HEADER_MAGIC_NO);
Note
This snippet is one of the gems you'll find when you browse the RPM source code. Use the source.
To read values from the Header, call headerGetEntry. To call headerGetEntry, you pass in a Header and a tag ID. You get back the type of the tag, a pointer to the tag values, and a count of the number of values stored under this tag.
int headerGetEntry(Header header,
int_32 tag,
hTYP_t type,
void **pointer,
hCNT_t data_size);
The call to headerGetEntry returns a 1 on success, or a 0 on failure. On success, the pointer will point at the retrieved data, with the type parameter set to one of the following enum values:
enum rpmTagType_e {
RPM_NULL_TYPE = 0,
RPM_CHAR_TYPE = 1,
RPM_INT8_TYPE = 2,
RPM_INT16_TYPE = 3,
RPM_INT32_TYPE = 4,
RPM_STRING_TYPE = 6,
RPM_BIN_TYPE = 7,
RPM_STRING_ARRAY_TYPE = 8,
RPM_I18NSTRING_TYPE
}
Note
If the type is RPM_STRING_ARRAY_TYPE or RPM_BIN_TYPE, you must free the pointer. Call headerFreeData to free the data:
void* headerFreeData(const void *pointer,
rpmTagType type);
You need to pass in the data pointer and the type flag. You can safely call headerFreeData for all types. The function will do nothing if the type is not set up to require freeing.
When you call headerGetEntry, you must identify the tag you want from the header. This tag is an identifier for the --queryformat tags introduced in Chapter 4, Using the RPM Database . The file rpmlib.h lists the various tags, such as RPMTAG_NAME, RPMTAG_VERSION, and RPMTAG_RELEASE.
The following function shows how to read a string entry from a Header:
/* Function to read a string header entry. */
char* readHeaderString(Header header, int_32 tag_id) {
int_32 type;
void* pointer;
int_32 data_size;
int header_status = headerGetEntry(header,
tag_id,
&type,
&pointer,
&data_size);
if (header_status) {
if (type == RPM_STRING_TYPE) {
return pointer;
}
}
return NULL;
}
Pass the Header object and the ID of the tag to read. For example:
char* name = readHeaderString(header, RPMTAG_NAME);
char* version = readHeaderString(header, RPMTAG_VERSION);
char* release = readHeaderString(header, RPMTAG_RELEASE);
To just get the name, version, and release number, you can call the utility function headerNVR, which has the following function signature:
int headerNVR(Header header,
const char **nameptr,
const char **versionptr,
const char **releaseptr);
When you are through with a header, free it by calling headerFree:
Header headerFree(Header header);
The call to headerFree returns NULL, so you can use the call to set the original pointer to to NULL to prevent accidental reuse. For example:
header = headerFree(header);