Blame agent/mibgroup/host/data_access/swrun.c.iterator-fix

Packit d812c0
/*
Packit d812c0
 *  Swrun MIB architecture support
Packit d812c0
 *
Packit d812c0
 * $Id: swrun.c 15768 2007-01-22 16:18:29Z rstory $
Packit d812c0
 */
Packit d812c0
/*
Packit d812c0
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
Packit d812c0
 * Use is subject to license terms specified in the COPYING file
Packit d812c0
 * distributed with the Net-SNMP package.
Packit d812c0
 */
Packit d812c0
#include <net-snmp/net-snmp-config.h>
Packit d812c0
#include <net-snmp/net-snmp-features.h>
Packit d812c0
#include <net-snmp/net-snmp-includes.h>
Packit d812c0
Packit d812c0
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit d812c0
#include <net-snmp/data_access/swrun.h>
Packit d812c0
#include "swrun.h"
Packit d812c0
#include "swrun_private.h"
Packit d812c0
Packit d812c0
#if HAVE_PCRE_H
Packit d812c0
#include <pcre.h>
Packit d812c0
#endif
Packit d812c0
Packit d812c0
netsnmp_feature_child_of(software_running, libnetsnmpmibs)
Packit d812c0
Packit d812c0
netsnmp_feature_child_of(swrun_max_processes, software_running)
Packit d812c0
netsnmp_feature_child_of(swrun_count_processes_by_name, software_running)
Packit d812c0
netsnmp_feature_child_of(swrun_count_processes_by_regex, software_running)
Packit d812c0
Packit d812c0
/**---------------------------------------------------------------------*/
Packit d812c0
/*
Packit d812c0
 * local static vars
Packit d812c0
 */
Packit d812c0
static int _swrun_init = 0;
Packit d812c0
       int _swrun_max  = 0;
Packit d812c0
static netsnmp_cache     *swrun_cache     = NULL;
Packit d812c0
static netsnmp_container *swrun_container = NULL;
Packit d812c0
Packit d812c0
/*
Packit d812c0
 * local static prototypes
Packit d812c0
 */
Packit d812c0
static void _swrun_entry_release(netsnmp_swrun_entry * entry,
Packit d812c0
                                            void *unused);
Packit d812c0
Packit d812c0
/**
Packit d812c0
 * initialization
Packit d812c0
 */
Packit d812c0
void
Packit d812c0
init_swrun(void)
Packit d812c0
{
Packit d812c0
    DEBUGMSGTL(("swrun:access", "init\n"));
Packit d812c0
Packit d812c0
    if (1 == _swrun_init)
Packit d812c0
        return;
Packit d812c0
Packit d812c0
    _swrun_init = 1;
Packit d812c0
Packit d812c0
    (void)netsnmp_swrun_container();
Packit d812c0
    netsnmp_arch_swrun_init();
Packit d812c0
    (void) netsnmp_swrun_cache();
Packit d812c0
}
Packit d812c0
Packit d812c0
void
Packit d812c0
shutdown_swrun(void)
Packit d812c0
{
Packit d812c0
    DEBUGMSGTL(("swrun:access", "shutdown\n"));
Packit d812c0
Packit d812c0
}
Packit d812c0
Packit d812c0
int
Packit d812c0
swrun_count_processes(int include_kthreads)
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_entry *entry;
Packit d812c0
    netsnmp_iterator  *it;
Packit d812c0
    int i = 0;
Packit d812c0
Packit d812c0
    netsnmp_cache_check_and_reload(swrun_cache);
Packit d812c0
    if ( !swrun_container )
Packit d812c0
        return 0;    /* or -1 */
Packit d812c0
Packit d812c0
    if (include_kthreads)
Packit d812c0
        return ( swrun_container ? CONTAINER_SIZE(swrun_container) : 0 );
Packit d812c0
Packit d812c0
    it = CONTAINER_ITERATOR( swrun_container );
Packit d812c0
    while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) {
Packit d812c0
        if (4 == entry->hrSWRunType)
Packit d812c0
            i++;
Packit d812c0
    }
Packit d812c0
    ITERATOR_RELEASE( it );
Packit d812c0
Packit d812c0
    return i;
