00001
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include <rpmlib.h>
00008 #include <rpmmacro.h>
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
00019
00020
00030 static char * triggertypeFormat(int_32 type, const void * data,
00031 char * formatPrefix, int padding,
00032 int element)
00033
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 char * permsFormat(int_32 type, const void * data,
00063 char * formatPrefix, int padding, int element)
00064
00065
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
00075 strcat(formatPrefix, "s");
00076
00077 buf = rpmPermsString(*((int_32 *) data));
00078
00079 sprintf(val, formatPrefix, buf);
00080
00081 buf = _free(buf);
00082 }
00083
00084 return val;
00085 }
00086
00096 static char * fflagsFormat(int_32 type, const void * data,
00097 char * formatPrefix, int padding, int element)
00098
00099
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
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
00127
00128 val = xmalloc(5 + padding);
00129
00130 strcat(formatPrefix, "s");
00131
00132
00133 sprintf(val, formatPrefix, buf);
00134
00135 }
00136
00137 return val;
00138 }
00139
00150 static char * armorFormat(int_32 type, const void * data,
00151 char * formatPrefix, 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
00164 ns = element;
00165 atype = PGPARMOR_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;
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 break;
00183 }
00184
00185
00186 return pgpArmorWrap(atype, s, ns);
00187 }
00188
00199 static char * base64Format(int_32 type, const void * data,
00200 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
00212 size_t ns = element;
00213 size_t nt = ((ns + 2) / 3) * 4;
00214
00215
00216
00217
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
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
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
00248 while ((c = *s++) != '\0')
00249
00250 {
00251 switch (c) {
00252 case '<': case '>': len += 4; break;
00253 case '&': len += 5; break;
00254 default: len += 1; break;
00255 }
00256 }
00257 return len;
00258 }
00259
00262 static char * xmlstrcpy( char * t, const char * s)
00263
00264 {
00265 char * te = t;
00266 int c;
00267
00268
00269 while ((c = *s++) != '\0') {
00270 switch (c) {
00271 case '<': te = stpcpy(te, "<"); break;
00272 case '>': te = stpcpy(te, ">"); break;
00273 case '&': te = stpcpy(te, "&"); break;
00274 default: *te++ = c; break;
00275 }
00276 }
00277 *te = '\0';
00278
00279 return t;
00280 }
00281
00291
00292 static char * xmlFormat(int_32 type, const void * data,
00293 char * formatPrefix, int padding,
00294 int element)
00295
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
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
00315 b64encode_chars_per_line = 0;
00316
00317
00318 s = base64Format(type, data, formatPrefix, padding, element);
00319
00320
00321 b64encode_chars_per_line = cpl;
00322
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 break;
00340 }
00341
00342
00343
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
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
00369
00370 if (!strcmp(xtag, "base64"))
00371 s = _free(s);
00372
00373
00374 nb += padding;
00375 val = xmalloc(nb+1);
00376
00377 strcat(formatPrefix, "s");
00378
00379
00380 xx = snprintf(val, nb, formatPrefix, t);
00381
00382 val[nb] = '\0';
00383
00384 return val;
00385 }
00386
00387
00397 static char * pgpsigFormat(int_32 type, const void * data,
00398 char * formatPrefix, int padding,
00399 int element)
00400
00401
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
00411 unsigned int v = *pkt;
00412
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 = 0;
00436 const char *tempstr;
00437
00438 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00439
00440 val = NULL;
00441 again:
00442 nb += 100;
00443 val = t = xrealloc(val, nb + 1);
00444
00445
00446 switch (sigp->pubkey_algo) {
00447 case PGPPUBKEYALGO_DSA:
00448 t = stpcpy(t, "DSA");
00449 break;
00450 case PGPPUBKEYALGO_RSA:
00451 t = stpcpy(t, "RSA");
00452 break;
00453 default:
00454 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
00455 t += strlen(t);
00456 break;
00457 }
00458 if (t + 5 >= val + nb)
00459 goto again;
00460 *t++ = '/';
00461 switch (sigp->hash_algo) {
00462 case PGPHASHALGO_MD5:
00463 t = stpcpy(t, "MD5");
00464 break;
00465 case PGPHASHALGO_SHA1:
00466 t = stpcpy(t, "SHA1");
00467 break;
00468 default:
00469 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
00470 t += strlen(t);
00471 break;
00472 }
00473 if (t + strlen (", ") + 1 >= val + nb)
00474 goto again;
00475
00476 t = stpcpy(t, ", ");
00477
00478
00479 { time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00480 struct tm * tstruct = localtime(&dateint);
00481 if (tstruct)
00482 (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00483 }
00484 t += strlen(t);
00485 if (t + strlen (", Key ID ") + 1 >= val + nb)
00486 goto again;
00487 t = stpcpy(t, ", Key ID ");
00488 tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
00489 if (t + strlen (tempstr) > val + nb)
00490 goto again;
00491 t = stpcpy(t, tempstr);
00492
00493
00494 dig = pgpFreeDig(dig);
00495 }
00496 }
00497
00498 return val;
00499 }
00500
00510 static char * depflagsFormat(int_32 type, const void * data,
00511 char * formatPrefix, int padding, int element)
00512
00513
00514 {
00515 char * val;
00516 char buf[10];
00517 int anint;
00518
00519 if (type != RPM_INT32_TYPE) {
00520 val = xstrdup(_("(not a number)"));
00521 } else {
00522 anint = *((int_32 *) data);
00523 buf[0] = '\0';
00524
00525
00526 if (anint & RPMSENSE_LESS)
00527 strcat(buf, "<");
00528 if (anint & RPMSENSE_GREATER)
00529 strcat(buf, ">");
00530 if (anint & RPMSENSE_EQUAL)
00531 strcat(buf, "=");
00532
00533
00534 val = xmalloc(5 + padding);
00535
00536 strcat(formatPrefix, "s");
00537
00538
00539 sprintf(val, formatPrefix, buf);
00540
00541 }
00542
00543 return val;
00544 }
00545
00555 static int fsnamesTag( Header h, int_32 * type,
00556 void ** data, int_32 * count,
00557 int * freeData)
00558
00559
00560
00561
00562
00563 {
00564 const char ** list;
00565
00566
00567 if (rpmGetFilesystemList(&list, count))
00568 return 1;
00569
00570
00571 if (type) *type = RPM_STRING_ARRAY_TYPE;
00572 if (data) *((const char ***) data) = list;
00573 if (freeData) *freeData = 0;
00574
00575 return 0;
00576 }
00577
00587 static int instprefixTag(Header h, rpmTagType * type,
00588 const void ** data,
00589 int_32 * count,
00590 int * freeData)
00591
00592
00593
00594 {
00595 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00596 HFD_t hfd = headerFreeData;
00597 rpmTagType ipt;
00598 char ** array;
00599
00600 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00601 if (freeData) *freeData = 0;
00602 return 0;
00603 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00604 if (type) *type = RPM_STRING_TYPE;
00605
00606 if (data) *data = xstrdup(array[0]);
00607
00608 if (freeData) *freeData = 1;
00609 array = hfd(array, ipt);
00610 return 0;
00611 }
00612
00613 return 1;
00614 }
00615
00625 static int fssizesTag(Header h, rpmTagType * type,
00626 const void ** data, int_32 * count,
00627 int * freeData)
00628
00629
00630
00631
00632
00633
00634 {
00635 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00636 const char ** filenames;
00637 int_32 * filesizes;
00638 uint_32 * usages;
00639 int numFiles;
00640
00641 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00642 filesizes = NULL;
00643 numFiles = 0;
00644 filenames = NULL;
00645 } else {
00646 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00647 }
00648
00649
00650 if (rpmGetFilesystemList(NULL, count))
00651 return 1;
00652
00653
00654 *type = RPM_INT32_TYPE;
00655 *freeData = 1;
00656
00657 if (filenames == NULL) {
00658 usages = xcalloc((*count), sizeof(usages));
00659 *data = usages;
00660
00661 return 0;
00662 }
00663
00664
00665 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00666 return 1;
00667
00668
00669 *data = usages;
00670
00671 filenames = _free(filenames);
00672
00673 return 0;
00674 }
00675
00685 static int triggercondsTag(Header h, rpmTagType * type,
00686 const void ** data, int_32 * count,
00687 int * freeData)
00688
00689
00690
00691 {
00692 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00693 HFD_t hfd = headerFreeData;
00694 rpmTagType tnt, tvt, tst;
00695 int_32 * indices, * flags;
00696 char ** names, ** versions;
00697 int numNames, numScripts;
00698 char ** conds, ** s;
00699 char * item, * flagsStr;
00700 char * chptr;
00701 int i, j, xx;
00702 char buf[5];
00703
00704 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00705 *freeData = 0;
00706 return 0;
00707 }
00708
00709 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00710 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00711 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00712 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00713 s = hfd(s, tst);
00714
00715 *freeData = 1;
00716 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00717 *count = numScripts;
00718 *type = RPM_STRING_ARRAY_TYPE;
00719
00720 for (i = 0; i < numScripts; i++) {
00721 chptr = xstrdup("");
00722
00723 for (j = 0; j < numNames; j++) {
00724 if (indices[j] != i)
00725 continue;
00726
00727 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00728 if (flags[j] & RPMSENSE_SENSEMASK) {
00729 buf[0] = '%', buf[1] = '\0';
00730 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00731 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00732 flagsStr = _free(flagsStr);
00733 } else {
00734 strcpy(item, names[j]);
00735 }
00736
00737 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00738 if (*chptr != '\0') strcat(chptr, ", ");
00739 strcat(chptr, item);
00740 item = _free(item);
00741 }
00742
00743 conds[i] = chptr;
00744 }
00745
00746
00747 names = hfd(names, tnt);
00748 versions = hfd(versions, tvt);
00749
00750 return 0;
00751 }
00752
00762 static int triggertypeTag(Header h, rpmTagType * type,
00763 const void ** data, int_32 * count,
00764 int * freeData)
00765
00766
00767
00768 {
00769 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00770 HFD_t hfd = headerFreeData;
00771 rpmTagType tst;
00772 int_32 * indices, * flags;
00773 const char ** conds;
00774 const char ** s;
00775 int i, j, xx;
00776 int numScripts, numNames;
00777
00778 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00779 *freeData = 0;
00780 return 1;
00781 }
00782
00783 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00784 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00785 s = hfd(s, tst);
00786
00787 *freeData = 1;
00788 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00789 *count = numScripts;
00790 *type = RPM_STRING_ARRAY_TYPE;
00791
00792 for (i = 0; i < numScripts; i++) {
00793 for (j = 0; j < numNames; j++) {
00794 if (indices[j] != i)
00795 continue;
00796
00797 if (flags[j] & RPMSENSE_TRIGGERPREIN)
00798 conds[i] = xstrdup("prein");
00799 else if (flags[j] & RPMSENSE_TRIGGERIN)
00800 conds[i] = xstrdup("in");
00801 else if (flags[j] & RPMSENSE_TRIGGERUN)
00802 conds[i] = xstrdup("un");
00803 else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00804 conds[i] = xstrdup("postun");
00805 else
00806 conds[i] = xstrdup("");
00807 break;
00808 }
00809 }
00810
00811
00812 return 0;
00813 }
00814
00824 static int filenamesTag(Header h, rpmTagType * type,
00825 const void ** data, int_32 * count,
00826 int * freeData)
00827
00828
00829
00830 {
00831 *type = RPM_STRING_ARRAY_TYPE;
00832 rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00833 *freeData = 1;
00834 return 0;
00835 }
00836
00846 static int fileclassTag(Header h, rpmTagType * type,
00847 const void ** data, int_32 * count,
00848 int * freeData)
00849
00850
00851
00852
00853
00854 {
00855 *type = RPM_STRING_ARRAY_TYPE;
00856 rpmfiBuildFClasses(h, (const char ***) data, count);
00857 *freeData = 1;
00858 return 0;
00859 }
00860
00870 static int filecontextsTag(Header h, rpmTagType * type,
00871 const void ** data, int_32 * count,
00872 int * freeData)
00873
00874
00875
00876
00877
00878 {
00879 *type = RPM_STRING_ARRAY_TYPE;
00880 rpmfiBuildFContexts(h, (const char ***) data, count);
00881 *freeData = 1;
00882 return 0;
00883 }
00884
00894 static int fscontextsTag(Header h, rpmTagType * type,
00895 const void ** data, int_32 * count,
00896 int * freeData)
00897
00898
00899
00900
00901
00902 {
00903 *type = RPM_STRING_ARRAY_TYPE;
00904 rpmfiBuildFSContexts(h, (const char ***) data, count);
00905 *freeData = 1;
00906 return 0;
00907 }
00908
00918 static int recontextsTag(Header h, rpmTagType * type,
00919 const void ** data, int_32 * count,
00920 int * freeData)
00921
00922
00923
00924
00925
00926 {
00927 *type = RPM_STRING_ARRAY_TYPE;
00928 rpmfiBuildREContexts(h, (const char ***) data, count);
00929 *freeData = 1;
00930 return 0;
00931 }
00932
00942 static int fileprovideTag(Header h, rpmTagType * type,
00943 const void ** data, int_32 * count,
00944 int * freeData)
00945
00946
00947
00948
00949
00950 {
00951 *type = RPM_STRING_ARRAY_TYPE;
00952 rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00953 *freeData = 1;
00954 return 0;
00955 }
00956
00966 static int filerequireTag(Header h, rpmTagType * type,
00967 const void ** data, int_32 * count,
00968 int * freeData)
00969
00970
00971
00972
00973
00974 {
00975 *type = RPM_STRING_ARRAY_TYPE;
00976 rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00977 *freeData = 1;
00978 return 0;
00979 }
00980
00981
00982
00983 #if defined(ENABLE_NLS)
00984
00985
00986 extern int _nl_msg_cat_cntr;
00987
00988 #endif
00989
00990 static const char * language = "LANGUAGE";
00991
00992
00993 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00994
01005 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
01006 const void ** data, int_32 * count,
01007 int * freeData)
01008
01009
01010
01011
01012 {
01013 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01014 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01015 int rc;
01016
01017 *type = RPM_STRING_TYPE;
01018 *data = NULL;
01019 *count = 0;
01020 *freeData = 0;
01021
01022 if (dstring && *dstring) {
01023 char *domain, *de;
01024 const char * langval;
01025 const char * msgkey;
01026 const char * msgid;
01027
01028 { const char * tn = tagName(tag);
01029 const char * n;
01030 char * mk;
01031 size_t nb = sizeof("()");
01032 int xx = headerNVR(h, &n, NULL, NULL);
01033 if (tn) nb += strlen(tn);
01034 if (n) nb += strlen(n);
01035 mk = alloca(nb);
01036 sprintf(mk, "%s(%s)", n, tn);
01037 msgkey = mk;
01038 }
01039
01040
01041 langval = getenv(language);
01042 (void) setenv(language, "en_US", 1);
01043 #if defined(ENABLE_NLS)
01044 ++_nl_msg_cat_cntr;
01045 #endif
01046
01047 msgid = NULL;
01048
01049 for (domain = dstring; domain != NULL; domain = de) {
01050 de = strchr(domain, ':');
01051 if (de) *de++ = '\0';
01052 msgid = dgettext(domain, msgkey) ;
01053 if (msgid != msgkey) break;
01054 }
01055
01056
01057
01058 if (langval)
01059 (void) setenv(language, langval, 1);
01060 else
01061 unsetenv(language);
01062 #if defined(ENABLE_NLS)
01063 ++_nl_msg_cat_cntr;
01064 #endif
01065
01066 if (domain && msgid) {
01067 *data = dgettext(domain, msgid) ;
01068 *data = xstrdup(*data);
01069 *count = 1;
01070 *freeData = 1;
01071 }
01072 dstring = _free(dstring);
01073 if (*data)
01074 return 0;
01075 }
01076
01077 dstring = _free(dstring);
01078
01079 rc = hge(h, tag, type, (void **)data, count);
01080
01081 if (rc && (*data) != NULL) {
01082 *data = xstrdup(*data);
01083 *freeData = 1;
01084 return 0;
01085 }
01086
01087 *freeData = 0;
01088 *data = NULL;
01089 *count = 0;
01090 return 1;
01091 }
01092
01102 static int summaryTag(Header h, rpmTagType * type,
01103 const void ** data, int_32 * count,
01104 int * freeData)
01105
01106
01107
01108
01109 {
01110 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01111 }
01112
01122 static int descriptionTag(Header h, rpmTagType * type,
01123 const void ** data, int_32 * count,
01124 int * freeData)
01125
01126
01127
01128
01129 {
01130 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01131 }
01132
01142 static int groupTag(Header h, rpmTagType * type,
01143 const void ** data, int_32 * count,
01144 int * freeData)
01145
01146
01147
01148
01149 {
01150 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01151 }
01152
01153
01154 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01155 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
01156 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
01157 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
01158 { HEADER_EXT_TAG, "RPMTAG_FILECLASS", { fileclassTag } },
01159 { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS", { filecontextsTag } },
01160 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
01161 { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE", { fileprovideTag } },
01162 { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE", { filerequireTag } },
01163 { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS", { fscontextsTag } },
01164 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
01165 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
01166 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
01167 { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS", { recontextsTag } },
01168 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
01169 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
01170 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
01171 { HEADER_EXT_FORMAT, "base64", { base64Format } },
01172 { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
01173 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
01174 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
01175 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
01176 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
01177 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
01178 { HEADER_EXT_FORMAT, "xml", { xmlFormat } },
01179 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
01180 } ;
01181