6 #include "rpmio_internal.h"
8 #include <rpmmacro.h> /* XXX for %_i18ndomains */
19 /*@access pgpDigParams @*/
22 * Identify type of trigger.
23 * @param type tag type
24 * @param data tag value
25 * @param formatPrefix (unused)
26 * @param padding (unused)
27 * @param element (unused)
28 * @return formatted string
30 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data,
31 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
32 /*@unused@*/ int element)
33 /*@requires maxRead(data) >= 0 @*/
35 const int_32 * item = data;
38 if (type != RPM_INT32_TYPE)
39 val = xstrdup(_("(not a number)"));
40 else if (*item & RPMSENSE_TRIGGERPREIN)
41 val = xstrdup("prein");
42 else if (*item & RPMSENSE_TRIGGERIN)
44 else if (*item & RPMSENSE_TRIGGERUN)
46 else if (*item & RPMSENSE_TRIGGERPOSTUN)
47 val = xstrdup("postun");
54 * Format file permissions for display.
55 * @param type tag type
56 * @param data tag value
59 * @param element (unused)
60 * @return formatted string
62 static /*@only@*/ char * permsFormat(int_32 type, const void * data,
63 char * formatPrefix, int padding, /*@unused@*/ int element)
64 /*@modifies formatPrefix @*/
65 /*@requires maxRead(data) >= 0 @*/
70 if (type != RPM_INT32_TYPE) {
71 val = xstrdup(_("(not a number)"));
73 val = xmalloc(15 + padding);
75 strcat(formatPrefix, "s");
77 buf = rpmPermsString(*((int_32 *) data));
79 sprintf(val, formatPrefix, buf);
88 * Format file flags for display.
89 * @param type tag type
90 * @param data tag value
93 * @param element (unused)
94 * @return formatted string
96 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data,
97 char * formatPrefix, int padding, /*@unused@*/ int element)
98 /*@modifies formatPrefix @*/
99 /*@requires maxRead(data) >= 0 @*/
103 int anint = *((int_32 *) data);
105 if (type != RPM_INT32_TYPE) {
106 val = xstrdup(_("(not a number)"));
110 if (anint & RPMFILE_DOC)
112 if (anint & RPMFILE_CONFIG)
114 if (anint & RPMFILE_SPECFILE)
116 if (anint & RPMFILE_MISSINGOK)
118 if (anint & RPMFILE_NOREPLACE)
120 if (anint & RPMFILE_GHOST)
122 if (anint & RPMFILE_LICENSE)
124 if (anint & RPMFILE_README)
128 val = xmalloc(5 + padding);
130 strcat(formatPrefix, "s");
133 sprintf(val, formatPrefix, buf);
141 * Wrap a pubkey in ascii armor for display.
142 * @todo Permit selectable display formats (i.e. binary).
143 * @param type tag type
144 * @param data tag value
145 * @param formatPrefix (unused)
146 * @param padding (unused)
147 * @param element no. bytes of binary data
148 * @return formatted string
150 static /*@only@*/ char * armorFormat(int_32 type, const void * data,
151 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
156 const unsigned char * s;
163 /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
165 atype = PGPARMOR_SIGNATURE; /* XXX check pkt for signature */
167 case RPM_STRING_TYPE:
168 case RPM_STRING_ARRAY_TYPE:
170 if (b64decode(enc, (void **)&s, &ns))
171 return xstrdup(_("(not base64)"));
172 atype = PGPARMOR_PUBKEY; /* XXX check pkt for pubkey */
179 case RPM_I18NSTRING_TYPE:
181 return xstrdup(_("(invalid type)"));
182 /*@notreached@*/ break;
185 /* XXX this doesn't use padding directly, assumes enough slop in retval. */
186 return pgpArmorWrap(atype, s, ns);
190 * Encode binary data in base64 for display.
191 * @todo Permit selectable display formats (i.e. binary).
192 * @param type tag type
193 * @param data tag value
194 * @param formatPrefix (unused)
197 * @return formatted string
199 static /*@only@*/ char * base64Format(int_32 type, const void * data,
200 /*@unused@*/ char * formatPrefix, int padding, int element)
205 if (type != RPM_BIN_TYPE) {
206 val = xstrdup(_("(not a blob)"));
211 /* XXX HACK ALERT: element field abused as no. bytes of binary data. */
213 size_t nt = ((ns + 2) / 3) * 4;
217 /* Add additional bytes necessary for eol string(s). */
218 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
219 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
220 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
222 nt += lc * strlen(b64encode_eolstr);
226 val = t = xmalloc(nt + padding + 1);
229 if ((enc = b64encode(data, ns)) != NULL) {
241 static size_t xmlstrlen(const char * s)
248 while ((c = *s++) != '\0')
252 case '<': case '>': len += 4; /*@switchbreak@*/ break;
253 case '&': len += 5; /*@switchbreak@*/ break;
254 default: len += 1; /*@switchbreak@*/ break;
262 static char * xmlstrcpy(/*@returned@*/ char * t, const char * s)
269 while ((c = *s++) != '\0') {
271 case '<': te = stpcpy(te, "<"); /*@switchbreak@*/ break;
272 case '>': te = stpcpy(te, ">"); /*@switchbreak@*/ break;
273 case '&': te = stpcpy(te, "&"); /*@switchbreak@*/ break;
274 default: *te++ = c; /*@switchbreak@*/ break;
283 * Wrap tag data in simple header xml markup.
284 * @param type tag type
285 * @param data tag value
286 * @param formatPrefix
288 * @param element (unused)
289 * @return formatted string
292 static /*@only@*/ char * xmlFormat(int_32 type, const void * data,
293 char * formatPrefix, int padding,
294 /*@unused@*/ int element)
295 /*@modifies formatPrefix @*/
297 const char * xtag = NULL;
300 const char * s = NULL;
302 unsigned long anint = 0;
307 case RPM_I18NSTRING_TYPE:
308 case RPM_STRING_TYPE:
313 { int cpl = b64encode_chars_per_line;
315 b64encode_chars_per_line = 0;
318 s = base64Format(type, data, formatPrefix, padding, element);
321 b64encode_chars_per_line = cpl;
327 anint = *((uint_8 *) data);
330 anint = *((uint_16 *) data);
333 anint = *((uint_32 *) data);
336 case RPM_STRING_ARRAY_TYPE:
338 return xstrdup(_("(invalid xml type)"));
339 /*@notreached@*/ break;
346 t = memset(alloca(tlen+1), 0, tlen+1);
348 xx = snprintf(t, tlen, "%lu", anint);
356 nb += strlen(xtag) + sizeof("\t</>");
358 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), "/>");
360 nb += 2 * strlen(xtag) + sizeof("\t<></>");
362 te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">");
363 te = xmlstrcpy(te, s);
365 te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">");
368 /* XXX s was malloc'd */
370 if (!strcmp(xtag, "base64"))
377 strcat(formatPrefix, "s");
380 xx = snprintf(val, nb, formatPrefix, t);
389 * Display signature fingerprint and time.
390 * @param type tag type
391 * @param data tag value
392 * @param formatPrefix (unused)
394 * @param element (unused)
395 * @return formatted string
397 static /*@only@*/ char * pgpsigFormat(int_32 type, const void * data,
398 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
399 /*@unused@*/ int element)
400 /*@globals fileSystem, internalState @*/
401 /*@modifies fileSystem, internalState @*/
405 if (type != RPM_BIN_TYPE) {
406 val = xstrdup(_("(not a blob)"));
408 unsigned char * pkt = (byte *) data;
409 unsigned int pktlen = 0;
411 unsigned int v = *pkt;
415 unsigned int hlen = 0;
420 plen = pgpLen(pkt+1, &hlen);
422 tag = (v >> 2) & 0xf;
423 plen = (1 << (v & 0x3));
424 hlen = pgpGrab(pkt+1, plen);
427 pktlen = 1 + plen + hlen;
430 if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
431 val = xstrdup(_("(not an OpenPGP signature)"));
433 pgpDig dig = pgpNewDig();
434 pgpDigParams sigp = &dig->signature;
438 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
443 val = t = xrealloc(val, nb + 1);
446 switch (sigp->pubkey_algo) {
447 case PGPPUBKEYALGO_DSA:
448 t = stpcpy(t, "DSA");
450 case PGPPUBKEYALGO_RSA:
451 t = stpcpy(t, "RSA");
454 (void) snprintf(t, nb - (t - val), "%d", sigp->pubkey_algo);
458 if (t + 5 >= val + nb)
461 switch (sigp->hash_algo) {
462 case PGPHASHALGO_MD5:
463 t = stpcpy(t, "MD5");
465 case PGPHASHALGO_SHA1:
466 t = stpcpy(t, "SHA1");
469 (void) snprintf(t, nb - (t - val), "%d", sigp->hash_algo);
473 if (t + strlen (", ") + 1 >= val + nb)
478 /* this is important if sizeof(int_32) ! sizeof(time_t) */
479 { time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
480 struct tm * tstruct = localtime(&dateint);
482 (void) strftime(t, (nb - (t - val)), "%c", tstruct);
485 if (t + strlen (", Key ID ") + 1 >= val + nb)
487 t = stpcpy(t, ", Key ID ");
488 tempstr = pgpHexStr(sigp->signid, sizeof(sigp->signid));
489 if (t + strlen (tempstr) > val + nb)
491 t = stpcpy(t, tempstr);
494 dig = pgpFreeDig(dig);
502 * Format dependency flags for display.
503 * @param type tag type
504 * @param data tag value
505 * @param formatPrefix
507 * @param element (unused)
508 * @return formatted string
510 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data,
511 char * formatPrefix, int padding, /*@unused@*/ int element)
512 /*@modifies formatPrefix @*/
513 /*@requires maxRead(data) >= 0 @*/
519 if (type != RPM_INT32_TYPE) {
520 val = xstrdup(_("(not a number)"));
522 anint = *((int_32 *) data);
526 if (anint & RPMSENSE_LESS)
528 if (anint & RPMSENSE_GREATER)
530 if (anint & RPMSENSE_EQUAL)
534 val = xmalloc(5 + padding);
536 strcat(formatPrefix, "s");
539 sprintf(val, formatPrefix, buf);
547 * Retrieve mounted file system paths.
549 * @retval *type tag type
550 * @retval *data tag value
551 * @retval *count no. of data items
552 * @retval *freeData data-was-malloc'ed indicator
553 * @return 0 on success
555 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
556 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
557 /*@out@*/ int * freeData)
558 /*@globals fileSystem, internalState @*/
559 /*@modifies *type, *data, *count, *freeData,
560 fileSystem, internalState @*/
561 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
562 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
567 if (rpmGetFilesystemList(&list, count))
571 if (type) *type = RPM_STRING_ARRAY_TYPE;
572 if (data) *((const char ***) data) = list;
573 if (freeData) *freeData = 0;
579 * Retrieve install prefixes.
581 * @retval *type tag type
582 * @retval *data tag value
583 * @retval *count no. of data items
584 * @retval *freeData data-was-malloc'ed indicator
585 * @return 0 on success
587 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
588 /*@null@*/ /*@out@*/ const void ** data,
589 /*@null@*/ /*@out@*/ int_32 * count,
590 /*@null@*/ /*@out@*/ int * freeData)
591 /*@modifies *type, *data, *freeData @*/
592 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
593 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
595 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
596 HFD_t hfd = headerFreeData;
600 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
601 if (freeData) *freeData = 0;
603 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
604 if (type) *type = RPM_STRING_TYPE;
606 if (data) *data = xstrdup(array[0]);
608 if (freeData) *freeData = 1;
609 array = hfd(array, ipt);
617 * Retrieve mounted file system space.
619 * @retval *type tag type
620 * @retval *data tag value
621 * @retval *count no. of data items
622 * @retval *freeData data-was-malloc'ed indicator
623 * @return 0 on success
625 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
626 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
627 /*@out@*/ int * freeData)
628 /*@globals rpmGlobalMacroContext, h_errno,
629 fileSystem, internalState @*/
630 /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
631 fileSystem, internalState @*/
632 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
633 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
635 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
636 const char ** filenames;
641 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
646 rpmfiBuildFNames(h, RPMTAG_BASENAMES, &filenames, &numFiles);
650 if (rpmGetFilesystemList(NULL, count))
654 *type = RPM_INT32_TYPE;
657 if (filenames == NULL) {
658 usages = xcalloc((*count), sizeof(usages));
665 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
671 filenames = _free(filenames);
677 * Retrieve trigger info.
679 * @retval *type tag type
680 * @retval *data tag value
681 * @retval *count no. of data items
682 * @retval *freeData data-was-malloc'ed indicator
683 * @return 0 on success
685 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
686 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
687 /*@out@*/ int * freeData)
688 /*@modifies *type, *data, *count, *freeData @*/
689 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
690 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
692 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
693 HFD_t hfd = headerFreeData;
694 rpmTagType tnt, tvt, tst;
695 int_32 * indices, * flags;
696 char ** names, ** versions;
697 int numNames, numScripts;
699 char * item, * flagsStr;
704 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
709 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
710 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
711 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
712 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
716 *data = conds = xmalloc(sizeof(*conds) * numScripts);
718 *type = RPM_STRING_ARRAY_TYPE;
720 for (i = 0; i < numScripts; i++) {
723 for (j = 0; j < numNames; j++) {
725 /*@innercontinue@*/ continue;
727 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
728 if (flags[j] & RPMSENSE_SENSEMASK) {
729 buf[0] = '%', buf[1] = '\0';
730 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
731 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
732 flagsStr = _free(flagsStr);
734 strcpy(item, names[j]);
737 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
738 if (*chptr != '\0') strcat(chptr, ", ");
747 names = hfd(names, tnt);
748 versions = hfd(versions, tvt);
754 * Retrieve trigger type info.
756 * @retval *type tag type
757 * @retval *data tag value
758 * @retval *count no. of data items
759 * @retval *freeData data-was-malloc'ed indicator
760 * @return 0 on success
762 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
763 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
764 /*@out@*/ int * freeData)
765 /*@modifies *type, *data, *count, *freeData @*/
766 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
767 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
769 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
770 HFD_t hfd = headerFreeData;
772 int_32 * indices, * flags;
776 int numScripts, numNames;
778 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
783 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
784 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
788 *data = conds = xmalloc(sizeof(*conds) * numScripts);
790 *type = RPM_STRING_ARRAY_TYPE;
792 for (i = 0; i < numScripts; i++) {
793 for (j = 0; j < numNames; j++) {
795 /*@innercontinue@*/ continue;
797 if (flags[j] & RPMSENSE_TRIGGERPREIN)
798 conds[i] = xstrdup("prein");
799 else if (flags[j] & RPMSENSE_TRIGGERIN)
800 conds[i] = xstrdup("in");
801 else if (flags[j] & RPMSENSE_TRIGGERUN)
802 conds[i] = xstrdup("un");
803 else if (flags[j] & RPMSENSE_TRIGGERPOSTUN)
804 conds[i] = xstrdup("postun");
806 conds[i] = xstrdup("");
807 /*@innerbreak@*/ break;
816 * Retrieve file paths.
818 * @retval *type tag type
819 * @retval *data tag value
820 * @retval *count no. of data items
821 * @retval *freeData data-was-malloc'ed indicator
822 * @return 0 on success
824 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
825 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
826 /*@out@*/ int * freeData)
827 /*@modifies *type, *data, *count, *freeData @*/
828 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
829 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
831 *type = RPM_STRING_ARRAY_TYPE;
832 rpmfiBuildFNames(h, RPMTAG_BASENAMES, (const char ***) data, count);
838 * Retrieve file classes.
840 * @retval *type tag type
841 * @retval *data tag value
842 * @retval *count no. of data items
843 * @retval *freeData data-was-malloc'ed indicator
844 * @return 0 on success
846 static int fileclassTag(Header h, /*@out@*/ rpmTagType * type,
847 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
848 /*@out@*/ int * freeData)
849 /*@globals rpmGlobalMacroContext, h_errno, fileSystem @*/
850 /*@modifies h, *type, *data, *count, *freeData,
851 rpmGlobalMacroContext, fileSystem @*/
852 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
853 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
855 *type = RPM_STRING_ARRAY_TYPE;
856 rpmfiBuildFClasses(h, (const char ***) data, count);
862 * Retrieve file provides.
864 * @retval *type tag type
865 * @retval *data tag value
866 * @retval *count no. of data items
867 * @retval *freeData data-was-malloc'ed indicator
868 * @return 0 on success
870 static int fileprovideTag(Header h, /*@out@*/ rpmTagType * type,
871 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
872 /*@out@*/ int * freeData)
873 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
874 /*@modifies h, *type, *data, *count, *freeData,
875 rpmGlobalMacroContext, fileSystem, internalState @*/
876 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
877 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
879 *type = RPM_STRING_ARRAY_TYPE;
880 rpmfiBuildFDeps(h, RPMTAG_PROVIDENAME, (const char ***) data, count);
886 * Retrieve file requires.
888 * @retval *type tag type
889 * @retval *data tag value
890 * @retval *count no. of data items
891 * @retval *freeData data-was-malloc'ed indicator
892 * @return 0 on success
894 static int filerequireTag(Header h, /*@out@*/ rpmTagType * type,
895 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
896 /*@out@*/ int * freeData)
897 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
898 /*@modifies h, *type, *data, *count, *freeData,
899 rpmGlobalMacroContext, fileSystem, internalState @*/
900 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
901 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
903 *type = RPM_STRING_ARRAY_TYPE;
904 rpmfiBuildFDeps(h, RPMTAG_REQUIRENAME, (const char ***) data, count);
909 /* I18N look aside diversions */
911 #if defined(ENABLE_NLS)
912 /*@-exportlocal -exportheadervar@*/
914 extern int _nl_msg_cat_cntr; /* XXX GNU gettext voodoo */
915 /*@=exportlocal =exportheadervar@*/
917 /*@observer@*/ /*@unchecked@*/
918 static const char * language = "LANGUAGE";
920 /*@observer@*/ /*@unchecked@*/
921 static const char * _macro_i18ndomains = "%{?_i18ndomains}";
924 * Retrieve i18n text.
927 * @retval *type tag type
928 * @retval *data tag value
929 * @retval *count no. of data items
930 * @retval *freeData data-was-malloc'ed indicator
931 * @return 0 on success
933 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
934 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
935 /*@out@*/ int * freeData)
936 /*@globals rpmGlobalMacroContext, h_errno @*/
937 /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
938 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
939 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
941 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
942 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
945 *type = RPM_STRING_TYPE;
950 if (dstring && *dstring) {
952 const char * langval;
956 { const char * tn = tagName(tag);
959 size_t nb = sizeof("()");
961 xx = headerNVR(h, &n, NULL, NULL);
962 if (tn) nb += strlen(tn);
963 if (n) nb += strlen(n);
965 sprintf(mk, "%s(%s)", n, tn);
969 /* change to en_US for msgkey -> msgid resolution */
970 langval = getenv(language);
971 (void) setenv(language, "en_US", 1);
972 #if defined(ENABLE_NLS)
973 /*@i@*/ ++_nl_msg_cat_cntr;
978 for (domain = dstring; domain != NULL; domain = de) {
979 de = strchr(domain, ':');
980 if (de) *de++ = '\0';
981 msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
982 if (msgid != msgkey) break;
986 /* restore previous environment for msgid -> msgstr resolution */
988 (void) setenv(language, langval, 1);
991 #if defined(ENABLE_NLS)
992 /*@i@*/ ++_nl_msg_cat_cntr;
995 if (domain && msgid) {
996 *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
997 *data = xstrdup(*data); /* XXX xstrdup has side effects. */
1001 dstring = _free(dstring);
1006 dstring = _free(dstring);
1008 rc = hge(h, tag, type, (void **)data, count);
1010 if (rc && (*data) != NULL) {
1011 *data = xstrdup(*data);
1023 * Retrieve summary text.
1025 * @retval *type tag type
1026 * @retval *data tag value
1027 * @retval *count no. of data items
1028 * @retval *freeData data-was-malloc'ed indicator
1029 * @return 0 on success
1031 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
1032 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
1033 /*@out@*/ int * freeData)
1034 /*@globals rpmGlobalMacroContext, h_errno @*/
1035 /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
1036 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
1037 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
1039 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
1043 * Retrieve description text.
1045 * @retval *type tag type
1046 * @retval *data tag value
1047 * @retval *count no. of data items
1048 * @retval *freeData data-was-malloc'ed indicator
1049 * @return 0 on success
1051 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
1052 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
1053 /*@out@*/ int * freeData)
1054 /*@globals rpmGlobalMacroContext, h_errno @*/
1055 /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
1056 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
1057 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
1059 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
1063 * Retrieve group text.
1065 * @retval *type tag type
1066 * @retval *data tag value
1067 * @retval *count no. of data items
1068 * @retval *freeData data-was-malloc'ed indicator
1069 * @return 0 on success
1071 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
1072 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
1073 /*@out@*/ int * freeData)
1074 /*@globals rpmGlobalMacroContext, h_errno @*/
1075 /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
1076 /*@requires maxSet(type) >= 0 /\ maxSet(data) >= 0
1077 /\ maxSet(count) >= 0 /\ maxSet(freeData) >= 0 @*/
1079 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
1082 /*@-type@*/ /* FIX: cast? */
1083 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
1084 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
1085 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
1086 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
1087 { HEADER_EXT_TAG, "RPMTAG_FILECLASS", { fileclassTag } },
1088 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
1089 { HEADER_EXT_TAG, "RPMTAG_FILEPROVIDE", { fileprovideTag } },
1090 { HEADER_EXT_TAG, "RPMTAG_FILEREQUIRE", { filerequireTag } },
1091 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
1092 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
1093 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
1094 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
1095 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
1096 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
1097 { HEADER_EXT_FORMAT, "base64", { base64Format } },
1098 { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
1099 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
1100 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
1101 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
1102 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
1103 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
1104 { HEADER_EXT_FORMAT, "xml", { xmlFormat } },
1105 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }