Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

lib/formats.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 
00007 #include "rpmio_internal.h"
00008 #include <rpmlib.h>
00009 #include <rpmmacro.h>   /* XXX for %_i18ndomains */
00010 
00011 #define _RPMEVR_INTERNAL
00012 #include <rpmds.h>
00013 #include <rpmfi.h>
00014 
00015 #include "legacy.h"
00016 #include "manifest.h"
00017 #include "argv.h"
00018 #include "misc.h"
00019 #include "fs.h"
00020 
00021 #include "debug.h"
00022 
00023 /*@access pgpDig @*/
00024 /*@access pgpDigParams @*/
00025 
00035 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data,
00036                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00037                 /*@unused@*/ int element)
00038         /*@requires maxRead(data) >= 0 @*/
00039 {
00040     const int_32 * item = data;
00041     char * val;
00042 
00043     if (type != RPM_INT32_TYPE)
00044         val = xstrdup(_("(invalid type)"));
00045     else if (*item & RPMSENSE_TRIGGERPREIN)
00046         val = xstrdup("prein");
00047     else if (*item & RPMSENSE_TRIGGERIN)
00048         val = xstrdup("in");
00049     else if (*item & RPMSENSE_TRIGGERUN)
00050         val = xstrdup("un");
00051     else if (*item & RPMSENSE_TRIGGERPOSTUN)
00052         val = xstrdup("postun");
00053     else
00054         val = xstrdup("");
00055     return val;
00056 }
00057 
00067 static /*@only@*/ char * permsFormat(int_32 type, const void * data,
00068                 char * formatPrefix, int padding, /*@unused@*/ int element)
00069         /*@modifies formatPrefix @*/
00070         /*@requires maxRead(data) >= 0 @*/
00071 {
00072     char * val;
00073     char * buf;
00074 
00075     if (type != RPM_INT32_TYPE) {
00076         val = xstrdup(_("(invalid type)"));
00077     } else {
00078         val = xmalloc(15 + padding);
00079 /*@-boundswrite@*/
00080         strcat(formatPrefix, "s");
00081 /*@=boundswrite@*/
00082         buf = rpmPermsString(*((int_32 *) data));
00083         /*@-formatconst@*/
00084         sprintf(val, formatPrefix, buf);
00085         /*@=formatconst@*/
00086         buf = _free(buf);
00087     }
00088 
00089     return val;
00090 }
00091 
00101 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data,
00102                 char * formatPrefix, int padding, /*@unused@*/ int element)
00103         /*@modifies formatPrefix @*/
00104         /*@requires maxRead(data) >= 0 @*/
00105 {
00106     char * val;
00107     char buf[15];
00108     int anint = *((int_32 *) data);
00109 
00110     if (type != RPM_INT32_TYPE) {
00111         val = xstrdup(_("(invalid type)"));
00112     } else {
00113         buf[0] = '\0';
00114 /*@-boundswrite@*/
00115         if (anint & RPMFILE_DOC)
00116             strcat(buf, "d");
00117         if (anint & RPMFILE_CONFIG)
00118             strcat(buf, "c");
00119         if (anint & RPMFILE_SPECFILE)
00120             strcat(buf, "s");
00121         if (anint & RPMFILE_MISSINGOK)
00122             strcat(buf, "m");
00123         if (anint & RPMFILE_NOREPLACE)
00124             strcat(buf, "n");
00125         if (anint & RPMFILE_GHOST)
00126             strcat(buf, "g");
00127         if (anint & RPMFILE_LICENSE)
00128             strcat(buf, "l");
00129         if (anint & RPMFILE_README)
00130             strcat(buf, "r");
00131 /*@=boundswrite@*/
00132 
00133         val = xmalloc(5 + padding);
00134 /*@-boundswrite@*/
00135         strcat(formatPrefix, "s");
00136 /*@=boundswrite@*/
00137         /*@-formatconst@*/
00138         sprintf(val, formatPrefix, buf);
00139         /*@=formatconst@*/
00140     }
00141 
00142     return val;
00143 }
00144 
00155 static /*@only@*/ char * armorFormat(int_32 type, const void * data,
00156                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00157                 int element)
00158         /*@*/
00159 {
00160     const char * enc;
00161     const unsigned char * s;
00162     size_t ns;
00163     int atype;
00164 
00165     switch (type) {
00166     case RPM_OPENPGP_TYPE:
00167     case RPM_ASN1_TYPE:         /* XXX WRONG */
00168     case RPM_BIN_TYPE:
00169         s = data;
00170         /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
00171         ns = element;
00172         atype = PGPARMOR_SIGNATURE;     /* XXX check pkt for signature */
00173         break;
00174     case RPM_STRING_TYPE:
00175     case RPM_STRING_ARRAY_TYPE:
00176         enc = data;
00177         if (b64decode(enc, (void **)&s, &ns))
00178             return xstrdup(_("(not base64)"));
00179         atype = PGPARMOR_PUBKEY;        /* XXX check pkt for pubkey */
00180         break;
00181     case RPM_NULL_TYPE:
00182     case RPM_CHAR_TYPE:
00183     case RPM_INT8_TYPE:
00184     case RPM_INT16_TYPE:
00185     case RPM_INT32_TYPE:
00186     case RPM_INT64_TYPE:
00187     case RPM_I18NSTRING_TYPE:
00188     default:
00189         return xstrdup(_("(invalid type)"));
00190         /*@notreached@*/ break;
00191     }
00192 
00193     /* XXX this doesn't use padding directly, assumes enough slop in retval. */
00194     return pgpArmorWrap(atype, s, ns);
00195 }
00196 
00207 static /*@only@*/ char * base64Format(int_32 type, const void * data,
00208                 /*@unused@*/ char * formatPrefix, int padding, int element)
00209         /*@*/
00210 {
00211     char * val;
00212 
00213     if (!(type == RPM_BIN_TYPE || type == RPM_ASN1_TYPE || type == RPM_OPENPGP_TYPE)) {
00214         val = xstrdup(_("(not a blob)"));
00215     } else {
00216         const char * enc;
00217         char * t;
00218         int lc;
00219         /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
00220         size_t ns = element;
00221         size_t nt = ((ns + 2) / 3) * 4;
00222 
00223 /*@-boundswrite@*/
00224         /*@-globs@*/
00225         /* Add additional bytes necessary for eol string(s). */
00226         if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00227             lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00228         if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00229             ++lc;
00230             nt += lc * strlen(b64encode_eolstr);
00231         }
00232         /*@=globs@*/
00233 
00234         val = t = xcalloc(1, nt + padding + 1);
00235         *t = '\0';
00236 
00237     /* XXX b64encode accesses uninitialized memory. */
00238     {   unsigned char * _data = xcalloc(1, ns+1);
00239         memcpy(_data, data, ns);
00240         if ((enc = b64encode(_data, ns)) != NULL) {
00241             t = stpcpy(t, enc);
00242             enc = _free(enc);
00243         }
00244         _data = _free(_data);
00245     }
00246 /*@=boundswrite@*/
00247     }
00248 
00249     return val;
00250 }
00251 
00257 static size_t xmlstrlen(const char * s)
00258         /*@*/
00259 {
00260     size_t len = 0;
00261     int c;
00262 
00263 /*@-boundsread@*/
00264     while ((c = *s++) != '\0')
00265 /*@=boundsread@*/
00266     {
00267         switch (c) {
00268         case '<':
00269         case '>':       len += sizeof("&lt;") - 1;      /*@switchbreak@*/ break;
00270         case '&':       len += sizeof("&amp;") - 1;     /*@switchbreak@*/ break;
00271         default:        len += 1;                       /*@switchbreak@*/ break;
00272         }
00273     }
00274     return len;
00275 }
00276 
00283 static char * xmlstrcpy(/*@returned@*/ char * t, const char * s)
00284         /*@modifies t @*/
00285 {
00286     char * te = t;
00287     int c;
00288 
00289 /*@-bounds@*/
00290     while ((c = *s++) != '\0') {
00291         switch (c) {
00292         case '<':       te = stpcpy(te, "&lt;");        /*@switchbreak@*/ break;
00293         case '>':       te = stpcpy(te, "&gt;");        /*@switchbreak@*/ break;
00294         case '&':       te = stpcpy(te, "&amp;");       /*@switchbreak@*/ break;
00295         default:        *te++ = c;                      /*@switchbreak@*/ break;
00296         }
00297     }
00298     *te = '\0';
00299 /*@=bounds@*/
00300     return t;
00301 }
00302 
00312 /*@-bounds@*/
00313 static /*@only@*/ char * xmlFormat(int_32 type, const void * data,
00314                 char * formatPrefix, int padding,
00315                 /*@unused@*/ int element)
00316         /*@modifies formatPrefix @*/
00317 {
00318     const char * xtag = NULL;
00319     size_t nb;
00320     char * val;
00321     const char * s = NULL;
00322     char * t, * te;
00323     unsigned long long anint = 0;
00324     int freeit = 0;
00325     int xx;
00326 
00327 /*@-branchstate@*/
00328     switch (type) {
00329     case RPM_I18NSTRING_TYPE:
00330     case RPM_STRING_TYPE:
00331         s = data;
00332         xtag = "string";
00333         /* XXX Force utf8 strings. */
00334         s = xstrdup(s);
00335         s = xstrtolocale(s);
00336         freeit = 1;
00337         break;
00338     case RPM_OPENPGP_TYPE:
00339     case RPM_ASN1_TYPE:
00340     case RPM_BIN_TYPE:
00341     {   int cpl = b64encode_chars_per_line;
00342 /*@-mods@*/
00343         b64encode_chars_per_line = 0;
00344 /*@=mods@*/
00345 /*@-formatconst@*/
00346         s = base64Format(type, data, formatPrefix, padding, element);
00347 /*@=formatconst@*/
00348 /*@-mods@*/
00349         b64encode_chars_per_line = cpl;
00350 /*@=mods@*/
00351         xtag = "base64";
00352         freeit = 1;
00353     }   break;
00354     case RPM_CHAR_TYPE:
00355     case RPM_INT8_TYPE:
00356         anint = *((uint_8 *) data);
00357         break;
00358     case RPM_INT16_TYPE:
00359         anint = *((uint_16 *) data);
00360         break;
00361     case RPM_INT32_TYPE:
00362         anint = *((uint_32 *) data);
00363         break;
00364     case RPM_INT64_TYPE:
00365         anint = *((uint_64 *) data);
00366         break;
00367     case RPM_NULL_TYPE:
00368     case RPM_STRING_ARRAY_TYPE:
00369     default:
00370         return xstrdup(_("(invalid xml type)"));
00371         /*@notreached@*/ break;
00372     }
00373 /*@=branchstate@*/
00374 
00375 /*@-branchstate@*/
00376     if (s == NULL) {
00377         int tlen = 64;
00378         t = memset(alloca(tlen+1), 0, tlen+1);
00379 /*@-duplicatequals@*/
00380         if (anint != 0)
00381             xx = snprintf(t, tlen, "%llu", anint);
00382 /*@=duplicatequals@*/
00383         s = t;
00384         xtag = "integer";
00385     }
00386 /*@=branchstate@*/
00387 
00388     nb = xmlstrlen(s);
00389     if (nb == 0) {
00390         nb += strlen(xtag) + sizeof("\t</>");
00391         te = t = alloca(nb);
00392         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
00393     } else {
00394         nb += 2 * strlen(xtag) + sizeof("\t<></>");
00395         te = t = alloca(nb);
00396         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00397         te = xmlstrcpy(te, s);
00398         te += strlen(te);
00399         te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00400     }
00401 
00402 /*@-branchstate@*/
00403     if (freeit)
00404         s = _free(s);
00405 /*@=branchstate@*/
00406 
00407     nb += padding;
00408     val = xmalloc(nb+1);
00409 /*@-boundswrite@*/
00410     strcat(formatPrefix, "s");
00411 /*@=boundswrite@*/
00412 /*@-formatconst@*/
00413     xx = snprintf(val, nb, formatPrefix, t);
00414 /*@=formatconst@*/
00415     val[nb] = '\0';
00416 
00417     return val;
00418 }
00419 /*@=bounds@*/
00420 
00427 static size_t yamlstrlen(const char * s, int lvl)
00428         /*@*/
00429 {
00430     size_t len = 0;
00431     int indent = (lvl > 0);
00432     int c;
00433 
00434 /*@-boundsread@*/
00435     while ((c = *s++) != '\0')
00436 /*@=boundsread@*/
00437     {
00438         if (indent) {
00439             len += 2 * lvl;
00440             indent = 0;
00441         }
00442         if (c == '\n')
00443             indent = (lvl > 0);
00444         len++;
00445     }
00446     return len;
00447 }
00448 
00456 static char * yamlstrcpy(/*@out@*/ /*@returned@*/ char * t, const char * s, int lvl)
00457         /*@modifies t @*/
00458 {
00459     char * te = t;
00460     int indent = (lvl > 0);
00461     int c;
00462 
00463 /*@-bounds@*/
00464     while ((c = *s++) != '\0') {
00465         if (indent) {
00466             int i;
00467             for (i = 0; i < lvl; i++) {
00468                 *te++ = ' ';
00469                 *te++ = ' ';
00470             }
00471             indent = 0;
00472         }
00473         if (c == '\n')
00474             indent = (lvl > 0);
00475         *te++ = c;
00476     }
00477     *te = '\0';
00478 /*@=bounds@*/
00479     return t;
00480 }
00481 
00491 /*@-bounds@*/
00492 static /*@only@*/ char * yamlFormat(int_32 type, const void * data,
00493                 char * formatPrefix, int padding,
00494                 int element)
00495         /*@modifies formatPrefix @*/
00496 {
00497     const char * xtag = NULL;
00498     const char * ytag = NULL;
00499     size_t nb;
00500     char * val;
00501     const char * s = NULL;
00502     char * t, * te;
00503     unsigned long long anint = 0;
00504     int freeit = 0;
00505     int lvl = 0;
00506     int xx;
00507     int c;
00508 
00509 /*@-branchstate@*/
00510     switch (type) {
00511     case RPM_I18NSTRING_TYPE:
00512     case RPM_STRING_TYPE:
00513         xx = 0;
00514         s = data;
00515         if (strchr("[", s[0]))  /* leading [ */
00516             xx = 1;
00517         if (xx == 0)
00518         while ((c = *s++) != '\0') {
00519             switch (c) {
00520             default:
00521                 continue;
00522             case '\n':  /* multiline */
00523                 xx = 1;
00524                 /*@switchbreak@*/ break;
00525             case '-':   /* leading "- \"" */
00526             case ':':   /* embedded ": " or ":" at EOL */
00527                 if (s[0] != ' ' && s[0] != '\0' && s[1] != '"')
00528                     continue;
00529                 xx = 1;
00530                 /*@switchbreak@*/ break;
00531             }
00532             /*@loopbreak@*/ break;
00533         }
00534         if (xx) {
00535             if (element >= 0) {
00536                 xtag = "- |-\n";
00537                 lvl = 3;
00538             } else {
00539                 xtag = "|-\n";
00540                 lvl = 2;
00541             }
00542         } else {
00543             xtag = (element >= 0 ? "- " : NULL);
00544         }
00545 
00546         /* XXX Force utf8 strings. */
00547         s = xstrdup(data);
00548         s = xstrtolocale(s);
00549         freeit = 1;
00550         break;
00551     case RPM_OPENPGP_TYPE:
00552     case RPM_ASN1_TYPE:
00553     case RPM_BIN_TYPE:
00554     {   int cpl = b64encode_chars_per_line;
00555 /*@-mods@*/
00556         b64encode_chars_per_line = 0;
00557 /*@=mods@*/
00558 /*@-formatconst@*/
00559         s = base64Format(type, data, formatPrefix, padding, element);
00560         element = -element;     /* XXX skip "    " indent. */
00561 /*@=formatconst@*/
00562 /*@-mods@*/
00563         b64encode_chars_per_line = cpl;
00564 /*@=mods@*/
00565         xtag = "!!binary ";
00566         freeit = 1;
00567     }   break;
00568     case RPM_CHAR_TYPE:
00569     case RPM_INT8_TYPE:
00570         anint = *((uint_8 *) data);
00571         break;
00572     case RPM_INT16_TYPE:
00573         anint = *((uint_16 *) data);
00574         break;
00575     case RPM_INT32_TYPE:
00576         anint = *((uint_32 *) data);
00577         break;
00578     case RPM_INT64_TYPE:
00579         anint = *((uint_64 *) data);
00580         break;
00581     case RPM_NULL_TYPE:
00582     case RPM_STRING_ARRAY_TYPE:
00583     default:
00584         return xstrdup(_("(invalid yaml type)"));
00585         /*@notreached@*/ break;
00586     }
00587 /*@=branchstate@*/
00588 
00589 /*@-branchstate@*/
00590     if (s == NULL) {
00591         int tlen = 64;
00592         t = memset(alloca(tlen+1), 0, tlen+1);
00593 /*@-duplicatequals@*/
00594         xx = snprintf(t, tlen, "%llu", anint);
00595 /*@=duplicatequals@*/
00596         s = t;
00597         xtag = (element >= 0 ? "- " : NULL);
00598     }
00599 /*@=branchstate@*/
00600 
00601     nb = yamlstrlen(s, lvl);
00602     if (nb == 0) {
00603         if (element >= 0)
00604             nb += sizeof("    ") - 1;
00605         nb += sizeof("- ~") - 1;
00606         nb++;
00607         te = t = alloca(nb);
00608         if (element >= 0)
00609             te = stpcpy(te, "    ");
00610         te = stpcpy(te, "- ~");
00611     } else {
00612         if (element >= 0)
00613             nb += sizeof("    ") - 1;
00614         if (xtag)
00615             nb += strlen(xtag);
00616         if (ytag)
00617             nb += strlen(ytag);
00618         nb++;
00619         te = t = alloca(nb);
00620         if (element >= 0)
00621             te = stpcpy(te, "    ");
00622         if (xtag)
00623             te = stpcpy(te, xtag);
00624         te = yamlstrcpy(te, s, lvl);
00625         te += strlen(te);
00626         if (ytag)
00627             te = stpcpy(te, ytag);
00628     }
00629 
00630     /* XXX s was malloc'd */
00631 /*@-branchstate@*/
00632     if (freeit)
00633         s = _free(s);
00634 /*@=branchstate@*/
00635 
00636     nb += padding;
00637     val = xmalloc(nb+1);
00638 /*@-boundswrite@*/
00639     strcat(formatPrefix, "s");
00640 /*@=boundswrite@*/
00641 /*@-formatconst@*/
00642     xx = snprintf(val, nb, formatPrefix, t);
00643 /*@=formatconst@*/
00644     val[nb] = '\0';
00645 
00646     return val;
00647 }
00648 /*@=bounds@*/
00649 
00659 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data,
00660                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00661                 /*@unused@*/ int element)
00662         /*@globals fileSystem, internalState @*/
00663         /*@modifies fileSystem, internalState @*/
00664 {
00665     char * val, * t;
00666 
00667     if (!(type == RPM_BIN_TYPE || type == RPM_ASN1_TYPE || type == RPM_OPENPGP_TYPE)) {
00668         val = xstrdup(_("(not a blob)"));
00669     } else {
00670         unsigned char * pkt = (byte *) data;
00671         unsigned int pktlen = 0;
00672 /*@-boundsread@*/
00673         unsigned int v = *pkt;
00674 /*@=boundsread@*/
00675         pgpTag tag = 0;
00676         unsigned int plen;
00677         unsigned int hlen = 0;
00678 
00679         if (v & 0x80) {
00680             if (v & 0x40) {
00681                 tag = (v & 0x3f);
00682                 plen = pgpLen(pkt+1, &hlen);
00683             } else {
00684                 tag = (v >> 2) & 0xf;
00685                 plen = (1 << (v & 0x3));
00686                 hlen = pgpGrab(pkt+1, plen);
00687             }
00688         
00689             pktlen = 1 + plen + hlen;
00690         }
00691 
00692         if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00693             val = xstrdup(_("(not an OpenPGP signature)"));
00694         } else {
00695             pgpDig dig = pgpNewDig();
00696             pgpDigParams sigp = &dig->signature;
00697             size_t nb = 0;
00698             const char *tempstr;
00699 
00700             (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00701 
00702             val = NULL;
00703         again:
00704             nb += 100;
00705             val = t = xrealloc(val, nb + 1);
00706 
00707 /*@-boundswrite@*/
00708             switch (sigp->pubkey_algo) {
00709             case PGPPUBKEYALGO_DSA:
00710                 t = stpcpy(t, "DSA");
00711                 break;
00712             case PGPPUBKEYALGO_RSA:
00713                 t = stpcpy(t, "RSA");
00714                 break;
00715             default:
00716                 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
00717                 t += strlen(t);
00718                 break;
00719             }
00720             if (t + 5 >= val + nb)
00721                 goto again;
00722             *t++ = '/';
00723             switch (sigp->hash_algo) {
00724             case PGPHASHALGO_MD5:
00725                 t = stpcpy(t, "MD5");
00726                 break;
00727             case PGPHASHALGO_SHA1:
00728                 t = stpcpy(t, "SHA1");
00729                 break;
00730             default:
00731                 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
00732                 t += strlen(t);
00733                 break;
00734             }
00735             if (t + strlen (", ") + 1 >= val + nb)
00736                 goto again;
00737 
00738             t = stpcpy(t, ", ");
00739 
00740             /* this is important if sizeof(int_32) ! sizeof(time_t) */
00741             {   time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00742                 struct tm * tstruct = localtime(&dateint);
00743                 if (tstruct)
00744                     (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00745             }
00746             t += strlen(t);
00747             if (t + strlen (", Key ID ") + 1 >= val + nb)
00748                 goto again;
00749             t = stpcpy(t, ", Key ID ");
00750             tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
00751             if (t + strlen (tempstr) > val + nb)
00752                 goto again;
00753             t = stpcpy(t, tempstr);
00754 /*@=boundswrite@*/
00755 
00756             dig = pgpFreeDig(dig);
00757         }
00758     }
00759 
00760     return val;
00761 }
00762 
00772 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data,
00773                 char * formatPrefix, int padding, /*@unused@*/ int element)
00774         /*@modifies formatPrefix @*/
00775         /*@requires maxRead(data) >= 0 @*/
00776 {
00777     char * val;
00778 
00779     if (type != RPM_INT32_TYPE) {
00780         val = xstrdup(_("(invalid type)"));
00781     } else {
00782         int anint = *((int_32 *) data);
00783         char *t, *buf;
00784 
00785         t = buf = alloca(32);
00786         *t = '\0';
00787 
00788 /*@-boundswrite@*/
00789 #ifdef  NOTYET  /* XXX appending markers breaks :depflags format. */
00790         if (anint & RPMSENSE_SCRIPT_PRE)
00791             t = stpcpy(t, "(pre)");
00792         if (anint & RPMSENSE_SCRIPT_POST)
00793             t = stpcpy(t, "(post)");
00794         if (anint & RPMSENSE_SCRIPT_PREUN)
00795             t = stpcpy(t, "(preun)");
00796         if (anint & RPMSENSE_SCRIPT_POSTUN)
00797             t = stpcpy(t, "(postun)");
00798 #endif
00799         if (anint & RPMSENSE_SENSEMASK)
00800             *t++ = ' ';
00801         if (anint & RPMSENSE_LESS)
00802             *t++ = '<';
00803         if (anint & RPMSENSE_GREATER)
00804             *t++ = '>';
00805         if (anint & RPMSENSE_EQUAL)
00806             *t++ = '=';
00807         if (anint & RPMSENSE_SENSEMASK)
00808             *t++ = ' ';
00809         *t = '\0';
00810 /*@=boundswrite@*/
00811 
00812         val = xmalloc(5 + padding);
00813 /*@-boundswrite@*/
00814         strcat(formatPrefix, "s");
00815 /*@=boundswrite@*/
00816         /*@-formatconst@*/
00817         sprintf(val, formatPrefix, buf);
00818         /*@=formatconst@*/
00819     }
00820 
00821     return val;
00822 }
00823 
00833 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00834                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00835                 /*@out@*/ int * freeData)
00836         /*@globals fileSystem, internalState @*/
00837         /*@modifies *type, *data, *count, *freeData,
00838                 fileSystem, internalState @*/
00839         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00840                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00841 {
00842     const char ** list;
00843 
00844 /*@-boundswrite@*/
00845     if (rpmGetFilesystemList(&list, count))
00846         return 1;
00847 /*@=boundswrite@*/
00848 
00849     if (type) *type = RPM_STRING_ARRAY_TYPE;
00850     if (data) *((const char ***) data) = list;
00851     if (freeData) *freeData = 0;
00852 
00853     return 0;
00854 }
00855 
00865 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00866                 /*@null@*/ /*@out@*/ const void ** data,
00867                 /*@null@*/ /*@out@*/ int_32 * count,
00868                 /*@null@*/ /*@out@*/ int * freeData)
00869         /*@modifies *type, *data, *freeData @*/
00870         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00871                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00872 {
00873     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00874     HFD_t hfd = headerFreeData;
00875     rpmTagType ipt;
00876     char ** array;
00877 
00878     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00879         if (freeData) *freeData = 0;
00880         return 0;
00881     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00882         if (type) *type = RPM_STRING_TYPE;
00883 /*@-boundsread@*/
00884         if (data) *data = xstrdup(array[0]);
00885 /*@=boundsread@*/
00886         if (freeData) *freeData = 1;
00887         array = hfd(array, ipt);
00888         return 0;
00889     }
00890 
00891     return 1;
00892 }
00893 
00903 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00904                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00905                 /*@out@*/ int * freeData)
00906         /*@globals rpmGlobalMacroContext, h_errno,
00907                 fileSystem, internalState @*/
00908         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00909                 fileSystem, internalState @*/
00910         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00911                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00912 {
00913     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00914     const char ** filenames;
00915     int_32 * filesizes;
00916     uint_64 * usages;
00917     int numFiles;
00918 
00919     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00920         filesizes = NULL;
00921         numFiles = 0;
00922         filenames = NULL;
00923     } else {
00924         rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00925     }
00926 
00927 /*@-boundswrite@*/
00928     if (rpmGetFilesystemList(NULL, count))
00929         return 1;
00930 /*@=boundswrite@*/
00931 
00932     *type = RPM_INT64_TYPE;
00933     *freeData = 1;
00934 
00935     if (filenames == NULL) {
00936         usages = xcalloc((*count), sizeof(*usages));
00937         *data = usages;
00938 
00939         return 0;
00940     }
00941 
00942 /*@-boundswrite@*/
00943     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00944         return 1;
00945 /*@=boundswrite@*/
00946 
00947     *data = usages;
00948 
00949     filenames = _free(filenames);
00950 
00951     return 0;
00952 }
00953 
00963 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00964                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00965                 /*@out@*/ int * freeData)
00966         /*@modifies *type, *data, *count, *freeData @*/
00967         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00968                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00969 {
00970     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00971     HFD_t hfd = headerFreeData;
00972     rpmTagType tnt, tvt, tst;
00973     int_32 * indices, * flags;
00974     char ** names, ** versions;
00975     int numNames, numScripts;
00976     char ** conds, ** s;
00977     char * item, * flagsStr;
00978     char * chptr;
00979     int i, j, xx;
00980     char buf[5];
00981 
00982     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00983         *freeData = 0;
00984         return 0;
00985     }
00986 
00987     xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00988     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00989     xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00990     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00991     s = hfd(s, tst);
00992 
00993     *freeData = 1;
00994     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00995     *count = numScripts;
00996     *type = RPM_STRING_ARRAY_TYPE;
00997 /*@-bounds@*/
00998     for (i = 0; i < numScripts; i++) {
00999         chptr = xstrdup("");
01000 
01001         for (j = 0; j < numNames; j++) {
01002             if (indices[j] != i)
01003                 /*@innercontinue@*/ continue;
01004 
01005             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
01006             if (flags[j] & RPMSENSE_SENSEMASK) {
01007                 buf[0] = '%', buf[1] = '\0';
01008                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
01009                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
01010                 flagsStr = _free(flagsStr);
01011             } else {
01012                 strcpy(item, names[j]);
01013             }
01014 
01015             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
01016             if (*chptr != '\0') strcat(chptr, ", ");
01017             strcat(chptr, item);
01018             item = _free(item);
01019         }
01020 
01021         conds[i] = chptr;
01022     }
01023 /*@=bounds@*/
01024 
01025     names = hfd(names, tnt);
01026     versions = hfd(versions, tvt);
01027 
01028     return 0;
01029 }
01030 
01040 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
01041                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01042                 /*@out@*/ int * freeData)
01043         /*@modifies *type, *data, *count, *freeData @*/
01044         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01045                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01046 {
01047     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01048     HFD_t hfd = headerFreeData;
01049     rpmTagType tst;
01050     int_32 * indices, * flags;
01051     const char ** conds;
01052     const char ** s;
01053     int i, j, xx;
01054     int numScripts, numNames;
01055 
01056     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
01057         *freeData = 0;
01058         return 1;
01059     }
01060 
01061     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
01062     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
01063     s = hfd(s, tst);
01064 
01065     *freeData = 1;
01066     *data = conds = xmalloc(sizeof(*conds) * numScripts);
01067     *count = numScripts;
01068     *type = RPM_STRING_ARRAY_TYPE;
01069 /*@-bounds@*/
01070     for (i = 0; i < numScripts; i++) {
01071         for (j = 0; j < numNames; j++) {
01072             if (indices[j] != i)
01073                 /*@innercontinue@*/ continue;
01074 
01075             if (flags[j] & RPMSENSE_TRIGGERPREIN)
01076                 conds[i] = xstrdup("prein");
01077             else if (flags[j] & RPMSENSE_TRIGGERIN)
01078                 conds[i] = xstrdup("in");
01079             else if (flags[j] & RPMSENSE_TRIGGERUN)
01080                 conds[i] = xstrdup("un");
01081             else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
01082                 conds[i] = xstrdup("postun");
01083             else
01084                 conds[i] = xstrdup("");
01085             /*@innerbreak@*/ break;
01086         }
01087     }
01088 /*@=bounds@*/
01089 
01090     return 0;
01091 }
01092 
01102 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
01103                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01104                 /*@out@*/ int * freeData)
01105         /*@modifies *type, *data, *count, *freeData @*/
01106         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01107                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01108 {
01109     *type = RPM_STRING_ARRAY_TYPE;
01110     rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
01111     *freeData = 1;
01112     return 0;
01113 }
01114 
01124 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
01125                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01126                 /*@out@*/ int * freeData)
01127         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
01128         /*@modifies h, *type, *data, *count, *freeData,
01129                 rpmGlobalMacroContext, fileSystem @*/
01130         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01131                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01132 {
01133     *type = RPM_STRING_ARRAY_TYPE;
01134     rpmfiBuildFClasses(h, (const char ***) data, count);
01135     *freeData = 1;
01136     return 0;
01137 }
01138 
01148 static int filecontextsTag(Header h, /*@out@*/ rpmTagType * type,
01149                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01150                 /*@out@*/ int * freeData)
01151         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
01152         /*@modifies h, *type, *data, *count, *freeData,
01153                 rpmGlobalMacroContext, fileSystem @*/
01154         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01155                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01156 {
01157     *type = RPM_STRING_ARRAY_TYPE;
01158     rpmfiBuildFContexts(h, (const char ***) data, count);
01159     *freeData = 1;
01160     return 0;
01161 }
01162 
01172 static int fscontextsTag(Header h, /*@out@*/ rpmTagType * type,
01173                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01174                 /*@out@*/ int * freeData)
01175         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
01176         /*@modifies h, *type, *data, *count, *freeData,
01177                 rpmGlobalMacroContext, fileSystem @*/
01178         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01179                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01180 {
01181     *type = RPM_STRING_ARRAY_TYPE;
01182     rpmfiBuildFSContexts(h, (const char ***) data, count);
01183     *freeData = 1;
01184     return 0;
01185 }
01186 
01196 static int recontextsTag(Header h, /*@out@*/ rpmTagType * type,
01197                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01198                 /*@out@*/ int * freeData)
01199         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
01200         /*@modifies h, *type, *data, *count, *freeData,
01201                 rpmGlobalMacroContext, fileSystem @*/
01202         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01203                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01204 {
01205     *type = RPM_STRING_ARRAY_TYPE;
01206     rpmfiBuildREContexts(h, (const char ***) data, count);
01207     *freeData = 1;
01208     return 0;
01209 }
01210 
01220 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
01221                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01222                 /*@out@*/ int * freeData)
01223         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
01224         /*@modifies h, *type, *data, *count, *freeData,
01225                 rpmGlobalMacroContext, fileSystem, internalState @*/
01226         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01227                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01228 {
01229     *type = RPM_STRING_ARRAY_TYPE;
01230     rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
01231     *freeData = 1;
01232     return 0;
01233 }
01234 
01244 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
01245                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01246                 /*@out@*/ int * freeData)
01247         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
01248         /*@modifies h, *type, *data, *count, *freeData,
01249                 rpmGlobalMacroContext, fileSystem, internalState @*/
01250         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01251                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01252 {
01253     *type = RPM_STRING_ARRAY_TYPE;
01254     rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
01255     *freeData = 1;
01256     return 0;
01257 }
01258 
01268 static int missingokTag(Header h, /*@out@*/ rpmTagType * type,
01269                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01270                 /*@out@*/ int * freeData)
01271         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
01272         /*@modifies h, *type, *data, *count, *freeData,
01273                 rpmGlobalMacroContext, fileSystem, internalState @*/
01274         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01275                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01276 {
01277     rpmds ds = rpmdsNew(h, RPMTAG_REQUIRENAME, 0);
01278     ARGV_t av = NULL;
01279     ARGV_t argv;
01280     int argc = 0;
01281     char * t;
01282     size_t nb = 0;
01283     int i;
01284 
01285 assert(ds != NULL);
01286     /* Collect dependencies marked as hints. */
01287     ds = rpmdsInit(ds);
01288     if (ds != NULL)
01289     while (rpmdsNext(ds) >= 0) {
01290         int Flags = rpmdsFlags(ds);
01291         const char * DNEVR;
01292         if (!(Flags & RPMSENSE_MISSINGOK))
01293             continue;
01294         DNEVR = rpmdsDNEVR(ds);
01295         if (DNEVR == NULL)
01296             continue;
01297         nb += sizeof(*argv) + strlen(DNEVR+2) + 1;
01298         (void) argvAdd(&av, DNEVR+2);
01299         argc++;
01300     }
01301     nb += sizeof(*argv);        /* final argv NULL */
01302 
01303     /* Create contiguous header string array. */
01304     argv = (ARGV_t) xcalloc(nb, 1);
01305     t = (char *)(argv + argc);
01306     for (i = 0; i < argc; i++) {
01307         argv[i] = t;
01308         t = stpcpy(t, av[i]);
01309         *t++ = '\0';
01310     }
01311     av = argvFree(av);
01312     ds = rpmdsFree(ds);
01313 
01314     /* XXX perhaps return "(none)" inband if no suggests/enhances <shrug>. */
01315 
01316     *type = RPM_STRING_ARRAY_TYPE;
01317     *data = argv;
01318     *count = argc;
01319     *freeData = 1;
01320     return 0;
01321 }
01322 
01323 /* I18N look aside diversions */
01324 
01325 #if defined(ENABLE_NLS)
01326 /*@-exportlocal -exportheadervar@*/
01327 /*@unchecked@*/
01328 extern int _nl_msg_cat_cntr;    /* XXX GNU gettext voodoo */
01329 /*@=exportlocal =exportheadervar@*/
01330 #endif
01331 /*@observer@*/ /*@unchecked@*/
01332 static const char * language = "LANGUAGE";
01333 
01334 /*@observer@*/ /*@unchecked@*/
01335 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
01336 
01347 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
01348                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01349                 /*@out@*/ int * freeData)
01350         /*@globals rpmGlobalMacroContext, h_errno @*/
01351         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01352         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01353                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01354 {
01355     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01356     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01357     int rc;
01358 
01359     *type = RPM_STRING_TYPE;
01360     *data = NULL;
01361     *count = 0;
01362     *freeData = 0;
01363 
01364     if (dstring && *dstring) {
01365         char *domain, *de;
01366         const char * langval;
01367         const char * msgkey;
01368         const char * msgid;
01369 
01370         {   const char * tn = tagName(tag);
01371             const char * n = NULL;
01372             char * mk;
01373             size_t nb = sizeof("()");
01374             int xx = headerNVR(h, &n, NULL, NULL);
01375             if (tn)     nb += strlen(tn);
01376             if (n)      nb += strlen(n);
01377             mk = alloca(nb);
01378             sprintf(mk, "%s(%s)", (n?n:""), (tn?tn:""));
01379             msgkey = mk;
01380         }
01381 
01382         /* change to en_US for msgkey -> msgid resolution */
01383         langval = getenv(language);
01384         (void) setenv(language, "en_US", 1);
01385 #if defined(ENABLE_NLS)
01386 /*@i@*/ ++_nl_msg_cat_cntr;
01387 #endif
01388 
01389         msgid = NULL;
01390         /*@-branchstate@*/
01391         for (domain = dstring; domain != NULL; domain = de) {
01392             de = strchr(domain, ':');
01393             if (de) *de++ = '\0';
01394             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
01395             if (msgid != msgkey) break;
01396         }
01397         /*@=branchstate@*/
01398 
01399         /* restore previous environment for msgid -> msgstr resolution */
01400         if (langval)
01401             (void) setenv(language, langval, 1);
01402         else
01403             unsetenv(language);
01404 #if defined(ENABLE_NLS)
01405 /*@i@*/ ++_nl_msg_cat_cntr;
01406 #endif
01407 
01408         if (domain && msgid) {
01409             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
01410             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
01411             *count = 1;
01412             *freeData = 1;
01413         }
01414         dstring = _free(dstring);
01415         if (*data)
01416             return 0;
01417     }
01418 
01419     dstring = _free(dstring);
01420 
01421     rc = hge(h, tag, type, (void **)data, count);
01422 
01423     if (rc && (*data) != NULL) {
01424         *data = xstrdup(*data);
01425         *data = xstrtolocale(*data);
01426         *freeData = 1;
01427         return 0;
01428     }
01429 
01430     *freeData = 0;
01431     *data = NULL;
01432     *count = 0;
01433     return 1;
01434 }
01435 
01439 static int localeTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
01440                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01441                 /*@out@*/ int * freeData)
01442         /*@modifies *type, *data, *count, *freeData @*/
01443 {
01444     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01445     rpmTagType t;
01446     char **d, **d2, *dp;
01447     int rc, i, l;
01448 
01449     rc = hge(h, tag, &t, (void **)&d, count);
01450     if (!rc || d == NULL || *count == 0) {
01451         *freeData = 0;
01452         *data = NULL;
01453         *count = 0;
01454         return 1;
01455     }
01456     if (type)
01457         *type = t;
01458     if (t == RPM_STRING_TYPE) {
01459         d = (char **)xstrdup((char *)d);
01460         d = (char **)xstrtolocale((char *)d);
01461         *freeData = 1;
01462     } else if (t == RPM_STRING_ARRAY_TYPE) {
01463         l = 0;
01464         for (i = 0; i < *count; i++) {
01465             d[i] = xstrdup(d[i]);
01466             d[i] = (char *)xstrtolocale(d[i]);
01467 assert(d[i] != NULL);
01468             l += strlen(d[i]) + 1;
01469         }
01470         d2 = xmalloc(*count * sizeof(*d2) + l);
01471         dp = (char *)(d2 + *count);
01472         for (i = 0; i < *count; i++) {
01473             d2[i] = dp;
01474             strcpy(dp, d[i]);
01475             dp += strlen(dp) + 1;
01476             d[i] = _free(d[i]);
01477         }
01478         d = _free(d);
01479         d = d2;
01480         *freeData = 1;
01481     } else
01482         *freeData = 0;
01483     *data = (void **)d;
01484     return 0;
01485 }
01486 
01496 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
01497                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01498                 /*@out@*/ int * freeData)
01499         /*@globals rpmGlobalMacroContext, h_errno @*/
01500         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01501         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01502                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01503 {
01504     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01505 }
01506 
01516 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
01517                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01518                 /*@out@*/ int * freeData)
01519         /*@globals rpmGlobalMacroContext, h_errno @*/
01520         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01521         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01522                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01523 {
01524     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01525 }
01526 
01527 static int changelognameTag(Header h, /*@out@*/ rpmTagType * type,
01528                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01529                 /*@out@*/ int * freeData)
01530         /*@modifies *type, *data, *count, *freeData @*/
01531         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01532                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01533 {
01534     return localeTag(h, RPMTAG_CHANGELOGNAME, type, data, count, freeData);
01535 }
01536 
01537 static int changelogtextTag(Header h, /*@out@*/ rpmTagType * type,
01538                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01539                 /*@out@*/ int * freeData)
01540         /*@modifies *type, *data, *count, *freeData @*/
01541         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01542                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01543 {
01544     return localeTag(h, RPMTAG_CHANGELOGTEXT, type, data, count, freeData);
01545 }
01546 
01556 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
01557                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01558                 /*@out@*/ int * freeData)
01559         /*@globals rpmGlobalMacroContext, h_errno @*/
01560         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01561         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01562                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01563 {
01564     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01565 }
01566 
01567 /*@-type@*/ /* FIX: cast? */
01568 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01569     { HEADER_EXT_TAG, "RPMTAG_CHANGELOGNAME",   { changelognameTag } },
01570     { HEADER_EXT_TAG, "RPMTAG_CHANGELOGTEXT",   { changelogtextTag } },
01571     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION",     { descriptionTag } },
01572     { HEADER_EXT_TAG, "RPMTAG_ENHANCES",        { missingokTag } },
01573     { HEADER_EXT_TAG, "RPMTAG_FILECLASS",       { fileclassTag } },
01574     { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS",    { filecontextsTag } },
01575     { HEADER_EXT_TAG, "RPMTAG_FILENAMES",       { filenamesTag } },
01576     { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",     { fileprovideTag } },
01577     { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",     { filerequireTag } },
01578     { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS",      { fscontextsTag } },
01579     { HEADER_EXT_TAG, "RPMTAG_FSNAMES",         { fsnamesTag } },
01580     { HEADER_EXT_TAG, "RPMTAG_FSSIZES",         { fssizesTag } },
01581     { HEADER_EXT_TAG, "RPMTAG_GROUP",           { groupTag } },
01582     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX",   { instprefixTag } },
01583     { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS",      { recontextsTag } },
01584     { HEADER_EXT_TAG, "RPMTAG_SUGGESTS",        { missingokTag } },
01585     { HEADER_EXT_TAG, "RPMTAG_SUMMARY",         { summaryTag } },
01586     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS",    { triggercondsTag } },
01587     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE",     { triggertypeTag } },
01588     { HEADER_EXT_FORMAT, "armor",               { armorFormat } },
01589     { HEADER_EXT_FORMAT, "base64",              { base64Format } },
01590     { HEADER_EXT_FORMAT, "depflags",            { depflagsFormat } },
01591     { HEADER_EXT_FORMAT, "fflags",              { fflagsFormat } },
01592     { HEADER_EXT_FORMAT, "perms",               { permsFormat } },
01593     { HEADER_EXT_FORMAT, "permissions",         { permsFormat } },
01594     { HEADER_EXT_FORMAT, "pgpsig",              { pgpsigFormat } },
01595     { HEADER_EXT_FORMAT, "triggertype",         { triggertypeFormat } },
01596     { HEADER_EXT_FORMAT, "xml",                 { xmlFormat } },
01597     { HEADER_EXT_FORMAT, "yaml",                { yamlFormat } },
01598     { HEADER_EXT_MORE, NULL,            { (void *) headerDefaultFormats } }
01599 } ;
01600 /*@=type@*/

Generated on Sat Oct 1 16:24:14 2011 for rpm by  doxygen 1.4.4