Packit d812c0
}
Packit d812c0
Packit d812c0
#ifndef NETSNMP_FEATURE_REMOVE_SWRUN_MAX_PROCESSES
Packit d812c0
int
Packit d812c0
swrun_max_processes( void )
Packit d812c0
{
Packit d812c0
    return _swrun_max;
Packit d812c0
}
Packit d812c0
#endif /* NETSNMP_FEATURE_REMOVE_SWRUN_MAX_PROCESSES */
Packit d812c0
Packit d812c0
#ifndef NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_REGEX
Packit d812c0
#if HAVE_PCRE_H
Packit d812c0
int
Packit d812c0
swrun_count_processes_by_regex( char *name, struct real_pcre *regexp )
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_entry *entry;
Packit d812c0
    netsnmp_iterator  *it;
Packit d812c0
    int i = 0;
Packit d812c0
    int found_ndx[30];
Packit d812c0
    int found;
Packit d812c0
    char fullCommand[64 + 128 + 128 + 3];
Packit d812c0
Packit d812c0
    netsnmp_cache_check_and_reload(swrun_cache);
Packit d812c0
    if ( !swrun_container || !name || !regexp )
Packit d812c0
        return 0;    /* or -1 */
Packit d812c0
Packit d812c0
    it = CONTAINER_ITERATOR( swrun_container );
Packit d812c0
    while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) {
Packit d812c0
        /* need to assemble full command back so regexps can get full picture */
Packit d812c0
        sprintf(fullCommand, "%s %s", entry->hrSWRunPath, entry->hrSWRunParameters);
Packit d812c0
        found = pcre_exec(regexp, NULL, fullCommand, strlen(fullCommand), 0, 0, found_ndx, 30);
Packit d812c0
        if (found > 0) {
Packit d812c0
            i++;
Packit d812c0
        }
Packit d812c0
    }
Packit d812c0
    ITERATOR_RELEASE( it );
Packit d812c0
Packit d812c0
    return i;
Packit d812c0
}
Packit d812c0
#endif /* HAVE_PCRE_H */
Packit d812c0
#endif /* NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_REGEX */
Packit d812c0
Packit d812c0
#ifndef NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_NAME
Packit d812c0
int
Packit d812c0
swrun_count_processes_by_name( char *name )
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_entry *entry;
Packit d812c0
    netsnmp_iterator  *it;
Packit d812c0
    int i = 0;
Packit d812c0
Packit d812c0
    netsnmp_cache_check_and_reload(swrun_cache);
Packit d812c0
    if ( !swrun_container || !name )
Packit d812c0
        return 0;    /* or -1 */
Packit d812c0
Packit d812c0
    it = CONTAINER_ITERATOR( swrun_container );
Packit d812c0
    while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) {
Packit d812c0
        if (0 == strcmp( entry->hrSWRunName, name ))
Packit d812c0
            i++;
Packit d812c0
    }
Packit d812c0
    ITERATOR_RELEASE( it );
Packit d812c0
Packit d812c0
    return i;
Packit d812c0
}
Packit d812c0
#endif /* NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_NAME */
Packit d812c0
Packit d812c0
/**---------------------------------------------------------------------*/
Packit d812c0
/*
Packit d812c0
 * cache functions
Packit d812c0
 */
Packit d812c0
Packit d812c0
static int
Packit d812c0
_cache_load( netsnmp_cache *cache,  void *magic )
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_container_load( swrun_container, 0 );
Packit d812c0
    return 0;
Packit d812c0
}
Packit d812c0
Packit d812c0
static void
Packit d812c0
_cache_free( netsnmp_cache *cache,  void *magic )
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_container_free_items( swrun_container );
Packit d812c0
    return;
Packit d812c0
}
Packit d812c0
Packit d812c0
/**
Packit d812c0
 * create swrun cache
Packit d812c0
 */
Packit d812c0
netsnmp_cache *
Packit d812c0
netsnmp_swrun_cache(void)
Packit d812c0
{
Packit d812c0
    oid    hrSWRunTable_oid[]   = { 1, 3, 6, 1, 2, 1, 25, 4, 2 };
Packit d812c0
    size_t hrSWRunTable_oid_len = OID_LENGTH(hrSWRunTable_oid);
Packit d812c0
Packit d812c0
    if ( !swrun_cache ) {
Packit d812c0
        swrun_cache = netsnmp_cache_create(30,   /* timeout in seconds */
Packit d812c0
                           _cache_load,  _cache_free,
Packit d812c0
                           hrSWRunTable_oid, hrSWRunTable_oid_len);
Packit d812c0
        if (swrun_cache)
Packit d812c0
            swrun_cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
Packit d812c0
    }
Packit d812c0
    return swrun_cache;
Packit d812c0
}
Packit d812c0
Packit d812c0
Packit d812c0
/**---------------------------------------------------------------------*/
Packit d812c0
/*
Packit d812c0
 * container functions
Packit d812c0
 */
