Product SiteDocumentation Site

15.4. Programming with the RPM Database

Many functions in rpmlib require a transaction set. In particular, accessing the rpm database is quite easy using a transaction set.
Create a transaction set by calling rpmtsCreate:
rpmts rpmtsCreate(void);
RPM uses transaction sets to bracket operations on the RPM database. As the RPM API evolves, transaction sets will become more and more important. Transaction sets also help in that the RPM library will automatically open the RPM database as needed.
When you are done with a transaction set, call rpmtsFree:
rpmts rpmtsFree(rpmts ts);
The call to rpmtsFree returns NULL.

15.4.1. Database iterators

Once you have a transaction set, you can iterate over the installed packages in the RPM database by creating an iterator. To do this, call rpmtsInitIterator:
rpmdbMatchIterator rpmtsInitIterator(const rpmts ts,
rpmTag rpmtag,
const void *keypointer,
size_t keylen);
You need to specify which tag to iterate by, which in most cases will be the package name, RPMTAG_NAME, introduced previously With the RPMTAG_NAME tag, you need to pass the name of a package to look for in the keypointer parameter. (The keypointer varies based on the tag you pass.)
For string data, you can pass 0 for the keylen parameter. For example, this call to rpmtsInitIterator looks for all packages named sendmail.
rpmdbMatchIterator iter;
iter = rpmtsInitIterator(ts, RPMTAG_NAME, "sendmail", 0);
The rpmdbMatchIterator allows you to iterate through a number of packages, in this case, all the packages that match a given name. After calling rpmtsInitIterator, the next step is to call rpmdbNextIterator:
Header rpmdbNextIterator(rpmdbMatchIterator iter);
This function returns the next package Header object in the iterator. The Header will be NULL if there are no more packages in the iterator.
If the Header is not NULL, you can get entries from it, as shown previously. You can use a while loop to go through all the matching packages. For example:
while ( (installed_header = rpmdbNextIterator(iter) ) != NULL) {
/* Do something... */
}
Note
In future versions of the RPM library, rpmtsNextIterator, will replace rpmdbNextIterator.
You do not need to free the Header returned by rpmdbNextIterator. Also, the next call to rpmdbNextIterator will reset the Header.
You can customize how an iterator works by adding a pattern to the iterator with rpmdbSetIteratorRE:
int rpmdbSetIteratorRE(rpmdbMatchIterator iter,
rpmTag tag,
rpmMireMode mode,
const char * pattern);
Calling rpmdbSetIteratorRE modifies the passed-in iterator to use the given pattern as a further test on the given tag. The mode parameter names the type of pattern used, which can be one of those listed in Table 16-9.
Table 16-9 Types of patterns for rpmdbSetIteratorRE
Type
Meaning
RPMMIRE_DEFAULT
Same as regular expressions but with \., .*, and ^..$ added.
RPMMIRE_GLOB
Glob-style patterns using fnmatch.
RPMMIRE_REGEX
Regular expressions using regcomp.
RPMMIRE_STRCMP
String comparisons using strcmp.
Cross Reference
For more on these patterns, see the online manual pages for fnmatch(3), glob(7), regcomp(3), regex(7), and strcmp(3).
Free the iterator when done with rpmdbFreeIterator:
rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator iter);
The call to rpmdbFreeIterator returns NULL.