lib/formats.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include <rpmlib.h>
00008 #include <rpmmacro.h>   /* XXX for %_i18ndomains */
00009 
00010 #include <rpmfi.h>
00011 
00012 #include "legacy.h"
00013 #include "manifest.h"
00014 #include "misc.h"
00015 
00016 #include "debug.h"
00017 
00018 /*@access pgpDig @*/
00019 /*@access pgpDigParams @*/
00020 
00030 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data, 
00031                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00032                 /*@unused@*/ int element)
00033         /*@requires maxRead(data) >= 0 @*/
00034 {
00035     const int_32 * item = data;
00036     char * val;
00037 
00038     if (type != RPM_INT32_TYPE)
00039         val = xstrdup(_("(not a number)"));
00040     else if (*item & RPMSENSE_TRIGGERPREIN)
00041         val = xstrdup("prein");
00042     else if (*item & RPMSENSE_TRIGGERIN)
00043         val = xstrdup("in");
00044     else if (*item & RPMSENSE_TRIGGERUN)
00045         val = xstrdup("un");
00046     else if (*item & RPMSENSE_TRIGGERPOSTUN)
00047         val = xstrdup("postun");
00048     else
00049         val = xstrdup("");
00050     return val;
00051 }
00052 
00062 static /*@only@*/ char * permsFormat(int_32 type, const void * data,
00063                 char * formatPrefix, int padding, /*@unused@*/ int element)
00064         /*@modifies formatPrefix @*/
00065         /*@requires maxRead(data) >= 0 @*/
00066 {
00067     char * val;
00068     char * buf;
00069 
00070     if (type != RPM_INT32_TYPE) {
00071         val = xstrdup(_("(not a number)"));
00072     } else {
00073         val = xmalloc(15 + padding);
00074 /*@-boundswrite@*/
00075         strcat(formatPrefix, "s");
00076 /*@=boundswrite@*/
00077         buf = rpmPermsString(*((int_32 *) data));
00078         /*@-formatconst@*/
00079         sprintf(val, formatPrefix, buf);
00080         /*@=formatconst@*/
00081         buf = _free(buf);
00082     }
00083 
00084     return val;
00085 }
00086 
00096 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00097                 char * formatPrefix, int padding, /*@unused@*/ int element)
00098         /*@modifies formatPrefix @*/
00099         /*@requires maxRead(data) >= 0 @*/
00100 {
00101     char * val;
00102     char buf[15];
00103     int anint = *((int_32 *) data);
00104 
00105     if (type != RPM_INT32_TYPE) {
00106         val = xstrdup(_("(not a number)"));
00107     } else {
00108         buf[0] = '\0';
00109 /*@-boundswrite@*/
00110         if (anint & RPMFILE_DOC)
00111             strcat(buf, "d");
00112         if (anint & RPMFILE_CONFIG)
00113             strcat(buf, "c");
00114         if (anint & RPMFILE_SPECFILE)
00115             strcat(buf, "s");
00116         if (anint & RPMFILE_MISSINGOK)
00117             strcat(buf, "m");
00118         if (anint & RPMFILE_NOREPLACE)
00119             strcat(buf, "n");
00120         if (anint & RPMFILE_GHOST)
00121             strcat(buf, "g");
00122         if (anint & RPMFILE_LICENSE)
00123             strcat(buf, "l");
00124         if (anint & RPMFILE_README)
00125             strcat(buf, "r");
00126 /*@=boundswrite@*/
00127 
00128         val = xmalloc(5 + padding);
00129 /*@-boundswrite@*/
00130         strcat(formatPrefix, "s");
00131 /*@=boundswrite@*/
00132         /*@-formatconst@*/
00133         sprintf(val, formatPrefix, buf);
00134         /*@=formatconst@*/
00135     }
00136 
00137     return val;
00138 }
00139 
00150 static /*@only@*/ char * armorFormat(int_32 type, const void * data, 
00151                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00152                 int element)
00153         /*@*/
00154 {
00155     const char * enc;
00156     const unsigned char * s;
00157     size_t ns;
00158     int atype;
00159 
00160     switch (type) {
00161     case RPM_BIN_TYPE:
00162         s = data;
00163         /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
00164         ns = element;
00165         atype = PGPARMOR_SIGNATURE;     /* XXX check pkt for signature */
00166         break;
00167     case RPM_STRING_TYPE:
00168     case RPM_STRING_ARRAY_TYPE:
00169         enc = data;
00170         if (b64decode(enc, (void **)&s, &ns))
00171             return xstrdup(_("(not base64)"));
00172         atype = PGPARMOR_PUBKEY;        /* XXX check pkt for pubkey */
00173         break;
00174     case RPM_NULL_TYPE:
00175     case RPM_CHAR_TYPE:
00176     case RPM_INT8_TYPE:
00177     case RPM_INT16_TYPE:
00178     case RPM_INT32_TYPE:
00179     case RPM_I18NSTRING_TYPE:
00180     default:
00181         return xstrdup(_("(invalid type)"));
00182         /*@notreached@*/ break;
00183     }
00184 
00185     /* XXX this doesn't use padding directly, assumes enough slop in retval. */
00186     return pgpArmorWrap(atype, s, ns);
00187 }
00188 
00199 static /*@only@*/ char * base64Format(int_32 type, const void * data, 
00200                 /*@unused@*/ char * formatPrefix, int padding, int element)
00201         /*@*/
00202 {
00203     char * val;
00204 
00205     if (type != RPM_BIN_TYPE) {
00206         val = xstrdup(_("(not a blob)"));
00207     } else {
00208         const char * enc;
00209         char * t;
00210         int lc;
00211         /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
00212         size_t ns = element;
00213         size_t nt = 0;
00214 
00215 /*@-boundswrite@*/
00216         if ((enc = b64encode(data, ns, -1)) != NULL) {
00217                 nt = strlen(enc);
00218         }
00219 
00220         val = t = xmalloc(nt + padding + 1);
00221 
00222         *t = '\0';
00223         if (enc != NULL) {
00224             t = stpcpy(t, enc);
00225             enc = _free(enc);
00226         }
00227 /*@=boundswrite@*/
00228     }
00229 
00230     return val;
00231 }
00232 
00235 static size_t xmlstrlen(const char * s)
00236         /*@*/
00237 {
00238     size_t len = 0;
00239     int c;
00240 
00241 /*@-boundsread@*/
00242     while ((c = *s++) != '\0')
00243 /*@=boundsread@*/
00244     {
00245         switch (c) {
00246         case '<': case '>':     len += 4;       /*@switchbreak@*/ break;
00247         case '&':               len += 5;       /*@switchbreak@*/ break;
00248         default:                len += 1;       /*@switchbreak@*/ break;
00249         }
00250     }
00251     return len;
00252 }
00253 
00256 static char * xmlstrcpy(/*@returned@*/ char * t, const char * s)
00257         /*@modifies t @*/
00258 {
00259     char * te = t;
00260     int c;
00261 
00262 /*@-bounds@*/
00263     while ((c = *s++) != '\0') {
00264         switch (c) {
00265         case '<':       te = stpcpy(te, "&lt;");        /*@switchbreak@*/ break;
00266         case '>':       te = stpcpy(te, "&gt;");        /*@switchbreak@*/ break;
00267         case '&':       te = stpcpy(te, "&amp;");       /*@switchbreak@*/ break;
00268         default:        *te++ = c;                      /*@switchbreak@*/ break;
00269         }
00270     }
00271     *te = '\0';
00272 /*@=bounds@*/
00273     return t;
00274 }
00275 
00285 /*@-bounds@*/
00286 static /*@only@*/ char * xmlFormat(int_32 type, const void * data, 
00287                 char * formatPrefix, int padding,
00288                 /*@unused@*/ int element)
00289         /*@modifies formatPrefix @*/
00290 {
00291     const char * xtag = NULL;
00292     size_t nb;
00293     char * val;
00294     const char * s = NULL;
00295     char * t, * te;
00296     unsigned long anint = 0;
00297     int xx;
00298 
00299 /*@-branchstate@*/
00300     switch (type) {
00301     case RPM_I18NSTRING_TYPE:
00302     case RPM_STRING_TYPE:
00303         s = data;
00304         xtag = "string";
00305         break;
00306     case RPM_BIN_TYPE:
00307     {   
00308         /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
00309         size_t ns = element;
00310         if ((s = b64encode(data, ns, 0)) == NULL) {
00311                 /* XXX proper error handling would be better. */
00312                 s = xcalloc(1, padding + (ns / 3) * 4 + 1);
00313         }
00314         xtag = "base64";
00315     }   break;
00316     case RPM_CHAR_TYPE:
00317     case RPM_INT8_TYPE:
00318         anint = *((uint_8 *) data);
00319         break;
00320     case RPM_INT16_TYPE:
00321         anint = *((uint_16 *) data);
00322         break;
00323     case RPM_INT32_TYPE:
00324         anint = *((uint_32 *) data);
00325         break;
00326     case RPM_NULL_TYPE:
00327     case RPM_STRING_ARRAY_TYPE:
00328     default:
00329         return xstrdup(_("(invalid xml type)"));
00330         /*@notreached@*/ break;
00331     }
00332 /*@=branchstate@*/
00333 
00334 /*@-branchstate@*/
00335     if (s == NULL) {
00336         int tlen = 32;
00337         t = memset(alloca(tlen+1), 0, tlen+1);
00338         if (anint != 0)
00339             xx = snprintf(t, tlen, "%lu", anint);
00340         s = t;
00341         xtag = "integer";
00342     }
00343 /*@=branchstate@*/
00344 
00345     nb = xmlstrlen(s);
00346     if (nb == 0) {
00347         nb += strlen(xtag) + sizeof("\t</>");
00348         te = t = alloca(nb);
00349         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
00350     } else {
00351         nb += 2 * strlen(xtag) + sizeof("\t<></>");
00352         te = t = alloca(nb);
00353         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00354         te = xmlstrcpy(te, s);
00355         te += strlen(te);
00356         te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00357     }
00358 
00359     /* XXX s was malloc'd */
00360 /*@-branchstate@*/
00361     if (!strcmp(xtag, "base64"))
00362         s = _free(s);
00363 /*@=branchstate@*/
00364 
00365     nb += padding;
00366     val = xmalloc(nb+1);
00367 /*@-boundswrite@*/
00368     strcat(formatPrefix, "s");
00369 /*@=boundswrite@*/
00370 /*@-formatconst@*/
00371     xx = snprintf(val, nb, formatPrefix, t);
00372 /*@=formatconst@*/
00373     val[nb] = '\0';
00374 
00375     return val;
00376 }
00377 /*@=bounds@*/
00378 
00388 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data, 
00389                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00390                 /*@unused@*/ int element)
00391         /*@globals fileSystem, internalState @*/
00392         /*@modifies fileSystem, internalState @*/
00393 {
00394     char * val, * t;
00395 
00396     if (type != RPM_BIN_TYPE) {
00397         val = xstrdup(_("(not a blob)"));
00398     } else {
00399         unsigned char * pkt = (byte *) data;
00400         unsigned int pktlen = 0;
00401 /*@-boundsread@*/
00402         unsigned int v = *pkt;
00403 /*@=boundsread@*/
00404         pgpTag tag = 0;
00405         unsigned int plen;
00406         unsigned int hlen = 0;
00407 
00408         if (v & 0x80) {
00409             if (v & 0x40) {
00410                 tag = (v & 0x3f);
00411                 plen = pgpLen(pkt+1, &hlen);
00412             } else {
00413                 tag = (v >> 2) & 0xf;
00414                 plen = (1 << (v & 0x3));
00415                 hlen = pgpGrab(pkt+1, plen);
00416             }
00417         
00418             pktlen = 1 + plen + hlen;
00419         }
00420 
00421         if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00422             val = xstrdup(_("(not an OpenPGP signature)"));
00423         } else {
00424             pgpDig dig = pgpNewDig();
00425             pgpDigParams sigp = &dig->signature;
00426             size_t nb = 0;
00427             const char *tempstr;
00428 
00429             (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00430 
00431             val = NULL;
00432         again:
00433             nb += 100;
00434             val = t = xrealloc(val, nb + 1);
00435 
00436 /*@-boundswrite@*/
00437             switch (sigp->pubkey_algo) {
00438             case PGPPUBKEYALGO_DSA:
00439                 t = stpcpy(t, "DSA");
00440                 break;
00441             case PGPPUBKEYALGO_RSA:
00442                 t = stpcpy(t, "RSA");
00443                 break;
00444             default:
00445                 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
00446                 t += strlen(t);
00447                 break;
00448             }
00449             if (t + 5 >= val + nb)
00450                 goto again;
00451             *t++ = '/';
00452             switch (sigp->hash_algo) {
00453             case PGPHASHALGO_MD5:
00454                 t = stpcpy(t, "MD5");
00455                 break;
00456             case PGPHASHALGO_SHA1:
00457                 t = stpcpy(t, "SHA1");
00458                 break;
00459             default:
00460                 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
00461                 t += strlen(t);
00462                 break;
00463             }
00464             if (t + strlen (", ") + 1 >= val + nb)
00465                 goto again;
00466 
00467             t = stpcpy(t, ", ");
00468 
00469             /* this is important if sizeof(int_32) ! sizeof(time_t) */
00470             {   time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00471                 struct tm * tstruct = localtime(&dateint);
00472                 if (tstruct)
00473                     (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00474             }
00475             t += strlen(t);
00476             if (t + strlen (", Key ID ") + 1 >= val + nb)
00477                 goto again;
00478             t = stpcpy(t, ", Key ID ");
00479             tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
00480             if (t + strlen (tempstr) > val + nb)
00481                 goto again;
00482             t = stpcpy(t, tempstr);
00483 /*@=boundswrite@*/
00484 
00485             dig = pgpFreeDig(dig);
00486         }
00487     }
00488 
00489     return val;
00490 }
00491 
00501 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00502                 char * formatPrefix, int padding, /*@unused@*/ int element)
00503         /*@modifies formatPrefix @*/
00504         /*@requires maxRead(data) >= 0 @*/
00505 {
00506     char * val;
00507     char buf[10];
00508     int anint;
00509 
00510     if (type != RPM_INT32_TYPE) {
00511         val = xstrdup(_("(not a number)"));
00512     } else {
00513         anint = *((int_32 *) data);
00514         buf[0] = '\0';
00515 
00516 /*@-boundswrite@*/
00517         if (anint & RPMSENSE_LESS) 
00518             strcat(buf, "<");
00519         if (anint & RPMSENSE_GREATER)
00520             strcat(buf, ">");
00521         if (anint & RPMSENSE_EQUAL)
00522             strcat(buf, "=");
00523 /*@=boundswrite@*/
00524 
00525         val = xmalloc(5 + padding);
00526 /*@-boundswrite@*/
00527         strcat(formatPrefix, "s");
00528 /*@=boundswrite@*/
00529         /*@-formatconst@*/
00530         sprintf(val, formatPrefix, buf);
00531         /*@=formatconst@*/
00532     }
00533 
00534     return val;
00535 }
00536 
00546 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00547                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00548                 /*@out@*/ int * freeData)
00549         /*@globals fileSystem, internalState @*/
00550         /*@modifies *type, *data, *count, *freeData,
00551                 fileSystem, internalState @*/
00552         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00553                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00554 {
00555     const char ** list;
00556 
00557 /*@-boundswrite@*/
00558     if (rpmGetFilesystemList(&list, count))
00559         return 1;
00560 /*@=boundswrite@*/
00561 
00562     if (type) *type = RPM_STRING_ARRAY_TYPE;
00563     if (data) *((const char ***) data) = list;
00564     if (freeData) *freeData = 0;
00565 
00566     return 0; 
00567 }
00568 
00578 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00579                 /*@null@*/ /*@out@*/ const void ** data,
00580                 /*@null@*/ /*@out@*/ int_32 * count,
00581                 /*@null@*/ /*@out@*/ int * freeData)
00582         /*@modifies *type, *data, *freeData @*/
00583         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00584                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00585 {
00586     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00587     HFD_t hfd = headerFreeData;
00588     rpmTagType ipt;
00589     char ** array;
00590 
00591     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00592         if (freeData) *freeData = 0;
00593         return 0;
00594     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00595         if (type) *type = RPM_STRING_TYPE;
00596 /*@-boundsread@*/
00597         if (data) *data = xstrdup(array[0]);
00598 /*@=boundsread@*/
00599         if (freeData) *freeData = 1;
00600         array = hfd(array, ipt);
00601         return 0;
00602     }
00603 
00604     return 1;
00605 }
00606 
00616 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00617                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00618                 /*@out@*/ int * freeData)
00619         /*@globals rpmGlobalMacroContext, h_errno,
00620                 fileSystem, internalState @*/
00621         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00622                 fileSystem, internalState @*/
00623         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00624                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00625 {
00626     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00627     const char ** filenames;
00628     int_32 * filesizes;
00629     uint_32 * usages;
00630     int numFiles;
00631 
00632     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00633         filesizes = NULL;
00634         numFiles = 0;
00635         filenames = NULL;
00636     } else {
00637         rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00638     }
00639 
00640 /*@-boundswrite@*/
00641     if (rpmGetFilesystemList(NULL, count))
00642         return 1;
00643 /*@=boundswrite@*/
00644 
00645     *type = RPM_INT32_TYPE;
00646     *freeData = 1;
00647 
00648     if (filenames == NULL) {
00649         usages = xcalloc((*count), sizeof(usages));
00650         *data = usages;
00651 
00652         return 0;
00653     }
00654 
00655 /*@-boundswrite@*/
00656     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00657         return 1;
00658 /*@=boundswrite@*/
00659 
00660     *data = usages;
00661 
00662     filenames = _free(filenames);
00663 
00664     return 0;
00665 }
00666 
00676 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00677                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00678                 /*@out@*/ int * freeData)
00679         /*@modifies *type, *data, *count, *freeData @*/
00680         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00681                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00682 {
00683     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00684     HFD_t hfd = headerFreeData;
00685     rpmTagType tnt, tvt, tst;
00686     int_32 * indices, * flags;
00687     char ** names, ** versions;
00688     int numNames, numScripts;
00689     char ** conds, ** s;
00690     char * item, * flagsStr;
00691     char * chptr;
00692     int i, j, xx;
00693     char buf[5];
00694 
00695     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00696         *freeData = 0;
00697         return 0;
00698     }
00699 
00700     xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00701     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00702     xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00703     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00704     s = hfd(s, tst);
00705 
00706     *freeData = 1;
00707     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00708     *count = numScripts;
00709     *type = RPM_STRING_ARRAY_TYPE;
00710 /*@-bounds@*/
00711     for (i = 0; i < numScripts; i++) {
00712         chptr = xstrdup("");
00713 
00714         for (j = 0; j < numNames; j++) {
00715             if (indices[j] != i)
00716                 /*@innercontinue@*/ continue;
00717 
00718             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00719             if (flags[j] & RPMSENSE_SENSEMASK) {
00720                 buf[0] = '%', buf[1] = '\0';
00721                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00722                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00723                 flagsStr = _free(flagsStr);
00724             } else {
00725                 strcpy(item, names[j]);
00726             }
00727 
00728             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00729             if (*chptr != '\0') strcat(chptr, ", ");
00730             strcat(chptr, item);
00731             item = _free(item);
00732         }
00733 
00734         conds[i] = chptr;
00735     }
00736 /*@=bounds@*/
00737 
00738     names = hfd(names, tnt);
00739     versions = hfd(versions, tvt);
00740 
00741     return 0;
00742 }
00743 
00753 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00754                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00755                 /*@out@*/ int * freeData)
00756         /*@modifies *type, *data, *count, *freeData @*/
00757         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00758                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00759 {
00760     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00761     HFD_t hfd = headerFreeData;
00762     rpmTagType tst;
00763     int_32 * indices, * flags;
00764     const char ** conds;
00765     const char ** s;
00766     int i, j, xx;
00767     int numScripts, numNames;
00768 
00769     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00770         *freeData = 0;
00771         return 1;
00772     }
00773 
00774     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00775     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00776     s = hfd(s, tst);
00777 
00778     *freeData = 1;
00779     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00780     *count = numScripts;
00781     *type = RPM_STRING_ARRAY_TYPE;
00782 /*@-bounds@*/
00783     for (i = 0; i < numScripts; i++) {
00784         for (j = 0; j < numNames; j++) {
00785             if (indices[j] != i)
00786                 /*@innercontinue@*/ continue;
00787 
00788             if (flags[j] & RPMSENSE_TRIGGERPREIN)
00789                 conds[i] = xstrdup("prein");
00790             else if (flags[j] & RPMSENSE_TRIGGERIN)
00791                 conds[i] = xstrdup("in");
00792             else if (flags[j] & RPMSENSE_TRIGGERUN)
00793                 conds[i] = xstrdup("un");
00794             else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00795                 conds[i] = xstrdup("postun");
00796             else
00797                 conds[i] = xstrdup("");
00798             /*@innerbreak@*/ break;
00799         }
00800     }
00801 /*@=bounds@*/
00802 
00803     return 0;
00804 }
00805 
00815 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00816                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00817                 /*@out@*/ int * freeData)
00818         /*@modifies *type, *data, *count, *freeData @*/
00819         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00820                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00821 {
00822     *type = RPM_STRING_ARRAY_TYPE;
00823     rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00824     *freeData = 1;
00825     return 0; 
00826 }
00827 
00837 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
00838                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00839                 /*@out@*/ int * freeData)
00840         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00841         /*@modifies h, *type, *data, *count, *freeData,
00842                 rpmGlobalMacroContext, fileSystem @*/
00843         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00844                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00845 {
00846     *type = RPM_STRING_ARRAY_TYPE;
00847     rpmfiBuildFClasses(h, (const char ***) data, count);
00848     *freeData = 1;
00849     return 0; 
00850 }
00851 
00861 static int filecontextsTag(Header h, /*@out@*/ rpmTagType * type,
00862                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00863                 /*@out@*/ int * freeData)
00864         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00865         /*@modifies h, *type, *data, *count, *freeData,
00866                 rpmGlobalMacroContext, fileSystem @*/
00867         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00868                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00869 {
00870     *type = RPM_STRING_ARRAY_TYPE;
00871     rpmfiBuildFContexts(h, (const char ***) data, count);
00872     *freeData = 1;
00873     return 0; 
00874 }
00875 
00885 static int fscontextsTag(Header h, /*@out@*/ rpmTagType * type,
00886                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00887                 /*@out@*/ int * freeData)
00888         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00889         /*@modifies h, *type, *data, *count, *freeData,
00890                 rpmGlobalMacroContext, fileSystem @*/
00891         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00892                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00893 {
00894     *type = RPM_STRING_ARRAY_TYPE;
00895     rpmfiBuildFSContexts(h, (const char ***) data, count);
00896     *freeData = 1;
00897     return 0; 
00898 }
00899 
00909 static int recontextsTag(Header h, /*@out@*/ rpmTagType * type,
00910                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00911                 /*@out@*/ int * freeData)
00912         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00913         /*@modifies h, *type, *data, *count, *freeData,
00914                 rpmGlobalMacroContext, fileSystem @*/
00915         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00916                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00917 {
00918     *type = RPM_STRING_ARRAY_TYPE;
00919     rpmfiBuildREContexts(h, (const char ***) data, count);
00920     *freeData = 1;
00921     return 0; 
00922 }
00923 
00933 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
00934                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00935                 /*@out@*/ int * freeData)
00936         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00937         /*@modifies h, *type, *data, *count, *freeData,
00938                 rpmGlobalMacroContext, fileSystem, internalState @*/
00939         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00940                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00941 {
00942     *type = RPM_STRING_ARRAY_TYPE;
00943     rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00944     *freeData = 1;
00945     return 0; 
00946 }
00947 
00957 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
00958                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00959                 /*@out@*/ int * freeData)
00960         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00961         /*@modifies h, *type, *data, *count, *freeData,
00962                 rpmGlobalMacroContext, fileSystem, internalState @*/
00963         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00964                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00965 {
00966     *type = RPM_STRING_ARRAY_TYPE;
00967     rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00968     *freeData = 1;
00969     return 0; 
00970 }
00971 
00972 /* I18N look aside diversions */
00973 
00974 #if defined(ENABLE_NLS)
00975 /*@-exportlocal -exportheadervar@*/
00976 /*@unchecked@*/
00977 extern int _nl_msg_cat_cntr;    /* XXX GNU gettext voodoo */
00978 /*@=exportlocal =exportheadervar@*/
00979 #endif
00980 /*@observer@*/ /*@unchecked@*/
00981 static const char * language = "LANGUAGE";
00982 
00983 /*@observer@*/ /*@unchecked@*/
00984 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00985 
00996 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00997                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00998                 /*@out@*/ int * freeData)
00999         /*@globals rpmGlobalMacroContext, h_errno @*/
01000         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01001         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01002                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01003 {
01004     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01005     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01006     int rc;
01007 
01008     *type = RPM_STRING_TYPE;
01009     *data = NULL;
01010     *count = 0;
01011     *freeData = 0;
01012 
01013     if (dstring && *dstring) {
01014         char *domain, *de;
01015         const char * langval;
01016         const char * msgkey;
01017         const char * msgid;
01018 
01019         {   const char * tn = tagName(tag);
01020             const char * n;
01021             char * mk;
01022             size_t nb = sizeof("()");
01023             int xx = headerNVR(h, &n, NULL, NULL);
01024             if (tn)     nb += strlen(tn);
01025             if (n)      nb += strlen(n);
01026             mk = alloca(nb);
01027             sprintf(mk, "%s(%s)", n, tn);
01028             msgkey = mk;
01029         }
01030 
01031         /* change to en_US for msgkey -> msgid resolution */
01032         langval = getenv(language);
01033         (void) setenv(language, "en_US", 1);
01034 #if defined(ENABLE_NLS)
01035 /*@i@*/ ++_nl_msg_cat_cntr;
01036 #endif
01037 
01038         msgid = NULL;
01039         /*@-branchstate@*/
01040         for (domain = dstring; domain != NULL; domain = de) {
01041             de = strchr(domain, ':');
01042             if (de) *de++ = '\0';
01043             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
01044             if (msgid != msgkey) break;
01045         }
01046         /*@=branchstate@*/
01047 
01048         /* restore previous environment for msgid -> msgstr resolution */
01049         if (langval)
01050             (void) setenv(language, langval, 1);
01051         else
01052             unsetenv(language);
01053 #if defined(ENABLE_NLS)
01054 /*@i@*/ ++_nl_msg_cat_cntr;
01055 #endif
01056 
01057         if (domain && msgid) {
01058             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
01059             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
01060             *count = 1;
01061             *freeData = 1;
01062         }
01063         dstring = _free(dstring);
01064         if (*data)
01065             return 0;
01066     }
01067 
01068     dstring = _free(dstring);
01069 
01070     rc = hge(h, tag, type, (void **)data, count);
01071 
01072     if (rc && (*data) != NULL) {
01073         *data = xstrdup(*data);
01074         *freeData = 1;
01075         return 0;
01076     }
01077 
01078     *freeData = 0;
01079     *data = NULL;
01080     *count = 0;
01081     return 1;
01082 }
01083 
01093 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
01094                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01095                 /*@out@*/ int * freeData)
01096         /*@globals rpmGlobalMacroContext, h_errno @*/
01097         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01098         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01099                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01100 {
01101     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01102 }
01103 
01113 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
01114                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01115                 /*@out@*/ int * freeData)
01116         /*@globals rpmGlobalMacroContext, h_errno @*/
01117         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01118         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01119                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01120 {
01121     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01122 }
01123 
01133 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
01134                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01135                 /*@out@*/ int * freeData)
01136         /*@globals rpmGlobalMacroContext, h_errno @*/
01137         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01138         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01139                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01140 {
01141     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01142 }
01143 
01144 /*@-type@*/ /* FIX: cast? */
01145 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01146     { HEADER_EXT_TAG, "RPMTAG_GROUP",           { groupTag } },
01147     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION",     { descriptionTag } },
01148     { HEADER_EXT_TAG, "RPMTAG_SUMMARY",         { summaryTag } },
01149     { HEADER_EXT_TAG, "RPMTAG_FILECLASS",       { fileclassTag } },
01150     { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS",    { filecontextsTag } },
01151     { HEADER_EXT_TAG, "RPMTAG_FILENAMES",       { filenamesTag } },
01152     { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",     { fileprovideTag } },
01153     { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",     { filerequireTag } },
01154     { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS",      { fscontextsTag } },
01155     { HEADER_EXT_TAG, "RPMTAG_FSNAMES",         { fsnamesTag } },
01156     { HEADER_EXT_TAG, "RPMTAG_FSSIZES",         { fssizesTag } },
01157     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX",   { instprefixTag } },
01158     { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS",      { recontextsTag } },
01159     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS",    { triggercondsTag } },
01160     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE",     { triggertypeTag } },
01161     { HEADER_EXT_FORMAT, "armor",               { armorFormat } },
01162     { HEADER_EXT_FORMAT, "base64",              { base64Format } },
01163     { HEADER_EXT_FORMAT, "pgpsig",              { pgpsigFormat } },
01164     { HEADER_EXT_FORMAT, "depflags",            { depflagsFormat } },
01165     { HEADER_EXT_FORMAT, "fflags",              { fflagsFormat } },
01166     { HEADER_EXT_FORMAT, "perms",               { permsFormat } },
01167     { HEADER_EXT_FORMAT, "permissions",         { permsFormat } },
01168     { HEADER_EXT_FORMAT, "triggertype",         { triggertypeFormat } },
01169     { HEADER_EXT_FORMAT, "xml",                 { xmlFormat } },
01170     { HEADER_EXT_MORE, NULL,            { (void *) headerDefaultFormats } }
01171 } ;
01172 /*@=type@*/

Generated on Sun Sep 6 17:58:15 2009 for rpm by  doxygen 1.4.7