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 #include "manifest.h"
00010 #include "misc.h"
00011 #include "debug.h"
00012 
00013 /*@access pgpDig @*/
00014 /*@access pgpDigParams @*/
00015 
00025 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data, 
00026                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00027                 /*@unused@*/ int element)
00028         /*@requires maxRead(data) >= 0 @*/
00029 {
00030     const int_32 * item = data;
00031     char * val;
00032 
00033     if (type != RPM_INT32_TYPE)
00034         val = xstrdup(_("(not a number)"));
00035     else if (*item & RPMSENSE_TRIGGERIN)
00036         val = xstrdup("in");
00037     else
00038         val = xstrdup("un");
00039     return val;
00040 }
00041 
00051 static /*@only@*/ char * permsFormat(int_32 type, const void * data,
00052                 char * formatPrefix, int padding, /*@unused@*/ int element)
00053         /*@modifies formatPrefix @*/
00054         /*@requires maxRead(data) >= 0 @*/
00055 {
00056     char * val;
00057     char * buf;
00058 
00059     if (type != RPM_INT32_TYPE) {
00060         val = xstrdup(_("(not a number)"));
00061     } else {
00062         val = xmalloc(15 + padding);
00063 /*@-boundswrite@*/
00064         strcat(formatPrefix, "s");
00065 /*@=boundswrite@*/
00066         buf = rpmPermsString(*((int_32 *) data));
00067         /*@-formatconst@*/
00068         sprintf(val, formatPrefix, buf);
00069         /*@=formatconst@*/
00070         buf = _free(buf);
00071     }
00072 
00073     return val;
00074 }
00075 
00085 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00086                 char * formatPrefix, int padding, /*@unused@*/ int element)
00087         /*@modifies formatPrefix @*/
00088         /*@requires maxRead(data) >= 0 @*/
00089 {
00090     char * val;
00091     char buf[15];
00092     int anint = *((int_32 *) data);
00093 
00094     if (type != RPM_INT32_TYPE) {
00095         val = xstrdup(_("(not a number)"));
00096     } else {
00097         buf[0] = '\0';
00098 /*@-boundswrite@*/
00099         if (anint & RPMFILE_DOC)
00100             strcat(buf, "d");
00101         if (anint & RPMFILE_CONFIG)
00102             strcat(buf, "c");
00103         if (anint & RPMFILE_SPECFILE)
00104             strcat(buf, "s");
00105         if (anint & RPMFILE_MISSINGOK)
00106             strcat(buf, "m");
00107         if (anint & RPMFILE_NOREPLACE)
00108             strcat(buf, "n");
00109         if (anint & RPMFILE_GHOST)
00110             strcat(buf, "g");
00111         if (anint & RPMFILE_LICENSE)
00112             strcat(buf, "l");
00113         if (anint & RPMFILE_README)
00114             strcat(buf, "r");
00115 /*@=boundswrite@*/
00116 
00117         val = xmalloc(5 + padding);
00118 /*@-boundswrite@*/
00119         strcat(formatPrefix, "s");
00120 /*@=boundswrite@*/
00121         /*@-formatconst@*/
00122         sprintf(val, formatPrefix, buf);
00123         /*@=formatconst@*/
00124     }
00125 
00126     return val;
00127 }
00128 
00139 static /*@only@*/ char * armorFormat(int_32 type, const void * data, 
00140                 /*@unused@*/ char * formatPrefix, int padding, int element)
00141         /*@*/
00142 {
00143     const char * enc;
00144     const char * s;
00145     char * t;
00146     char * val;
00147     int atype;
00148     int lc, ns, nt;
00149 
00150     switch (type) {
00151     case RPM_BIN_TYPE:
00152         s = data;
00153         ns = element;
00154         atype = PGPARMOR_SIGNATURE;     /* XXX check pkt for signature */
00155         break;
00156     case RPM_STRING_TYPE:
00157     case RPM_STRING_ARRAY_TYPE:
00158         enc = data;
00159         if (b64decode(enc, (void **)&s, &ns))
00160             return xstrdup(_("(not base64)"));
00161         atype = PGPARMOR_PUBKEY;        /* XXX check pkt for pubkey */
00162         break;
00163     case RPM_NULL_TYPE:
00164     case RPM_CHAR_TYPE:
00165     case RPM_INT8_TYPE:
00166     case RPM_INT16_TYPE:
00167     case RPM_INT32_TYPE:
00168     case RPM_I18NSTRING_TYPE:
00169     default:
00170         return xstrdup(_("(invalid type)"));
00171         /*@notreached@*/ break;
00172     }
00173 
00174     nt = ((ns + 2) / 3) * 4;
00175     /*@-globs@*/
00176     /* Add additional bytes necessary for eol string(s). */
00177     if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00178         lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00179        if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00180         ++lc;
00181         nt += lc * strlen(b64encode_eolstr);
00182     }
00183     /*@=globs@*/
00184 
00185     nt += 512;  /* XXX slop for armor and crc */
00186 
00187 /*@-boundswrite@*/
00188     val = t = xmalloc(nt + padding + 1);
00189     *t = '\0';
00190     t = stpcpy(t, "-----BEGIN PGP ");
00191     t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00192     /*@-globs@*/
00193     t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), RPMVERSION);
00194     /*@=globs@*/
00195     t = stpcpy(t, " (beecrypt-2.2.0)\n\n");
00196 
00197     if ((enc = b64encode(s, ns)) != NULL) {
00198         t = stpcpy(t, enc);
00199         enc = _free(enc);
00200         if ((enc = b64crc(s, ns)) != NULL) {
00201             *t++ = '=';
00202             t = stpcpy(t, enc);
00203             enc = _free(enc);
00204         }
00205     }
00206         
00207     t = stpcpy(t, "-----END PGP ");
00208     t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00209     t = stpcpy(t, "-----\n");
00210 /*@=boundswrite@*/
00211 
00212     /*@-branchstate@*/
00213     if (s != data) s = _free(s);
00214     /*@=branchstate@*/
00215 
00216     return val;
00217 }
00218 
00229 static /*@only@*/ char * base64Format(int_32 type, const void * data, 
00230                 /*@unused@*/ char * formatPrefix, int padding, int element)
00231         /*@*/
00232 {
00233     char * val;
00234 
00235     if (type != RPM_BIN_TYPE) {
00236         val = xstrdup(_("(not a blob)"));
00237     } else {
00238         const char * enc;
00239         char * t;
00240         int lc;
00241         int nt = ((element + 2) / 3) * 4;
00242 
00243 /*@-boundswrite@*/
00244         /*@-globs@*/
00245         /* Add additional bytes necessary for eol string(s). */
00246         if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00247             lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00248         if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00249             ++lc;
00250             nt += lc * strlen(b64encode_eolstr);
00251         }
00252         /*@=globs@*/
00253 
00254         val = t = xmalloc(nt + padding + 1);
00255 
00256         *t = '\0';
00257         if ((enc = b64encode(data, element)) != NULL) {
00258             t = stpcpy(t, enc);
00259             enc = _free(enc);
00260         }
00261 /*@=boundswrite@*/
00262     }
00263 
00264     return val;
00265 }
00266 
00276 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data, 
00277                 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00278                 /*@unused@*/ int element)
00279         /*@globals fileSystem @*/
00280         /*@modifies fileSystem @*/
00281 {
00282     char * val, * t;
00283 
00284     if (type != RPM_BIN_TYPE) {
00285         val = xstrdup(_("(not a blob)"));
00286     } else {
00287         unsigned char * pkt = (byte *) data;
00288         unsigned int pktlen = 0;
00289 /*@-boundsread@*/
00290         unsigned int v = *pkt;
00291 /*@=boundsread@*/
00292         pgpTag tag = 0;
00293         unsigned int plen;
00294         unsigned int hlen = 0;
00295 
00296         if (v & 0x80) {
00297             if (v & 0x40) {
00298                 tag = (v & 0x3f);
00299                 plen = pgpLen(pkt+1, &hlen);
00300             } else {
00301                 tag = (v >> 2) & 0xf;
00302                 plen = (1 << (v & 0x3));
00303                 hlen = pgpGrab(pkt+1, plen);
00304             }
00305         
00306             pktlen = 1 + plen + hlen;
00307         }
00308 
00309         if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00310             val = xstrdup(_("(not an OpenPGP signature)"));
00311         } else {
00312             pgpDig dig = pgpNewDig();
00313             pgpDigParams sigp = &dig->signature;
00314             size_t nb = 80;
00315 
00316             (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00317 
00318             val = t = xmalloc(nb + 1);
00319 
00320 /*@-boundswrite@*/
00321             switch (sigp->pubkey_algo) {
00322             case PGPPUBKEYALGO_DSA:
00323                 t = stpcpy(t, "DSA");
00324                 break;
00325             case PGPPUBKEYALGO_RSA:
00326                 t = stpcpy(t, "RSA");
00327                 break;
00328             default:
00329                 sprintf(t, "%d", sigp->pubkey_algo);
00330                 t += strlen(t);
00331                 break;
00332             }
00333             *t++ = '/';
00334             switch (sigp->hash_algo) {
00335             case PGPHASHALGO_MD5:
00336                 t = stpcpy(t, "MD5");
00337                 break;
00338             case PGPHASHALGO_SHA1:
00339                 t = stpcpy(t, "SHA1");
00340                 break;
00341             default:
00342                 sprintf(t, "%d", sigp->hash_algo);
00343                 t += strlen(t);
00344                 break;
00345             }
00346 
00347             t = stpcpy(t, ", ");
00348 
00349             /* this is important if sizeof(int_32) ! sizeof(time_t) */
00350             {   time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00351                 struct tm * tstruct = localtime(&dateint);
00352                 if (tstruct)
00353                     (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00354             }
00355             t += strlen(t);
00356             t = stpcpy(t, ", Key ID ");
00357             t = stpcpy(t, pgpHexStr(sigp->signid, sizeof(sigp->signid)));
00358 /*@=boundswrite@*/
00359 
00360             dig = pgpFreeDig(dig);
00361         }
00362     }
00363 
00364     return val;
00365 }
00366 
00376 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00377                 char * formatPrefix, int padding, /*@unused@*/ int element)
00378         /*@modifies formatPrefix @*/
00379         /*@requires maxRead(data) >= 0 @*/
00380 {
00381     char * val;
00382     char buf[10];
00383     int anint = *((int_32 *) data);
00384 
00385     if (type != RPM_INT32_TYPE) {
00386         val = xstrdup(_("(not a number)"));
00387     } else {
00388         buf[0] = '\0';
00389 
00390 /*@-boundswrite@*/
00391         if (anint & RPMSENSE_LESS) 
00392             strcat(buf, "<");
00393         if (anint & RPMSENSE_GREATER)
00394             strcat(buf, ">");
00395         if (anint & RPMSENSE_EQUAL)
00396             strcat(buf, "=");
00397 /*@=boundswrite@*/
00398 
00399         val = xmalloc(5 + padding);
00400 /*@-boundswrite@*/
00401         strcat(formatPrefix, "s");
00402 /*@=boundswrite@*/
00403         /*@-formatconst@*/
00404         sprintf(val, formatPrefix, buf);
00405         /*@=formatconst@*/
00406     }
00407 
00408     return val;
00409 }
00410 
00420 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00421                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00422                 /*@out@*/ int * freeData)
00423         /*@globals fileSystem, internalState @*/
00424         /*@modifies *type, *data, *count, *freeData,
00425                 fileSystem, internalState @*/
00426         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00427                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00428 {
00429     const char ** list;
00430 
00431 /*@-boundswrite@*/
00432     if (rpmGetFilesystemList(&list, count))
00433         return 1;
00434 /*@=boundswrite@*/
00435 
00436     if (type) *type = RPM_STRING_ARRAY_TYPE;
00437     if (data) *((const char ***) data) = list;
00438     if (freeData) *freeData = 0;
00439 
00440     return 0; 
00441 }
00442 
00452 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00453                 /*@null@*/ /*@out@*/ const void ** data,
00454                 /*@null@*/ /*@out@*/ int_32 * count,
00455                 /*@null@*/ /*@out@*/ int * freeData)
00456         /*@modifies *type, *data, *freeData @*/
00457         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00458                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00459 {
00460     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00461     HFD_t hfd = headerFreeData;
00462     rpmTagType ipt;
00463     char ** array;
00464 
00465     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00466         if (freeData) *freeData = 0;
00467         return 0;
00468     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00469         if (type) *type = RPM_STRING_TYPE;
00470 /*@-boundsread@*/
00471         if (data) *data = xstrdup(array[0]);
00472 /*@=boundsread@*/
00473         if (freeData) *freeData = 1;
00474         array = hfd(array, ipt);
00475         return 0;
00476     }
00477 
00478     return 1;
00479 }
00480 
00490 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00491                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00492                 /*@out@*/ int * freeData)
00493         /*@globals rpmGlobalMacroContext,
00494                 fileSystem, internalState @*/
00495         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00496                 fileSystem, internalState @*/
00497         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00498                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00499 {
00500     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00501     const char ** filenames;
00502     int_32 * filesizes;
00503     uint_32 * usages;
00504     int numFiles;
00505 
00506     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00507         filesizes = NULL;
00508         numFiles = 0;
00509         filenames = NULL;
00510     } else {
00511         rpmBuildFileList(h, &filenames, &numFiles);
00512     }
00513 
00514 /*@-boundswrite@*/
00515     if (rpmGetFilesystemList(NULL, count))
00516         return 1;
00517 /*@=boundswrite@*/
00518 
00519     *type = RPM_INT32_TYPE;
00520     *freeData = 1;
00521 
00522     if (filenames == NULL) {
00523         usages = xcalloc((*count), sizeof(usages));
00524         *data = usages;
00525 
00526         return 0;
00527     }
00528 
00529 /*@-boundswrite@*/
00530     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00531         return 1;
00532 /*@=boundswrite@*/
00533 
00534     *data = usages;
00535 
00536     filenames = _free(filenames);
00537 
00538     return 0;
00539 }
00540 
00550 /*@-bounds@*/   /* LCL: segfault */
00551 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00552                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00553                 /*@out@*/ int * freeData)
00554         /*@modifies *type, *data, *count, *freeData @*/
00555         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00556                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00557 {
00558     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00559     HFD_t hfd = headerFreeData;
00560     rpmTagType tnt, tvt, tst;
00561     int_32 * indices, * flags;
00562     char ** names, ** versions;
00563     int numNames, numScripts;
00564     char ** conds, ** s;
00565     char * item, * flagsStr;
00566     char * chptr;
00567     int i, j, xx;
00568     char buf[5];
00569 
00570     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00571         *freeData = 0;
00572         return 0;
00573     }
00574 
00575     xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00576     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00577     xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00578     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00579     s = hfd(s, tst);
00580 
00581     *freeData = 1;
00582     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00583     *count = numScripts;
00584     *type = RPM_STRING_ARRAY_TYPE;
00585     for (i = 0; i < numScripts; i++) {
00586         chptr = xstrdup("");
00587 
00588         for (j = 0; j < numNames; j++) {
00589             if (indices[j] != i)
00590                 /*@innercontinue@*/ continue;
00591 
00592             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00593             if (flags[j] & RPMSENSE_SENSEMASK) {
00594                 buf[0] = '%', buf[1] = '\0';
00595                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00596                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00597                 flagsStr = _free(flagsStr);
00598             } else {
00599                 strcpy(item, names[j]);
00600             }
00601 
00602             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00603             if (*chptr != '\0') strcat(chptr, ", ");
00604             strcat(chptr, item);
00605             item = _free(item);
00606         }
00607 
00608         conds[i] = chptr;
00609     }
00610 
00611     names = hfd(names, tnt);
00612     versions = hfd(versions, tvt);
00613 
00614     return 0;
00615 }
00616 /*@=bounds@*/
00617 
00627 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00628                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00629                 /*@out@*/ int * freeData)
00630         /*@modifies *type, *data, *count, *freeData @*/
00631         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00632                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00633 {
00634     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00635     HFD_t hfd = headerFreeData;
00636     rpmTagType tst;
00637     int_32 * indices, * flags;
00638     const char ** conds;
00639     const char ** s;
00640     int i, j, xx;
00641     int numScripts, numNames;
00642 
00643     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00644         *freeData = 0;
00645         return 1;
00646     }
00647 
00648     xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00649     xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00650     s = hfd(s, tst);
00651 
00652     *freeData = 1;
00653     *data = conds = xmalloc(sizeof(*conds) * numScripts);
00654     *count = numScripts;
00655     *type = RPM_STRING_ARRAY_TYPE;
00656     for (i = 0; i < numScripts; i++) {
00657         for (j = 0; j < numNames; j++) {
00658             if (indices[j] != i)
00659                 /*@innercontinue@*/ continue;
00660 
00661             if (flags[j] & RPMSENSE_TRIGGERIN)
00662                 conds[i] = xstrdup("in");
00663             else if (flags[j] & RPMSENSE_TRIGGERUN)
00664                 conds[i] = xstrdup("un");
00665             else
00666                 conds[i] = xstrdup("postun");
00667             /*@innerbreak@*/ break;
00668         }
00669     }
00670 
00671     return 0;
00672 }
00673 
00683 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00684                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00685                 /*@out@*/ int * freeData)
00686         /*@modifies *type, *data, *count, *freeData @*/
00687         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00688                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00689 {
00690     *type = RPM_STRING_ARRAY_TYPE;
00691 
00692     rpmBuildFileList(h, (const char ***) data, count);
00693     *freeData = 1;
00694 
00695     *freeData = 0;      /* XXX WTFO? */
00696 
00697     return 0; 
00698 }
00699 
00700 /* I18N look aside diversions */
00701 
00702 /*@-exportlocal -exportheadervar@*/
00703 /*@unchecked@*/
00704 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00705 /*@=exportlocal =exportheadervar@*/
00706 /*@observer@*/ /*@unchecked@*/
00707 static const char * language = "LANGUAGE";
00708 
00709 /*@observer@*/ /*@unchecked@*/
00710 static const char * _macro_i18ndomains =
00711                 "%{?_i18ndomains:%{_i18ndomains}}";
00712 
00723 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00724                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00725                 /*@out@*/ int * freeData)
00726         /*@globals rpmGlobalMacroContext @*/
00727         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00728         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00729                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00730 {
00731     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00732     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00733     int rc;
00734 
00735     *type = RPM_STRING_TYPE;
00736     *data = NULL;
00737     *count = 0;
00738     *freeData = 0;
00739 
00740     if (dstring && *dstring) {
00741         char *domain, *de;
00742         const char * langval;
00743         const char * msgkey;
00744         const char * msgid;
00745 
00746         {   const char * tn = tagName(tag);
00747             const char * n;
00748             char * mk;
00749             (void) headerNVR(h, &n, NULL, NULL);
00750             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00751             sprintf(mk, "%s(%s)", n, tn);
00752             msgkey = mk;
00753         }
00754 
00755         /* change to en_US for msgkey -> msgid resolution */
00756         langval = getenv(language);
00757         (void) setenv(language, "en_US", 1);
00758 /*@i@*/ ++_nl_msg_cat_cntr;
00759 
00760         msgid = NULL;
00761         /*@-branchstate@*/
00762         for (domain = dstring; domain != NULL; domain = de) {
00763             de = strchr(domain, ':');
00764             if (de) *de++ = '\0';
00765             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00766             if (msgid != msgkey) break;
00767         }
00768         /*@=branchstate@*/
00769 
00770         /* restore previous environment for msgid -> msgstr resolution */
00771         if (langval)
00772             (void) setenv(language, langval, 1);
00773         else
00774             unsetenv(language);
00775 /*@i@*/ ++_nl_msg_cat_cntr;
00776 
00777         if (domain && msgid) {
00778             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00779             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00780             *count = 1;
00781             *freeData = 1;
00782         }
00783         dstring = _free(dstring);
00784         if (*data)
00785             return 0;
00786     }
00787 
00788     dstring = _free(dstring);
00789 
00790     rc = hge(h, tag, type, (void **)data, count);
00791 
00792     if (rc && (*data) != NULL) {
00793         *data = xstrdup(*data);
00794         *freeData = 1;
00795         return 0;
00796     }
00797 
00798     *freeData = 0;
00799     *data = NULL;
00800     *count = 0;
00801     return 1;
00802 }
00803 
00813 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
00814                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00815                 /*@out@*/ int * freeData)
00816         /*@globals rpmGlobalMacroContext @*/
00817         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00818         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00819                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00820 {
00821     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00822 }
00823 
00833 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
00834                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00835                 /*@out@*/ int * freeData)
00836         /*@globals rpmGlobalMacroContext @*/
00837         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00838         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00839                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00840 {
00841     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00842 }
00843 
00853 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
00854                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00855                 /*@out@*/ int * freeData)
00856         /*@globals rpmGlobalMacroContext @*/
00857         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00858         /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
00859                 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
00860 {
00861     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00862 }
00863 
00864 /*@-type@*/ /* FIX: cast? */
00865 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00866     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00867     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00868     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00869     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00870     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00871     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00872     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00873     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00874     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00875     { HEADER_EXT_FORMAT, "armor", { armorFormat } },
00876     { HEADER_EXT_FORMAT, "base64", { base64Format } },
00877     { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
00878     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00879     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00880     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00881     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00882     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00883     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00884 } ;
00885 /*@=type@*/

Generated on Tue Sep 17 15:56:39 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002