Blame agent/mibgroup/host/data_access/swinst_rpm.c.rpm-memory-leak

Packit f2355f
/*
Packit f2355f
 * swinst_rpm.c:
Packit f2355f
 *     hrSWInstalledTable data access:
Packit f2355f
 */
Packit f2355f
#include <net-snmp/net-snmp-config.h>
Packit f2355f
#include <net-snmp/net-snmp-features.h>
Packit f2355f
Packit f2355f
#include <stdio.h>
Packit f2355f
#ifdef HAVE_STDLIB_H
Packit f2355f
#include <stdlib.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_UNISTD_H
Packit f2355f
#include <unistd.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_SYS_TYPES_H
Packit f2355f
#include <sys/types.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_STRING_H
Packit f2355f
#include <string.h>
Packit f2355f
#else
Packit f2355f
#include <strings.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_FCNTL_H
Packit f2355f
#include <fcntl.h>
Packit f2355f
#endif
Packit f2355f
Packit f2355f
#ifdef HAVE_RPM_RPMLIB_H
Packit f2355f
#include <rpm/rpmlib.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_RPM_RPMLIB_H
Packit f2355f
#include <rpm/header.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_RPMGETPATH		/* HAVE_RPM_RPMMACRO_H */
Packit f2355f
#include <rpm/rpmmacro.h>
Packit f2355f
#endif
Packit f2355f
#ifdef HAVE_RPM_RPMTS_H
Packit f2355f
#include <rpm/rpmts.h>
Packit f2355f
#include <rpm/rpmdb.h>
Packit f2355f
#endif
Packit f2355f
Packit f2355f
#include <net-snmp/net-snmp-includes.h>
Packit f2355f
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit f2355f
#include <net-snmp/library/container.h>
Packit f2355f
#include <net-snmp/library/snmp_debug.h>
Packit f2355f
#include <net-snmp/data_access/swinst.h>
Packit f2355f
#include "swinst_private.h"
Packit f2355f
Packit f2355f
netsnmp_feature_require(date_n_time)
Packit f2355f
Packit f2355f
   /*
Packit f2355f
    * Location of RPM package directory.
Packit f2355f
    * Used for:
Packit f2355f
    *    - reporting hrSWInstalledLast* objects
Packit f2355f
    *    - detecting when the cached contents are out of date.
Packit f2355f
    */
Packit f2355f
char pkg_directory[SNMP_MAXPATH];
Packit f2355f
Packit f2355f
/* ---------------------------------------------------------------------
Packit f2355f
 */
Packit f2355f
void
Packit f2355f
netsnmp_swinst_arch_init(void)
Packit f2355f
{
Packit f2355f
    char        *rpmdbpath = NULL;
Packit f2355f
    const char  *dbpath;
Packit f2355f
    struct stat  stat_buf;
Packit f2355f
Packit f2355f
#ifdef HAVE_RPMGETPATH
Packit f2355f
    rpmReadConfigFiles( NULL, NULL );
Packit f2355f
    rpmdbpath = rpmGetPath( "%{_dbpath}", NULL );
Packit f2355f
    dbpath = rpmdbpath;
Packit f2355f
#else
Packit f2355f
    dbpath = "/var/lib/rpm";   /* Most likely */
Packit f2355f
#endif
Packit f2355f
Packit f2355f
    snprintf( pkg_directory, SNMP_MAXPATH, "%s/Packages", dbpath );
Packit f2355f
    SNMP_FREE(rpmdbpath);
Packit f2355f
    dbpath = NULL;
Packit f2355f
    if (-1 == stat( pkg_directory, &stat_buf )) {
Packit f2355f
        snmp_log(LOG_ERR, "Can't find directory of RPM packages");
Packit f2355f
        pkg_directory[0] = '\0';
Packit f2355f
    }
Packit f2355f
}
Packit f2355f
Packit f2355f
void
Packit f2355f
netsnmp_swinst_arch_shutdown(void)
Packit f2355f
{
Packit f2355f
     /* Nothing to do */
Packit f2355f
     return;
Packit f2355f
}
Packit f2355f
Packit f2355f
/* ---------------------------------------------------------------------
Packit f2355f
 */
Packit f2355f
int
Packit f2355f
netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
Packit f2355f
{
Packit f2355f
    rpmts                 ts;
Packit f2355f
Packit f2355f
    rpmdbMatchIterator    mi;
Packit f2355f
    Header                h;
Packit f2355f
#if HAVE_HEADERGET
Packit f2355f
    const char           *g;
Packit f2355f
    rpmtd                 td_name, td_version, td_release, td_group, td_time;
Packit f2355f
#else
Packit f2355f
    char                 *n, *v, *r, *g;
Packit f2355f
    int32_t              *t;
Packit f2355f
#endif
Packit f2355f
    time_t                install_time;
Packit f2355f
    size_t                date_len;
Packit f2355f
    int                   i = 1;
Packit f2355f
    netsnmp_swinst_entry *entry;
Packit f2355f
Packit f2355f
#if HAVE_HEADERGET
Packit f2355f
    td_name = rpmtdNew();
Packit f2355f
    td_version = rpmtdNew();
Packit f2355f
    td_release = rpmtdNew();
Packit f2355f
    td_group = rpmtdNew();
Packit f2355f
    td_time = rpmtdNew();
Packit f2355f
#endif
Packit f2355f
    ts = rpmtsCreate();
Packit f2355f
    rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS));
