Product SiteDocumentation Site

15.4.2. Dependency Sets

To compare package versions, create a dependency set. The rpm command, for example, uses dependency sets to compare package versions.
Note
You could compare the version numbers directly, calling headerGetEntry to get the version and release tags, converting these strings to numbers and then comparing, but this would cause problems. The custom comparison is not as exact as the code in this section, especially since many packages have version numbers that are not true numbers, such as 1.12.4, with one too many decimal points. This makes the comparisons harder. In addition, there is more than just the version number to take into account. You need to deal with the Epoch value, as well as the release, too.
To handle all the complicated logic of comparing versions, you can use the code in this section, or call rpmvercmp. Do not try to compare version numbers with custom code.
To create a dependency set for a given package Header, call rpmdsThis. Calling rpmdsThis creates a dependency set that holds a triple of the package name, the Epoch/Version/Release information, and the flags.
rpmds rpmdsThis(Header header,
rpmTag tagID,
int_32 Flags);
For comparing packages, you can pass RPMTAG_REQUIRENAME for the tagID. The actual tagID here is ignored for the version check. What you do need, though, are flags to check whether another package is less than or equal to the Epoch/Version/Release information in this dependency set. For this task, pass the following bit flags:
(RPMSENSE_EQUAL|RPMSENSE_LESS)
Once you have a dependency set, you can use the handy function rpmdsNVRMatchesDep to compare the NVR, or Name, Version, Release entries in the header of one package against the data in the dependency set.
int rpmdsNVRMatchesDep(const Header header,
const rpmds dependency_set,
int nopromote);
After checking the dependencies, rpmdsNVRMatchesDep returns 1 if the dependency overlaps, or 0 otherwise. In terms of comparing packages, 1 means that the package file is as old or older than the installed package, and 0 means that the package already installed is newer. Pass 1 to prevent promoting the Epoch value in the packages during the comparison.
The actual comparison is controlled by the call that creates the dependency set, especially the flags. Thus, passing flags of (RPMSENSE_EQUAL|RPMSENSE_LESS) to rpmdsThis set up the test as a less than or equal test.
Note
The RPM C API documentation marks rpmdsNVRMatchesDep as deprecated, to be replaced in the future.
You can also call rpmVersionCompare to compare the versions of two packages:
int rpmVersionCompare(Header header1, Header header2);
The return value is -1 if the header1 represents an older version than header2, 0 if the two headers represent the same version, and 1 if header1 represents a newer version than header2.
To get the name of the package from a dependency set, call rpmdsN:
const char* rpmdsN(const rpmds dependency_set);
You can use rpmdsN to get the name when calling rpmtsInitIterator if you are working with dependency sets when searching the RPM database.
Free a dependency set when done by calling rpmdsFree:
rpmds rpmdsFree(rpmds dependency_set);
As with other free functions, rpmdsFree returns NULL.