-->
Page 326
The functions in this section provide the basic operations necessary to manipulate header entries. The following header entry types are currently defined:
This function retrieves the entry matching tag from header h:
#include <rpm/rpmlib.h> #include <rpm/header.h> int headerGetEntry(Header h, int_32 tag, int_32 *type, void **p, int_32 *c);
The type of the entry is returned in type, a pointer to the data is returned in p, and the size of the data is returned in c. Both type and c may be NULL, in which case that data will not be returned. Note that if the entry type is RPM_STRING_ARRAY_TYPE, you must issue a free() on p when done with the data.
This function returns 1 on success, and 0 on failure.
This function adds a new entry to the header h:
#include <rpm/rpmlib.h> #include <rpm/header.h> int headerAddEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c);
The entry's tag is specified by the tag parameter, and the entry's type is specified by the type parameter.
Page 327
The entry's data is pointed to by p, and the size of the data is specified by c. This function always returns 1.
NOTE |
In versions of RPM prior to 2.3.3, headerAddEntry() will only work successfully with headers produced by headerCopy() and headerNew(). In particular, headerAddEntry() is not supported when used to add entries to a header produced by headerRead(). Later versions of RPM lift this restriction. |
This function returns 1 if an entry with tag tag is present in header h. If the tag is not present, this function returns 0:
#include <rpm/rpmlib.h> #include <rpm/header.h> int headerIsEntry(Header h, int_32 tag);
Iterators are used as a means to step from entry to entry, through an entire header. The functions in this section are used to create, use, and free iterators.
This function returns a newly created iterator for the header h:
#include <rpm/rpmlib.h> #include <rpm/header.h> HeaderIterator headerInitIterator(Header h);
This function steps to the next entry in the header specified when the iterator iter was created with headerInitIterator():
#include <rpm/rpmlib.h> #include <rpm/header.h> int headerNextIterator(HeaderIterator iter, int_32 *tag, int_32 *type, void **p, int_32 *c);
Page 328
The next entry's tag, type, data, and size are returned in tag, type, p, and c, respectively. Note that if the entry type is RPM_STRING_ARRAY_TYPE, you must issue a free() on p when done with the data.
This function returns 1 if successful, and 0 if there are no more entries in the header.
This function frees the resources used by the iterator iter:
#include <rpm/rpmlib.h> #include <rpm/header.h> void headerFreeIterator(HeaderIterator iter);
In this section, we'll study sample programs that make use of rpmlib to perform an assortment of commonly required operations. We'll intersperse sections of code with a running commentary to minimize page turning.
In this example, we'll use a number of rpmlib's header-manipulation functions.
Here we've included rpmlib.h, which is necessary for all programs that use rpmlib:
#include <errno.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <rpm/rpmlib.h>
Here we've defined the program's storage. Note in particular the HeaderIterator, Header, and int_32 data types:
void main(int argc, char ** argv) { HeaderIterator iter; Header h, sig; int_32 itertag, type, count; void **p = NULL; char *blather; char * name; int fd, stat;
Page 329
Standard stuff here. The first argument is supposed to be an RPM package file. It is opened here. If there is no argument on the command line, the program will use stdin instead:
if (argc == 1) { fd = 0; } else { fd = open(argv[1], O_RDONLY, 0644); } if (fd < 0) { perror("open"); exit(1); }
Here things start to get interesting! The signature and headers are read from the package file that was just opened. Notice in the preceding code that we've defined sig and h to be of type Header. That means we can use rpmlib's header-related functions on them. After a little bit of error checking, it's time to move on .
stat = rpmReadPackageInfo(fd, &sig, &h); if (stat) { fprintf(stderr, "rpmReadPackageInfo error status: %d\n%s\n", stat, strerror(errno)); exit(stat); }
Now that we have the package's header, we get the package name (specified by the RPMTAG_NAME in the call to headerGetEntry). Next, we see if the package has preinstall (RPMTAG_PREIN) or postinstall (RPMTAG_POSTIN) scripts. If it does, we print out a message, along with the package name:
headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count); if (headerIsEntry(h, RPMTAG_PREIN)) { printf("There is a preinstall script for %s\n", name); } if (headerIsEntry(h, RPMTAG_POSTIN)) { printf("There is a postinstall script for %s\n", name); }
Turning to the other Header structure we've read, we print out the package's signatures in human-readable form. When we're done, we free the block of signatures:
printf("Dumping signatures...\n"); headerDump(sig, stdout, 1); rpmFreeSignature(sig);
Here we set up an iterator for the package's header. This will allow us to step through each entry in the header:
printf("Iterating through the header...\n"); iter = headerInitIterator(h);