diff options
Diffstat (limited to 'lib/tagexts.c')
-rw-r--r-- | lib/tagexts.c | 186 |
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 }, |