--- pcp-3.9.6/configure.ac.orig 2014-05-28 22:05:42.575179206 +0200 +++ pcp-3.9.6/configure.ac 2014-05-30 20:21:36.818374363 +0200 @@ -2369,8 +2369,8 @@ savedLIBS=$LIBS AC_MSG_CHECKING([for rpmlib > 4.4.2]) AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include ]], - [[(void)HEADERGET_EXT;]])], + [AC_LANG_PROGRAM([[#include ]], + [[(void)RPMSCRIPT_PREIN;]])], [AC_MSG_RESULT([yes]) have_rpmlib=1], [AC_MSG_RESULT([no]) --- pcp-3.9.4/src/pmdas/rpm/GNUmakefile.orig 2014-04-15 11:10:23.000000000 +0200 +++ pcp-3.9.4/src/pmdas/rpm/GNUmakefile 2014-06-01 07:52:17.205709769 +0200 @@ -31,9 +31,9 @@ VERSION_SCRIPT = exports LSRCFILES = Install Remove pmns root help LDIRT = domain.h $(IAM).log $(VERSION_SCRIPT) -LIB_FOR_RPM = -lrpm +LIB_FOR_RPM = -lrpm -lrpmdb -lrpmio LLDLIBS = $(PCP_PMDALIB) $(LIB_FOR_RPM) $(LIB_FOR_PTHREADS) -LCFLAGS = $(INVISIBILITY) +LCFLAGS = $(INVISIBILITY) -I/usr/include/rpm default: build-me --- pcp-3.9.4/src/pmdas/rpm/rpm.c.orig 2014-04-15 11:10:23.000000000 +0200 +++ pcp-3.9.4/src/pmdas/rpm/rpm.c 2014-06-01 07:51:37.589043928 +0200 @@ -17,9 +17,9 @@ #include #include #include +#include #include -#include -#include +#include #include #include #include @@ -436,7 +436,7 @@ rpm_extract_metadata(const char *name, r m->license = dict_insert(rpm_extract_string(td, h, RPMTAG_LICENSE)); m->packager = dict_insert(rpm_extract_string(td, h, RPMTAG_PACKAGER)); m->release = dict_insert(rpm_extract_string(td, h, RPMTAG_RELEASE)); - m->longsize = rpm_extract_value(td, h, RPMTAG_LONGSIZE); + m->longsize = rpm_extract_value(td, h, RPMTAG_PACKAGESIZE); m->sourcerpm = dict_insert(rpm_extract_string(td, h, RPMTAG_SOURCERPM)); m->summary = dict_insert(rpm_extract_string(td, h, RPMTAG_SUMMARY)); m->url = dict_insert(rpm_extract_string(td, h, RPMTAG_URL)); @@ -444,6 +444,157 @@ rpm_extract_metadata(const char *name, r m->version = dict_insert(rpm_extract_string(td, h, RPMTAG_VERSION)); } +/* from rpm.org */ +static char *rstrscat(char **dest, const char *arg, ...) +{ + va_list ap; + size_t arg_size, dst_size; + const char *s; + char *dst, *p; + + dst = dest ? *dest : NULL; + + if ( arg == NULL ) { + return dst; + } + + va_start(ap, arg); + for (arg_size=0, s=arg; s; s = va_arg(ap, const char *)) + arg_size += strlen(s); + va_end(ap); + + dst_size = dst ? strlen(dst) : 0; + dst = realloc(dst, dst_size+arg_size+1); /* include '\0' */ + p = &dst[dst_size]; + + va_start(ap, arg); + for (s = arg; s; s = va_arg(ap, const char *)) { + size_t size = strlen(s); + memmove(p, s, size); + p += size; + } + va_end(ap); + *p = '\0'; + + if ( dest ) { + *dest = dst; + } + + return dst; +} + +static const char * headerGetString(Header h, int32_t tag) +{ + const char *res = NULL; + struct rpmtd_s td; + + if (headerGet(h, tag, &td, HEADERGET_MINMEM)) { + if (rpmtdCount(&td) == 1) { + res = rpmtdGetString(&td); + } + rpmtdFreeData(&td); + } + return res; +} + +static int rasprintf(char **strp, const char *fmt, ...) +{ + int n; + va_list ap; + char * p = NULL; + + if (strp == NULL) + return -1; + + va_start(ap, fmt); + n = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (n >= -1) { + size_t nb = n + 1; + p = malloc(nb); + va_start(ap, fmt); + n = vsnprintf(p, nb, fmt, ap); + va_end(ap); + } + *strp = p; + return n; +} + +static uint64_t rpmtdGetNumber(rpmtd td) +{ + uint64_t val = 0; + int ix = (td->ix >= 0 ? td->ix : 0); + + switch (td->type) { + case RPM_INT64_TYPE: + val = *((uint64_t *) td->data + ix); + break; + case RPM_INT32_TYPE: + val = *((uint32_t *) td->data + ix); + break; + case RPM_INT16_TYPE: + val = *((uint16_t *) td->data + ix); + break; + case RPM_INT8_TYPE: + val = *((uint8_t *) td->data + ix); + break; + default: + break; + } + return val; +} + +static char * headerGetNumericAsString(Header h, int32_t tag) +{ + char *res = NULL; + struct rpmtd_s td; + + if (headerGet(h, tag, &td, HEADERGET_EXT)) { + if (rpmtdCount(&td) == 1) { + rasprintf(&res, "%" PRIu64, rpmtdGetNumber(&td)); + } + rpmtdFreeData(&td); + } + return res; +} + +static int headerIsSource(Header h) +{ + return (!headerIsEntry(h, RPMTAG_SOURCERPM)); +} + +char *getNEVRA(Header h) +{ + const char *val = NULL; + char *res = NULL; + + { + val = headerGetString(h, RPMTAG_NAME); + if (val) rstrscat(&res, val, "-", NULL); + } + { + char *e = headerGetNumericAsString(h, RPMTAG_EPOCH); + if (e) rstrscat(&res, e, ":", NULL); + free(e); + } + { + val = headerGetString(h, RPMTAG_VERSION); + if (val) rstrscat(&res, val, "-", NULL); + } + { + val = headerGetString(h, RPMTAG_RELEASE); + if (val) rstrscat(&res, val, NULL); + } + { + val = headerGetString(h, RPMTAG_ARCH); + if (headerIsSource(h) && val == NULL) val = "src"; + if (val) rstrscat(&res, ".", val, NULL); + } + + return res; +} + /* * Refresh the RPM package names and values in the cache. * This is to be only ever invoked from a single thread. @@ -470,7 +621,8 @@ rpm_update_cache(void *ptr) * since the only (?) thing that can fail is memory allocation, which * rpmlib internally maps to an exit(1). */ - td = rpmtdNew(); + td = malloc(sizeof(*td)); + rpmtdReset(td); ts = rpmtsCreate(); if (rpmReadConfigFiles_p == 0) { @@ -483,8 +635,7 @@ rpm_update_cache(void *ptr) /* Iterate through the entire list of RPMs, extract names and values */ mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0); while ((h = rpmdbNextIterator(mi)) != NULL) { - headerGet(h, RPMTAG_NEVRA, td, HEADERGET_EXT | HEADERGET_MINMEM); - const char *name = rpmtdGetString(td); + char *name = getNEVRA(h); metadata meta; package *pp = NULL; int sts, err = 0; @@ -522,10 +673,13 @@ rpm_update_cache(void *ptr) } } pthread_mutex_unlock(&indom_mutex); + free(name); } rpmdbFreeIterator(mi); rpmtsFree(ts); + rpmtdFreeData(td); + free(td); pthread_mutex_lock(&indom_mutex); stop_timing();