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 int freeit = 0;
00305
00306
00307 switch (type) {
00308 case RPM_I18NSTRING_TYPE:
00309 case RPM_STRING_TYPE:
00310 s = data;
00311 xtag = "string";
00312
00313 s = xstrdup(s);
00314 s = xstrtolocale(s);
00315 freeit = 1;
00316 break;
00317 case RPM_BIN_TYPE:
00318 { int cpl = b64encode_chars_per_line;
00319
00320 b64encode_chars_per_line = 0;
00321
00322
00323 s = base64Format(type, data, formatPrefix, padding, element);
00324
00325
00326 b64encode_chars_per_line = cpl;
00327
00328 xtag = "base64";
00329 freeit = 1;
00330 } break;
00331 case RPM_CHAR_TYPE:
00332 case RPM_INT8_TYPE:
00333 anint = *((uint_8 *) data);
00334 break;
00335 case RPM_INT16_TYPE:
00336 anint = *((uint_16 *) data);
00337 break;
00338 case RPM_INT32_TYPE:
00339 anint = *((uint_32 *) data);
00340 break;
00341 case RPM_NULL_TYPE:
00342 case RPM_STRING_ARRAY_TYPE:
00343 default:
00344 return xstrdup(_("(invalid xml type)"));
00345 break;
00346 }
00347
00348
00349
00350 if (s == NULL) {
00351 int tlen = 32;
00352 t = memset(alloca(tlen+1), 0, tlen+1);
00353 if (anint != 0)
00354 xx = snprintf(t, tlen, "%lu", anint);
00355 s = t;
00356 xtag = "integer";
00357 }
00358
00359
00360 nb = xmlstrlen(s);
00361 if (nb == 0) {
00362 nb += strlen(xtag) + sizeof("\t</>");
00363 te = t = alloca(nb);
00364 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
00365 } else {
00366 nb += 2 * strlen(xtag) + sizeof("\t<></>");
00367 te = t = alloca(nb);
00368 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00369 te = xmlstrcpy(te, s);
00370 te += strlen(te);
00371 te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00372 }
00373
00374
00375
00376 if (freeit)
00377 s = _free(s);
00378
00379
00380 nb += padding;
00381 val = xmalloc(nb+1);
00382
00383 strcat(formatPrefix, "s");
00384
00385
00386 xx = snprintf(val, nb, formatPrefix, t);
00387
00388 val[nb] = '\0';
00389
00390 return val;
00391 }
00392
00393
00403 static char * pgpsigFormat(int_32 type, const void * data,
00404 char * formatPrefix, int padding,
00405 int element)
00406
00407
00408 {
00409 char * val, * t;
00410
00411 if (type != RPM_BIN_TYPE) {
00412 val = xstrdup(_("(not a blob)"));
00413 } else {
00414 unsigned char * pkt = (byte *) data;
00415 unsigned int pktlen = 0;
00416
00417 unsigned int v = *pkt;
00418
00419 pgpTag tag = 0;
00420 unsigned int plen;
00421 unsigned int hlen = 0;
00422
00423 if (v & 0x80) {
00424 if (v & 0x40) {
00425 tag = (v & 0x3f);
00426 plen = pgpLen(pkt+1, &hlen);
00427 } else {
00428 tag = (v >> 2) & 0xf;
00429 plen = (1 << (v & 0x3));
00430 hlen = pgpGrab(pkt+1, plen);
00431 }
00432
00433 pktlen = 1 + plen + hlen;
00434 }
00435
00436 if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00437 val = xstrdup(_("(not an OpenPGP signature)"));
00438 } else {
00439 pgpDig dig = pgpNewDig();
00440 pgpDigParams sigp = &dig->signature;
00441 size_t nb = 0;
00442 const char *tempstr;
00443
00444 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00445
00446 val = NULL;
00447 again:
00448 nb += 100;
00449 val = t = xrealloc(val, nb + 1);
00450
00451
00452 switch (sigp->pubkey_algo) {
00453 case PGPPUBKEYALGO_DSA:
00454 t = stpcpy(t, "DSA");
00455 break;
00456 case PGPPUBKEYALGO_RSA:
00457 t = stpcpy(t, "RSA");
00458 break;
00459 default:
00460 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
00461 t += strlen(t);
00462 break;
00463 }
00464 if (t + 5 >= val + nb)
00465 goto again;
00466 *t++ = '/';
00467 switch (sigp->hash_algo) {
00468 case PGPHASHALGO_MD5:
00469 t = stpcpy(t, "MD5");
00470 break;
00471 case PGPHASHALGO_SHA1:
00472 t = stpcpy(t, "SHA1");
00473 break;
00474 default:
00475 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
00476 t += strlen(t);
00477 break;
00478 }
00479 if (t + strlen (", ") + 1 >= val + nb)
00480 goto again;
00481
00482 t = stpcpy(t, ", ");
00483
00484
00485 { time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00486 struct tm * tstruct = localtime(&dateint);
00487 if (tstruct)
00488 (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00489 }
00490 t += strlen(t);
00491 if (t + strlen (", Key ID ") + 1 >= val + nb)
00492 goto again;
00493 t = stpcpy(t, ", Key ID ");
00494 tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
00495 if (t + strlen (tempstr) > val + nb)
00496 goto again;
00497 t = stpcpy(t, tempstr);
00498
00499
00500 dig = pgpFreeDig(dig);
00501 }
00502 }
00503
00504 return val;
00505 }
00506
00516 static char * depflagsFormat(int_32 type, const void * data,
00517 char * formatPrefix, int padding, int element)
00518
00519
00520 {
00521 char * val;
00522 char buf[10];
00523 int anint;
00524
00525 if (type != RPM_INT32_TYPE) {
00526 val = xstrdup(_("(not a number)"));
00527 } else {
00528 anint = *((int_32 *) data);
00529 buf[0] = '\0';
00530
00531
00532 if (anint & RPMSENSE_LESS)
00533 strcat(buf, "<");
00534 if (anint & RPMSENSE_GREATER)
00535 strcat(buf, ">");
00536 if (anint & RPMSENSE_EQUAL)
00537 strcat(buf, "=");
00538
00539
00540 val = xmalloc(5 + padding);
00541
00542 strcat(formatPrefix, "s");
00543
00544
00545 sprintf(val, formatPrefix, buf);
00546
00547 }
00548
00549 return val;
00550 }
00551
00561 static int fsnamesTag( Header h, int_32 * type,
00562 void ** data, int_32 * count,
00563 int * freeData)
00564
00565
00566
00567
00568
00569 {
00570 const char ** list;
00571
00572
00573 if (rpmGetFilesystemList(&list, count))
00574 return 1;
00575
00576
00577 if (type) *type = RPM_STRING_ARRAY_TYPE;
00578 if (data) *((const char ***) data) = list;
00579 if (freeData) *freeData = 0;
00580
00581 return 0;
00582 }
00583
00593 static int instprefixTag(Header h, rpmTagType * type,
00594 const void ** data,
00595 int_32 * count,
00596 int * freeData)
00597
00598
00599
00600 {
00601 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00602 HFD_t hfd = headerFreeData;
00603 rpmTagType ipt;
00604 char ** array;
00605
00606 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00607 if (freeData) *freeData = 0;
00608 return 0;
00609 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00610 if (type) *type = RPM_STRING_TYPE;
00611
00612 if (data) *data = xstrdup(array[0]);
00613
00614 if (freeData) *freeData = 1;
00615 array = hfd(array, ipt);
00616 return 0;
00617 }
00618
00619 return 1;
00620 }
00621
00631 static int fssizesTag(Header h, rpmTagType * type,
00632 const void ** data, int_32 * count,
00633 int * freeData)
00634
00635
00636
00637
00638
00639
00640 {
00641 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00642 const char ** filenames;
00643 int_32 * filesizes;
00644 uint_32 * usages;
00645 int numFiles;
00646
00647 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00648 filesizes = NULL;
00649 numFiles = 0;
00650 filenames = NULL;
00651 } else {
00652 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00653 }
00654
00655
00656 if (rpmGetFilesystemList(NULL, count))
00657 return 1;
00658
00659
00660 *type = RPM_INT32_TYPE;
00661 *freeData = 1;
00662
00663 if (filenames == NULL) {
00664 usages = xcalloc((*count), sizeof(usages));
00665 *data = usages;
00666
00667 return 0;
00668 }
00669
00670
00671 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00672 return 1;
00673
00674
00675 *data = usages;
00676
00677 filenames = _free(filenames);
00678
00679 return 0;
00680 }
00681
00691 static int triggercondsTag(Header h, rpmTagType * type,
00692 const void ** data, int_32 * count,
00693 int * freeData)
00694
00695
00696
00697 {
00698 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00699 HFD_t hfd = headerFreeData;
00700 rpmTagType tnt, tvt, tst;
00701 int_32 * indices, * flags;
00702 char ** names, ** versions;
00703 int numNames, numScripts;
00704 char ** conds, ** s;
00705 char * item, * flagsStr;
00706 char * chptr;
00707 int i, j, xx;
00708 char buf[5];
00709
00710 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00711 *freeData = 0;
00712 return 0;
00713 }
00714
00715 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00716 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00717 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00718 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00719 s = hfd(s, tst);
00720
00721 *freeData = 1;
00722 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00723 *count = numScripts;
00724 *type = RPM_STRING_ARRAY_TYPE;
00725
00726 for (i = 0; i < numScripts; i++) {
00727 chptr = xstrdup("");
00728
00729 for (j = 0; j < numNames; j++) {
00730 if (indices[j] != i)
00731 continue;
00732
00733 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00734 if (flags[j] & RPMSENSE_SENSEMASK) {
00735 buf[0] = '%', buf[1] = '\0';
00736 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00737 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00738 flagsStr = _free(flagsStr);
00739 } else {
00740 strcpy(item, names[j]);
00741 }
00742
00743 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00744 if (*chptr != '\0') strcat(chptr, ", ");
00745 strcat(chptr, item);
00746 item = _free(item);
00747 }
00748
00749 conds[i] = chptr;
00750 }
00751
00752
00753 names = hfd(names, tnt);
00754 versions = hfd(versions, tvt);
00755
00756 return 0;
00757 }
00758
00768 static int triggertypeTag(Header h, rpmTagType * type,
00769 const void ** data, int_32 * count,
00770 int * freeData)
00771
00772
00773
00774 {
00775 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00776 HFD_t hfd = headerFreeData;
00777 rpmTagType tst;
00778 int_32 * indices, * flags;
00779 const char ** conds;
00780 const char ** s;
00781 int i, j, xx;
00782 int numScripts, numNames;
00783
00784 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00785 *freeData = 0;
00786 return 1;
00787 }
00788
00789 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00790 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00791 s = hfd(s, tst);
00792
00793 *freeData = 1;
00794 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00795 *count = numScripts;
00796 *type = RPM_STRING_ARRAY_TYPE;
00797
00798 for (i = 0; i < numScripts; i++) {
00799 for (j = 0; j < numNames; j++) {
00800 if (indices[j] != i)
00801 continue;
00802
00803 if (flags[j] & RPMSENSE_TRIGGERPREIN)
00804 conds[i] = xstrdup("prein");
00805 else if (flags[j] & RPMSENSE_TRIGGERIN)
00806 conds[i] = xstrdup("in");
00807 else if (flags[j] & RPMSENSE_TRIGGERUN)
00808 conds[i] = xstrdup("un");
00809 else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00810 conds[i] = xstrdup("postun");
00811 else
00812 conds[i] = xstrdup("");
00813 break;
00814 }
00815 }
00816
00817
00818 return 0;
00819 }
00820
00830 static int filenamesTag(Header h, rpmTagType * type,
00831 const void ** data, int_32 * count,
00832 int * freeData)
00833
00834
00835
00836 {
00837 *type = RPM_STRING_ARRAY_TYPE;
00838 rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00839 *freeData = 1;
00840 return 0;
00841 }
00842
00852 static int fileclassTag(Header h, rpmTagType * type,
00853 const void ** data, int_32 * count,
00854 int * freeData)
00855
00856
00857
00858
00859
00860 {
00861 *type = RPM_STRING_ARRAY_TYPE;
00862 rpmfiBuildFClasses(h, (const char ***) data, count);
00863 *freeData = 1;
00864 return 0;
00865 }
00866
00876 static int filecontextsTag(Header h, rpmTagType * type,
00877 const void ** data, int_32 * count,
00878 int * freeData)
00879
00880
00881
00882
00883
00884 {
00885 *type = RPM_STRING_ARRAY_TYPE;
00886 rpmfiBuildFContexts(h, (const char ***) data, count);
00887 *freeData = 1;
00888 return 0;
00889 }
00890
00900 static int fscontextsTag(Header h, rpmTagType * type,
00901 const void ** data, int_32 * count,
00902 int * freeData)
00903
00904
00905
00906
00907
00908 {
00909 *type = RPM_STRING_ARRAY_TYPE;
00910 rpmfiBuildFSContexts(h, (const char ***) data, count);
00911 *freeData = 1;
00912 return 0;
00913 }
00914
00924 static int recontextsTag(Header h, rpmTagType * type,
00925 const void ** data, int_32 * count,
00926 int * freeData)
00927
00928
00929
00930
00931
00932 {
00933 *type = RPM_STRING_ARRAY_TYPE;
00934 rpmfiBuildREContexts(h, (const char ***) data, count);
00935 *freeData = 1;
00936 return 0;
00937 }
00938
00948 static int fileprovideTag(Header h, rpmTagType * type,
00949 const void ** data, int_32 * count,
00950 int * freeData)
00951
00952
00953
00954
00955
00956 {
00957 *type = RPM_STRING_ARRAY_TYPE;
00958 rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00959 *freeData = 1;
00960 return 0;
00961 }
00962
00972 static int filerequireTag(Header h, rpmTagType * type,
00973 const void ** data, int_32 * count,
00974 int * freeData)
00975
00976
00977
00978
00979
00980 {
00981 *type = RPM_STRING_ARRAY_TYPE;
00982 rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00983 *freeData = 1;
00984 return 0;
00985 }
00986
00987
00988
00989 #if defined(ENABLE_NLS)
00990
00991
00992 extern int _nl_msg_cat_cntr;
00993
00994 #endif
00995
00996 static const char * language = "LANGUAGE";
00997
00998
00999 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
01000
01011 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
01012 const void ** data, int_32 * count,
01013 int * freeData)
01014
01015
01016
01017
01018 {
01019 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01020 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01021 int rc;
01022
01023 *type = RPM_STRING_TYPE;
01024 *data = NULL;
01025 *count = 0;
01026 *freeData = 0;
01027
01028 if (dstring && *dstring) {
01029 char *domain, *de;
01030 const char * langval;
01031 const char * msgkey;
01032 const char * msgid;
01033
01034 { const char * tn = tagName(tag);
01035 const char * n;
01036 char * mk;
01037 (void) headerNVR(h, &n, NULL, NULL);
01038 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
01039 sprintf(mk, "%s(%s)", n, tn);
01040 msgkey = mk;
01041 }
01042
01043
01044 langval = getenv(language);
01045 (void) setenv(language, "en_US", 1);
01046 #if defined(ENABLE_NLS)
01047 ++_nl_msg_cat_cntr;
01048 #endif
01049
01050 msgid = NULL;
01051
01052 for (domain = dstring; domain != NULL; domain = de) {
01053 de = strchr(domain, ':');
01054 if (de) *de++ = '\0';
01055 msgid = dgettext(domain, msgkey) ;
01056 if (msgid != msgkey) break;
01057 }
01058
01059
01060
01061 if (langval)
01062 (void) setenv(language, langval, 1);
01063 else
01064 unsetenv(language);
01065 #if defined(ENABLE_NLS)
01066 ++_nl_msg_cat_cntr;
01067 #endif
01068
01069 if (domain && msgid) {
01070 *data = dgettext(domain, msgid) ;
01071 *data = xstrdup(*data);
01072 *count = 1;
01073 *freeData = 1;
01074 }
01075 dstring = _free(dstring);
01076 if (*data)
01077 return 0;
01078 }
01079
01080 dstring = _free(dstring);
01081
01082 rc = hge(h, tag, type, (void **)data, count);
01083
01084 if (rc && (*data) != NULL) {
01085 *data = xstrdup(*data);
01086 *data = xstrtolocale(*data);
01087 *freeData = 1;
01088 return 0;
01089 }
01090
01091 *freeData = 0;
01092 *data = NULL;
01093 *count = 0;
01094 return 1;
01095 }
01096
01106 static int summaryTag(Header h, rpmTagType * type,
01107 const void ** data, int_32 * count,
01108 int * freeData)
01109
01110
01111
01112
01113 {
01114 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01115 }
01116
01126 static int descriptionTag(Header h, rpmTagType * type,
01127 const void ** data, int_32 * count,
01128 int * freeData)
01129
01130
01131
01132
01133 {
01134 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01135 }
01136
01146 static int groupTag(Header h, rpmTagType * type,
01147 const void ** data, int_32 * count,
01148 int * freeData)
01149
01150
01151
01152
01153 {
01154 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01155 }
01156
01157
01158 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01159 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
01160 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
01161 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
01162 { HEADER_EXT_TAG, "RPMTAG_FILECLASS", { fileclassTag } },
01163 { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS", { filecontextsTag } },
01164 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
01165 { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE", { fileprovideTag } },
01166 { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE", { filerequireTag } },
01167 { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS", { fscontextsTag } },
01168 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
01169 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
01170 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
01171 { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS", { recontextsTag } },
01172 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
01173 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
01174 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
01175 { HEADER_EXT_FORMAT, "base64", { base64Format } },
01176 { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
01177 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
01178 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
01179 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
01180 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
01181 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
01182 { HEADER_EXT_FORMAT, "xml", { xmlFormat } },
01183 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
01184 } ;
01185