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 #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 = ((ns + 2) / 3) * 4;
00214 
00215 /*@-boundswrite@*/
00216         /*@-globs@*/
00217         /* Add additional bytes necessary for eol string(s). */
00218         if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00219             lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00220         if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00221             ++lc;
00222             nt += lc * strlen(b64encode_eolstr);
00223         }
00224         /*@=globs@*/
00225 
00226         val = t = xmalloc(nt + padding + 1);
00227 
00228         *t = '\0';
00229         if ((enc = b64encode(data, ns)) != NULL) {
00230             t = stpcpy(t, enc);
00231             enc = _free(enc);
00232         }
00233 /*@=boundswrite@*/
00234     }
00235 
00236     return val;
00237 }
00238 
00241 static size_t xmlstrlen(const char * s)
00242         /*@*/
00243 {
00244     size_t len = 0;
00245     int c;
00246 
00247 /*@-boundsread@*/
00248     while ((c = *s++) != '\0')
00249 /*@=boundsread@*/
00250     {
00251         switch (c) {
00252         case '<': case '>':     len += 4;       /*@switchbreak@*/ break;
00253         case '&':               len += 5;       /*@switchbreak@*/ break;
00254         default:                len += 1;       /*@switchbreak@*/ break;
00255         }
00256     }
00257     return len;
00258 }
00259 
00262 static char * xmlstrcpy(/*@returned@*/ char * t, const char * s)
00263         /*@modifies t @*/
00264 {
00265     char * te = t;
00266     int c;
00267 
00268 /*@-bounds@*/
00269     while ((c = *s++) != '\0') {
00270         switch (c) {
00271         case '<':       te = stpcpy(te, "&lt;");        /*@switchbreak@*/ break;
00272         case '>':       te = stpcpy(te, "&gt;");        /*@switchbreak@*/ break;
00273         case '&':       te = stpcpy(te, "&amp;");       /*@switchbreak@*/ break;
00274         default:        *te++ = c;                      /*@switchbreak@*/ break;
00275         }
00276     }
00277     *te = '\0';
00278 /*@=bounds@*/
00279     return t;
00280 }
00281 
00291 /*@-bounds@*/
00292 static /*@only@*/ char * xmlFormat(int_32 type, const void * data, 
00293                 char * formatPrefix, int padding,
00294                 /*@unused@*/ int element)
00295         /*@modifies formatPrefix @*/
00296 {
00297     const char * xtag = NULL;
00298     size_t nb;
00299     char * val;
00300     const char * s = NULL;
00301     char * t, * te;
00302     unsigned long anint = 0;
00303     int xx;
00304 
00305 /*@-branchstate@*/
00306     switch (type) {
00307     case RPM_I18NSTRING_TYPE:
00308     case RPM_STRING_TYPE:
00309         s = data;
00310         xtag = "string";
00311         break;
00312     case RPM_BIN_TYPE:
00313     {   int cpl = b64encode_chars_per_line;
00314 /*@-mods@*/
00315         b64encode_chars_per_line = 0;
00316 /*@=mods@*/
00317 /*@-formatconst@*/
00318         s = base64Format(type, data, formatPrefix, padding, element);
00319 /*@=formatconst@*/
00320 /*@-mods@*/
00321         b64encode_chars_per_line = cpl;
00322 /*@=mods@*/
00323         xtag = "base64";
00324     }   break;
00325     case RPM_CHAR_TYPE:
00326     case RPM_INT8_TYPE:
00327         anint = *((uint_8 *) data);
00328         break;
00329     case RPM_INT16_TYPE:
00330         anint = *((uint_16 *) data);
00331         break;
00332     case RPM_INT32_TYPE:
00333         anint = *((uint_32 *) data);
00334         break;
00335     case RPM_NULL_TYPE:
00336     case RPM_STRING_ARRAY_TYPE:
00337     default:
00338         return xstrdup(_("(invalid xml type)"));
00339         /*@notreached@*/ break;
00340     }
00341 /*@=branchstate@*/
00342 
00343 /*@-branchstate@*/
00344     if (s == NULL) {
00345         int tlen = 32;
00346         t = memset(alloca(tlen+1), 0, tlen+1);
00347         xx = snprintf(t, tlen, "%lu", anint);
00348         s = t;
00349         xtag = "integer";
00350     }
00351 /*@=branchstate@*/
00352 
00353     nb = 2 * strlen(xtag) + sizeof("\t<></>") + xmlstrlen(s);
00354     te = t = alloca(nb);
00355     te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00356     te = xmlstrcpy(te, s);
00357     te += strlen(te);
00358     te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00359 
00360     /* XXX s was malloc'd */
00361 /*@-branchstate@*/
00362     if (!strcmp(xtag, "base64"))
00363         s = _free(s);
00364 /*@=branchstate@*/
00365 
00366     nb += padding;
00367     val = xmalloc(nb+1);
00368 /*@-boundswrite@*/
00369     strcat(formatPrefix, "s");
00370 /*@=boundswrite@*/
00371 /*@-formatconst@*/
00372     xx = snprintf(val, nb, formatPrefix, t);
00373 /*@=formatconst@*/
00374     val[nb] = '\0';
00375 
00376     return val;
00377 }
00378 /*@=bounds@*/
00379 
00389 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data, 
00390                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00391                 /*@unused@*/ int element)
00392         /*@globals fileSystem, internalState @*/
00393         /*@modifies fileSystem, internalState @*/
00394 {
00395     char * val, * t;
00396 
00397     if (type != RPM_BIN_TYPE) {
00398         val = xstrdup(_("(not a blob)"));
00399     } else {
00400         unsigned char * pkt = (byte *) data;
00401         unsigned int pktlen = 0;
00402 /*@-boundsread@*/
00403         unsigned int v = *pkt;
00404 /*@=boundsread@*/
00405         pgpTag tag = 0;
00406         unsigned int plen;
00407         unsigned int hlen = 0;
00408 
00409         if (v & 0x80) {
00410             if (v & 0x40) {
00411                 tag = (v & 0x3f);
00412                 plen = pgpLen(pkt+1, &hlen);
00413             } else {
00414                 tag = (v >> 2) & 0xf;
00415                 plen = (1 << (v & 0x3));
00416                 hlen = pgpGrab(pkt+1, plen);
00417             }
00418         
00419             pktlen = 1 + plen + hlen;
00420         }
00421 
00422         if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00423             val = xstrdup(_("(not an OpenPGP signature)"));
00424         } else {
00425             pgpDig dig = pgpNewDig();
00426             pgpDigParams sigp = &dig->signature;
00427             size_t nb = 80;
00428 
00429             (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00430 
00431             val = t = xmalloc(nb + 1);
00432 
00433 /*@-boundswrite@*/
00434             switch (sigp->pubkey_algo) {
00435             case PGPPUBKEYALGO_DSA:
00436                 t = stpcpy(t, "DSA");
00437                 break;
00438             case PGPPUBKEYALGO_RSA:
00439                 t = stpcpy(t, "RSA");
00440                 break;
00441             default:
00442                 sprintf(t, "%d", sigp->pubkey_algo);
00443                 t += strlen(t);
00444                 break;
00445             }
00446             *t++ = '/';
00447             switch (sigp->hash_algo) {
00448             case PGPHASHALGO_MD5:
00449                 t = stpcpy(t, "MD5");
00450                 break;
00451             case PGPHASHALGO_SHA1:
00452                 t = stpcpy(t, "SHA1");
00453                 break;
00454             default:
00455                 sprintf(t, "%d", sigp->hash_algo);
00456                 t += strlen(t);
00457                 break;
00458             }
00459 
00460             t = stpcpy(t, ", ");
00461 
00462             /* this is important if sizeof(int_32) ! sizeof(time_t) */
00463             {   time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00464                 struct tm * tstruct = localtime(&dateint);
00465                 if (tstruct)
00466                     (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00467             }
00468             t += strlen(t);
00469             t = stpcpy(t, ", Key ID ");
00470             t = stpcpy(t, pgpHexStr(sigp->signid, sizeof(sigp->signid)));
00471 /*@=boundswrite@*/
00472 
00473             dig = pgpFreeDig(dig);
00474         }
00475     }
00476 
00477     return val;
00478 }
00479 
00489 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00490                 char * formatPrefix, int padding, /*@unused@*/ int element)
00491         /*@modifies formatPrefix @*/
00492         /*@requires maxRead(data) >= 0 @*/
00493 {
00494     char * val;
00495     char buf[10];
00496     int anint;
00497 
00498     if (type != RPM_INT32_TYPE) {
00499         val = xstrdup(_("(not a number)"));
00500     } else {
00501         anint = *((int_32 *) data);
00502         buf[0] = '\0';
00503 
00504 /*@-boundswrite@*/
00505         if (anint & RPMSENSE_LESS) 
00506             strcat(buf, "<");
00507         if (anint & RPMSENSE_GREATER)
00508             strcat(buf, ">");
00509         if (anint & RPMSENSE_EQUAL)
00510             strcat(buf, "=");
00511 /*@=boundswrite@*/
00512 
00513         val = xmalloc(5 + padding);
00514 /*@-boundswrite@*/
00515         strcat(formatPrefix, "s");
00516 /*@=boundswrite@*/
00517         /*@-formatconst@*/
00518         sprintf(val, formatPrefix, buf);
00519         /*@=formatconst@*/
00520     }
00521 
00522     return val;
00523 }
00524 
00534 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00535                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00536                 /*@out@*/ int * freeData)
00537         /*@globals fileSystem, internalState @*/
00538         /*@modifies *type, *data, *count, *freeData,
00539                 fileSystem, internalState @*/
00540         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00541                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00542 {
00543     const char ** list;
00544 
00545 /*@-boundswrite@*/
00546     if (rpmGetFilesystemList(&list, count))
00547         return 1;
00548 /*@=boundswrite@*/
00549 
00550     if (type) *type = RPM_STRING_ARRAY_TYPE;
00551     if (data) *((const char ***) data) = list;
00552     if (freeData) *freeData = 0;
00553 
00554     return 0; 
00555 }
00556 
00566 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00567                 /*@null@*/ /*@out@*/ const void ** data,
00568                 /*@null@*/ /*@out@*/ int_32 * count,
00569                 /*@null@*/ /*@out@*/ int * freeData)
00570         /*@modifies *type, *data, *freeData @*/
00571         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00572                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00573 {
00574     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00575     HFD_t hfd = headerFreeData;
00576     rpmTagType ipt;
00577     char ** array;
00578 
00579     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00580         if (freeData) *freeData = 0;
00581         return 0;
00582     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00583         if (type) *type = RPM_STRING_TYPE;
00584 /*@-boundsread@*/
00585         if (data) *data = xstrdup(array[0]);
00586 /*@=boundsread@*/
00587         if (freeData) *freeData = 1;
00588         array = hfd(array, ipt);
00589         return 0;
00590     }
00591 
00592     return 1;
00593 }
00594 
00604 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00605                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00606                 /*@out@*/ int * freeData)
00607         /*@globals rpmGlobalMacroContext, h_errno,
00608                 fileSystem, internalState @*/
00609         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00610                 fileSystem, internalState @*/
00611         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00612                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00613 {
00614     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00615     const char ** filenames;
00616     int_32 * filesizes;
00617     uint_32 * usages;
00618     int numFiles;
00619 
00620     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00621         filesizes = NULL;
00622         numFiles = 0;
00623         filenames = NULL;
00624     } else {
00625         rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00626     }
00627 
00628 /*@-boundswrite@*/
00629     if (rpmGetFilesystemList(NULL, count))
00630         return 1;
00631 /*@=boundswrite@*/
00632 
00633     *type = RPM_INT32_TYPE;
00634     *freeData = 1;
00635 
00636     if (filenames == NULL) {
00637         usages = xcalloc((*count), sizeof(usages));
00638         *data = usages;
00639 
00640         return 0;
00641     }
00642 
00643 /*@-boundswrite@*/
00644     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00645         return 1;
00646 /*@=boundswrite@*/
00647 
00648     *data = usages;
00649 
00650     filenames = _free(filenames);
00651 
00652     return 0;
00653 }
00654 
00664 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00665                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00666                 /*@out@*/ int * freeData)
00667         /*@modifies *type, *data, *count, *freeData @*/
00668         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00669                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00670 {
00671     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00672     HFD_t hfd = headerFreeData;
00673     rpmTagType tnt, tvt, tst;
00674     int_32 * indices, * flags;
00675     char ** names, ** versions;
00676     int numNames, numScripts;
00677     char ** conds, ** s;
00678     char * item, * flagsStr;
00679     char * chptr;
00680     int i, j, xx;
00681     char buf[5];
00682 
00683     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00684         *freeData = 0;
00685         return 0;
00686     }
00687 
00688     xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00689     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00690     xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00691     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00692     s = hfd(s, tst);
00693 
00694     *freeData = 1;
00695     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00696     *count = numScripts;
00697     *type = RPM_STRING_ARRAY_TYPE;
00698 /*@-bounds@*/
00699     for (i = 0; i < numScripts; i++) {
00700         chptr = xstrdup("");
00701 
00702         for (j = 0; j < numNames; j++) {
00703             if (indices[j] != i)
00704                 /*@innercontinue@*/ continue;
00705 
00706             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00707             if (flags[j] & RPMSENSE_SENSEMASK) {
00708                 buf[0] = '%', buf[1] = '\0';
00709                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00710                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00711                 flagsStr = _free(flagsStr);
00712             } else {
00713                 strcpy(item, names[j]);
00714             }
00715 
00716             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00717             if (*chptr != '\0') strcat(chptr, ", ");
00718             strcat(chptr, item);
00719             item = _free(item);
00720         }
00721 
00722         conds[i] = chptr;
00723     }
00724 /*@=bounds@*/
00725 
00726     names = hfd(names, tnt);
00727     versions = hfd(versions, tvt);
00728 
00729     return 0;
00730 }
00731 
00741 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00742                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00743                 /*@out@*/ int * freeData)
00744         /*@modifies *type, *data, *count, *freeData @*/
00745         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00746                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00747 {
00748     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00749     HFD_t hfd = headerFreeData;
00750     rpmTagType tst;
00751     int_32 * indices, * flags;
00752     const char ** conds;
00753     const char ** s;
00754     int i, j, xx;
00755     int numScripts, numNames;
00756 
00757     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00758         *freeData = 0;
00759         return 1;
00760     }
00761 
00762     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00763     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00764     s = hfd(s, tst);
00765 
00766     *freeData = 1;
00767     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00768     *count = numScripts;
00769     *type = RPM_STRING_ARRAY_TYPE;
00770 /*@-bounds@*/
00771     for (i = 0; i < numScripts; i++) {
00772         for (j = 0; j < numNames; j++) {
00773             if (indices[j] != i)
00774                 /*@innercontinue@*/ continue;
00775 
00776             if (flags[j] & RPMSENSE_TRIGGERPREIN)
00777                 conds[i] = xstrdup("prein");
00778             else if (flags[j] & RPMSENSE_TRIGGERIN)
00779                 conds[i] = xstrdup("in");
00780             else if (flags[j] & RPMSENSE_TRIGGERUN)
00781                 conds[i] = xstrdup("un");
00782             else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00783                 conds[i] = xstrdup("postun");
00784             else
00785                 conds[i] = xstrdup("");
00786             /*@innerbreak@*/ break;
00787         }
00788     }
00789 /*@=bounds@*/
00790 
00791     return 0;
00792 }
00793 
00803 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00804                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00805                 /*@out@*/ int * freeData)
00806         /*@modifies *type, *data, *count, *freeData @*/
00807         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00808                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00809 {
00810     *type = RPM_STRING_ARRAY_TYPE;
00811 
00812     rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00813     *freeData = 1;
00814 
00815     *freeData = 0;      /* XXX WTFO? */
00816 
00817     return 0; 
00818 }
00819 
00829 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
00830                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00831                 /*@out@*/ int * freeData)
00832         /*@globals fileSystem @*/
00833         /*@modifies h, *type, *data, *count, *freeData, fileSystem @*/
00834         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00835                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00836 {
00837     *type = RPM_STRING_ARRAY_TYPE;
00838     rpmfiBuildFClasses(h, (const char ***) data, count);
00839     *freeData = 1;
00840     return 0; 
00841 }
00842 
00852 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
00853                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00854                 /*@out@*/ int * freeData)
00855         /*@globals fileSystem @*/
00856         /*@modifies h, *type, *data, *count, *freeData, fileSystem @*/
00857         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00858                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00859 {
00860     *type = RPM_STRING_ARRAY_TYPE;
00861     rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00862     *freeData = 1;
00863     return 0; 
00864 }
00865 
00875 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
00876                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00877                 /*@out@*/ int * freeData)
00878         /*@globals fileSystem @*/
00879         /*@modifies h, *type, *data, *count, *freeData, fileSystem @*/
00880         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00881                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00882 {
00883     *type = RPM_STRING_ARRAY_TYPE;
00884     rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00885     *freeData = 1;
00886     return 0; 
00887 }
00888 
00889 /* I18N look aside diversions */
00890 
00891 /*@-exportlocal -exportheadervar@*/
00892 /*@unchecked@*/
00893 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00894 /*@=exportlocal =exportheadervar@*/
00895 /*@observer@*/ /*@unchecked@*/
00896 static const char * language = "LANGUAGE";
00897 
00898 /*@observer@*/ /*@unchecked@*/
00899 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00900 
00911 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00912                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00913                 /*@out@*/ int * freeData)
00914         /*@globals rpmGlobalMacroContext, h_errno @*/
00915         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00916         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00917                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00918 {
00919     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00920     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00921     int rc;
00922 
00923     *type = RPM_STRING_TYPE;
00924     *data = NULL;
00925     *count = 0;
00926     *freeData = 0;
00927 
00928     if (dstring && *dstring) {
00929         char *domain, *de;
00930         const char * langval;
00931         const char * msgkey;
00932         const char * msgid;
00933 
00934         {   const char * tn = tagName(tag);
00935             const char * n;
00936             char * mk;
00937             (void) headerNVR(h, &n, NULL, NULL);
00938             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00939             sprintf(mk, "%s(%s)", n, tn);
00940             msgkey = mk;
00941         }
00942 
00943         /* change to en_US for msgkey -> msgid resolution */
00944         langval = getenv(language);
00945         (void) setenv(language, "en_US", 1);
00946 /*@i@*/ ++_nl_msg_cat_cntr;
00947 
00948         msgid = NULL;
00949         /*@-branchstate@*/
00950         for (domain = dstring; domain != NULL; domain = de) {
00951             de = strchr(domain, ':');
00952             if (de) *de++ = '\0';
00953             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00954             if (msgid != msgkey) break;
00955         }
00956         /*@=branchstate@*/
00957 
00958         /* restore previous environment for msgid -> msgstr resolution */
00959         if (langval)
00960             (void) setenv(language, langval, 1);
00961         else
00962             unsetenv(language);
00963 /*@i@*/ ++_nl_msg_cat_cntr;
00964 
00965         if (domain && msgid) {
00966             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00967             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00968             *count = 1;
00969             *freeData = 1;
00970         }
00971         dstring = _free(dstring);
00972         if (*data)
00973             return 0;
00974     }
00975 
00976     dstring = _free(dstring);
00977 
00978     rc = hge(h, tag, type, (void **)data, count);
00979 
00980     if (rc && (*data) != NULL) {
00981         *data = xstrdup(*data);
00982         *freeData = 1;
00983         return 0;
00984     }
00985 
00986     *freeData = 0;
00987     *data = NULL;
00988     *count = 0;
00989     return 1;
00990 }
00991 
01001 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
01002                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01003                 /*@out@*/ int * freeData)
01004         /*@globals rpmGlobalMacroContext, h_errno @*/
01005         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01006         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01007                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01008 {
01009     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01010 }
01011 
01021 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
01022                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01023                 /*@out@*/ int * freeData)
01024         /*@globals rpmGlobalMacroContext, h_errno @*/
01025         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01026         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01027                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01028 {
01029     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01030 }
01031 
01041 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
01042                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01043                 /*@out@*/ int * freeData)
01044         /*@globals rpmGlobalMacroContext, h_errno @*/
01045         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01046         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01047                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01048 {
01049     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01050 }
01051 
01052 /*@-type@*/ /* FIX: cast? */
01053 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01054     { HEADER_EXT_TAG, "RPMTAG_GROUP",           { groupTag } },
01055     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION",     { descriptionTag } },
01056     { HEADER_EXT_TAG, "RPMTAG_SUMMARY",         { summaryTag } },
01057     { HEADER_EXT_TAG, "RPMTAG_FILECLASS",       { fileclassTag } },
01058     { HEADER_EXT_TAG, "RPMTAG_FILENAMES",       { filenamesTag } },
01059     { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",     { fileprovideTag } },
01060     { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",     { filerequireTag } },
01061     { HEADER_EXT_TAG, "RPMTAG_FSSIZES",         { fssizesTag } },
01062     { HEADER_EXT_TAG, "RPMTAG_FSNAMES",         { fsnamesTag } },
01063     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX",   { instprefixTag } },
01064     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS",    { triggercondsTag } },
01065     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE",     { triggertypeTag } },
01066     { HEADER_EXT_FORMAT, "armor",               { armorFormat } },
01067     { HEADER_EXT_FORMAT, "base64",              { base64Format } },
01068     { HEADER_EXT_FORMAT, "pgpsig",              { pgpsigFormat } },
01069     { HEADER_EXT_FORMAT, "depflags",            { depflagsFormat } },
01070     { HEADER_EXT_FORMAT, "fflags",              { fflagsFormat } },
01071     { HEADER_EXT_FORMAT, "perms",               { permsFormat } },
01072     { HEADER_EXT_FORMAT, "permissions",         { permsFormat } },
01073     { HEADER_EXT_FORMAT, "triggertype",         { triggertypeFormat } },
01074     { HEADER_EXT_FORMAT, "xml",                 { xmlFormat } },
01075     { HEADER_EXT_MORE, NULL,            { (void *) headerDefaultFormats } }
01076 } ;
01077 /*@=type@*/

Generated on Sun Oct 26 13:01:59 2003 for rpm by doxygen1.2.18