diff options
-rw-r--r-- | lib/formats.c | 147 | ||||
-rw-r--r-- | rpmdb/hdrinline.h | 22 | ||||
-rw-r--r-- | rpmdb/header.c | 244 | ||||
-rw-r--r-- | rpmdb/header.h | 16 | ||||
-rw-r--r-- | rpmdb/header_internal.h | 3 |
5 files changed, 254 insertions, 178 deletions
diff --git a/lib/formats.c b/lib/formats.c index e16a8cc24..eef8ec197 100644 --- a/lib/formats.c +++ b/lib/formats.c @@ -138,76 +138,6 @@ static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, } /** - * Wrap tag data in simple header xml markup. - * @param type tag type - * @param data tag value - * @param formatPrefix - * @param padding - * @param element (unused) - * @return formatted string - */ -static /*@only@*/ char * xmlFormat(int_32 type, const void * data, - char * formatPrefix, int padding, - /*@unused@*/ int element) - /*@modifies formatPrefix @*/ -{ - const char * xtag; - size_t nb; - char * val; - char * s = NULL; - char * t, * te; - long anint = 0; - - switch (type) { - case RPM_I18NSTRING_TYPE: - case RPM_STRING_TYPE: - s = data; - xtag = "string"; - break; - case RPM_CHAR_TYPE: - case RPM_INT8_TYPE: - anint = *((int_8 *) data); - break; - case RPM_INT16_TYPE: - anint = *((int_16 *) data); - break; - case RPM_INT32_TYPE: - anint = *((int_32 *) data); - break; - case RPM_NULL_TYPE: - case RPM_STRING_ARRAY_TYPE: - case RPM_BIN_TYPE: - default: - return xstrdup(_("(invalid type)")); - /*@notreached@*/ break; - } - - if (s == NULL) { - int slen = 32; - s = memset(alloca(slen+1), 0, slen+1); - snprintf(s, slen, "%ld", anint); - xtag = "integer"; - } - - nb = 2 * strlen(xtag) + sizeof("<></>") + strlen(s); - - te = t = alloca(nb); - te = stpcpy( stpcpy( stpcpy(te, "<"), xtag), ">"); - te = stpcpy(te, s); - te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">"); - - nb += padding; - val = xmalloc(nb+1); -/*@-boundswrite@*/ - strcat(formatPrefix, "s"); -/*@=boundswrite@*/ - snprintf(val, nb, formatPrefix, t); - val[nb] = '\0'; - - return val; -} - -/** * Wrap a pubkey in ascii armor for display. * @todo Permit selectable display formats (i.e. binary). * @param type tag type @@ -307,6 +237,83 @@ static /*@only@*/ char * base64Format(int_32 type, const void * data, } /** + * Wrap tag data in simple header xml markup. + * @param type tag type + * @param data tag value + * @param formatPrefix + * @param padding + * @param element (unused) + * @return formatted string + */ +static /*@only@*/ char * xmlFormat(int_32 type, const void * data, + char * formatPrefix, int padding, + /*@unused@*/ int element) + /*@modifies formatPrefix @*/ +{ + const char * xtag = NULL; + size_t nb; + char * val; + const char * s = NULL; + char * t, * te; + unsigned long anint = 0; + + switch (type) { + case RPM_I18NSTRING_TYPE: + case RPM_STRING_TYPE: + s = data; + xtag = "string"; + break; + case RPM_BIN_TYPE: + s = base64Format(type, data, formatPrefix, padding, element); + xtag = "base64"; + break; + case RPM_CHAR_TYPE: + case RPM_INT8_TYPE: + anint = *((uint_8 *) data); + break; + case RPM_INT16_TYPE: + anint = *((uint_16 *) data); + break; + case RPM_INT32_TYPE: + anint = *((uint_32 *) data); + break; + case RPM_NULL_TYPE: + case RPM_STRING_ARRAY_TYPE: + default: + return xstrdup(_("(invalid xml type)")); + /*@notreached@*/ break; + } + + if (s == NULL) { + int tlen = 32; + t = memset(alloca(tlen+1), 0, tlen+1); + snprintf(t, tlen, "%lu", anint); + s = t; + xtag = "integer"; + } + + nb = 2 * strlen(xtag) + sizeof("\t<></>") + strlen(s); + te = t = alloca(nb); + te = stpcpy( stpcpy( stpcpy(te, "\t<"), xtag), ">"); + te = stpcpy(te, s); + te = stpcpy( stpcpy( stpcpy(te, "</"), xtag), ">"); + + /* XXX s was malloc'd */ + if (!strcmp(xtag, "base64")) + s = _free(s); + + nb += padding; + val = xmalloc(nb+1); +/*@-boundswrite@*/ + strcat(formatPrefix, "s"); +/*@=boundswrite@*/ + snprintf(val, nb, formatPrefix, t); + val[nb] = '\0'; + + return val; +} + +/** * Display signature fingerprint and time. * @param type tag type * @param data tag value diff --git a/rpmdb/hdrinline.h b/rpmdb/hdrinline.h index 83f38463d..40d6d050c 100644 --- a/rpmdb/hdrinline.h +++ b/rpmdb/hdrinline.h @@ -239,7 +239,7 @@ int headerIsEntry(/*@null@*/ Header h, int_32 tag) /** \ingroup header * Free data allocated when retrieved from header. * @param h header - * @param data address of data (or NULL) + * @param data pointer to tag value(s) * @param type type of data (or -1 to force free) * @return NULL always */ @@ -259,9 +259,9 @@ int headerIsEntry(/*@null@*/ Header h, int_32 tag) * * @param h header * @param tag tag - * @retval type address of tag value data type (or NULL) - * @retval p address of pointer to tag value(s) (or NULL) - * @retval c address of number of values (or NULL) + * @retval *type tag value data type (or NULL) + * @retval *p pointer to tag value(s) (or NULL) + * @retval *c number of values (or NULL) * @return 1 on success, 0 on failure */ /*@unused@*/ static inline @@ -281,9 +281,9 @@ int headerGetEntry(Header h, int_32 tag, * * @param h header * @param tag tag - * @retval type address of tag value data type (or NULL) - * @retval p address of pointer to tag value(s) (or NULL) - * @retval c address of number of values (or NULL) + * @retval *type tag value data type (or NULL) + * @retval *p pointer to tag value(s) (or NULL) + * @retval *c number of values (or NULL) * @return 1 on success, 0 on failure */ /*@unused@*/ static inline @@ -484,10 +484,10 @@ HeaderIterator headerInitIterator(Header h) /** \ingroup header * Return next tag from header. * @param hi header tag iterator - * @retval tag address of tag - * @retval type address of tag value data type - * @retval p address of pointer to tag value(s) - * @retval c address of number of values + * @retval *tag tag + * @retval *type tag value data type + * @retval *p pointer to tag value(s) + * @retval *c number of values * @return 1 on success, 0 on failure */ /*@unused@*/ static inline diff --git a/rpmdb/header.c b/rpmdb/header.c index 7cd0e7045..56d815164 100644 --- a/rpmdb/header.c +++ b/rpmdb/header.c @@ -35,6 +35,12 @@ int _hdr_debug = 0; #define PARSER_IN_ARRAY 1 #define PARSER_IN_EXPR 2 +/* XXX for xml support */ +/*@-redecl@*/ +/*@observer@*/ extern const char *const tagName(int tag) + /*@*/; +/*@=redecl@*/ + /** \ingroup header */ /*@observer@*/ /*@unchecked@*/ @@ -2409,8 +2415,22 @@ typedef struct headerSprintfArgs_s { static headerSprintfArgs hsaInit(/*@returned@*/ headerSprintfArgs hsa) /*@modifies hsa */ { + sprintfTag tag = + (hsa->format->type == PTOK_TAG + ? &hsa->format->u.tag : + (hsa->format->type == PTOK_ARRAY + ? &hsa->format->u.array.format->u.tag : + NULL)); + if (hsa != NULL) { +#if 0 +if (tag != NULL) { +fprintf(stderr, "*** hsaInit(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad); +} +#endif hsa->i = 0; + if (tag != NULL && tag->tag == -2) + hsa->hi = headerInitIterator(hsa->h); } return hsa; } @@ -2425,10 +2445,34 @@ static sprintfToken hsaNext(/*@returned@*/ headerSprintfArgs hsa) /*@modifies hsa */ { sprintfToken fmt = NULL; + sprintfTag tag = + (hsa->format->type == PTOK_TAG + ? &hsa->format->u.tag : + (hsa->format->type == PTOK_ARRAY + ? &hsa->format->u.array.format->u.tag : + NULL)); if (hsa != NULL && hsa->i >= 0 && hsa->i < hsa->numTokens) { - fmt = hsa->format + hsa->i++; + fmt = hsa->format + hsa->i; + if (hsa->hi == NULL) { + hsa->i++; + } else { + int_32 tagno; + int_32 type; + int_32 count; + + if (!headerNextIterator(hsa->hi, &tagno, &type, NULL, &count)) + fmt = NULL; + tag->tag = tagno; + } } + +#if 0 +if (tag != NULL) { +fprintf(stderr, "*** hsaNext(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d ret %p\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad, fmt); +} +#endif + return fmt; } @@ -2440,6 +2484,19 @@ static sprintfToken hsaNext(/*@returned@*/ headerSprintfArgs hsa) static headerSprintfArgs hsaFini(/*@returned@*/ headerSprintfArgs hsa) /*@modifies hsa */ { +#if 0 + sprintfTag tag = + (hsa->format->type == PTOK_TAG + ? &hsa->format->u.tag : + (hsa->format->type == PTOK_ARRAY + ? &hsa->format->u.array.format->u.tag : + NULL)); + +if (tag != NULL) { +fprintf(stderr, "*** hsaFini(%d): fmt %p ext[%d] %p #%d 1? %d format \"%s\" type \"%s\" pad %d\n", hsa->format->type, tag->fmt, tag->extNum, tag->ext, tag->tag, tag->justOne, tag->format, tag->type, tag->pad); +} +#endif + if (hsa != NULL) { hsa->hi = headerFreeIterator(hsa->hi); hsa->i = 0; @@ -2468,51 +2525,75 @@ static char * hsaReserve(headerSprintfArgs hsa, size_t need) /** * @param hsa headerSprintf args - * @param tagname - * @retval *tagMatch - * @retval *extMatch - */ -static void findTag(headerSprintfArgs hsa, const char * tagname, - /*@out@*/ headerTagTableEntry *const tagMatch, - /*@out@*/ headerSprintfExtension *const extMatch) - /*@modifies *tagMatch, *extMatch @*/ - /*@requires maxSet(tagMatch) >= 0 /\ maxSet(extMatch) >= 0 @*/ + * @param token parsed fields + * @param name name to find + * @return 0 on success, 1 on not found + */ +static int findTag(headerSprintfArgs hsa, sprintfToken token, const char * name) + /*@modifies token @*/ { - headerTagTableEntry entry; + headerTagTableEntry tag; headerSprintfExtension ext; + sprintfTag stag = (token->type == PTOK_COND + ? &token->u.cond.tag : &token->u.tag); + + stag->fmt = NULL; + stag->ext = NULL; + stag->extNum = 0; + stag->tag = -1; - *tagMatch = NULL; - *extMatch = NULL; + if (!strcmp(name, "*")) { + stag->tag = -2; + goto bingo; + } /*@-branchstate@*/ - if (strncmp("RPMTAG_", tagname, sizeof("RPMTAG_")-1)) { + if (strncmp("RPMTAG_", name, sizeof("RPMTAG_")-1)) { /*@-boundswrite@*/ - char * t = alloca(strlen(tagname) + sizeof("RPMTAG_")); - (void) stpcpy( stpcpy(t, "RPMTAG_"), tagname); - tagname = t; + char * t = alloca(strlen(name) + sizeof("RPMTAG_")); + (void) stpcpy( stpcpy(t, "RPMTAG_"), name); + name = t; /*@=boundswrite@*/ } /*@=branchstate@*/ - /* Search extensions first to permit overriding header tags. */ + /* Search extensions for specific tag override. */ for (ext = hsa->exts; ext != NULL && ext->type != HEADER_EXT_LAST; ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) { if (ext->name == NULL || ext->type != HEADER_EXT_TAG) continue; - if (!xstrcasecmp(ext->name, tagname)) { - *extMatch = ext; - return; + if (!xstrcasecmp(ext->name, name)) { + stag->ext = ext->u.tagFunction; + stag->extNum = ext - hsa->exts; + goto bingo; } } - /* Search header tags. */ - for (entry = hsa->tags; entry->name != NULL; entry++) { - if (!xstrcasecmp(entry->name, tagname)) { - *tagMatch = entry; - return; + /* Search tag names. */ + for (tag = hsa->tags; tag->name != NULL; tag++) { + if (!xstrcasecmp(tag->name, name)) { + stag->tag = tag->val; + goto bingo; + } + } + + return 1; + +bingo: + /* Search extensions for specific format. */ + if (stag->type != NULL) + for (ext = hsa->exts; ext != NULL && ext->type != HEADER_EXT_LAST; + ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) + { + if (ext->name == NULL || ext->type != HEADER_EXT_FORMAT) + continue; + if (!strcmp(ext->name, stag->type)) { + stag->fmt = ext->u.formatFunction; + break; } } + return 0; } /* forward ref */ @@ -2548,8 +2629,6 @@ static int parseFormat(headerSprintfArgs hsa, /*@null@*/ char * str, sprintfToken format; sprintfToken token; int numTokens; - headerTagTableEntry tag; - headerSprintfExtension ext; int i; int done = 0; @@ -2682,26 +2761,15 @@ static int parseFormat(headerSprintfArgs hsa, /*@null@*/ char * str, } i = 0; -/*@-boundswrite@*/ - findTag(hsa, start, &tag, &ext); -/*@=boundswrite@*/ + token->type = PTOK_TAG; - if (tag) { - token->u.tag.ext = NULL; - token->u.tag.tag = tag->val; - } else if (ext) { - token->u.tag.ext = ext->u.tagFunction; - token->u.tag.extNum = ext - hsa->exts; - } else { + if (findTag(hsa, token, start)) { hsa->errmsg = _("unknown tag"); format = freeFormat(format, numTokens); return 1; } - token->type = PTOK_TAG; - start = next; - /*@switchbreak@*/ break; case '[': @@ -2805,8 +2873,6 @@ static int parseFormat(headerSprintfArgs hsa, /*@null@*/ char * str, static int parseExpression(headerSprintfArgs hsa, sprintfToken token, char * str, /*@out@*/ char ** endPtr) { - headerTagTableEntry tag; - headerSprintfExtension ext; char * chptr; char * end; @@ -2895,21 +2961,10 @@ static int parseExpression(headerSprintfArgs hsa, sprintfToken token, *endPtr = chptr; - findTag(hsa, str, &tag, &ext); - - if (tag) { - token->u.cond.tag.ext = NULL; - token->u.cond.tag.tag = tag->val; - } else if (ext) { - token->u.cond.tag.ext = ext->u.tagFunction; - token->u.cond.tag.extNum = ext - hsa->exts; - } else { - token->u.cond.tag.ext = NULL; - token->u.cond.tag.tag = -1; - } - token->type = PTOK_COND; + (void) findTag(hsa, token, str); + return 0; } /*@=boundswrite@*/ @@ -2966,8 +3021,6 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) const char ** strarray; int datafree = 0; int countBuf; - headerTagFormatFunction tagtype = NULL; - headerSprintfExtension ext; memset(buf, 0, sizeof(buf)); if (tag->ext) { @@ -3023,27 +3076,14 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) (void) stpcpy( stpcpy(buf, "%"), tag->format); /*@=boundswrite@*/ - if (tag->type) { - for (ext = hsa->exts; ext != NULL && ext->type != HEADER_EXT_LAST; - ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) - { - if (ext->name == NULL || ext->type != HEADER_EXT_FORMAT) - continue; - if (!strcmp(ext->name, tag->type)) { - tagtype = ext->u.formatFunction; - break; - } - } - } - /*@-branchstate@*/ if (data) switch (type) { case RPM_STRING_ARRAY_TYPE: strarray = (const char **)data; - if (tagtype) - val = tagtype(RPM_STRING_TYPE, strarray[element], buf, tag->pad, 0); + if (tag->fmt) + val = tag->fmt(RPM_STRING_TYPE, strarray[element], buf, tag->pad, element); if (val) { need = strlen(val); @@ -3059,8 +3099,8 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) break; case RPM_STRING_TYPE: - if (tagtype) - val = tagtype(RPM_STRING_TYPE, data, buf, tag->pad, 0); + if (tag->fmt) + val = tag->fmt(RPM_STRING_TYPE, data, buf, tag->pad, 0); if (val) { need = strlen(val); @@ -3092,8 +3132,8 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) /*@innerbreak@*/ break; } - if (tagtype) - val = tagtype(RPM_INT32_TYPE, &intVal, buf, tag->pad, element); + if (tag->fmt) + val = tag->fmt(RPM_INT32_TYPE, &intVal, buf, tag->pad, element); if (val) { need = strlen(val); @@ -3109,8 +3149,8 @@ static char * formatValue(headerSprintfArgs hsa, sprintfTag tag, int element) case RPM_BIN_TYPE: /* XXX HACK ALERT: element field abused as no. bytes of binary data. */ - if (tagtype) - val = tagtype(RPM_BIN_TYPE, data, buf, tag->pad, count); + if (tag->fmt) + val = tag->fmt(RPM_BIN_TYPE, data, buf, tag->pad, count); if (val) { need = strlen(val); @@ -3230,7 +3270,8 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, case PTOK_ARRAY: numElements = -1; spft = token->u.array.format; - for (i = 0; i < token->u.array.numTokens; i++, spft++) { + for (i = 0; i < token->u.array.numTokens; i++, spft++) + { if (spft->type != PTOK_TAG || spft->u.tag.arrayCount || spft->u.tag.justOne) continue; @@ -3247,6 +3288,10 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, continue; /*@=boundswrite@*/ } + + if (type == RPM_BIN_TYPE) + count = 1; /* XXX count abused as no. of bytes. */ + if (numElements > 1 && count != numElements) switch (type) { default: @@ -3270,9 +3315,28 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, /*@=boundswrite@*/ hsa->vallen += (te - t); } else { + int isxml; + need = numElements * token->u.array.numTokens * 10; if (need == 0) break; + spft = token->u.array.format; + isxml = + (spft->type == PTOK_TAG && !strcmp(spft->u.tag.type, "xml")); + + if (isxml) { + const char * tagN = tagName(spft->u.tag.tag); + + need = strlen(tagN) + sizeof("<rpmTag name=>\n") - 1; + t = hsaReserve(hsa, need); +/*@-boundswrite@*/ + te = stpcpy(t, "<rpmTag name="); + te = stpcpy(te, tagN); + te = stpcpy(te, ">\n"); +/*@=boundswrite@*/ + hsa->vallen += (te - t); + } + t = hsaReserve(hsa, need); for (j = 0; j < numElements; j++) { spft = token->u.array.format; @@ -3282,6 +3346,16 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, return NULL; } } + + if (isxml) { + need = sizeof("<rpmTag/>\n") - 1; + t = hsaReserve(hsa, need); +/*@-boundswrite@*/ + te = stpcpy(t, "<rpmTag/>\n"); +/*@=boundswrite@*/ + hsa->vallen += (te - t); + } + } break; } @@ -3291,18 +3365,18 @@ static char * singleSprintf(headerSprintfArgs hsa, sprintfToken token, /** * Create an extension cache. - * @param extensions + * @param exts * @return new extension cache */ static /*@only@*/ rpmec -rpmecNew(const headerSprintfExtension extensions) +rpmecNew(const headerSprintfExtension exts) /*@*/ { headerSprintfExtension ext; rpmec ec; int i = 0; - for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST; + for (ext = exts; ext != NULL && ext->type != HEADER_EXT_LAST; ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) { i++; @@ -3319,13 +3393,13 @@ rpmecNew(const headerSprintfExtension extensions) * @return NULL always */ static /*@null@*/ rpmec -rpmecFree(const headerSprintfExtension extensions, /*@only@*/ rpmec ec) +rpmecFree(const headerSprintfExtension exts, /*@only@*/ rpmec ec) /*@modifies ec @*/ { headerSprintfExtension ext; int i = 0; - for (ext = extensions; ext != NULL && ext->type != HEADER_EXT_LAST; + for (ext = exts; ext != NULL && ext->type != HEADER_EXT_LAST; ext = (ext->type == HEADER_EXT_MORE ? ext->u.more : ext+1)) { /*@-boundswrite@*/ diff --git a/rpmdb/header.h b/rpmdb/header.h index 9c310a787..7dc6dac77 100644 --- a/rpmdb/header.h +++ b/rpmdb/header.h @@ -86,17 +86,6 @@ extern "C" { #endif -#if defined(__alpha__) || defined(__alpha) -typedef long int int_64; -typedef int int_32; -typedef short int int_16; -typedef char int_8; - -typedef unsigned int uint_32; -typedef unsigned short uint_16; - -#else - #if 0 /* XXX hpux needs -Ae in CFLAGS to grok this */ typedef long long int int_64; #endif @@ -104,9 +93,12 @@ typedef int int_32; typedef short int int_16; typedef char int_8; +#if 0 /* XXX hpux needs -Ae in CFLAGS to grok this */ +typedef unsigned long long int uint_64; +#endif typedef unsigned int uint_32; typedef unsigned short uint_16; -#endif +typedef unsigned char uint_8; /*@-redef@*/ /* LCL: no clue */ /** \ingroup header diff --git a/rpmdb/header_internal.h b/rpmdb/header_internal.h index 83056bdef..a85a219d1 100644 --- a/rpmdb/header_internal.h +++ b/rpmdb/header_internal.h @@ -75,6 +75,8 @@ struct headerToken_s { typedef /*@abstract@*/ struct sprintfTag_s * sprintfTag; struct sprintfTag_s { /*@null@*/ + headerTagFormatFunction fmt; +/*@null@*/ headerTagTagFunction ext; /*!< NULL if tag element is invalid */ int extNum; int_32 tag; @@ -117,6 +119,7 @@ struct sprintfToken_s { struct { /*@only@*/ sprintfToken format; + int i; int numTokens; } array; /*!< PTOK_ARRAY */ struct { |