Packit d812c0
/**
Packit d812c0
 * create swrun container
Packit d812c0
 */
Packit d812c0
netsnmp_container *
Packit d812c0
netsnmp_swrun_container(void)
Packit d812c0
{
Packit d812c0
    DEBUGMSGTL(("swrun:container", "init\n"));
Packit d812c0
Packit d812c0
    /*
Packit d812c0
     * create the container.
Packit d812c0
     */
Packit d812c0
  if (!swrun_container) {
Packit d812c0
    swrun_container = netsnmp_container_find("swrun:table_container");
Packit d812c0
    if (NULL == swrun_container)
Packit d812c0
        return NULL;
Packit d812c0
Packit d812c0
    swrun_container->container_name = strdup("swrun container");
Packit d812c0
  }
Packit d812c0
Packit d812c0
    return swrun_container;
Packit d812c0
}
Packit d812c0
Packit d812c0
/**
Packit d812c0
 * load swrun information in specified container
Packit d812c0
 *
Packit d812c0
 * @param container empty container to be filled.
Packit d812c0
 *                  pass NULL to have the function create one.
Packit d812c0
 * @param load_flags flags to modify behaviour. Examples:
Packit d812c0
 *                   NETSNMP_SWRUN_ALL_OR_NONE
Packit d812c0
 *
Packit d812c0
 * @retval NULL  error
Packit d812c0
 * @retval !NULL pointer to container
Packit d812c0
 */
Packit d812c0
netsnmp_container*
Packit d812c0
netsnmp_swrun_container_load(netsnmp_container* user_container, u_int load_flags)
Packit d812c0
{
Packit d812c0
    netsnmp_container* container = user_container;
Packit d812c0
    int rc;
Packit d812c0
Packit d812c0
    DEBUGMSGTL(("swrun:container:load", "load\n"));
Packit d812c0
    netsnmp_assert(1 == _swrun_init);
Packit d812c0
Packit d812c0
    if (NULL == container)
Packit d812c0
        container = netsnmp_swrun_container();
Packit d812c0
    if (NULL == container) {
Packit d812c0
        snmp_log(LOG_ERR, "no container specified/found for swrun\n");
Packit d812c0
        return NULL;
Packit d812c0
    }
Packit d812c0
Packit d812c0
    rc =  netsnmp_arch_swrun_container_load(container, load_flags);
Packit d812c0
    if (0 != rc) {
Packit d812c0
        if (NULL == user_container) {
Packit d812c0
            netsnmp_swrun_container_free(container, NETSNMP_SWRUN_NOFLAGS);
Packit d812c0
            container = NULL;
Packit d812c0
        }
Packit d812c0
        else if (load_flags & NETSNMP_SWRUN_ALL_OR_NONE) {
Packit d812c0
            DEBUGMSGTL(("swrun:container:load",
Packit d812c0
                        " discarding partial results\n"));
Packit d812c0
            netsnmp_swrun_container_free_items(container);
Packit d812c0
        }
Packit d812c0
    }
Packit d812c0
Packit d812c0
    return container;
Packit d812c0
}
Packit d812c0
Packit d812c0
void
Packit d812c0
netsnmp_swrun_container_free(netsnmp_container *container, u_int free_flags)
Packit d812c0
{
Packit d812c0
    DEBUGMSGTL(("swrun:container", "free\n"));
Packit d812c0
Packit d812c0
    if (NULL == container) {
Packit d812c0
        snmp_log(LOG_ERR, "invalid container for netsnmp_swrun_container_free\n");
Packit d812c0
        return;
Packit d812c0
    }
Packit d812c0
Packit d812c0
    if(! (free_flags & NETSNMP_SWRUN_DONT_FREE_ITEMS))
Packit d812c0
        netsnmp_swrun_container_free_items(container);
Packit d812c0
Packit d812c0
    CONTAINER_FREE(container);
Packit d812c0
}
Packit d812c0
Packit d812c0
void
Packit d812c0
netsnmp_swrun_container_free_items(netsnmp_container *container)
Packit d812c0
{
Packit d812c0
    DEBUGMSGTL(("swrun:container", "free_items\n"));
Packit d812c0
Packit d812c0
    if (NULL == container) {
Packit d812c0
        snmp_log(LOG_ERR, "invalid container for netsnmp_swrun_container_free_items\n");
Packit d812c0
        return;
Packit d812c0
    }
Packit d812c0
Packit d812c0
    /*
Packit d812c0
     * free all items.
Packit d812c0
     */
Packit d812c0
    CONTAINER_CLEAR(container,
Packit d812c0
                    (netsnmp_container_obj_func*)_swrun_entry_release,
Packit d812c0
                    NULL);
Packit d812c0
}
Packit d812c0
Packit d812c0
/**---------------------------------------------------------------------*/
Packit d812c0
/*
Packit d812c0
 * swrun_entry functions
Packit d812c0
 */
