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     rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00812     *freeData = 1;
00813     return 0; 
00814 }
00815 
00825 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
00826                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00827                 /*@out@*/ int * freeData)
00828         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00829         /*@modifies h, *type, *data, *count, *freeData,
00830                 rpmGlobalMacroContext, fileSystem @*/
00831         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00832                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00833 {
00834     *type = RPM_STRING_ARRAY_TYPE;
00835     rpmfiBuildFClasses(h, (const char ***) data, count);
00836     *freeData = 1;
00837     return 0; 
00838 }
00839 
00849 static int filecontextsTag(Header h, /*@out@*/ rpmTagType * type,
00850                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00851                 /*@out@*/ int * freeData)
00852         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00853         /*@modifies h, *type, *data, *count, *freeData,
00854                 rpmGlobalMacroContext, fileSystem @*/
00855         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00856                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00857 {
00858     *type = RPM_STRING_ARRAY_TYPE;
00859     rpmfiBuildFContexts(h, (const char ***) data, count);
00860     *freeData = 1;
00861     return 0; 
00862 }
00863 
00873 static int fscontextsTag(Header h, /*@out@*/ rpmTagType * type,
00874                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00875                 /*@out@*/ int * freeData)
00876         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00877         /*@modifies h, *type, *data, *count, *freeData,
00878                 rpmGlobalMacroContext, fileSystem @*/
00879         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00880                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00881 {
00882     *type = RPM_STRING_ARRAY_TYPE;
00883     rpmfiBuildFSContexts(h, (const char ***) data, count);
00884     *freeData = 1;
00885     return 0; 
00886 }
00887 
00897 static int recontextsTag(Header h, /*@out@*/ rpmTagType * type,
00898                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00899                 /*@out@*/ int * freeData)
00900         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00901         /*@modifies h, *type, *data, *count, *freeData,
00902                 rpmGlobalMacroContext, fileSystem @*/
00903         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00904                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00905 {
00906     *type = RPM_STRING_ARRAY_TYPE;
00907     rpmfiBuildREContexts(h, (const char ***) data, count);
00908     *freeData = 1;
00909     return 0; 
00910 }
00911 
00921 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
00922                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00923                 /*@out@*/ int * freeData)
00924         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00925         /*@modifies h, *type, *data, *count, *freeData,
00926                 rpmGlobalMacroContext, fileSystem @*/
00927         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00928                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00929 {
00930     *type = RPM_STRING_ARRAY_TYPE;
00931     rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00932     *freeData = 1;
00933     return 0; 
00934 }
00935 
00945 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
00946                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00947                 /*@out@*/ int * freeData)
00948         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00949         /*@modifies h, *type, *data, *count, *freeData,
00950                 rpmGlobalMacroContext, fileSystem @*/
00951         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00952                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00953 {
00954     *type = RPM_STRING_ARRAY_TYPE;
00955     rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00956     *freeData = 1;
00957     return 0; 
00958 }
00959 
00960 /* I18N look aside diversions */
00961 
00962 /*@-exportlocal -exportheadervar@*/
00963 /*@unchecked@*/
00964 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00965 /*@=exportlocal =exportheadervar@*/
00966 /*@observer@*/ /*@unchecked@*/
00967 static const char * language = "LANGUAGE";
00968 
00969 /*@observer@*/ /*@unchecked@*/
00970 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00971 
00982 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00983                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00984                 /*@out@*/ int * freeData)
00985         /*@globals rpmGlobalMacroContext, h_errno @*/
00986         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00987         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00988                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00989 {
00990     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00991     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00992     int rc;
00993 
00994     *type = RPM_STRING_TYPE;
00995     *data = NULL;
00996     *count = 0;
00997     *freeData = 0;
00998 
00999     if (dstring && *dstring) {
01000         char *domain, *de;
01001         const char * langval;
01002         const char * msgkey;
01003         const char * msgid;
01004 
01005         {   const char * tn = tagName(tag);
01006             const char * n;
01007             char * mk;
01008             (void) headerNVR(h, &n, NULL, NULL);
01009             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
01010             sprintf(mk, "%s(%s)", n, tn);
01011             msgkey = mk;
01012         }
01013 
01014         /* change to en_US for msgkey -> msgid resolution */
01015         langval = getenv(language);
01016         (void) setenv(language, "en_US", 1);
01017 /*@i@*/ ++_nl_msg_cat_cntr;
01018 
01019         msgid = NULL;
01020         /*@-branchstate@*/
01021         for (domain = dstring; domain != NULL; domain = de) {
01022             de = strchr(domain, ':');
01023             if (de) *de++ = '\0';
01024             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
01025             if (msgid != msgkey) break;
01026         }
01027         /*@=branchstate@*/
01028 
01029         /* restore previous environment for msgid -> msgstr resolution */
01030         if (langval)
01031             (void) setenv(language, langval, 1);
01032         else
01033             unsetenv(language);
01034 /*@i@*/ ++_nl_msg_cat_cntr;
01035 
01036         if (domain && msgid) {
01037             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
01038             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
01039             *count = 1;
01040             *freeData = 1;
01041         }
01042         dstring = _free(dstring);
01043         if (*data)
01044             return 0;
01045     }
01046 
01047     dstring = _free(dstring);
01048 
01049     rc = hge(h, tag, type, (void **)data, count);
01050 
01051     if (rc && (*data) != NULL) {
01052         *data = xstrdup(*data);
01053         *freeData = 1;
01054         return 0;
01055     }
01056 
01057     *freeData = 0;
01058     *data = NULL;
01059     *count = 0;
01060     return 1;
01061 }
01062 
01072 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
01073                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01074                 /*@out@*/ int * freeData)
01075         /*@globals rpmGlobalMacroContext, h_errno @*/
01076         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01077         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01078                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01079 {
01080     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01081 }
01082 
01092 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
01093                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01094                 /*@out@*/ int * freeData)
01095         /*@globals rpmGlobalMacroContext, h_errno @*/
01096         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01097         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01098                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01099 {
01100     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01101 }
01102 
01112 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
01113                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01114                 /*@out@*/ int * freeData)
01115         /*@globals rpmGlobalMacroContext, h_errno @*/
01116         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01117         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01118                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01119 {
01120     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01121 }
01122 
01123 /*@-type@*/ /* FIX: cast? */
01124 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01125     { HEADER_EXT_TAG, "RPMTAG_GROUP",           { groupTag } },
01126     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION",     { descriptionTag } },
01127     { HEADER_EXT_TAG, "RPMTAG_SUMMARY",         { summaryTag } },
01128     { HEADER_EXT_TAG, "RPMTAG_FILECLASS",       { fileclassTag } },
01129     { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS",    { filecontextsTag } },
01130     { HEADER_EXT_TAG, "RPMTAG_FILENAMES",       { filenamesTag } },
01131     { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",     { fileprovideTag } },
01132     { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",     { filerequireTag } },
01133     { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS",      { fscontextsTag } },
01134     { HEADER_EXT_TAG, "RPMTAG_FSNAMES",         { fsnamesTag } },
01135     { HEADER_EXT_TAG, "RPMTAG_FSSIZES",         { fssizesTag } },
01136     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX",   { instprefixTag } },
01137     { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS",      { recontextsTag } },
01138     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS",    { triggercondsTag } },
01139     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE",     { triggertypeTag } },
01140     { HEADER_EXT_FORMAT, "armor",               { armorFormat } },
01141     { HEADER_EXT_FORMAT, "base64",              { base64Format } },
01142     { HEADER_EXT_FORMAT, "pgpsig",              { pgpsigFormat } },
01143     { HEADER_EXT_FORMAT, "depflags",            { depflagsFormat } },
01144     { HEADER_EXT_FORMAT, "fflags",              { fflagsFormat } },
01145     { HEADER_EXT_FORMAT, "perms",               { permsFormat } },
01146     { HEADER_EXT_FORMAT, "permissions",         { permsFormat } },
01147     { HEADER_EXT_FORMAT, "triggertype",         { triggertypeFormat } },
01148     { HEADER_EXT_FORMAT, "xml",                 { xmlFormat } },
01149     { HEADER_EXT_MORE, NULL,            { (void *) headerDefaultFormats } }
01150 } ;
01151 /*@=type@*/

Generated on Fri Apr 16 16:36:52 2004 for rpm by doxygen 1.3.6