diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/agent/mibgroup/host/data_access/swinst.c APPLE/agent/mibgroup/host/data_access/swinst.c --- SVN/agent/mibgroup/host/data_access/swinst.c +++ APPLE/agent/mibgroup/host/data_access/swinst.c @@ -0,0 +1,211 @@ +/* + * swinst.c : hrSWInstalledTable data access + */ +#include +#include +#include +#include + +#include +#include + +/* --------------------------------------------------------------------- + */ + +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 %d\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 diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/agent/mibgroup/host/data_access/swinst.h APPLE/agent/mibgroup/host/data_access/swinst.h --- SVN/agent/mibgroup/host/data_access/swinst.h +++ APPLE/agent/mibgroup/host/data_access/swinst.h @@ -0,0 +1,46 @@ +/* + * swinst data access header + * + * $Id: swinst.patch,v 1.3 2007/08/16 22:09:13 randall Exp $ + */ +#ifndef NETSNMP_ACCESS_SWINST_CONFIG_H +#define NETSNMP_ACCESS_SWINST_CONFIG_H + +/* + * all platforms use this generic code + */ +config_require(host/data_access/swinst) + +/**---------------------------------------------------------------------*/ +/* + * configure required files + * + * Notes: + * + * 1) prefer functionality over platform, where possible. If a method + * is available for multiple platforms, test that first. That way + * when a new platform is ported, it won't need a new test here. + * + * 2) don't do detail requirements here. If, for example, + * HPUX11 had different reuirements than other HPUX, that should + * be handled in the *_hpux.h header file. + */ + +#ifdef NETSNMP_INCLUDE_HRSWINST_REWRITES + +config_exclude(host/hr_swinst) + +# if defined( darwin ) + + config_require(host/data_access/swinst_darwin) + +# else + + config_error(This platform does not yet support hrSWInstalledTable rewrites) + +# endif +#else +# define NETSNMP_ACCESS_SWINST_NOARCH 1 +#endif + +#endif /* NETSNMP_ACCESS_SWINST_CONFIG_H */ diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/agent/mibgroup/host/data_access/swinst_darwin.c APPLE/agent/mibgroup/host/data_access/swinst_darwin.c --- SVN/agent/mibgroup/host/data_access/swinst_darwin.c +++ APPLE/agent/mibgroup/host/data_access/swinst_darwin.c @@ -0,0 +1,385 @@ +/* + * swinst.c : hrSWInstalledTable data access + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define __APPLE_API_EVOLVING 1 +#include /* or else CoreFoundation.h barfs */ +#undef __APPLE_API_EVOLVING + +#include +#include + +/* --------------------------------------------------------------------- + */ +static int _add_applications_in_dir(netsnmp_container *, const char* path); +static int32_t _index; +static int _check_bundled_app(CFURLRef currentURL, CFStringRef *name, + CFStringRef *info, const char* path); +static int _check_classic_app(CFURLRef currentURL, CFStringRef *name, + CFStringRef *info, const char* path); +static netsnmp_container *dirs = NULL; + +/* --------------------------------------------------------------------- + */ +void +netsnmp_swinst_arch_init( void ) +{ + struct stat stat_buf; + const char *default_dirs[] = { + "/Applications", + "/Applications (Mac OS 9)", + "/System/Library/CoreServices", + "/System/Library/Extensions", + "/System/Library/Services" +#ifdef TEST + , "/Developer/Applications" + , "/Volumes/audX/Applications (Mac OS 9)" +#endif + }; + int i, count = sizeof(default_dirs)/sizeof(default_dirs[0]); + + /* + * create the container, if needed + */ + if (NULL == dirs) { + dirs = netsnmp_container_find("directory_container:cstring"); + if (NULL == dirs) { + snmp_log(LOG_ERR, "couldn't allocate container for dir list\n"); + return; + } + dirs->container_name = strdup("directory search list"); + netsnmp_binary_array_options_set(dirs, 1, CONTAINER_KEY_UNSORTED); + } + + /* + * add dirs + */ + for(i = 0; i < count; ++i) { + char * tmp; + /** xxx: get/save the last mod date? */ + if(-1 == stat(default_dirs[i], &stat_buf)) { + DEBUGMSGTL(("swinst:arch:darwin", "skipping dir %s\n", + default_dirs[i])); + continue; + } + DEBUGMSGTL(("swinst:arch:darwin", "adding dir %s\n", + default_dirs[i])); + tmp = strdup(default_dirs[i]); + if (NULL == tmp) { + snmp_log(LOG_ERR,"strdup failed\n"); + break; + } + CONTAINER_INSERT(dirs, tmp); + } +} + +void +netsnmp_swinst_arch_shutdown( void ) +{ + netsnmp_directory_container_free(dirs); +} + +/* --------------------------------------------------------------------- + */ + +int +netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags ) +{ + netsnmp_iterator *it; + const char *dir; + int rc; + + DEBUGMSGTL(("swinst:arch:darwin", "load\n")); + + if (NULL == dirs) { + DEBUGMSGTL(("swinst:arch:darwin", "no dirs to scan!\n")); + return -1; + } + + _index = 0; + + it = CONTAINER_ITERATOR(dirs); + for (dir = ITERATOR_FIRST(it); dir; dir = ITERATOR_NEXT(it)) { + rc = _add_applications_in_dir(container, dir); + } + ITERATOR_RELEASE(it); + DEBUGMSGTL(("swinst:arch:darwin", "loaded %d apps\n",_index)); + + return 0; +} + +void _dump_flags(u_long flags) +{ + static struct { + const char*name; + u_long bits; + } names[] = { + { "kLSItemInfoIsPlainFile", 0x00000001 }, + { "kLSItemInfoIsPackage", 0x00000002 }, + { "kLSItemInfoIsApplication", 0x00000004 }, + { "kLSItemInfoIsContainer", 0x00000008 }, + { "kLSItemInfoIsAliasFile", 0x00000010 }, + { "kLSItemInfoIsSymlink", 0x00000020 }, + { "kLSItemInfoIsInvisible", 0x00000040 }, + { "kLSItemInfoIsNativeApp", 0x00000080 }, + { "kLSItemInfoIsClassicApp", 0x00000100 }, + { "kLSItemInfoAppPrefersNative", 0x00000200 }, + { "kLSItemInfoAppPrefersClassic", 0x00000400 }, + { "kLSItemInfoAppIsScriptable", 0x00000800 }, + { "kLSItemInfoIsVolume", 0x00001000 }, + { "kLSItemInfoExtensionIsHidden", 0x00100000 } + }; + int i, count = sizeof(names)/sizeof(names[0]); + + for(i = 0; i < count; ++i) { + if (flags & names[i].bits) { + DEBUGMSGTL(("swinst:arch:darwin:flags", "\t%s\n", + names[i].name)); + } + } +} + +static int +_add_applications_in_dir(netsnmp_container *container, const char* path) +{ + netsnmp_container *files; + netsnmp_iterator *it; + const char *file; + netsnmp_swinst_entry *entry = NULL; + struct stat stat_buf; + size_t date_len; + u_char *date_buf; + int rc = 0; + + CFStringRef currentPath = NULL; + CFURLRef currentURL = NULL; + LSItemInfoRecord itemInfoRecord; + CFStringRef prodName = NULL; + CFStringRef version = NULL; + + DEBUGMSGTL(("swinst:arch:darwin", " adding files from %s\n", path)); + files = netsnmp_directory_container_read(NULL, path, 0); + if (NULL == files) { + snmp_log(LOG_ERR, "swinst: could not read directory %s\n", path); + return -1; + } + + it = CONTAINER_ITERATOR(files); + if (NULL == it) { + snmp_log(LOG_ERR, "could not get iterator\n"); + netsnmp_directory_container_free(files); + return -1; + } + for (file = ITERATOR_FIRST(it); + file; + file = ITERATOR_NEXT(it), + CFRelease(currentPath), + CFRelease(currentURL)) { + + int rc2 = 0; + + currentPath = + CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, file, + kCFStringEncodingUTF8, + kCFAllocatorNull); + currentURL = + CFURLCreateWithFileSystemPath(kCFAllocatorDefault, currentPath, + kCFURLPOSIXPathStyle, true); + LSCopyItemInfoForURL(currentURL, + kLSRequestBasicFlagsOnly|kLSRequestAppTypeFlags, + &itemInfoRecord); + if((0 == itemInfoRecord.flags) || + (kLSItemInfoIsPlainFile == itemInfoRecord.flags) || + (itemInfoRecord.flags & kLSItemInfoIsInvisible) || + (itemInfoRecord.flags & kLSItemInfoIsAliasFile)) { + continue; + } + /** recurse on non-application containers (i.e. directory) */ + if ((itemInfoRecord.flags & kLSItemInfoIsContainer) && + (!(itemInfoRecord.flags & kLSItemInfoIsApplication))) { + netsnmp_directory_container_read(files, file, 0); + continue; + } + + /** skip any other non-application files */ + if (!(itemInfoRecord.flags & kLSItemInfoIsApplication)) { + continue; + } + + if ((itemInfoRecord.flags & kLSItemInfoIsPackage) || + (itemInfoRecord.flags & kLSItemInfoIsContainer)) { + rc2 = _check_bundled_app(currentURL, &prodName, &version, file); + } + else if ((itemInfoRecord.flags & kLSItemInfoIsClassicApp) || + (itemInfoRecord.flags & kLSItemInfoIsPlainFile)) { + rc2 = _check_classic_app(currentURL, &prodName, &version, file); + } else { + snmp_log(LOG_ERR,"swinst shouldn't get here: %s\n", file); + _dump_flags(itemInfoRecord.flags); + continue; + } + if (rc2) { /* not an app. if directory, recurse; else continue */ + _dump_flags(itemInfoRecord.flags); + if (1 == rc2) + netsnmp_directory_container_read(files, file, 0); + continue; + } + + /* + * allocate entry + */ + entry = netsnmp_swinst_entry_create(++_index); + if (NULL == entry) { + snmp_log(LOG_ERR, "error creating swinst entry\n"); + rc = -1; + SNMP_CFRelease(prodName); + SNMP_CFRelease(version); + break; + } + + entry->swName_len = + snprintf(entry->swName, sizeof(entry->swName), + "%s %s", CFStringGetCStringPtr(prodName,0), + CFStringGetCStringPtr(version,0)); + + DEBUGMSGTL(("swinst:arch:darwin", "\t%s %s\n", file, entry->swName)); + + /** get the last mod date */ + if(stat(file, &stat_buf) != -1) { + date_buf = date_n_time(&stat_buf.st_mtime, &date_len); + entry->swDate_len = date_len; + memcpy(entry->swDate, date_buf, entry->swDate_len); + } + + CONTAINER_INSERT(container, entry); + entry = NULL; + SNMP_CFRelease(prodName); + SNMP_CFRelease(version); + } + ITERATOR_RELEASE(it); + netsnmp_directory_container_free(files); + + return rc; +} + +int +_check_bundled_app(CFURLRef currentURL, CFStringRef *prodName, + CFStringRef *version, const char* file) +{ + CFBundleRef theBundle = NULL; + CFDictionaryRef infoDict = NULL; + + if ((NULL == prodName) || (NULL == version)) + return -1; + + theBundle = CFBundleCreate (kCFAllocatorDefault, currentURL); + if(theBundle == NULL) + return -1; /* not a bundle */ + + infoDict = CFBundleGetInfoDictionary(theBundle); + if(0 == CFDictionaryGetCount(infoDict)) { + SNMP_CFRelease(theBundle); + return 1; /* directory */ + } + + *prodName = (CFStringRef) + CFDictionaryGetValue (infoDict, CFSTR("CFBundleName")); + if (NULL == *prodName) { + *prodName = (CFStringRef) + CFDictionaryGetValue (infoDict, CFSTR("CFBundleDisplayName")); + if (NULL == *prodName) { + *prodName = (CFStringRef) CFDictionaryGetValue (infoDict, + CFSTR("CFBundleExecutable")); + } + } + if(NULL == *prodName) { + DEBUGMSGTL(("swinst:arch:darwin", "\tmissing name: %s\n",file)); + /*CFShow(infoDict);*/ + SNMP_CFRelease(theBundle); + return -1; + } + + *version = (CFStringRef) + CFDictionaryGetValue (infoDict, CFSTR("CFBundleShortVersionString")); + if(NULL == *version) { + *version = (CFStringRef) + CFDictionaryGetValue (infoDict, CFSTR("CFBundleVersion")); + if (*version == NULL) + *version = (CFStringRef) CFDictionaryGetValue (infoDict, + CFSTR("CFBundleGetInfoString")); + } + if(NULL == *version) { + DEBUGMSGTL(("swinst:arch:darwin", "\tmissing version: %s\n",file)); + /*CFShow(infoDict);*/ + SNMP_CFRelease(theBundle); + return -1; + } + + if(theBundle != NULL) { + CFRetain(*prodName); + CFRetain(*version); + SNMP_CFRelease(theBundle); + } + return 0; +} + +static int +_check_classic_app(CFURLRef currentURL, CFStringRef *prodName, + CFStringRef *version, const char* file) +{ + /* + * get info for classic or single-file apps + */ + FSRef theFSRef; + int theResFile; + + if ((NULL == prodName) || (NULL == version)) + return -1; + + *prodName = CFURLCopyLastPathComponent(currentURL); + if (! CFURLGetFSRef(currentURL, &theFSRef)) { + DEBUGMSGTL(("swinst:arch:darwin", "GetFSRef failed: %s\n", file)); + SNMP_CFRelease(*prodName); + return -1; + } + theResFile = FSOpenResFile(&theFSRef, fsRdPerm); + if (ResError() != noErr) { + DEBUGMSGTL(("swinst:arch:darwin", "FSOpenResFile failed: %s\n", file)); + SNMP_CFRelease(*prodName); + return -1; + } + VersRecHndl versHandle = (VersRecHndl)Get1IndResource('vers', 1); + if (versHandle != NULL) { + *version = CFStringCreateWithPascalString(kCFAllocatorDefault, + (**versHandle).shortVersion, kCFStringEncodingMacRoman); + if (*version == NULL) { + StringPtr longVersionPtr = (**versHandle).shortVersion; + longVersionPtr = (StringPtr)(((Ptr) longVersionPtr) + + 1 + ((unsigned char) *longVersionPtr)); + *version = CFStringCreateWithPascalString(kCFAllocatorDefault, + longVersionPtr, kCFStringEncodingMacRoman); + } + ReleaseResource((Handle)versHandle); + } + CloseResFile(theResFile); + if(*version == NULL) { + DEBUGMSGTL(("swinst:arch:darwin", + "\tmissing classic/file version: %s\n", file)); + SNMP_CFRelease(*prodName); + return -1; + } + + return 0; +} diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/agent/mibgroup/host/hrSWInstalledTable.c APPLE/agent/mibgroup/host/hrSWInstalledTable.c --- SVN/agent/mibgroup/host/hrSWInstalledTable.c +++ APPLE/agent/mibgroup/host/hrSWInstalledTable.c @@ -0,0 +1,261 @@ +/* + * Note: this file originally auto-generated by mib2c using + * : mib2c.container.conf,v 1.8 2006/07/26 15:58:26 dts12 Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include "hrSWInstalledTable.h" + +#define MYTABLE "hrSWInstalledTable" + +static void _cache_free(netsnmp_cache * cache, void *magic); +static int _cache_load(netsnmp_cache * cache, void *magic); + +/** Initializes the hrSWInstalledTable module */ +void +init_hrSWInstalledTable(void) +{ + /* + * here we initialize all the tables we're planning on supporting + */ + initialize_table_hrSWInstalledTable(); +} + +/** Initialize the hrSWInstalledTable table by defining its contents and how it's structured */ +void +initialize_table_hrSWInstalledTable(void) +{ + static oid hrSWInstalledTable_oid[] = + { 1, 3, 6, 1, 2, 1, 25, 6, 3 }; + size_t hrSWInstalledTable_oid_len = + OID_LENGTH(hrSWInstalledTable_oid); + netsnmp_handler_registration *reg; + netsnmp_mib_handler *handler; + netsnmp_container *container; + netsnmp_cache *cache; + netsnmp_table_registration_info *table_info; + + DEBUGMSGTL(("hrSWInstalled", "initialize\n")); + + reg = + netsnmp_create_handler_registration("hrSWInstalledTable", + hrSWInstalledTable_handler, + hrSWInstalledTable_oid, + hrSWInstalledTable_oid_len, + HANDLER_CAN_RONLY); + if (NULL == reg) { + snmp_log(LOG_ERR,"error creating handler registration for " + MYTABLE "\n"); + goto bail; + } + + container = netsnmp_container_find("hrSWInstalledTable:table_container"); + if (NULL == container) { + snmp_log(LOG_ERR,"error creating container for " + MYTABLE "\n"); + goto bail; + } + + table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); + if (NULL == table_info) { + snmp_log(LOG_ERR,"error allocating table registration for " + MYTABLE "\n"); + goto bail; + } + + netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: hrSWInstalledIndex */ + 0); + table_info->min_column = COLUMN_HRSWINSTALLEDINDEX; + table_info->max_column = COLUMN_HRSWINSTALLEDDATE; + + /************************************************* + * + * inject container_table helper + */ + handler = netsnmp_container_table_handler_get(table_info, container, + TABLE_CONTAINER_KEY_NETSNMP_INDEX); + if (NULL == handler) { + snmp_log(LOG_ERR,"error allocating table registration for " + MYTABLE "\n"); + goto bail; + } + if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { + snmp_log(LOG_ERR,"error injecting container_table handler for " + MYTABLE "\n"); + goto bail; + } + handler = NULL; /* reg has it, will reuse below */ + + /************************************************* + * + * inject cache helper + */ + cache = netsnmp_cache_create(30, /* timeout in seconds */ + _cache_load, _cache_free, + hrSWInstalledTable_oid, + hrSWInstalledTable_oid_len); + + if (NULL == cache) { + snmp_log(LOG_ERR, "error creating cache for " + MYTABLE "\n"); + goto bail; + } + cache->magic = container; + + handler = netsnmp_cache_handler_get(cache); + if (NULL == handler) { + snmp_log(LOG_ERR, "error creating cache handler for " + MYTABLE "\n"); + goto bail; + } + if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { + snmp_log(LOG_ERR,"error injecting cache handler for " + MYTABLE "\n"); + goto bail; + } + handler = NULL; /* reg has it*/ + + if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { + snmp_log(LOG_ERR,"error registering table handler for " + MYTABLE "\n"); + goto bail; + } + + return; /* ok */ + + + bail: /* not ok */ + + if (handler) + netsnmp_handler_free(handler); + + if (cache) + netsnmp_cache_free(cache); + + if (table_info) + netsnmp_table_registration_info_free(table_info); + + if (container) + CONTAINER_FREE(container); + + if (reg) + netsnmp_handler_registration_free(reg); + +} + +/** handles requests for the hrSWInstalledTable table */ +int +hrSWInstalledTable_handler(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + + netsnmp_request_info *request; + netsnmp_table_request_info *table_info; + netsnmp_swinst_entry *table_entry; + + switch (reqinfo->mode) { + /* + * Read-support (also covers GetNext requests) + */ + case MODE_GET: + for (request = requests; request; request = request->next) { + if (request->processed) + continue; + table_entry = (netsnmp_swinst_entry *) + netsnmp_container_table_extract_context(request); + table_info = netsnmp_extract_table_info(request); + if ((NULL == table_entry) || (NULL == table_info)) { + snmp_log(LOG_ERR, "could not extract table entry or info for " + MYTABLE "\n"); + snmp_set_var_typed_value(request->requestvb, + SNMP_ERR_GENERR, NULL, 0); + continue; + } + + switch (table_info->colnum) { + case COLUMN_HRSWINSTALLEDINDEX: + snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, + table_entry->swIndex); + break; + case COLUMN_HRSWINSTALLEDNAME: { + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, + (u_char *) table_entry->swName, + table_entry->swName_len); + } break; + case COLUMN_HRSWINSTALLEDID: + snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, + (u_char *) &nullOid, nullOidLen); + break; + case COLUMN_HRSWINSTALLEDTYPE: + snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, + table_entry->swType); + break; + case COLUMN_HRSWINSTALLEDDATE: + snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, + (u_char *) table_entry->swDate, + table_entry->swDate_len); + break; + default: + /* + * An unsupported/unreadable column (if applicable) + */ + snmp_set_var_typed_value(request->requestvb, + SNMP_NOSUCHOBJECT, NULL, 0); + } + } + break; + + } + return SNMP_ERR_NOERROR; +} + +/*********************************************************************** + * + * DATA ACCESS + * + * The data access mechanism here is rather simple: let newsnmp_swinst_* + * take care of it. + ***********************************************************************/ +/** + * @internal + */ +static int +_cache_load(netsnmp_cache * cache, void *vmagic) +{ + DEBUGMSGTL(("hrSWInstalledTable:cache", "load\n")); + + if ((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache for hrSWInstalledTable_cache_load\n"); + return -1; + } + + /** should only be called for an invalid or expired cache */ + netsnmp_assert((0 == cache->valid) || (1 == cache->expired)); + + cache->magic = + netsnmp_swinst_container_load((netsnmp_container *) cache->magic, 0); + + return 0; +} /* _cache_load */ + +/** + * @internal + */ +static void +_cache_free(netsnmp_cache * cache, void *magic) +{ + if ((NULL == cache) || (NULL == cache->magic)) { + snmp_log(LOG_ERR, "invalid cache in hrSWInstalledTable_cache_free\n"); + return; + } + DEBUGMSGTL(("hrSWInstalledTable:cache", "free\n")); + + netsnmp_swinst_container_free_items((netsnmp_container *) cache->magic); +} /* _cache_free */ diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/agent/mibgroup/host/hrSWInstalledTable.h APPLE/agent/mibgroup/host/hrSWInstalledTable.h --- SVN/agent/mibgroup/host/hrSWInstalledTable.h +++ APPLE/agent/mibgroup/host/hrSWInstalledTable.h @@ -0,0 +1,25 @@ +/* + * Note: this file originally auto-generated by mib2c using + * : mib2c.container.conf,v 1.8 2006/07/26 15:58:26 dts12 Exp $ + */ +#ifndef HRSWINSTALLEDTABLE_H +#define HRSWINSTALLEDTABLE_H + +config_require(host/data_access/swinst) + +/* + * function declarations + */ +void init_hrSWInstalledTable(void); +void initialize_table_hrSWInstalledTable(void); +Netsnmp_Node_Handler hrSWInstalledTable_handler; + +/* + * column number definitions for table hrSWInstalledTable + */ +#define COLUMN_HRSWINSTALLEDINDEX 1 +#define COLUMN_HRSWINSTALLEDNAME 2 +#define COLUMN_HRSWINSTALLEDID 3 +#define COLUMN_HRSWINSTALLEDTYPE 4 +#define COLUMN_HRSWINSTALLEDDATE 5 +#endif /* HRSWINSTALLEDTABLE_H */ diff -I '\$Id: ' -u -r -b -w -p -d --new-file --exclude-from=/Users/rstory/.rcfiles/diff-ignore SVN/include/net-snmp/data_access/swinst.h APPLE/include/net-snmp/data_access/swinst.h --- SVN/include/net-snmp/data_access/swinst.h +++ APPLE/include/net-snmp/data_access/swinst.h @@ -0,0 +1,67 @@ +#ifndef NETSNMP_SWINST_H +#define NETSNMP_SWINST_H + +#ifdef __cplusplus +extern "C" { +#endif + + /* + * Data structure for a swinst entry + */ + typedef struct hrSWInstalledTable_entry { + netsnmp_index oid_index; + + /* + * Index values; MIB type is int32, but we use oid so this + * structure can be used directly with a table_container. + */ + oid swIndex; + + /* + * Column values + */ + char swName[64]; + char swDate[11]; +#ifdef NETSNMP_HAVE_SWID + oid *swID; + u_char swID_len; +#endif + u_char swType; + u_char swName_len; + u_char swDate_len; + } netsnmp_swinst_entry; + +#define HRSWINSTALLEDTYPE_UNKNOWN 1 +#define HRSWINSTALLEDTYPE_OPERATINGSYSTEM 2 +#define HRSWINSTALLEDTYPE_DEVICEDRIVER 3 +#define HRSWINSTALLEDTYPE_APPLICATION 4 + + +#define NETSNMP_SWINST_NOFLAGS 0x00000000 + +#define NETSNMP_SWINST_ALL_OR_NONE 0x00000001 +#define NETSNMP_SWINST_DONT_FREE_ITEMS 0x00000002 + + netsnmp_container * + netsnmp_swinst_container_load(netsnmp_container *container, int flags ); + + void netsnmp_swinst_container_free(netsnmp_container *container, + u_int flags); + void netsnmp_swinst_container_free_items(netsnmp_container *container); + + void netsnmp_swinst_entry_remove(netsnmp_container * container, + netsnmp_swinst_entry *entry); + + netsnmp_swinst_entry * netsnmp_swinst_entry_create(int32_t index); + void netsnmp_swinst_entry_free(netsnmp_swinst_entry *entry); + + int32_t netsnmp_swinst_add_name(const char *name); + int32_t netsnmp_swinst_get_id(const char *name); + const char * netsnmp_swinst_get_name(int32_t id); + +#ifdef __cplusplus +} +#endif + + +#endif /* NETSNMP_SWINST_H */