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 = 0;
00214
00215
00216 if ((enc = b64encode(data, ns, -1)) != NULL) {
00217 nt = strlen(enc);
00218 }
00219
00220 val = t = xmalloc(nt + padding + 1);
00221
00222 *t = '\0';
00223 if (enc != NULL) {
00224 t = stpcpy(t, enc);
00225 enc = _free(enc);
00226 }
00227
00228 }
00229
00230 return val;
00231 }
00232
00235 static size_t xmlstrlen(const char * s)
00236
00237 {
00238 size_t len = 0;
00239 int c;
00240
00241
00242 while ((c = *s++) != '\0')
00243
00244 {
00245 switch (c) {
00246 case '<': case '>': len += 4; break;
00247 case '&': len += 5; break;
00248 default: len += 1; break;
00249 }
00250 }
00251 return len;
00252 }
00253
00256 static char * xmlstrcpy( char * t, const char * s)
00257
00258 {
00259 char * te = t;
00260 int c;
00261
00262
00263 while ((c = *s++) != '\0') {
00264 switch (c) {
00265 case '<': te = stpcpy(te, "<"); break;
00266 case '>': te = stpcpy(te, ">"); break;
00267 case '&': te = stpcpy(te, "&"); break;
00268 default: *te++ = c; break;
00269 }
00270 }
00271 *te = '\0';
00272
00273 return t;
00274 }
00275
00285
00286 static char * xmlFormat(int_32 type, const void * data,
00287 char * formatPrefix, int padding,
00288 int element)
00289
00290 {
00291 const char * xtag = NULL;
00292 size_t nb;
00293 char * val;
00294 const char * s = NULL;
00295 char * t, * te;
00296 unsigned long anint = 0;
00297 int xx;
00298
00299
00300 switch (type) {
00301 case RPM_I18NSTRING_TYPE:
00302 case RPM_STRING_TYPE:
00303 s = data;
00304 xtag = "string";
00305 break;
00306 case RPM_BIN_TYPE:
00307 {
00308
00309 size_t ns = element;
00310 if ((s = b64encode(data, ns, 0)) == NULL) {
00311
00312 s = xcalloc(1, padding + (ns / 3) * 4 + 1);
00313 }
00314 xtag = "base64";
00315 } break;
00316 case RPM_CHAR_TYPE:
00317 case RPM_INT8_TYPE:
00318 anint = *((uint_8 *) data);
00319 break;
00320 case RPM_INT16_TYPE:
00321 anint = *((uint_16 *) data);
00322 break;
00323 case RPM_INT32_TYPE:
00324 anint = *((uint_32 *) data);
00325 break;
00326 case RPM_NULL_TYPE:
00327 case RPM_STRING_ARRAY_TYPE:
00328 default:
00329 return xstrdup(_("(invalid xml type)"));
00330 break;
00331 }
00332
00333
00334
00335 if (s == NULL) {
00336 int tlen = 32;
00337 t = memset(alloca(tlen+1), 0, tlen+1);
00338 if (anint != 0)
00339 xx = snprintf(t, tlen, "%lu", anint);
00340 s = t;
00341 xtag = "integer";
00342 }
00343
00344
00345 nb = xmlstrlen(s);
00346 if (nb == 0) {
00347 nb += strlen(xtag) + sizeof("\t</>");
00348 te = t = alloca(nb);
00349 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
00350 } else {
00351 nb += 2 * strlen(xtag) + sizeof("\t<></>");
00352 te = t = alloca(nb);
00353 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
00354 te = xmlstrcpy(te, s);
00355 te += strlen(te);
00356 te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
00357 }
00358
00359
00360
00361 if (!strcmp(xtag, "base64"))
00362 s = _free(s);
00363
00364
00365 nb += padding;
00366 val = xmalloc(nb+1);
00367
00368 strcat(formatPrefix, "s");
00369
00370
00371 xx = snprintf(val, nb, formatPrefix, t);
00372
00373 val[nb] = '\0';
00374
00375 return val;
00376 }
00377
00378
00388 static char * pgpsigFormat(int_32 type, const void * data,
00389 char * formatPrefix, int padding,
00390 int element)
00391
00392
00393 {
00394 char * val, * t;
00395
00396 if (type != RPM_BIN_TYPE) {
00397 val = xstrdup(_("(not a blob)"));
00398 } else {
00399 unsigned char * pkt = (byte *) data;
00400 unsigned int pktlen = 0;
00401
00402 unsigned int v = *pkt;
00403
00404 pgpTag tag = 0;
00405 unsigned int plen;
00406 unsigned int hlen = 0;
00407
00408 if (v & 0x80) {
00409 if (v & 0x40) {
00410 tag = (v & 0x3f);
00411 plen = pgpLen(pkt+1, &hlen);
00412 } else {
00413 tag = (v >> 2) & 0xf;
00414 plen = (1 << (v & 0x3));
00415 hlen = pgpGrab(pkt+1, plen);
00416 }
00417
00418 pktlen = 1 + plen + hlen;
00419 }
00420
00421 if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00422 val = xstrdup(_("(not an OpenPGP signature)"));
00423 } else {
00424 pgpDig dig = pgpNewDig();
00425 pgpDigParams sigp = &dig->signature;
00426 size_t nb = 0;
00427 const char *tempstr;
00428
00429 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00430
00431 val = NULL;
00432 again:
00433 nb += 100;
00434 val = t = xrealloc(val, nb + 1);
00435
00436
00437 switch (sigp->pubkey_algo) {
00438 case PGPPUBKEYALGO_DSA:
00439 t = stpcpy(t, "DSA");
00440 break;
00441 case PGPPUBKEYALGO_RSA:
00442 t = stpcpy(t, "RSA");
00443 break;
00444 default:
00445 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
00446 t += strlen(t);
00447 break;
00448 }
00449 if (t + 5 >= val + nb)
00450 goto again;
00451 *t++ = '/';
00452 switch (sigp->hash_algo) {
00453 case PGPHASHALGO_MD5:
00454 t = stpcpy(t, "MD5");
00455 break;
00456 case PGPHASHALGO_SHA1:
00457 t = stpcpy(t, "SHA1");
00458 break;
00459 default:
00460 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
00461 t += strlen(t);
00462 break;
00463 }
00464 if (t + strlen (", ") + 1 >= val + nb)
00465 goto again;
00466
00467 t = stpcpy(t, ", ");
00468
00469
00470 { time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00471 struct tm * tstruct = localtime(&dateint);
00472 if (tstruct)
00473 (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00474 }
00475 t += strlen(t);
00476 if (t + strlen (", Key ID ") + 1 >= val + nb)
00477 goto again;
00478 t = stpcpy(t, ", Key ID ");
00479 tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
00480 if (t + strlen (tempstr) > val + nb)
00481 goto again;
00482 t = stpcpy(t, tempstr);
00483
00484
00485 dig = pgpFreeDig(dig);
00486 }
00487 }
00488
00489 return val;
00490 }
00491
00501 static char * depflagsFormat(int_32 type, const void * data,
00502 char * formatPrefix, int padding, int element)
00503
00504
00505 {
00506 char * val;
00507 char buf[10];
00508 int anint;
00509
00510 if (type != RPM_INT32_TYPE) {
00511 val = xstrdup(_("(not a number)"));
00512 } else {
00513 anint = *((int_32 *) data);
00514 buf[0] = '\0';
00515
00516
00517 if (anint & RPMSENSE_LESS)
00518 strcat(buf, "<");
00519 if (anint & RPMSENSE_GREATER)
00520 strcat(buf, ">");
00521 if (anint & RPMSENSE_EQUAL)
00522 strcat(buf, "=");
00523
00524
00525 val = xmalloc(5 + padding);
00526
00527 strcat(formatPrefix, "s");
00528
00529
00530 sprintf(val, formatPrefix, buf);
00531
00532 }
00533
00534 return val;
00535 }
00536
00546 static int fsnamesTag( Header h, int_32 * type,
00547 void ** data, int_32 * count,
00548 int * freeData)
00549
00550
00551
00552
00553
00554 {
00555 const char ** list;
00556
00557
00558 if (rpmGetFilesystemList(&list, count))
00559 return 1;
00560
00561
00562 if (type) *type = RPM_STRING_ARRAY_TYPE;
00563 if (data) *((const char ***) data) = list;
00564 if (freeData) *freeData = 0;
00565
00566 return 0;
00567 }
00568
00578 static int instprefixTag(Header h, rpmTagType * type,
00579 const void ** data,
00580 int_32 * count,
00581 int * freeData)
00582
00583
00584
00585 {
00586 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00587 HFD_t hfd = headerFreeData;
00588 rpmTagType ipt;
00589 char ** array;
00590
00591 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00592 if (freeData) *freeData = 0;
00593 return 0;
00594 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00595 if (type) *type = RPM_STRING_TYPE;
00596
00597 if (data) *data = xstrdup(array[0]);
00598
00599 if (freeData) *freeData = 1;
00600 array = hfd(array, ipt);
00601 return 0;
00602 }
00603
00604 return 1;
00605 }
00606
00616 static int fssizesTag(Header h, rpmTagType * type,
00617 const void ** data, int_32 * count,
00618 int * freeData)
00619
00620
00621
00622
00623
00624
00625 {
00626 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00627 const char ** filenames;
00628 int_32 * filesizes;
00629 uint_32 * usages;
00630 int numFiles;
00631
00632 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00633 filesizes = NULL;
00634 numFiles = 0;
00635 filenames = NULL;
00636 } else {
00637 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
00638 }
00639
00640
00641 if (rpmGetFilesystemList(NULL, count))
00642 return 1;
00643
00644
00645 *type = RPM_INT32_TYPE;
00646 *freeData = 1;
00647
00648 if (filenames == NULL) {
00649 usages = xcalloc((*count), sizeof(usages));
00650 *data = usages;
00651
00652 return 0;
00653 }
00654
00655
00656 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00657 return 1;
00658
00659
00660 *data = usages;
00661
00662 filenames = _free(filenames);
00663
00664 return 0;
00665 }
00666
00676 static int triggercondsTag(Header h, rpmTagType * type,
00677 const void ** data, int_32 * count,
00678 int * freeData)
00679
00680
00681
00682 {
00683 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00684 HFD_t hfd = headerFreeData;
00685 rpmTagType tnt, tvt, tst;
00686 int_32 * indices, * flags;
00687 char ** names, ** versions;
00688 int numNames, numScripts;
00689 char ** conds, ** s;
00690 char * item, * flagsStr;
00691 char * chptr;
00692 int i, j, xx;
00693 char buf[5];
00694
00695 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00696 *freeData = 0;
00697 return 0;
00698 }
00699
00700 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00701 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00702 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00703 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00704 s = hfd(s, tst);
00705
00706 *freeData = 1;
00707 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00708 *count = numScripts;
00709 *type = RPM_STRING_ARRAY_TYPE;
00710
00711 for (i = 0; i < numScripts; i++) {
00712 chptr = xstrdup("");
00713
00714 for (j = 0; j < numNames; j++) {
00715 if (indices[j] != i)
00716 continue;
00717
00718 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00719 if (flags[j] & RPMSENSE_SENSEMASK) {
00720 buf[0] = '%', buf[1] = '\0';
00721 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00722 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00723 flagsStr = _free(flagsStr);
00724 } else {
00725 strcpy(item, names[j]);
00726 }
00727
00728 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00729 if (*chptr != '\0') strcat(chptr, ", ");
00730 strcat(chptr, item);
00731 item = _free(item);
00732 }
00733
00734 conds[i] = chptr;
00735 }
00736
00737
00738 names = hfd(names, tnt);
00739 versions = hfd(versions, tvt);
00740
00741 return 0;
00742 }
00743
00753 static int triggertypeTag(Header h, rpmTagType * type,
00754 const void ** data, int_32 * count,
00755 int * freeData)
00756
00757
00758
00759 {
00760 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00761 HFD_t hfd = headerFreeData;
00762 rpmTagType tst;
00763 int_32 * indices, * flags;
00764 const char ** conds;
00765 const char ** s;
00766 int i, j, xx;
00767 int numScripts, numNames;
00768
00769 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00770 *freeData = 0;
00771 return 1;
00772 }
00773
00774 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00775 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00776 s = hfd(s, tst);
00777
00778 *freeData = 1;
00779 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00780 *count = numScripts;
00781 *type = RPM_STRING_ARRAY_TYPE;
00782
00783 for (i = 0; i < numScripts; i++) {
00784 for (j = 0; j < numNames; j++) {
00785 if (indices[j] != i)
00786 continue;
00787
00788 if (flags[j] & RPMSENSE_TRIGGERPREIN)
00789 conds[i] = xstrdup("prein");
00790 else if (flags[j] & RPMSENSE_TRIGGERIN)
00791 conds[i] = xstrdup("in");
00792 else if (flags[j] & RPMSENSE_TRIGGERUN)
00793 conds[i] = xstrdup("un");
00794 else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
00795 conds[i] = xstrdup("postun");
00796 else
00797 conds[i] = xstrdup("");
00798 break;
00799 }
00800 }
00801
00802
00803 return 0;
00804 }
00805
00815 static int filenamesTag(Header h, rpmTagType * type,
00816 const void ** data, int_32 * count,
00817 int * freeData)
00818
00819
00820
00821 {
00822 *type = RPM_STRING_ARRAY_TYPE;
00823 rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
00824 *freeData = 1;
00825 return 0;
00826 }
00827
00837 static int fileclassTag(Header h, rpmTagType * type,
00838 const void ** data, int_32 * count,
00839 int * freeData)
00840
00841
00842
00843
00844
00845 {
00846 *type = RPM_STRING_ARRAY_TYPE;
00847 rpmfiBuildFClasses(h, (const char ***) data, count);
00848 *freeData = 1;
00849 return 0;
00850 }
00851
00861 static int filecontextsTag(Header h, rpmTagType * type,
00862 const void ** data, int_32 * count,
00863 int * freeData)
00864
00865
00866
00867
00868
00869 {
00870 *type = RPM_STRING_ARRAY_TYPE;
00871 rpmfiBuildFContexts(h, (const char ***) data, count);
00872 *freeData = 1;
00873 return 0;
00874 }
00875
00885 static int fscontextsTag(Header h, rpmTagType * type,
00886 const void ** data, int_32 * count,
00887 int * freeData)
00888
00889
00890
00891
00892
00893 {
00894 *type = RPM_STRING_ARRAY_TYPE;
00895 rpmfiBuildFSContexts(h, (const char ***) data, count);
00896 *freeData = 1;
00897 return 0;
00898 }
00899
00909 static int recontextsTag(Header h, rpmTagType * type,
00910 const void ** data, int_32 * count,
00911 int * freeData)
00912
00913
00914
00915
00916
00917 {
00918 *type = RPM_STRING_ARRAY_TYPE;
00919 rpmfiBuildREContexts(h, (const char ***) data, count);
00920 *freeData = 1;
00921 return 0;
00922 }
00923
00933 static int fileprovideTag(Header h, rpmTagType * type,
00934 const void ** data, int_32 * count,
00935 int * freeData)
00936
00937
00938
00939
00940
00941 {
00942 *type = RPM_STRING_ARRAY_TYPE;
00943 rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
00944 *freeData = 1;
00945 return 0;
00946 }
00947
00957 static int filerequireTag(Header h, rpmTagType * type,
00958 const void ** data, int_32 * count,
00959 int * freeData)
00960
00961
00962
00963
00964
00965 {
00966 *type = RPM_STRING_ARRAY_TYPE;
00967 rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
00968 *freeData = 1;
00969 return 0;
00970 }
00971
00972
00973
00974 #if defined(ENABLE_NLS)
00975
00976
00977 extern int _nl_msg_cat_cntr;
00978
00979 #endif
00980
00981 static const char * language = "LANGUAGE";
00982
00983
00984 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
00985
00996 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00997 const void ** data, int_32 * count,
00998 int * freeData)
00999
01000
01001
01002
01003 {
01004 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
01005 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
01006 int rc;
01007
01008 *type = RPM_STRING_TYPE;
01009 *data = NULL;
01010 *count = 0;
01011 *freeData = 0;
01012
01013 if (dstring && *dstring) {
01014 char *domain, *de;
01015 const char * langval;
01016 const char * msgkey;
01017 const char * msgid;
01018
01019 { const char * tn = tagName(tag);
01020 const char * n;
01021 char * mk;
01022 size_t nb = sizeof("()");
01023 int xx = headerNVR(h, &n, NULL, NULL);
01024 if (tn) nb += strlen(tn);
01025 if (n) nb += strlen(n);
01026 mk = alloca(nb);
01027 sprintf(mk, "%s(%s)", n, tn);
01028 msgkey = mk;
01029 }
01030
01031
01032 langval = getenv(language);
01033 (void) setenv(language, "en_US", 1);
01034 #if defined(ENABLE_NLS)
01035 ++_nl_msg_cat_cntr;
01036 #endif
01037
01038 msgid = NULL;
01039
01040 for (domain = dstring; domain != NULL; domain = de) {
01041 de = strchr(domain, ':');
01042 if (de) *de++ = '\0';
01043 msgid = dgettext(domain, msgkey) ;
01044 if (msgid != msgkey) break;
01045 }
01046
01047
01048
01049 if (langval)
01050 (void) setenv(language, langval, 1);
01051 else
01052 unsetenv(language);
01053 #if defined(ENABLE_NLS)
01054 ++_nl_msg_cat_cntr;
01055 #endif
01056
01057 if (domain && msgid) {
01058 *data = dgettext(domain, msgid) ;
01059 *data = xstrdup(*data);
01060 *count = 1;
01061 *freeData = 1;
01062 }
01063 dstring = _free(dstring);
01064 if (*data)
01065 return 0;
01066 }
01067
01068 dstring = _free(dstring);
01069
01070 rc = hge(h, tag, type, (void **)data, count);
01071
01072 if (rc && (*data) != NULL) {
01073 *data = xstrdup(*data);
01074 *freeData = 1;
01075 return 0;
01076 }
01077
01078 *freeData = 0;
01079 *data = NULL;
01080 *count = 0;
01081 return 1;
01082 }
01083
01093 static int summaryTag(Header h, rpmTagType * type,
01094 const void ** data, int_32 * count,
01095 int * freeData)
01096
01097
01098
01099
01100 {
01101 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
01102 }
01103
01113 static int descriptionTag(Header h, rpmTagType * type,
01114 const void ** data, int_32 * count,
01115 int * freeData)
01116
01117
01118
01119
01120 {
01121 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
01122 }
01123
01133 static int groupTag(Header h, rpmTagType * type,
01134 const void ** data, int_32 * count,
01135 int * freeData)
01136
01137
01138
01139
01140 {
01141 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
01142 }
01143
01144
01145 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
01146 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
01147 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
01148 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
01149 { HEADER_EXT_TAG, "RPMTAG_FILECLASS", { fileclassTag } },
01150 { HEADER_EXT_TAG, "RPMTAG_FILECONTEXTS", { filecontextsTag } },
01151 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
01152 { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE", { fileprovideTag } },
01153 { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE", { filerequireTag } },
01154 { HEADER_EXT_TAG, "RPMTAG_FSCONTEXTS", { fscontextsTag } },
01155 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
01156 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
01157 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
01158 { HEADER_EXT_TAG, "RPMTAG_RECONTEXTS", { recontextsTag } },
01159 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
01160 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
01161 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
01162 { HEADER_EXT_FORMAT, "base64", { base64Format } },
01163 { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
01164 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
01165 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
01166 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
01167 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
01168 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
01169 { HEADER_EXT_FORMAT, "xml", { xmlFormat } },
01170 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
01171 } ;
01172