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

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         if (anint != 0)
00348             xx = snprintf(t, tlen, "%lu", anint);
00349         s = t;
00350         xtag = "integer";
00351     }
00352 /*@=branchstate@*/
00353 
00354     nb = xmlstrlen(s);
00355     if (nb == 0) {
00356         nb += strlen(xtag) + sizeof("\t</>");
00357         te = t = alloca(nb);
00358         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
00359     } else {
00360         nb += 2 * strlen(xtag) + sizeof("\t<></>");
00361         te = t = alloca(nb);
00362         te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00363         te = xmlstrcpy(te, s);
00364         te += strlen(te);
00365         te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00366     }
00367 
00368     /* XXX s was malloc'd */
00369 /*@-branchstate@*/
00370     if (!strcmp(xtag, "base64"))
00371         s = _free(s);
00372 /*@=branchstate@*/
00373 
00374     nb += padding;
00375     val = xmalloc(nb+1);
00376 /*@-boundswrite@*/
00377     strcat(formatPrefix, "s");
00378 /*@=boundswrite@*/
00379 /*@-formatconst@*/
00380     xx = snprintf(val, nb, formatPrefix, t);
00381 /*@=formatconst@*/
00382     val[nb] = '\0';
00383 
00384     return val;
00385 }
00386 /*@=bounds@*/
00387 
00397 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data, 
00398                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00399                 /*@unused@*/ int element)
00400         /*@globals fileSystem, internalState @*/
00401         /*@modifies fileSystem, internalState @*/
00402 {
00403     char * val, * t;
00404 
00405     if (type != RPM_BIN_TYPE) {
00406         val = xstrdup(_("(not a blob)"));
00407     } else {
00408         unsigned char * pkt = (byte *) data;
00409         unsigned int pktlen = 0;
00410 /*@-boundsread@*/
00411         unsigned int v = *pkt;
00412 /*@=boundsread@*/
00413         pgpTag tag = 0;
00414         unsigned int plen;
00415         unsigned int hlen = 0;
00416 
00417         if (v & 0x80) {
00418             if (v & 0x40) {
00419                 tag = (v & 0x3f);
00420                 plen = pgpLen(pkt+1, &hlen);
00421             } else {
00422                 tag = (v >> 2) & 0xf;
00423                 plen = (1 << (v & 0x3));
00424                 hlen = pgpGrab(pkt+1, plen);
00425             }
00426         
00427             pktlen = 1 + plen + hlen;
00428         }
00429 
00430         if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00431             val = xstrdup(_("(not an OpenPGP signature)"));
00432         } else {
00433             pgpDig dig = pgpNewDig();
00434             pgpDigParams sigp = &dig->signature;
00435             size_t nb = 80;
00436 
00437             (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00438 
00439             val = t = xmalloc(nb + 1);
00440 
00441 /*@-boundswrite@*/
00442             switch (sigp->pubkey_algo) {
00443             case PGPPUBKEYALGO_DSA:
00444                 t = stpcpy(t, "DSA");
00445                 break;
00446             case PGPPUBKEYALGO_RSA:
00447                 t = stpcpy(t, "RSA");
00448                 break;
00449             default:
00450                 sprintf(t, "%d", sigp->pubkey_algo);
00451                 t += strlen(t);
00452                 break;
00453             }
00454             *t++ = '/';
00455             switch (sigp->hash_algo) {
00456             case PGPHASHALGO_MD5:
00457                 t = stpcpy(t, "MD5");
00458                 break;
00459             case PGPHASHALGO_SHA1:
00460                 t = stpcpy(t, "SHA1");
00461                 break;
00462             default:
00463                 sprintf(t, "%d", sigp->hash_algo);
00464                 t += strlen(t);
00465                 break;
00466             }
00467 
00468             t = stpcpy(t, ", ");
00469 
00470             /* this is important if sizeof(int_32) ! sizeof(time_t) */
00471             {   time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00472                 struct tm * tstruct = localtime(&dateint);
00473                 if (tstruct)
00474                     (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00475             }
00476             t += strlen(t);
00477             t = stpcpy(t, ", Key ID ");
00478             t = stpcpy(t, pgpHexStr(sigp->signid, sizeof(sigp->signid)));
00479 /*@=boundswrite@*/
00480 
00481             dig = pgpFreeDig(dig);
00482         }
00483     }
00484 
00485     return val;
00486 }
00487 
00497 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00498                 char * formatPrefix, int padding, /*@unused@*/ int element)
00499         /*@modifies formatPrefix @*/
00500         /*@requires maxRead(data) >= 0 @*/
00501 {
00502     char * val;
00503     char buf[10];
00504     int anint;
00505 
00506     if (type != RPM_INT32_TYPE) {
00507         val = xstrdup(_("(not a number)"));
00508     } else {
00509         anint = *((int_32 *) data);
00510         buf[0] = '\0';
00511 
00512 /*@-boundswrite@*/
00513         if (anint & RPMSENSE_LESS) 
00514             strcat(buf, "<");
00515         if (anint & RPMSENSE_GREATER)
00516             strcat(buf, ">");
00517         if (anint & RPMSENSE_EQUAL)
00518             strcat(buf, "=");
00519 /*@=boundswrite@*/
00520 
00521         val = xmalloc(5 + padding);
00522 /*@-boundswrite@*/
00523         strcat(formatPrefix, "s");
00524 /*@=boundswrite@*/
00525         /*@-formatconst@*/
00526         sprintf(val, formatPrefix, buf);
00527         /*@=formatconst@*/
00528     }
00529 
00530     return val;
00531 }
00532 
00542 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00543                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00544                 /*@out@*/ int * freeData)
00545         /*@globals fileSystem, internalState @*/
00546         /*@modifies *type, *data, *count, *freeData,
00547                 fileSystem, internalState @*/
00548         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00549                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00550 {
00551     const char ** list;
00552 
00553 /*@-boundswrite@*/
00554     if (rpmGetFilesystemList(&list, count))
00555         return 1;
00556 /*@=boundswrite@*/
00557 
00558     if (type) *type = RPM_STRING_ARRAY_TYPE;
00559     if (data) *((const char ***) data) = list;
00560     if (freeData) *freeData = 0;
00561 
00562     return 0; 
00563 }
00564 
00574 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00575                 /*@null@*/ /*@out@*/ const void ** data,
00576                 /*@null@*/ /*@out@*/ int_32 * count,
00577                 /*@null@*/ /*@out@*/ int * freeData)
00578         /*@modifies *type, *data, *freeData @*/
00579         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00580                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00581 {
00582     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00583     HFD_t hfd = headerFreeData;
00584     rpmTagType ipt;
00585     char ** array;
00586 
00587     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00588         if (freeData) *freeData = 0;
00589         return 0;
00590     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00591         if (type) *type = RPM_STRING_TYPE;
00592 /*@-boundsread@*/
00593         if (data) *data = xstrdup(array[0]);
00594 /*@=boundsread@*/
00595         if (freeData) *freeData = 1;
00596         array = hfd(array, ipt);
00597         return 0;
00598     }
00599 
00600     return 1;
00601 }
00602 
00612 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00613                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00614                 /*@out@*/ int * freeData)
00615         /*@globals rpmGlobalMacroContext, h_errno,
00616                 fileSystem, internalState @*/
00617         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00618                 fileSystem, internalState @*/
00619         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00620                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00621 {
00622     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00623     const char ** filenames;
00624     int_32 * filesizes;
00625     uint_32 * usages;
00626     int numFiles;
00627 
00628     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00629         filesizes = NULL;
00630         numFiles = 0;
00631         filenames = NULL;
00632     } else {
00633         rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00634     }
00635 
00636 /*@-boundswrite@*/
00637     if (rpmGetFilesystemList(NULL, count))
00638         return 1;
00639 /*@=boundswrite@*/
00640 
00641     *type = RPM_INT32_TYPE;
00642     *freeData = 1;
00643 
00644     if (filenames == NULL) {
00645         usages = xcalloc((*count), sizeof(usages));
00646         *data = usages;
00647 
00648         return 0;
00649     }
00650 
00651 /*@-boundswrite@*/
00652     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00653         return 1;
00654 /*@=boundswrite@*/
00655 
00656     *data = usages;
00657 
00658     filenames = _free(filenames);
00659 
00660     return 0;
00661 }
00662 
00672 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00673                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00674                 /*@out@*/ int * freeData)
00675         /*@modifies *type, *data, *count, *freeData @*/
00676         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00677                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00678 {
00679     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00680     HFD_t hfd = headerFreeData;
00681     rpmTagType tnt, tvt, tst;
00682     int_32 * indices, * flags;
00683     char ** names, ** versions;
00684     int numNames, numScripts;
00685     char ** conds, ** s;
00686     char * item, * flagsStr;
00687     char * chptr;
00688     int i, j, xx;
00689     char buf[5];
00690 
00691     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00692         *freeData = 0;
00693         return 0;
00694     }
00695 
00696     xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00697     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00698     xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00699     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00700     s = hfd(s, tst);
00701 
00702     *freeData = 1;
00703     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00704     *count = numScripts;
00705     *type = RPM_STRING_ARRAY_TYPE;
00706 /*@-bounds@*/
00707     for (i = 0; i < numScripts; i++) {
00708         chptr = xstrdup("");
00709 
00710         for (j = 0; j < numNames; j++) {
00711             if (indices[j] != i)
00712                 /*@innercontinue@*/ continue;
00713 
00714             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00715             if (flags[j] & RPMSENSE_SENSEMASK) {
00716                 buf[0] = '%', buf[1] = '\0';
00717                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00718                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00719                 flagsStr = _free(flagsStr);
00720             } else {
00721                 strcpy(item, names[j]);
00722             }
00723 
00724             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00725             if (*chptr != '\0') strcat(chptr, ", ");
00726             strcat(chptr, item);
00727             item = _free(item);
00728         }
00729 
00730         conds[i] = chptr;
00731     }
00732 /*@=bounds@*/
00733 
00734     names = hfd(names, tnt);
00735     versions = hfd(versions, tvt);
00736 
00737     return 0;
00738 }
00739 
00749 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00750                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00751                 /*@out@*/ int * freeData)
00752         /*@modifies *type, *data, *count, *freeData @*/
00753         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00754                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00755 {
00756     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00757     HFD_t hfd = headerFreeData;
00758     rpmTagType tst;
00759     int_32 * indices, * flags;
00760     const char ** conds;
00761     const char ** s;
00762     int i, j, xx;
00763     int numScripts, numNames;
00764 
00765     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00766         *freeData = 0;
00767         return 1;
00768     }
00769 
00770     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00771     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00772     s = hfd(s, tst);
00773 
00774     *freeData = 1;
00775     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00776     *count = numScripts;
00777     *type = RPM_STRING_ARRAY_TYPE;
00778 /*@-bounds@*/
00779     for (i = 0; i < numScripts; i++) {
00780         for (j = 0; j < numNames; j++) {
00781             if (indices[j] != i)
00782                 /*@innercontinue@*/ continue;
00783 
00784             if (flags[j] & RPMSENSE_TRIGGERPREIN)
00785                 conds[i] = xstrdup("prein");
00786             else if (flags[j] & RPMSENSE_TRIGGERIN)
00787                 conds[i] = xstrdup("in");
00788             else if (flags[j] & RPMSENSE_TRIGGERUN)
00789                 conds[i] = xstrdup("un");
00790             else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00791                 conds[i] = xstrdup("postun");
00792             else
00793                 conds[i] = xstrdup("");
00794             /*@innerbreak@*/ break;
00795         }
00796     }
00797 /*@=bounds@*/
00798 
00799     return 0;
00800 }
00801 
00811 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00812                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00813                 /*@out@*/ int * freeData)
00814         /*@modifies *type, *data, *count, *freeData @*/
00815         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00816                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00817 {
00818     *type = RPM_STRING_ARRAY_TYPE;
00819     rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00820     *freeData = 1;
00821     return 0; 
00822 }
00823 
00833 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
00834                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00835                 /*@out@*/ int * freeData)
00836         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00837         /*@modifies h, *type, *data, *count, *freeData,
00838                 rpmGlobalMacroContext, fileSystem @*/
00839         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00840                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00841 {
00842     *type = RPM_STRING_ARRAY_TYPE;
00843     rpmfiBuildFClasses(h, (const char ***) data, count);
00844     *freeData = 1;
00845     return 0; 
00846 }
00847 
00857 static int filecontextsTag(Header h, /*@out@*/ rpmTagType * type,
00858                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00859                 /*@out@*/ int * freeData)
00860         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00861         /*@modifies h, *type, *data, *count, *freeData,
00862                 rpmGlobalMacroContext, fileSystem @*/
00863         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00864                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00865 {
00866     *type = RPM_STRING_ARRAY_TYPE;
00867     rpmfiBuildFContexts(h, (const char ***) data, count);
00868     *freeData = 1;
00869     return 0; 
00870 }
00871 
00881 static int fscontextsTag(Header h, /*@out@*/ rpmTagType * type,
00882                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00883                 /*@out@*/ int * freeData)
00884         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00885         /*@modifies h, *type, *data, *count, *freeData,
00886                 rpmGlobalMacroContext, fileSystem @*/
00887         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00888                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00889 {
00890     *type = RPM_STRING_ARRAY_TYPE;
00891     rpmfiBuildFSContexts(h, (const char ***) data, count);
00892     *freeData = 1;
00893     return 0; 
00894 }
00895 
00905 static int recontextsTag(Header h, /*@out@*/ rpmTagType * type,
00906                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00907                 /*@out@*/ int * freeData)
00908         /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
00909         /*@modifies h, *type, *data, *count, *freeData,
00910                 rpmGlobalMacroContext, fileSystem @*/
00911         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00912                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00913 {
00914     *type = RPM_STRING_ARRAY_TYPE;
00915     rpmfiBuildREContexts(h, (const char ***) data, count);
00916     *freeData = 1;
00917     return 0; 
00918 }
00919 
00929 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
00930                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00931                 /*@out@*/ int * freeData)
00932         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00933         /*@modifies h, *type, *data, *count, *freeData,
00934                 rpmGlobalMacroContext, fileSystem, internalState @*/
00935         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00936                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00937 {
00938     *type = RPM_STRING_ARRAY_TYPE;
00939     rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00940     *freeData = 1;
00941     return 0; 
00942 }
00943 
00953 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
00954                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00955                 /*@out@*/ int * freeData)
00956         /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00957         /*@modifies h, *type, *data, *count, *freeData,
00958                 rpmGlobalMacroContext, fileSystem, internalState @*/
00959         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00960                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00961 {
00962     *type = RPM_STRING_ARRAY_TYPE;
00963     rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00964     *freeData = 1;
00965     return 0; 
00966 }
00967 
00968 /* I18N look aside diversions */
00969 
00970 /*@-exportlocal -exportheadervar@*/
00971 /*@unchecked@*/
00972 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00973 /*@=exportlocal =exportheadervar@*/
00974 /*@observer@*/ /*@unchecked@*/
00975 static const char * language = "LANGUAGE";
00976 
00977 /*@observer@*/ /*@unchecked@*/
00978 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00979 
00990 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00991                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00992                 /*@out@*/ int * freeData)
00993         /*@globals rpmGlobalMacroContext, h_errno @*/
00994         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00995         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00996                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00997 {
00998     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00999     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01000     int rc;
01001 
01002     *type = RPM_STRING_TYPE;
01003     *data = NULL;
01004     *count = 0;
01005     *freeData = 0;
01006 
01007     if (dstring && *dstring) {
01008         char *domain, *de;
01009         const char * langval;
01010         const char * msgkey;
01011         const char * msgid;
01012 
01013         {   const char * tn = tagName(tag);
01014             const char * n;
01015             char * mk;
01016             (void) headerNVR(h, &n, NULL, NULL);
01017             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
01018             sprintf(mk, "%s(%s)", n, tn);
01019             msgkey = mk;
01020         }
01021 
01022         /* change to en_US for msgkey -> msgid resolution */
01023         langval = getenv(language);
01024         (void) setenv(language, "en_US", 1);
01025 /*@i@*/ ++_nl_msg_cat_cntr;
01026 
01027         msgid = NULL;
01028         /*@-branchstate@*/
01029         for (domain = dstring; domain != NULL; domain = de) {
01030             de = strchr(domain, ':');
01031             if (de) *de++ = '\0';
01032             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
01033             if (msgid != msgkey) break;
01034         }
01035         /*@=branchstate@*/
01036 
01037         /* restore previous environment for msgid -> msgstr resolution */
01038         if (langval)
01039             (void) setenv(language, langval, 1);
01040         else
01041             unsetenv(language);
01042 /*@i@*/ ++_nl_msg_cat_cntr;
01043 
01044         if (domain && msgid) {
01045             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
01046             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
01047             *count = 1;
01048             *freeData = 1;
01049         }
01050         dstring = _free(dstring);
01051         if (*data)
01052             return 0;
01053     }
01054 
01055     dstring = _free(dstring);
01056 
01057     rc = hge(h, tag, type, (void **)data, count);
01058 
01059     if (rc && (*data) != NULL) {
01060         *data = xstrdup(*data);
01061         *freeData = 1;
01062         return 0;
01063     }
01064 
01065     *freeData = 0;
01066     *data = NULL;
01067     *count = 0;
01068     return 1;
01069 }
01070 
01080 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
01081                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01082                 /*@out@*/ int * freeData)
01083         /*@globals rpmGlobalMacroContext, h_errno @*/
01084         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01085         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01086                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01087 {
01088     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01089 }
01090 
01100 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
01101                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01102                 /*@out@*/ int * freeData)
01103         /*@globals rpmGlobalMacroContext, h_errno @*/
01104         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01105         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01106                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01107 {
01108     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01109 }
01110 
01120 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
01121                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
01122                 /*@out@*/ int * freeData)
01123         /*@globals rpmGlobalMacroContext, h_errno @*/
01124         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
01125         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
01126                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
01127 {
01128     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01129 }
01130 
01131 /*@-type@*/ /* FIX: cast? */
01132 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01133     { HEADER_EXT_TAG, "RPMTAG_GROUP",           { groupTag } },
01134     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION",     { descriptionTag } },
01135     { HEADER_EXT_TAG, "RPMTAG_SUMMARY",         { summaryTag } },
01136     { HEADER_EXT_TAG, "RPMTAG_FILECLASS",       { fileclassTag } },
01137     { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS",    { filecontextsTag } },
01138     { HEADER_EXT_TAG, "RPMTAG_FILENAMES",       { filenamesTag } },
01139     { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE",     { fileprovideTag } },
01140     { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE",     { filerequireTag } },
01141     { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS",      { fscontextsTag } },
01142     { HEADER_EXT_TAG, "RPMTAG_FSNAMES",         { fsnamesTag } },
01143     { HEADER_EXT_TAG, "RPMTAG_FSSIZES",         { fssizesTag } },
01144     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX",   { instprefixTag } },
01145     { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS",      { recontextsTag } },
01146     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS",    { triggercondsTag } },
01147     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE",     { triggertypeTag } },
01148     { HEADER_EXT_FORMAT, "armor",               { armorFormat } },
01149     { HEADER_EXT_FORMAT, "base64",              { base64Format } },
01150     { HEADER_EXT_FORMAT, "pgpsig",              { pgpsigFormat } },
01151     { HEADER_EXT_FORMAT, "depflags",            { depflagsFormat } },
01152     { HEADER_EXT_FORMAT, "fflags",              { fflagsFormat } },
01153     { HEADER_EXT_FORMAT, "perms",               { permsFormat } },
01154     { HEADER_EXT_FORMAT, "permissions",         { permsFormat } },
01155     { HEADER_EXT_FORMAT, "triggertype",         { triggertypeFormat } },
01156     { HEADER_EXT_FORMAT, "xml",                 { xmlFormat } },
01157     { HEADER_EXT_MORE, NULL,            { (void *) headerDefaultFormats } }
01158 } ;
01159 /*@=type@*/

Generated on Sun Jul 24 03:53:38 2005 for rpm by  doxygen 1.3.9.1