Packit d812c0
/**
Packit d812c0
 */
Packit d812c0
netsnmp_swrun_entry *
Packit d812c0
netsnmp_swrun_entry_get_by_index(netsnmp_container *container, oid index)
Packit d812c0
{
Packit d812c0
    netsnmp_index   tmp;
Packit d812c0
Packit d812c0
    DEBUGMSGTL(("swrun:entry", "by_index\n"));
Packit d812c0
    netsnmp_assert(1 == _swrun_init);
Packit d812c0
Packit d812c0
    if (NULL == container) {
Packit d812c0
        snmp_log(LOG_ERR,
Packit d812c0
                 "invalid container for netsnmp_swrun_entry_get_by_index\n");
Packit d812c0
        return NULL;
Packit d812c0
    }
Packit d812c0
Packit d812c0
    tmp.len = 1;
Packit d812c0
    tmp.oids = &index;
Packit d812c0
Packit d812c0
    return (netsnmp_swrun_entry *) CONTAINER_FIND(container, &tmp);
Packit d812c0
}
Packit d812c0
Packit d812c0
/**
Packit d812c0
 */
Packit d812c0
netsnmp_swrun_entry *
Packit d812c0
netsnmp_swrun_entry_create(int32_t index)
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_entry *entry =
Packit d812c0
        SNMP_MALLOC_TYPEDEF(netsnmp_swrun_entry);
Packit d812c0
Packit d812c0
    if(NULL == entry)
Packit d812c0
        return NULL;
Packit d812c0
Packit d812c0
    entry->hrSWRunIndex = index;
Packit d812c0
    entry->hrSWRunType = 1; /* unknown */
Packit d812c0
    entry->hrSWRunStatus = 2; /* runnable */
Packit d812c0
Packit d812c0
    entry->oid_index.len = 1;
Packit d812c0
    entry->oid_index.oids = (oid *) & entry->hrSWRunIndex;
Packit d812c0
Packit d812c0
    return entry;
Packit d812c0
}
Packit d812c0
Packit d812c0
/**
Packit d812c0
 */
Packit d812c0
NETSNMP_INLINE void
Packit d812c0
netsnmp_swrun_entry_free(netsnmp_swrun_entry * entry)
Packit d812c0
{
Packit d812c0
    if (NULL == entry)
Packit d812c0
        return;
Packit d812c0
Packit d812c0
    /*
Packit d812c0
     * SNMP_FREE not needed, for any of these, 
Packit d812c0
     * since the whole entry is about to be freed
Packit d812c0
     */
Packit d812c0
    free(entry);
Packit d812c0
}
Packit d812c0
Packit d812c0
/**---------------------------------------------------------------------*/
Packit d812c0
/*
Packit d812c0
 * Utility routines
Packit d812c0
 */
Packit d812c0
Packit d812c0
/**
Packit d812c0
 */
Packit d812c0
static void
Packit d812c0
_swrun_entry_release(netsnmp_swrun_entry * entry, void *context)
Packit d812c0
{
Packit d812c0
    netsnmp_swrun_entry_free(entry);
Packit d812c0
}
Packit d812c0
Packit d812c0
Packit d812c0
#ifdef TEST
Packit d812c0
int main(int argc, char *argv[])
Packit d812c0
{
Packit d812c0
    const char *tokens = getenv("SNMP_DEBUG");
Packit d812c0
Packit d812c0
    netsnmp_container_init_list();
Packit d812c0
Packit d812c0
    /** swrun,verbose:swrun,9:swrun,8:swrun,5:swrun */
Packit d812c0
    if (tokens)
Packit d812c0
        debug_register_tokens(tokens);
Packit d812c0
    else
Packit d812c0
        debug_register_tokens("swrun");
Packit d812c0
    snmp_set_do_debugging(1);
Packit d812c0
Packit d812c0
    init_swrun();
Packit d812c0
    netsnmp_swrun_container_load(NULL, 0);
Packit d812c0
    shutdown_swrun();
Packit d812c0
Packit d812c0
    return 0;
Packit d812c0
}
Packit d812c0
#endif