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;
|
|
int 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 = headerNVR(h, &n, NULL, NULL);
|
|
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@*/
|