6be20da468
These are the cases where even the release was not needed (so, the disttag is not needed, too), or one case where the filename is contructed (and it doesn't include the disttag). Now grep -Ee 'headerNVR[^D]' will show the remaining non-trivial cases, where adapting to disttags may be needed.
767 lines
20 KiB
C
767 lines
20 KiB
C
/** \ingroup header
|
|
* \file lib/formats.c
|
|
*/
|
|
|
|
#include "system.h"
|
|
#include "rpmlib.h"
|
|
#include "rpmmacro.h" /* XXX for %_i18ndomains */
|
|
#include "rpmpgp.h"
|
|
#include "manifest.h"
|
|
#include "misc.h"
|
|
#include "debug.h"
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix (unused)
|
|
* @param padding (unused)
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data,
|
|
/*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
|
|
/*@unused@*/ int element) /*@*/
|
|
{
|
|
const int_32 * item = data;
|
|
char * val;
|
|
|
|
if (type != RPM_INT32_TYPE)
|
|
val = xstrdup(_("(not a number)"));
|
|
else if (*item & RPMSENSE_TRIGGERIN)
|
|
val = xstrdup("in");
|
|
else
|
|
val = xstrdup("un");
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * permsFormat(int_32 type, const void * data, char * formatPrefix,
|
|
int padding, /*@unused@*/ int element)
|
|
/*@modifies formatPrefix @*/
|
|
{
|
|
char * val;
|
|
char * buf;
|
|
|
|
if (type != RPM_INT32_TYPE) {
|
|
val = xstrdup(_("(not a number)"));
|
|
} else {
|
|
val = xmalloc(15 + padding);
|
|
strcat(formatPrefix, "s");
|
|
buf = rpmPermsString(*((int_32 *) data));
|
|
/*@-formatconst@*/
|
|
sprintf(val, formatPrefix, buf);
|
|
/*@=formatconst@*/
|
|
buf = _free(buf);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * fflagsFormat(int_32 type, const void * data,
|
|
char * formatPrefix, int padding, /*@unused@*/ int element)
|
|
/*@modifies formatPrefix @*/
|
|
{
|
|
char * val;
|
|
char buf[15];
|
|
int anint = *((int_32 *) data);
|
|
|
|
if (type != RPM_INT32_TYPE) {
|
|
val = xstrdup(_("(not a number)"));
|
|
} else {
|
|
buf[0] = '\0';
|
|
if (anint & RPMFILE_DOC)
|
|
strcat(buf, "d");
|
|
if (anint & RPMFILE_CONFIG)
|
|
strcat(buf, "c");
|
|
if (anint & RPMFILE_SPECFILE)
|
|
strcat(buf, "s");
|
|
if (anint & RPMFILE_MISSINGOK)
|
|
strcat(buf, "m");
|
|
if (anint & RPMFILE_NOREPLACE)
|
|
strcat(buf, "n");
|
|
if (anint & RPMFILE_GHOST)
|
|
strcat(buf, "g");
|
|
|
|
val = xmalloc(5 + padding);
|
|
strcat(formatPrefix, "s");
|
|
/*@-formatconst@*/
|
|
sprintf(val, formatPrefix, buf);
|
|
/*@=formatconst@*/
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * armorFormat(int_32 type, const void * data,
|
|
/*@unused@*/ char * formatPrefix, int padding, int element)
|
|
/*@*/
|
|
{
|
|
const char * enc;
|
|
const char * s;
|
|
char * t;
|
|
char * val;
|
|
int atype;
|
|
size_t lc, ns, nt;
|
|
|
|
switch (type) {
|
|
case RPM_BIN_TYPE:
|
|
s = data;
|
|
ns = element;
|
|
atype = PGPARMOR_SIGNATURE; /* XXX check pkt for signature */
|
|
break;
|
|
case RPM_STRING_TYPE:
|
|
case RPM_STRING_ARRAY_TYPE:
|
|
enc = data;
|
|
if (b64decode(enc, (void **)&s, &ns))
|
|
return xstrdup(_("(not base64)"));
|
|
atype = PGPARMOR_PUBKEY; /* XXX check pkt for pubkey */
|
|
break;
|
|
case RPM_NULL_TYPE:
|
|
case RPM_CHAR_TYPE:
|
|
case RPM_INT8_TYPE:
|
|
case RPM_INT16_TYPE:
|
|
case RPM_INT32_TYPE:
|
|
case RPM_I18NSTRING_TYPE:
|
|
default:
|
|
return xstrdup(_("(invalid type)"));
|
|
/*@notreached@*/ break;
|
|
}
|
|
|
|
nt = ((ns + 2) / 3) * 4;
|
|
/*@-globs@*/
|
|
/* Add additional bytes necessary for eol string(s). */
|
|
if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
|
|
lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
|
|
if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
|
|
++lc;
|
|
nt += lc * strlen(b64encode_eolstr);
|
|
}
|
|
/*@=globs@*/
|
|
|
|
nt += 512; /* XXX slop for armor and crc */
|
|
|
|
val = t = xmalloc(nt + padding + 1);
|
|
*t = '\0';
|
|
t = stpcpy(t, "-----BEGIN PGP ");
|
|
t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
|
|
/*@-globs@*/
|
|
t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), RPMVERSION);
|
|
/*@=globs@*/
|
|
t = stpcpy(t, " (beecrypt-2.2.0)\n\n");
|
|
|
|
if ((enc = b64encode(s, ns)) != NULL) {
|
|
t = stpcpy(t, enc);
|
|
enc = _free(enc);
|
|
if ((enc = b64crc(s, ns)) != NULL) {
|
|
*t++ = '=';
|
|
t = stpcpy(t, enc);
|
|
enc = _free(enc);
|
|
}
|
|
}
|
|
|
|
t = stpcpy(t, "-----END PGP ");
|
|
t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
|
|
t = stpcpy(t, "-----\n");
|
|
|
|
/*@-branchstate@*/
|
|
if (s != data) s = _free(s);
|
|
/*@=branchstate@*/
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * base64Format(int_32 type, const void * data,
|
|
/*@unused@*/ char * formatPrefix, int padding, int element)
|
|
/*@*/
|
|
{
|
|
char * val;
|
|
|
|
if (type != RPM_BIN_TYPE) {
|
|
val = xstrdup(_("(not a blob)"));
|
|
} else {
|
|
const char * enc;
|
|
char * t;
|
|
int lc;
|
|
int nt = ((element + 2) / 3) * 4;
|
|
|
|
/*@-globs@*/
|
|
/* Add additional bytes necessary for eol string(s). */
|
|
if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
|
|
lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
|
|
if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
|
|
++lc;
|
|
nt += lc * strlen(b64encode_eolstr);
|
|
}
|
|
/*@=globs@*/
|
|
|
|
val = t = xmalloc(nt + padding + 1);
|
|
|
|
*t = '\0';
|
|
if ((enc = b64encode(data, element)) != NULL) {
|
|
t = stpcpy(t, enc);
|
|
enc = _free(enc);
|
|
}
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
#ifdef NOTYET
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * pgppktFormat(int_32 type, const void * data,
|
|
char * formatPrefix, int padding, int element)
|
|
/*@modifies formatPrefix @*/
|
|
{
|
|
char * val;
|
|
|
|
if (type != RPM_BIN_TYPE) {
|
|
val = xstrdup(_("(not a blob)"));
|
|
} else {
|
|
}
|
|
|
|
return val;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * depflagsFormat(int_32 type, const void * data,
|
|
char * formatPrefix, int padding, /*@unused@*/ int element)
|
|
/*@modifies formatPrefix @*/
|
|
{
|
|
char * val;
|
|
char buf[10];
|
|
int anint = *((int_32 *) data);
|
|
|
|
if (type != RPM_INT32_TYPE) {
|
|
val = xstrdup(_("(not a number)"));
|
|
} else {
|
|
buf[0] = '\0';
|
|
|
|
if (anint & RPMSENSE_LESS)
|
|
strcat(buf, "<");
|
|
if (anint & RPMSENSE_GREATER)
|
|
strcat(buf, ">");
|
|
if (anint & RPMSENSE_EQUAL)
|
|
strcat(buf, "=");
|
|
|
|
val = xmalloc(5 + padding);
|
|
strcat(formatPrefix, "s");
|
|
/*@-formatconst@*/
|
|
sprintf(val, formatPrefix, buf);
|
|
/*@=formatconst@*/
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param type tag type
|
|
* @param data tag value
|
|
* @param formatPrefix
|
|
* @param padding
|
|
* @param element (unused)
|
|
* @return formatted string
|
|
*/
|
|
static /*@only@*/ char * nothingFormat(int_32 type, const void * data,
|
|
char * formatPrefix, int padding, /*@unused@*/ int element)
|
|
/*@modifies formatPrefix @*/
|
|
{ /* based on depflagsFormat() code. */
|
|
char * val;
|
|
val = xmalloc(2 + padding);
|
|
strcat(formatPrefix, "s");
|
|
/*@-formatconst@*/
|
|
sprintf(val, formatPrefix, "");
|
|
/*@=formatconst@*/
|
|
|
|
return val;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
|
|
/*@out@*/ void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals fileSystem, internalState @*/
|
|
/*@modifies *type, *data, *count, *freeData,
|
|
fileSystem, internalState @*/
|
|
{
|
|
const char ** list;
|
|
|
|
if (rpmGetFilesystemList(&list, count)) {
|
|
return 1;
|
|
}
|
|
|
|
*type = RPM_STRING_ARRAY_TYPE;
|
|
*((const char ***) data) = list;
|
|
|
|
*freeData = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
|
|
/*@null@*/ /*@out@*/ const void ** data,
|
|
/*@null@*/ /*@out@*/ int_32 * count,
|
|
/*@null@*/ /*@out@*/ int * freeData)
|
|
/*@modifies *type, *data, *freeData @*/
|
|
{
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
HFD_t hfd = headerFreeData;
|
|
rpmTagType ipt;
|
|
char ** array;
|
|
|
|
if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
|
|
if (freeData) *freeData = 0;
|
|
return 0;
|
|
} else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
|
|
if (data) *data = xstrdup(array[0]);
|
|
if (freeData) *freeData = 1;
|
|
if (type) *type = RPM_STRING_TYPE;
|
|
array = hfd(array, ipt);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals rpmGlobalMacroContext,
|
|
fileSystem, internalState @*/
|
|
/*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
|
|
fileSystem, internalState @*/
|
|
{
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
const char ** filenames;
|
|
int_32 * filesizes;
|
|
uint_32 * usages;
|
|
int numFiles;
|
|
|
|
if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
|
|
filesizes = NULL;
|
|
numFiles = 0;
|
|
filenames = NULL;
|
|
} else {
|
|
rpmBuildFileList(h, &filenames, &numFiles);
|
|
}
|
|
|
|
if (rpmGetFilesystemList(NULL, count)) {
|
|
return 1;
|
|
}
|
|
|
|
*type = RPM_INT32_TYPE;
|
|
*freeData = 1;
|
|
|
|
if (filenames == NULL) {
|
|
usages = xcalloc((*count), sizeof(usages));
|
|
*data = usages;
|
|
|
|
return 0;
|
|
}
|
|
|
|
if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
|
|
return 1;
|
|
|
|
*data = usages;
|
|
|
|
filenames = _free(filenames);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@modifies *type, *data, *count, *freeData @*/
|
|
{
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
HFD_t hfd = headerFreeData;
|
|
rpmTagType tnt, tvt, tst;
|
|
int_32 * indices, * flags;
|
|
char ** names, ** versions;
|
|
int numNames, numScripts;
|
|
char ** conds, ** s;
|
|
char * item, * flagsStr;
|
|
char * chptr;
|
|
int i, j, xx;
|
|
char buf[5];
|
|
|
|
if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
|
|
*freeData = 0;
|
|
return 0;
|
|
}
|
|
|
|
xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
|
|
xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
|
|
xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
|
|
xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
|
|
s = hfd(s, tst);
|
|
|
|
*freeData = 1;
|
|
*data = conds = xmalloc(sizeof(*conds) * numScripts);
|
|
*count = numScripts;
|
|
*type = RPM_STRING_ARRAY_TYPE;
|
|
for (i = 0; i < numScripts; i++) {
|
|
chptr = xstrdup("");
|
|
|
|
for (j = 0; j < numNames; j++) {
|
|
if (indices[j] != i)
|
|
/*@innercontinue@*/ continue;
|
|
|
|
item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
|
|
if (flags[j] & RPMSENSE_SENSEMASK) {
|
|
buf[0] = '%', buf[1] = '\0';
|
|
flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
|
|
sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
|
|
flagsStr = _free(flagsStr);
|
|
} else {
|
|
strcpy(item, names[j]);
|
|
}
|
|
|
|
chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
|
|
if (*chptr != '\0') strcat(chptr, ", ");
|
|
strcat(chptr, item);
|
|
item = _free(item);
|
|
}
|
|
|
|
conds[i] = chptr;
|
|
}
|
|
|
|
names = hfd(names, tnt);
|
|
versions = hfd(versions, tvt);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@modifies *type, *data, *count, *freeData @*/
|
|
{
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
HFD_t hfd = headerFreeData;
|
|
rpmTagType tst;
|
|
int_32 * indices, * flags;
|
|
const char ** conds;
|
|
const char ** s;
|
|
int i, j, xx;
|
|
int numScripts, numNames;
|
|
|
|
if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
|
|
*freeData = 0;
|
|
return 1;
|
|
}
|
|
|
|
xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
|
|
xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
|
|
s = hfd(s, tst);
|
|
|
|
*freeData = 1;
|
|
*data = conds = xmalloc(sizeof(*conds) * numScripts);
|
|
*count = numScripts;
|
|
*type = RPM_STRING_ARRAY_TYPE;
|
|
for (i = 0; i < numScripts; i++) {
|
|
for (j = 0; j < numNames; j++) {
|
|
if (indices[j] != i)
|
|
/*@innercontinue@*/ continue;
|
|
|
|
if (flags[j] & RPMSENSE_TRIGGERIN)
|
|
conds[i] = xstrdup("in");
|
|
else if (flags[j] & RPMSENSE_TRIGGERUN)
|
|
conds[i] = xstrdup("un");
|
|
else
|
|
conds[i] = xstrdup("postun");
|
|
/*@innerbreak@*/ break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@modifies *type, *data, *count, *freeData @*/
|
|
{
|
|
*type = RPM_STRING_ARRAY_TYPE;
|
|
|
|
rpmBuildFileList(h, (const char ***) data, count);
|
|
*freeData = 1;
|
|
|
|
*freeData = 0; /* XXX WTFO? */
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* I18N look aside diversions */
|
|
|
|
/*@-exportlocal -exportheadervar@*/
|
|
/*@unchecked@*/
|
|
int _nl_msg_cat_cntr; /* XXX GNU gettext voodoo */
|
|
/*@=exportlocal =exportheadervar@*/
|
|
/*@observer@*/ /*@unchecked@*/
|
|
static const char * language = "LANGUAGE";
|
|
|
|
/*@observer@*/ /*@unchecked@*/
|
|
static const char *_macro_i18ndomains = "%{?_i18ndomains}";
|
|
|
|
/**
|
|
* @param h header
|
|
* @param tag tag
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals rpmGlobalMacroContext @*/
|
|
/*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
|
|
{
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
char * dstring = rpmExpand(_macro_i18ndomains, NULL);
|
|
int rc;
|
|
|
|
*type = RPM_STRING_TYPE;
|
|
*data = NULL;
|
|
*count = 0;
|
|
*freeData = 0;
|
|
|
|
if (dstring && *dstring) {
|
|
char *domain, *de;
|
|
const char * langval;
|
|
const char * msgkey;
|
|
const char * msgid;
|
|
|
|
{ const char * tn = tagName(tag);
|
|
const char * n;
|
|
char * mk;
|
|
size_t nb = sizeof("()");
|
|
int xx = headerName(h, &n);
|
|
if (tn) nb += strlen(tn);
|
|
if (n) nb += strlen(n);
|
|
mk = alloca(nb);
|
|
sprintf(mk, "%s(%s)", (n?n:""), (tn?tn:""));
|
|
msgkey = mk;
|
|
}
|
|
|
|
/* change to en_US for msgkey -> msgid resolution */
|
|
langval = getenv(language);
|
|
(void) setenv(language, "en_US", 1);
|
|
/*@i@*/ ++_nl_msg_cat_cntr;
|
|
|
|
msgid = NULL;
|
|
/*@-branchstate@*/
|
|
for (domain = dstring; domain != NULL; domain = de) {
|
|
de = strchr(domain, ':');
|
|
if (de) *de++ = '\0';
|
|
msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
|
|
if (msgid != msgkey) break;
|
|
}
|
|
/*@=branchstate@*/
|
|
|
|
/* restore previous environment for msgid -> msgstr resolution */
|
|
if (langval)
|
|
(void) setenv(language, langval, 1);
|
|
else
|
|
unsetenv(language);
|
|
/*@i@*/ ++_nl_msg_cat_cntr;
|
|
|
|
if (domain && msgid) {
|
|
*data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
|
|
*data = xstrdup(*data); /* XXX xstrdup has side effects. */
|
|
*count = 1;
|
|
*freeData = 1;
|
|
}
|
|
dstring = _free(dstring);
|
|
if (*data)
|
|
return 0;
|
|
}
|
|
|
|
dstring = _free(dstring);
|
|
|
|
rc = hge(h, tag, type, (void **)data, count);
|
|
|
|
if (rc && (*data) != NULL) {
|
|
*data = xstrdup(*data);
|
|
*freeData = 1;
|
|
return 0;
|
|
}
|
|
|
|
*freeData = 0;
|
|
*data = NULL;
|
|
*count = 0;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals rpmGlobalMacroContext @*/
|
|
/*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
|
|
{
|
|
return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals rpmGlobalMacroContext @*/
|
|
/*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
|
|
{
|
|
return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
|
|
}
|
|
|
|
/**
|
|
* @param h header
|
|
* @retval type address of tag type
|
|
* @retval data address of tag value pointer
|
|
* @retval count address of no. of data items
|
|
* @retval freeData address of data-was-malloc'ed indicator
|
|
* @return 0 on success
|
|
*/
|
|
static int groupTag(Header h, /*@out@*/ rpmTagType * type,
|
|
/*@out@*/ const void ** data, /*@out@*/ int_32 * count,
|
|
/*@out@*/ int * freeData)
|
|
/*@globals rpmGlobalMacroContext @*/
|
|
/*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
|
|
{
|
|
return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
|
|
}
|
|
|
|
/*@-type@*/ /* FIX: cast? */
|
|
const struct headerSprintfExtension_s rpmHeaderFormats[] = {
|
|
{ HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
|
|
{ HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
|
|
{ HEADER_EXT_FORMAT, "armor", { armorFormat } },
|
|
{ HEADER_EXT_FORMAT, "base64", { base64Format } },
|
|
#ifdef NOTYET
|
|
{ HEADER_EXT_FORMAT, "pgppkt", { pgppktFormat } },
|
|
#endif
|
|
{ HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
|
|
{ HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
|
|
{ HEADER_EXT_FORMAT, "perms", { permsFormat } },
|
|
{ HEADER_EXT_FORMAT, "permissions", { permsFormat } },
|
|
{ HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
|
|
{ HEADER_EXT_FORMAT, "nothing", { nothingFormat } },
|
|
{ HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
|
|
} ;
|
|
/*@=type@*/
|