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 = 80;
00436
00437 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00438
00439 val = t = xmalloc(nb + 1);
00440
00441
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
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
00480
00481 dig = pgpFreeDig(dig);
00482 }
00483 }
00484
00485 return val;
00486 }
00487
00497 static char * depflagsFormat(int_32 type, const void * data,
00498 char * formatPrefix, int padding, int element)
00499
00500
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
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
00520
00521 val = xmalloc(5 + padding);
00522
00523 strcat(formatPrefix, "s");
00524
00525
00526 sprintf(val, formatPrefix, buf);
00527
00528 }
00529
00530 return val;
00531 }
00532
00542 static int fsnamesTag( Header h, int_32 * type,
00543 void ** data, int_32 * count,
00544 int * freeData)
00545
00546
00547
00548
00549
00550 {
00551 const char ** list;
00552
00553
00554 if (rpmGetFilesystemList(&list, count))
00555 return 1;
00556
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, rpmTagType * type,
00575 const void ** data,
00576 int_32 * count,
00577 int * freeData)
00578
00579
00580
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
00593 if (data) *data = xstrdup(array[0]);
00594
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, rpmTagType * type,
00613 const void ** data, int_32 * count,
00614 int * freeData)
00615
00616
00617
00618
00619
00620
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
00637 if (rpmGetFilesystemList(NULL, count))
00638 return 1;
00639
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
00652 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00653 return 1;
00654
00655
00656 *data = usages;
00657
00658 filenames = _free(filenames);
00659
00660 return 0;
00661 }
00662
00672 static int triggercondsTag(Header h, rpmTagType * type,
00673 const void ** data, int_32 * count,
00674 int * freeData)
00675
00676
00677
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
00707 for (i = 0; i < numScripts; i++) {
00708 chptr = xstrdup("");
00709
00710 for (j = 0; j < numNames; j++) {
00711 if (indices[j] != i)
00712 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
00733
00734 names = hfd(names, tnt);
00735 versions = hfd(versions, tvt);
00736
00737 return 0;
00738 }
00739
00749 static int triggertypeTag(Header h, rpmTagType * type,
00750 const void ** data, int_32 * count,
00751 int * freeData)
00752
00753
00754
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
00779 for (i = 0; i < numScripts; i++) {
00780 for (j = 0; j < numNames; j++) {
00781 if (indices[j] != i)
00782 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 break;
00795 }
00796 }
00797
00798
00799 return 0;
00800 }
00801
00811 static int filenamesTag(Header h, rpmTagType * type,
00812 const void ** data, int_32 * count,
00813 int * freeData)
00814
00815
00816
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, rpmTagType * type,
00834 const void ** data, int_32 * count,
00835 int * freeData)
00836
00837
00838
00839
00840
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, rpmTagType * type,
00858 const void ** data, int_32 * count,
00859 int * freeData)
00860
00861
00862
00863
00864
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, rpmTagType * type,
00882 const void ** data, int_32 * count,
00883 int * freeData)
00884
00885
00886
00887
00888
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, rpmTagType * type,
00906 const void ** data, int_32 * count,
00907 int * freeData)
00908
00909
00910
00911
00912
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, rpmTagType * type,
00930 const void ** data, int_32 * count,
00931 int * freeData)
00932
00933
00934
00935
00936
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, rpmTagType * type,
00954 const void ** data, int_32 * count,
00955 int * freeData)
00956
00957
00958
00959
00960
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
00969
00970
00971
00972 int _nl_msg_cat_cntr;
00973
00974
00975 static const char * language = "LANGUAGE";
00976
00977
00978 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00979
00990 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00991 const void ** data, int_32 * count,
00992 int * freeData)
00993
00994
00995
00996
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
01023 langval = getenv(language);
01024 (void) setenv(language, "en_US", 1);
01025 ++_nl_msg_cat_cntr;
01026
01027 msgid = NULL;
01028
01029 for (domain = dstring; domain != NULL; domain = de) {
01030 de = strchr(domain, ':');
01031 if (de) *de++ = '\0';
01032 msgid = dgettext(domain, msgkey) ;
01033 if (msgid != msgkey) break;
01034 }
01035
01036
01037
01038 if (langval)
01039 (void) setenv(language, langval, 1);
01040 else
01041 unsetenv(language);
01042 ++_nl_msg_cat_cntr;
01043
01044 if (domain && msgid) {
01045 *data = dgettext(domain, msgid) ;
01046 *data = xstrdup(*data);
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, rpmTagType * type,
01081 const void ** data, int_32 * count,
01082 int * freeData)
01083
01084
01085
01086
01087 {
01088 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01089 }
01090
01100 static int descriptionTag(Header h, rpmTagType * type,
01101 const void ** data, int_32 * count,
01102 int * freeData)
01103
01104
01105
01106
01107 {
01108 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01109 }
01110
01120 static int groupTag(Header h, rpmTagType * type,
01121 const void ** data, int_32 * count,
01122 int * freeData)
01123
01124
01125
01126
01127 {
01128 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01129 }
01130
01131
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