Packit f2355f
Packit f2355f
    mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0);
Packit f2355f
    if (mi == NULL)
Packit f2355f
	NETSNMP_LOGONCE((LOG_ERR, "rpmdbOpen() failed\n"));
Packit f2355f
Packit f2355f
    while (NULL != (h = rpmdbNextIterator( mi )))
Packit f2355f
    {
Packit f2355f
        const u_char *dt;
Packit f2355f
Packit f2355f
        entry = netsnmp_swinst_entry_create( i++ );
Packit f2355f
        if (NULL == entry)
Packit f2355f
            continue;   /* error already logged by function */
Packit f2355f
        CONTAINER_INSERT(container, entry);
Packit f2355f
Packit f2355f
        h = headerLink( h );
Packit f2355f
#if HAVE_HEADERGET
Packit f2355f
        headerGet(h, RPMTAG_NAME, td_name, HEADERGET_EXT);
Packit f2355f
        headerGet(h, RPMTAG_VERSION, td_version, HEADERGET_EXT);
Packit f2355f
        headerGet(h, RPMTAG_RELEASE, td_release, HEADERGET_EXT);
Packit f2355f
        headerGet(h, RPMTAG_GROUP, td_group, HEADERGET_EXT);
Packit f2355f
        headerGet(h, RPMTAG_INSTALLTIME, td_time, HEADERGET_EXT);
Packit f2355f
        entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
Packit f2355f
                                      "%s-%s-%s", rpmtdGetString(td_name),
Packit f2355f
                                      rpmtdGetString(td_version),
Packit f2355f
                                      rpmtdGetString(td_release));
Packit f2355f
        install_time = rpmtdGetNumber(td_time);
Packit f2355f
        g = rpmtdGetString(td_group);
Packit f2355f
#else
Packit f2355f
        headerGetEntry( h, RPMTAG_NAME,        NULL, (void**)&n, NULL);
Packit f2355f
        headerGetEntry( h, RPMTAG_VERSION,     NULL, (void**)&v, NULL);
Packit f2355f
        headerGetEntry( h, RPMTAG_RELEASE,     NULL, (void**)&r, NULL);
Packit f2355f
        headerGetEntry( h, RPMTAG_GROUP,       NULL, (void**)&g, NULL);
Packit f2355f
        headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL);
Packit f2355f
        entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
Packit f2355f
                                      "%s-%s-%s", n, v, r);
Packit f2355f
        install_time = *t;
Packit f2355f
#endif
Packit f2355f
        entry->swType = (g && NULL != strstr( g, "System Environment"))
Packit f2355f
                        ? 2      /* operatingSystem */
Packit f2355f
                        : 4;     /*  application    */
Packit f2355f
        if (entry->swName_len > sizeof(entry->swName))
Packit f2355f
            entry->swName_len = sizeof(entry->swName);
Packit f2355f
Packit f2355f
        dt = date_n_time( &install_time, &date_len );
Packit f2355f
        if (date_len != 8 && date_len != 11) {
Packit f2355f
            snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName);
Packit f2355f
            entry->swDate_len = 0;
Packit f2355f
        }
Packit f2355f
        else {
Packit f2355f
            entry->swDate_len = date_len;
Packit f2355f
            memcpy(entry->swDate, dt, entry->swDate_len);
Packit f2355f
        }
Packit f2355f
Packit f2355f
#if HAVE_HEADERGET
Packit f2355f
        rpmtdFreeData(td_name);
Packit f2355f
        rpmtdFreeData(td_version);
Packit f2355f
        rpmtdFreeData(td_release);
Packit f2355f
        rpmtdFreeData(td_group);
Packit f2355f
        rpmtdFreeData(td_time);
Packit f2355f
#endif
Packit f2355f
        headerFree( h );
Packit f2355f
    }
Packit f2355f
    rpmdbFreeIterator( mi );
Packit f2355f
    rpmtsFree( ts );
Packit f2355f
#if HAVE_HEADERGET
Packit f2355f
    rpmtdFree(td_name);
Packit f2355f
    rpmtdFree(td_version);
Packit f2355f
    rpmtdFree(td_release);
Packit f2355f
    rpmtdFree(td_group);
Packit f2355f
    rpmtdFree(td_time);
Packit f2355f
#endif
Packit f2355f
Packit f2355f
    DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n",
Packit f2355f
                (int)CONTAINER_SIZE(container)));
Packit f2355f
Packit f2355f
    return 0;
Packit f2355f
}