Blame agent/mibgroup/host/data_access/swrun.c

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