| /* |
| * swinst.c : hrSWInstalledTable data access |
| */ |
| /* |
| * Copyright (C) 2007 Apple, Inc. All rights reserved. |
| * Use is subject to license terms specified in the COPYING file |
| * distributed with the Net-SNMP package. |
| */ |
| #include <net-snmp/net-snmp-config.h> |
| #include <net-snmp/net-snmp-includes.h> |
| #include <net-snmp/agent/net-snmp-agent-includes.h> |
| #include <net-snmp/data_access/swinst.h> |
| |
| #include <stdlib.h> |
| #include <unistd.h> |
| |
| /* --------------------------------------------------------------------- |
| */ |
| |
| static void netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *, void *); |
| |
| extern void netsnmp_swinst_arch_init(void); |
| extern void netsnmp_swinst_arch_shutdown(void); |
| extern int netsnmp_swinst_arch_load(netsnmp_container *, u_int); |
| |
| void init_swinst( void ) |
| { |
| static int initialized = 0; |
| |
| DEBUGMSGTL(("swinst", "init called\n")); |
| |
| if (initialized) |
| return; /* already initialized */ |
| |
| |
| /* |
| * call arch init code |
| */ |
| netsnmp_swinst_arch_init(); |
| } |
| |
| void shutdown_swinst( void ) |
| { |
| DEBUGMSGTL(("swinst", "shutdown called\n")); |
| |
| netsnmp_swinst_arch_shutdown(); |
| } |
| |
| /* --------------------------------------------------------------------- |
| */ |
| |
| /* |
| * load a container with installed software. If user_container is NULL, |
| * a new container will be allocated and returned, and the caller |
| * is responsible for releasing the allocated memory when done. |
| * |
| * if flags contains NETSNMP_SWINST_ALL_OR_NONE and any error occurs, |
| * the container will be completely cleared. |
| */ |
| netsnmp_container * |
| netsnmp_swinst_container_load( netsnmp_container *user_container, int flags ) |
| { |
| netsnmp_container *container = user_container; |
| int arch_rc; |
| |
| DEBUGMSGTL(("swinst:container", "load\n")); |
| |
| /* |
| * create the container, if needed |
| */ |
| if (NULL == container) { |
| container = netsnmp_container_find("swinst:table_container"); |
| if (NULL == container) |
| return NULL; |
| } |
| if (NULL == container->container_name) |
| container->container_name = strdup("swinst container"); |
| |
| /* |
| * call the arch specific code to load the container |
| */ |
| arch_rc = netsnmp_swinst_arch_load( container, flags ); |
| if (arch_rc && (flags & NETSNMP_SWINST_ALL_OR_NONE)) { |
| /* |
| * caller does not want a partial load, so empty the container. |
| * if we created the container, destroy it. |
| */ |
| netsnmp_swinst_container_free_items(container); |
| if (container != user_container) { |
| netsnmp_swinst_container_free(container, flags); |
| } |
| } |
| |
| return container; |
| } |
| |
| void |
| netsnmp_swinst_container_free(netsnmp_container *container, u_int free_flags) |
| { |
| DEBUGMSGTL(("swinst:container", "free\n")); |
| |
| if (NULL == container) { |
| snmp_log(LOG_ERR, |
| "invalid container for netsnmp_swinst_container_free\n"); |
| return; |
| } |
| |
| if(! (free_flags & NETSNMP_SWINST_DONT_FREE_ITEMS)) |
| netsnmp_swinst_container_free_items(container); |
| |
| CONTAINER_FREE(container); |
| } |
| |
| /* |
| * free a swinst container |
| */ |
| void netsnmp_swinst_container_free_items(netsnmp_container *container) |
| { |
| DEBUGMSGTL(("swinst:container", "free_items\n")); |
| |
| if (NULL == container) { |
| snmp_log(LOG_ERR, |
| "invalid container for netsnmp_swinst_container_free_items\n"); |
| return; |
| } |
| |
| /* |
| * free all items. |
| */ |
| CONTAINER_CLEAR(container, |
| (netsnmp_container_obj_func*)netsnmp_swinst_entry_free_cb, |
| NULL); |
| } |
| |
| |
| /* --------------------------------------------------------------------- |
| */ |
| |
| /* |
| * create a new row in the table |
| */ |
| netsnmp_swinst_entry * |
| netsnmp_swinst_entry_create(int32_t swIndex) |
| { |
| netsnmp_swinst_entry *entry; |
| |
| entry = SNMP_MALLOC_TYPEDEF(netsnmp_swinst_entry); |
| if (!entry) |
| return NULL; |
| |
| entry->swIndex = swIndex; |
| entry->oid_index.len = 1; |
| entry->oid_index.oids = &entry->swIndex; |
| |
| entry->swType = HRSWINSTALLEDTYPE_APPLICATION; |
| |
| return entry; |
| } |
| |
| /* |
| * free a row |
| */ |
| void |
| netsnmp_swinst_entry_free(netsnmp_swinst_entry *entry) |
| { |
| DEBUGMSGTL(("swinst:entry:free", "index %" NETSNMP_PRIo "u\n", |
| entry->swIndex)); |
| |
| free(entry); |
| } |
| |
| /* |
| * free a row |
| */ |
| static void |
| netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *entry, void *context) |
| { |
| free(entry); |
| } |
| |
| /* |
| * remove a row from the table |
| */ |
| void |
| netsnmp_swinst_entry_remove(netsnmp_container * container, |
| netsnmp_swinst_entry *entry) |
| { |
| DEBUGMSGTL(("swinst:container", "remove\n")); |
| if (!entry) |
| return; /* Nothing to remove */ |
| CONTAINER_REMOVE(container, entry); |
| } |
| |
| /* --------------------------------------------------------------------- |
| */ |
| |
| #ifdef TEST |
| int main(int argc, char *argv[]) |
| { |
| const char *tokens = getenv("SNMP_DEBUG"); |
| |
| netsnmp_container_init_list(); |
| |
| /** swinst,verbose:swinst */ |
| if (tokens) |
| debug_register_tokens(tokens); |
| else |
| debug_register_tokens("swinst"); |
| snmp_set_do_debugging(1); |
| |
| init_swinst(); |
| netsnmp_swinst_container_load(NULL, 0); |
| shutdown_swinst(); |
| |
| return 0; |
| } |
| #endif |