summaryrefslogtreecommitdiff
path: root/lib/tagexts.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tagexts.c')
-rw-r--r--lib/tagexts.c186
1 files changed, 175 insertions, 11 deletions
diff --git a/lib/tagexts.c b/lib/tagexts.c
index 563c1b43c..00b500c26 100644
--- a/lib/tagexts.c
+++ b/lib/tagexts.c
@@ -272,6 +272,7 @@ static char * strtolocale(char *str)
locisutf8 = 0;
if (locisutf8 == strisutf8) {
wstr = _free(wstr);
+ cc = _free(cc);
return str;
}
str = _free((char *)str);
@@ -300,28 +301,65 @@ static char * strtolocale(char *str)
return (char *)cc;
}
+typedef enum tMode_e {
+ NORMALTRIGGER = 0,
+ FILETRIGGER = 1,
+ TRANSFILETRIGGER = 2,
+} tMode;
+
/**
* Retrieve trigger info.
+ * @param mode type of trigger (see tMode_e)
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
-static int triggercondsTag(Header h, rpmtd td, headerGetFlags hgflags)
+static int triggercondsTagFor(tMode mode, Header h, rpmtd td,
+ headerGetFlags hgflags)
{
uint32_t * indices;
int i, j;
char ** conds;
struct rpmtd_s nametd, indextd, flagtd, versiontd, scripttd;
int hgeflags = HEADERGET_MINMEM;
+ rpmTagVal triggername, triggerindex, triggerflags;
+ rpmTagVal triggerversion, triggerscripts;
+
+ switch (mode) {
+ case NORMALTRIGGER:
+ triggername = RPMTAG_TRIGGERNAME;
+ triggerindex = RPMTAG_TRIGGERINDEX;
+ triggerflags = RPMTAG_TRIGGERFLAGS;
+ triggerversion = RPMTAG_TRIGGERVERSION;
+ triggerscripts = RPMTAG_TRIGGERSCRIPTS;
+ break;
+ case FILETRIGGER:
+ triggername = RPMTAG_FILETRIGGERNAME;
+ triggerindex = RPMTAG_FILETRIGGERINDEX;
+ triggerflags = RPMTAG_FILETRIGGERFLAGS;
+ triggerversion = RPMTAG_FILETRIGGERVERSION;
+ triggerscripts = RPMTAG_FILETRIGGERSCRIPTS;
+ break;
+ case TRANSFILETRIGGER:
+ triggername = RPMTAG_TRANSFILETRIGGERNAME;
+ triggerindex = RPMTAG_TRANSFILETRIGGERINDEX;
+ triggerflags = RPMTAG_TRANSFILETRIGGERFLAGS;
+ triggerversion = RPMTAG_TRANSFILETRIGGERVERSION;
+ triggerscripts = RPMTAG_TRANSFILETRIGGERSCRIPTS;
+ break;
+ default:
+ return 0;
+ }
- if (!headerGet(h, RPMTAG_TRIGGERNAME, &nametd, hgeflags)) {
+ if (!headerGet(h, triggername, &nametd, hgeflags)) {
return 0;
}
- headerGet(h, RPMTAG_TRIGGERINDEX, &indextd, hgeflags);
- headerGet(h, RPMTAG_TRIGGERFLAGS, &flagtd, hgeflags);
- headerGet(h, RPMTAG_TRIGGERVERSION, &versiontd, hgeflags);
- headerGet(h, RPMTAG_TRIGGERSCRIPTS, &scripttd, hgeflags);
+ headerGet(h, triggerindex, &indextd, hgeflags);
+ headerGet(h, triggerflags, &flagtd, hgeflags);
+ headerGet(h, triggerversion, &versiontd, hgeflags);
+ headerGet(h, triggerscripts, &scripttd, hgeflags);
td->type = RPM_STRING_ARRAY_TYPE;
td->flags = RPMTD_ALLOCED | RPMTD_PTR_ALLOCED;
@@ -370,24 +408,63 @@ static int triggercondsTag(Header h, rpmtd td, headerGetFlags hgflags)
return 1;
}
+static int triggercondsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggercondsTagFor(NORMALTRIGGER, h, td, hgflags);
+}
+
+static int filetriggercondsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggercondsTagFor(FILETRIGGER, h, td, hgflags);
+}
+
+static int transfiletriggercondsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggercondsTagFor(TRANSFILETRIGGER, h, td, hgflags);
+}
+
/**
* Retrieve trigger type info.
+ * @param mode type of trigger (see tMode_e)
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
-static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
+static int triggertypeTagFor(tMode mode, Header h, rpmtd td,
+ headerGetFlags hgflags)
{
int i;
char ** conds;
struct rpmtd_s indices, flags, scripts;
+ rpmTagVal triggerindex, triggerflags, triggerscripts;
+
+ switch (mode) {
+ case NORMALTRIGGER:
+ triggerindex = RPMTAG_TRIGGERINDEX;
+ triggerflags = RPMTAG_TRIGGERFLAGS;
+ triggerscripts = RPMTAG_TRIGGERSCRIPTS;
+ break;
+ case FILETRIGGER:
+ triggerindex = RPMTAG_FILETRIGGERINDEX;
+ triggerflags = RPMTAG_FILETRIGGERFLAGS;
+ triggerscripts = RPMTAG_FILETRIGGERSCRIPTS;
+ break;
+ case TRANSFILETRIGGER:
+ triggerindex = RPMTAG_TRANSFILETRIGGERINDEX;
+ triggerflags = RPMTAG_TRANSFILETRIGGERFLAGS;
+ triggerscripts = RPMTAG_TRANSFILETRIGGERSCRIPTS;
+ break;
+ default:
+ return 0;
+ }
- if (!headerGet(h, RPMTAG_TRIGGERINDEX, &indices, HEADERGET_MINMEM)) {
+ if (!headerGet(h, triggerindex, &indices, HEADERGET_MINMEM)) {
return 0;
}
- headerGet(h, RPMTAG_TRIGGERFLAGS, &flags, HEADERGET_MINMEM);
- headerGet(h, RPMTAG_TRIGGERSCRIPTS, &scripts, HEADERGET_MINMEM);
+ headerGet(h, triggerflags, &flags, HEADERGET_MINMEM);
+ headerGet(h, triggerscripts, &scripts, HEADERGET_MINMEM);
td->flags = RPMTD_ALLOCED | RPMTD_PTR_ALLOCED;
td->count = rpmtdCount(&scripts);
@@ -423,20 +500,38 @@ static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
return 1;
}
+static int triggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggertypeTagFor(NORMALTRIGGER, h, td, hgflags);
+}
+
+static int filetriggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggertypeTagFor(FILETRIGGER, h, td, hgflags);
+}
+
+static int transfiletriggertypeTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return triggertypeTagFor(TRANSFILETRIGGER, h, td, hgflags);
+}
+
/**
* Retrieve installed file paths.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int instfilenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
{
return fnTag(h, RPMTAG_BASENAMES, 1, td);
}
+
/**
* Retrieve file paths.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int filenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -448,6 +543,7 @@ static int filenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
* Retrieve original file paths (wrt relocation).
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int origfilenamesTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -498,6 +594,7 @@ static char *makeFClass(rpmfi fi)
* Retrieve/generate file classes.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int fileclassTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -528,6 +625,7 @@ static int fileclassTag(Header h, rpmtd td, headerGetFlags hgflags)
* Retrieve file provides.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int fileprovideTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -539,6 +637,7 @@ static int fileprovideTag(Header h, rpmtd td, headerGetFlags hgflags)
* Retrieve file requires.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int filerequireTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -560,6 +659,7 @@ static const char * const _macro_i18ndomains = "%{?_i18ndomains}";
* @param h header
* @param tag tag
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int i18nTag(Header h, rpmTag tag, rpmtd td, headerGetFlags hgflags)
@@ -655,6 +755,7 @@ static int localeTag(Header h, rpmTag tag, rpmtd td)
* Retrieve summary text.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int summaryTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -666,6 +767,7 @@ static int summaryTag(Header h, rpmtd td, headerGetFlags hgflags)
* Retrieve description text.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int descriptionTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -687,6 +789,7 @@ static int changelogtextTag(Header h, rpmtd td)
* Retrieve group text.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int groupTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -733,6 +836,7 @@ static int get64(Header h, rpmtd td, rpmTag newtag, rpmTag oldtag)
* Retrieve file sizes as 64bit regardless of how they're stored.
* @param h header
* @retval td tag data container
+ * @param hgflags header get flags
* @return 1 on success
*/
static int longfilesizesTag(Header h, rpmtd td, headerGetFlags hgflags)
@@ -799,7 +903,7 @@ typedef rpmFlags nevraFlags;
static int getNEVRA(Header h, rpmtd td, nevraFlags flags)
{
const char *val = NULL;
- char *res = NULL;
+ char *res = xstrdup("");
if ((flags & NEVRA_NAME)) {
val = headerGetString(h, RPMTAG_NAME);
@@ -906,11 +1010,63 @@ static int depnevrsTag(Header h, rpmtd td, headerGetFlags hgflags,
return (ndeps > 0);
}
+#define RPMSENSE_STRONG (1 << 27)
+
+static int depnevrsTagFiltered(Header h, rpmtd td, headerGetFlags hgflags,
+ rpmTagVal tag, int strong)
+{
+ rpmds ds = rpmdsNew(h, tag, 0);
+ int ndeps = rpmdsCount(ds);
+
+ if (ndeps > 0) {
+ char **deps = xmalloc(sizeof(*deps) * ndeps);
+ ndeps = 0;
+ while (rpmdsNext(ds) >= 0) {
+ if ((rpmdsFlags(ds) & RPMSENSE_STRONG) == (strong ? RPMSENSE_STRONG : 0))
+ deps[ndeps++] = rpmdsNewDNEVR(NULL, ds);
+ }
+ if (ndeps) {
+ td->data = deps;
+ td->type = RPM_STRING_ARRAY_TYPE;
+ td->count = ndeps;
+ td->flags |= (RPMTD_ALLOCED | RPMTD_PTR_ALLOCED);
+ } else {
+ _free(deps);
+ }
+ }
+ rpmdsFree(ds);
+ return (ndeps > 0);
+}
+
static int requirenevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
{
return depnevrsTag(h, td, hgflags, RPMTAG_REQUIRENAME);
}
+static int recommendnevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return depnevrsTag(h, td, hgflags, RPMTAG_RECOMMENDNAME) ||
+ depnevrsTagFiltered(h, td, hgflags, RPMTAG_OLDSUGGESTSNAME, 1);
+}
+
+static int suggestnevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return depnevrsTag(h, td, hgflags, RPMTAG_SUGGESTNAME) ||
+ depnevrsTagFiltered(h, td, hgflags, RPMTAG_OLDSUGGESTSNAME, 0);
+}
+
+static int supplementnevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return depnevrsTag(h, td, hgflags, RPMTAG_SUPPLEMENTNAME) ||
+ depnevrsTagFiltered(h, td, hgflags, RPMTAG_OLDENHANCESNAME, 1);
+}
+
+static int enhancenevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
+{
+ return depnevrsTag(h, td, hgflags, RPMTAG_ENHANCENAME) ||
+ depnevrsTagFiltered(h, td, hgflags, RPMTAG_OLDENHANCESNAME, 0);
+}
+
static int providenevrsTag(Header h, rpmtd td, headerGetFlags hgflags)
{
return depnevrsTag(h, td, hgflags, RPMTAG_PROVIDENAME);
@@ -957,7 +1113,11 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
{ RPMTAG_FILEPROVIDE, fileprovideTag },
{ RPMTAG_FILEREQUIRE, filerequireTag },
{ RPMTAG_TRIGGERCONDS, triggercondsTag },
+ { RPMTAG_FILETRIGGERCONDS, filetriggercondsTag },
+ { RPMTAG_TRANSFILETRIGGERCONDS, transfiletriggercondsTag },
{ RPMTAG_TRIGGERTYPE, triggertypeTag },
+ { RPMTAG_FILETRIGGERTYPE, filetriggertypeTag },
+ { RPMTAG_TRANSFILETRIGGERTYPE, transfiletriggertypeTag },
{ RPMTAG_LONGFILESIZES, longfilesizesTag },
{ RPMTAG_LONGARCHIVESIZE, longarchivesizeTag },
{ RPMTAG_LONGSIZE, longsizeTag },
@@ -975,6 +1135,10 @@ static const struct headerTagFunc_s rpmHeaderTagExtensions[] = {
{ RPMTAG_EPOCHNUM, epochnumTag },
{ RPMTAG_INSTFILENAMES, instfilenamesTag },
{ RPMTAG_REQUIRENEVRS, requirenevrsTag },
+ { RPMTAG_RECOMMENDNEVRS, recommendnevrsTag},
+ { RPMTAG_SUGGESTNEVRS, suggestnevrsTag},
+ { RPMTAG_SUPPLEMENTNEVRS, supplementnevrsTag},
+ { RPMTAG_ENHANCENEVRS, enhancenevrsTag},
{ RPMTAG_PROVIDENEVRS, providenevrsTag },
{ RPMTAG_OBSOLETENEVRS, obsoletenevrsTag },
{ RPMTAG_CONFLICTNEVRS, conflictnevrsTag },