1diff -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 2--- SVN/agent/mibgroup/host/data_access/swinst.c 3+++ APPLE/agent/mibgroup/host/data_access/swinst.c 4@@ -0,0 +1,211 @@ 5+/* 6+ * swinst.c : hrSWInstalledTable data access 7+ */ 8+#include <net-snmp/net-snmp-config.h> 9+#include <net-snmp/net-snmp-includes.h> 10+#include <net-snmp/agent/net-snmp-agent-includes.h> 11+#include <net-snmp/data_access/swinst.h> 12+ 13+#include <stdlib.h> 14+#include <unistd.h> 15+ 16+/* --------------------------------------------------------------------- 17+ */ 18+ 19+static void netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *, void *); 20+ 21+extern void netsnmp_swinst_arch_init(void); 22+extern void netsnmp_swinst_arch_shutdown(void); 23+extern int netsnmp_swinst_arch_load(netsnmp_container *, u_int); 24+ 25+void init_swinst( void ) 26+{ 27+ static int initialized = 0; 28+ 29+ DEBUGMSGTL(("swinst", "init called\n")); 30+ 31+ if (initialized) 32+ return; /* already initialized */ 33+ 34+ 35+ /* 36+ * call arch init code 37+ */ 38+ netsnmp_swinst_arch_init(); 39+} 40+ 41+void shutdown_swinst( void ) 42+{ 43+ DEBUGMSGTL(("swinst", "shutdown called\n")); 44+ 45+ netsnmp_swinst_arch_shutdown(); 46+} 47+ 48+/* --------------------------------------------------------------------- 49+ */ 50+ 51+/* 52+ * load a container with installed software. If user_container is NULL, 53+ * a new container will be allocated and returned, and the caller 54+ * is responsible for releasing the allocated memory when done. 55+ * 56+ * if flags contains NETSNMP_SWINST_ALL_OR_NONE and any error occurs, 57+ * the container will be completely cleared. 58+ */ 59+netsnmp_container * 60+netsnmp_swinst_container_load( netsnmp_container *user_container, int flags ) 61+{ 62+ netsnmp_container *container = user_container; 63+ int arch_rc; 64+ 65+ DEBUGMSGTL(("swinst:container", "load\n")); 66+ 67+ /* 68+ * create the container, if needed 69+ */ 70+ if (NULL == container) { 71+ container = netsnmp_container_find("swinst:table_container"); 72+ if (NULL == container) 73+ return NULL; 74+ } 75+ if (NULL == container->container_name) 76+ container->container_name = strdup("swinst container"); 77+ 78+ /* 79+ * call the arch specific code to load the container 80+ */ 81+ arch_rc = netsnmp_swinst_arch_load( container, flags ); 82+ if (arch_rc && (flags & NETSNMP_SWINST_ALL_OR_NONE)) { 83+ /* 84+ * caller does not want a partial load, so empty the container. 85+ * if we created the container, destroy it. 86+ */ 87+ netsnmp_swinst_container_free_items(container); 88+ if (container != user_container) { 89+ netsnmp_swinst_container_free(container, flags); 90+ } 91+ } 92+ 93+ return container; 94+} 95+ 96+void 97+netsnmp_swinst_container_free(netsnmp_container *container, u_int free_flags) 98+{ 99+ DEBUGMSGTL(("swinst:container", "free\n")); 100+ 101+ if (NULL == container) { 102+ snmp_log(LOG_ERR, 103+ "invalid container for netsnmp_swinst_container_free\n"); 104+ return; 105+ } 106+ 107+ if(! (free_flags & NETSNMP_SWINST_DONT_FREE_ITEMS)) 108+ netsnmp_swinst_container_free_items(container); 109+ 110+ CONTAINER_FREE(container); 111+} 112+ 113+/* 114+ * free a swinst container 115+ */ 116+void netsnmp_swinst_container_free_items(netsnmp_container *container) 117+{ 118+ DEBUGMSGTL(("swinst:container", "free_items\n")); 119+ 120+ if (NULL == container) { 121+ snmp_log(LOG_ERR, 122+ "invalid container for netsnmp_swinst_container_free_items\n"); 123+ return; 124+ } 125+ 126+ /* 127+ * free all items. 128+ */ 129+ CONTAINER_CLEAR(container, 130+ (netsnmp_container_obj_func*)netsnmp_swinst_entry_free_cb, 131+ NULL); 132+} 133+ 134+ 135+/* --------------------------------------------------------------------- 136+ */ 137+ 138+/* 139+ * create a new row in the table 140+ */ 141+netsnmp_swinst_entry * 142+netsnmp_swinst_entry_create(int32_t swIndex) 143+{ 144+ netsnmp_swinst_entry *entry; 145+ 146+ entry = SNMP_MALLOC_TYPEDEF(netsnmp_swinst_entry); 147+ if (!entry) 148+ return NULL; 149+ 150+ entry->swIndex = swIndex; 151+ entry->oid_index.len = 1; 152+ entry->oid_index.oids = &entry->swIndex; 153+ 154+ entry->swType = HRSWINSTALLEDTYPE_APPLICATION; 155+ 156+ return entry; 157+} 158+ 159+/* 160+ * free a row 161+ */ 162+void 163+netsnmp_swinst_entry_free(netsnmp_swinst_entry *entry) 164+{ 165+ DEBUGMSGTL(("swinst:entry:free", "index %d\n",entry->swIndex)); 166+ 167+ free(entry); 168+} 169+ 170+/* 171+ * free a row 172+ */ 173+static void 174+netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *entry, void *context) 175+{ 176+ free(entry); 177+} 178+ 179+/* 180+ * remove a row from the table 181+ */ 182+void 183+netsnmp_swinst_entry_remove(netsnmp_container * container, 184+ netsnmp_swinst_entry *entry) 185+{ 186+ DEBUGMSGTL(("swinst:container", "remove\n")); 187+ if (!entry) 188+ return; /* Nothing to remove */ 189+ CONTAINER_REMOVE(container, entry); 190+} 191+ 192+/* --------------------------------------------------------------------- 193+ */ 194+ 195+#ifdef TEST 196+int main(int argc, char *argv[]) 197+{ 198+ const char *tokens = getenv("SNMP_DEBUG"); 199+ 200+ netsnmp_container_init_list(); 201+ 202+ /** swinst,verbose:swinst */ 203+ if (tokens) 204+ debug_register_tokens(tokens); 205+ else 206+ debug_register_tokens("swinst"); 207+ snmp_set_do_debugging(1); 208+ 209+ init_swinst(); 210+ netsnmp_swinst_container_load(NULL, 0); 211+ shutdown_swinst(); 212+ 213+ return 0; 214+} 215+#endif 216diff -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 217--- SVN/agent/mibgroup/host/data_access/swinst.h 218+++ APPLE/agent/mibgroup/host/data_access/swinst.h 219@@ -0,0 +1,46 @@ 220+/* 221+ * swinst data access header 222+ * 223+ * $Id: swinst.patch,v 1.3 2007/08/16 22:09:13 randall Exp $ 224+ */ 225+#ifndef NETSNMP_ACCESS_SWINST_CONFIG_H 226+#define NETSNMP_ACCESS_SWINST_CONFIG_H 227+ 228+/* 229+ * all platforms use this generic code 230+ */ 231+config_require(host/data_access/swinst) 232+ 233+/**---------------------------------------------------------------------*/ 234+/* 235+ * configure required files 236+ * 237+ * Notes: 238+ * 239+ * 1) prefer functionality over platform, where possible. If a method 240+ * is available for multiple platforms, test that first. That way 241+ * when a new platform is ported, it won't need a new test here. 242+ * 243+ * 2) don't do detail requirements here. If, for example, 244+ * HPUX11 had different reuirements than other HPUX, that should 245+ * be handled in the *_hpux.h header file. 246+ */ 247+ 248+#ifdef NETSNMP_INCLUDE_HRSWINST_REWRITES 249+ 250+config_exclude(host/hr_swinst) 251+ 252+# if defined( darwin ) 253+ 254+ config_require(host/data_access/swinst_darwin) 255+ 256+# else 257+ 258+ config_error(This platform does not yet support hrSWInstalledTable rewrites) 259+ 260+# endif 261+#else 262+# define NETSNMP_ACCESS_SWINST_NOARCH 1 263+#endif 264+ 265+#endif /* NETSNMP_ACCESS_SWINST_CONFIG_H */ 266diff -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 267--- SVN/agent/mibgroup/host/data_access/swinst_darwin.c 268+++ APPLE/agent/mibgroup/host/data_access/swinst_darwin.c 269@@ -0,0 +1,385 @@ 270+/* 271+ * swinst.c : hrSWInstalledTable data access 272+ */ 273+#include <net-snmp/net-snmp-config.h> 274+#include <net-snmp/net-snmp-includes.h> 275+#include <net-snmp/agent/net-snmp-agent-includes.h> 276+#include <net-snmp/library/container.h> 277+#include <net-snmp/library/dir_utils.h> 278+#include <net-snmp/library/snmp_debug.h> 279+#include <net-snmp/data_access/swinst.h> 280+ 281+#include <stdlib.h> 282+#include <unistd.h> 283+#include <dirent.h> 284+#include <sys/stat.h> 285+ 286+#define __APPLE_API_EVOLVING 1 287+#include <sys/acl.h> /* or else CoreFoundation.h barfs */ 288+#undef __APPLE_API_EVOLVING 289+ 290+#include <CoreFoundation/CoreFoundation.h> 291+#include <ApplicationServices/ApplicationServices.h> 292+ 293+/* --------------------------------------------------------------------- 294+ */ 295+static int _add_applications_in_dir(netsnmp_container *, const char* path); 296+static int32_t _index; 297+static int _check_bundled_app(CFURLRef currentURL, CFStringRef *name, 298+ CFStringRef *info, const char* path); 299+static int _check_classic_app(CFURLRef currentURL, CFStringRef *name, 300+ CFStringRef *info, const char* path); 301+static netsnmp_container *dirs = NULL; 302+ 303+/* --------------------------------------------------------------------- 304+ */ 305+void 306+netsnmp_swinst_arch_init( void ) 307+{ 308+ struct stat stat_buf; 309+ const char *default_dirs[] = { 310+ "/Applications", 311+ "/Applications (Mac OS 9)", 312+ "/System/Library/CoreServices", 313+ "/System/Library/Extensions", 314+ "/System/Library/Services" 315+#ifdef TEST 316+ , "/Developer/Applications" 317+ , "/Volumes/audX/Applications (Mac OS 9)" 318+#endif 319+ }; 320+ int i, count = sizeof(default_dirs)/sizeof(default_dirs[0]); 321+ 322+ /* 323+ * create the container, if needed 324+ */ 325+ if (NULL == dirs) { 326+ dirs = netsnmp_container_find("directory_container:cstring"); 327+ if (NULL == dirs) { 328+ snmp_log(LOG_ERR, "couldn't allocate container for dir list\n"); 329+ return; 330+ } 331+ dirs->container_name = strdup("directory search list"); 332+ netsnmp_binary_array_options_set(dirs, 1, CONTAINER_KEY_UNSORTED); 333+ } 334+ 335+ /* 336+ * add dirs 337+ */ 338+ for(i = 0; i < count; ++i) { 339+ char * tmp; 340+ /** xxx: get/save the last mod date? */ 341+ if(-1 == stat(default_dirs[i], &stat_buf)) { 342+ DEBUGMSGTL(("swinst:arch:darwin", "skipping dir %s\n", 343+ default_dirs[i])); 344+ continue; 345+ } 346+ DEBUGMSGTL(("swinst:arch:darwin", "adding dir %s\n", 347+ default_dirs[i])); 348+ tmp = strdup(default_dirs[i]); 349+ if (NULL == tmp) { 350+ snmp_log(LOG_ERR,"strdup failed\n"); 351+ break; 352+ } 353+ CONTAINER_INSERT(dirs, tmp); 354+ } 355+} 356+ 357+void 358+netsnmp_swinst_arch_shutdown( void ) 359+{ 360+ netsnmp_directory_container_free(dirs); 361+} 362+ 363+/* --------------------------------------------------------------------- 364+ */ 365+ 366+int 367+netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags ) 368+{ 369+ netsnmp_iterator *it; 370+ const char *dir; 371+ int rc; 372+ 373+ DEBUGMSGTL(("swinst:arch:darwin", "load\n")); 374+ 375+ if (NULL == dirs) { 376+ DEBUGMSGTL(("swinst:arch:darwin", "no dirs to scan!\n")); 377+ return -1; 378+ } 379+ 380+ _index = 0; 381+ 382+ it = CONTAINER_ITERATOR(dirs); 383+ for (dir = ITERATOR_FIRST(it); dir; dir = ITERATOR_NEXT(it)) { 384+ rc = _add_applications_in_dir(container, dir); 385+ } 386+ ITERATOR_RELEASE(it); 387+ DEBUGMSGTL(("swinst:arch:darwin", "loaded %d apps\n",_index)); 388+ 389+ return 0; 390+} 391+ 392+void _dump_flags(u_long flags) 393+{ 394+ static struct { 395+ const char*name; 396+ u_long bits; 397+ } names[] = { 398+ { "kLSItemInfoIsPlainFile", 0x00000001 }, 399+ { "kLSItemInfoIsPackage", 0x00000002 }, 400+ { "kLSItemInfoIsApplication", 0x00000004 }, 401+ { "kLSItemInfoIsContainer", 0x00000008 }, 402+ { "kLSItemInfoIsAliasFile", 0x00000010 }, 403+ { "kLSItemInfoIsSymlink", 0x00000020 }, 404+ { "kLSItemInfoIsInvisible", 0x00000040 }, 405+ { "kLSItemInfoIsNativeApp", 0x00000080 }, 406+ { "kLSItemInfoIsClassicApp", 0x00000100 }, 407+ { "kLSItemInfoAppPrefersNative", 0x00000200 }, 408+ { "kLSItemInfoAppPrefersClassic", 0x00000400 }, 409+ { "kLSItemInfoAppIsScriptable", 0x00000800 }, 410+ { "kLSItemInfoIsVolume", 0x00001000 }, 411+ { "kLSItemInfoExtensionIsHidden", 0x00100000 } 412+ }; 413+ int i, count = sizeof(names)/sizeof(names[0]); 414+ 415+ for(i = 0; i < count; ++i) { 416+ if (flags & names[i].bits) { 417+ DEBUGMSGTL(("swinst:arch:darwin:flags", "\t%s\n", 418+ names[i].name)); 419+ } 420+ } 421+} 422+ 423+static int 424+_add_applications_in_dir(netsnmp_container *container, const char* path) 425+{ 426+ netsnmp_container *files; 427+ netsnmp_iterator *it; 428+ const char *file; 429+ netsnmp_swinst_entry *entry = NULL; 430+ struct stat stat_buf; 431+ size_t date_len; 432+ u_char *date_buf; 433+ int rc = 0; 434+ 435+ CFStringRef currentPath = NULL; 436+ CFURLRef currentURL = NULL; 437+ LSItemInfoRecord itemInfoRecord; 438+ CFStringRef prodName = NULL; 439+ CFStringRef version = NULL; 440+ 441+ DEBUGMSGTL(("swinst:arch:darwin", " adding files from %s\n", path)); 442+ files = netsnmp_directory_container_read(NULL, path, 0); 443+ if (NULL == files) { 444+ snmp_log(LOG_ERR, "swinst: could not read directory %s\n", path); 445+ return -1; 446+ } 447+ 448+ it = CONTAINER_ITERATOR(files); 449+ if (NULL == it) { 450+ snmp_log(LOG_ERR, "could not get iterator\n"); 451+ netsnmp_directory_container_free(files); 452+ return -1; 453+ } 454+ for (file = ITERATOR_FIRST(it); 455+ file; 456+ file = ITERATOR_NEXT(it), 457+ CFRelease(currentPath), 458+ CFRelease(currentURL)) { 459+ 460+ int rc2 = 0; 461+ 462+ currentPath = 463+ CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, file, 464+ kCFStringEncodingUTF8, 465+ kCFAllocatorNull); 466+ currentURL = 467+ CFURLCreateWithFileSystemPath(kCFAllocatorDefault, currentPath, 468+ kCFURLPOSIXPathStyle, true); 469+ LSCopyItemInfoForURL(currentURL, 470+ kLSRequestBasicFlagsOnly|kLSRequestAppTypeFlags, 471+ &itemInfoRecord); 472+ if((0 == itemInfoRecord.flags) || 473+ (kLSItemInfoIsPlainFile == itemInfoRecord.flags) || 474+ (itemInfoRecord.flags & kLSItemInfoIsInvisible) || 475+ (itemInfoRecord.flags & kLSItemInfoIsAliasFile)) { 476+ continue; 477+ } 478+ /** recurse on non-application containers (i.e. directory) */ 479+ if ((itemInfoRecord.flags & kLSItemInfoIsContainer) && 480+ (!(itemInfoRecord.flags & kLSItemInfoIsApplication))) { 481+ netsnmp_directory_container_read(files, file, 0); 482+ continue; 483+ } 484+ 485+ /** skip any other non-application files */ 486+ if (!(itemInfoRecord.flags & kLSItemInfoIsApplication)) { 487+ continue; 488+ } 489+ 490+ if ((itemInfoRecord.flags & kLSItemInfoIsPackage) || 491+ (itemInfoRecord.flags & kLSItemInfoIsContainer)) { 492+ rc2 = _check_bundled_app(currentURL, &prodName, &version, file); 493+ } 494+ else if ((itemInfoRecord.flags & kLSItemInfoIsClassicApp) || 495+ (itemInfoRecord.flags & kLSItemInfoIsPlainFile)) { 496+ rc2 = _check_classic_app(currentURL, &prodName, &version, file); 497+ } else { 498+ snmp_log(LOG_ERR,"swinst shouldn't get here: %s\n", file); 499+ _dump_flags(itemInfoRecord.flags); 500+ continue; 501+ } 502+ if (rc2) { /* not an app. if directory, recurse; else continue */ 503+ _dump_flags(itemInfoRecord.flags); 504+ if (1 == rc2) 505+ netsnmp_directory_container_read(files, file, 0); 506+ continue; 507+ } 508+ 509+ /* 510+ * allocate entry 511+ */ 512+ entry = netsnmp_swinst_entry_create(++_index); 513+ if (NULL == entry) { 514+ snmp_log(LOG_ERR, "error creating swinst entry\n"); 515+ rc = -1; 516+ SNMP_CFRelease(prodName); 517+ SNMP_CFRelease(version); 518+ break; 519+ } 520+ 521+ entry->swName_len = 522+ snprintf(entry->swName, sizeof(entry->swName), 523+ "%s %s", CFStringGetCStringPtr(prodName,0), 524+ CFStringGetCStringPtr(version,0)); 525+ 526+ DEBUGMSGTL(("swinst:arch:darwin", "\t%s %s\n", file, entry->swName)); 527+ 528+ /** get the last mod date */ 529+ if(stat(file, &stat_buf) != -1) { 530+ date_buf = date_n_time(&stat_buf.st_mtime, &date_len); 531+ entry->swDate_len = date_len; 532+ memcpy(entry->swDate, date_buf, entry->swDate_len); 533+ } 534+ 535+ CONTAINER_INSERT(container, entry); 536+ entry = NULL; 537+ SNMP_CFRelease(prodName); 538+ SNMP_CFRelease(version); 539+ } 540+ ITERATOR_RELEASE(it); 541+ netsnmp_directory_container_free(files); 542+ 543+ return rc; 544+} 545+ 546+int 547+_check_bundled_app(CFURLRef currentURL, CFStringRef *prodName, 548+ CFStringRef *version, const char* file) 549+{ 550+ CFBundleRef theBundle = NULL; 551+ CFDictionaryRef infoDict = NULL; 552+ 553+ if ((NULL == prodName) || (NULL == version)) 554+ return -1; 555+ 556+ theBundle = CFBundleCreate (kCFAllocatorDefault, currentURL); 557+ if(theBundle == NULL) 558+ return -1; /* not a bundle */ 559+ 560+ infoDict = CFBundleGetInfoDictionary(theBundle); 561+ if(0 == CFDictionaryGetCount(infoDict)) { 562+ SNMP_CFRelease(theBundle); 563+ return 1; /* directory */ 564+ } 565+ 566+ *prodName = (CFStringRef) 567+ CFDictionaryGetValue (infoDict, CFSTR("CFBundleName")); 568+ if (NULL == *prodName) { 569+ *prodName = (CFStringRef) 570+ CFDictionaryGetValue (infoDict, CFSTR("CFBundleDisplayName")); 571+ if (NULL == *prodName) { 572+ *prodName = (CFStringRef) CFDictionaryGetValue (infoDict, 573+ CFSTR("CFBundleExecutable")); 574+ } 575+ } 576+ if(NULL == *prodName) { 577+ DEBUGMSGTL(("swinst:arch:darwin", "\tmissing name: %s\n",file)); 578+ /*CFShow(infoDict);*/ 579+ SNMP_CFRelease(theBundle); 580+ return -1; 581+ } 582+ 583+ *version = (CFStringRef) 584+ CFDictionaryGetValue (infoDict, CFSTR("CFBundleShortVersionString")); 585+ if(NULL == *version) { 586+ *version = (CFStringRef) 587+ CFDictionaryGetValue (infoDict, CFSTR("CFBundleVersion")); 588+ if (*version == NULL) 589+ *version = (CFStringRef) CFDictionaryGetValue (infoDict, 590+ CFSTR("CFBundleGetInfoString")); 591+ } 592+ if(NULL == *version) { 593+ DEBUGMSGTL(("swinst:arch:darwin", "\tmissing version: %s\n",file)); 594+ /*CFShow(infoDict);*/ 595+ SNMP_CFRelease(theBundle); 596+ return -1; 597+ } 598+ 599+ if(theBundle != NULL) { 600+ CFRetain(*prodName); 601+ CFRetain(*version); 602+ SNMP_CFRelease(theBundle); 603+ } 604+ return 0; 605+} 606+ 607+static int 608+_check_classic_app(CFURLRef currentURL, CFStringRef *prodName, 609+ CFStringRef *version, const char* file) 610+{ 611+ /* 612+ * get info for classic or single-file apps 613+ */ 614+ FSRef theFSRef; 615+ int theResFile; 616+ 617+ if ((NULL == prodName) || (NULL == version)) 618+ return -1; 619+ 620+ *prodName = CFURLCopyLastPathComponent(currentURL); 621+ if (! CFURLGetFSRef(currentURL, &theFSRef)) { 622+ DEBUGMSGTL(("swinst:arch:darwin", "GetFSRef failed: %s\n", file)); 623+ SNMP_CFRelease(*prodName); 624+ return -1; 625+ } 626+ theResFile = FSOpenResFile(&theFSRef, fsRdPerm); 627+ if (ResError() != noErr) { 628+ DEBUGMSGTL(("swinst:arch:darwin", "FSOpenResFile failed: %s\n", file)); 629+ SNMP_CFRelease(*prodName); 630+ return -1; 631+ } 632+ VersRecHndl versHandle = (VersRecHndl)Get1IndResource('vers', 1); 633+ if (versHandle != NULL) { 634+ *version = CFStringCreateWithPascalString(kCFAllocatorDefault, 635+ (**versHandle).shortVersion, kCFStringEncodingMacRoman); 636+ if (*version == NULL) { 637+ StringPtr longVersionPtr = (**versHandle).shortVersion; 638+ longVersionPtr = (StringPtr)(((Ptr) longVersionPtr) + 639+ 1 + ((unsigned char) *longVersionPtr)); 640+ *version = CFStringCreateWithPascalString(kCFAllocatorDefault, 641+ longVersionPtr, kCFStringEncodingMacRoman); 642+ } 643+ ReleaseResource((Handle)versHandle); 644+ } 645+ CloseResFile(theResFile); 646+ if(*version == NULL) { 647+ DEBUGMSGTL(("swinst:arch:darwin", 648+ "\tmissing classic/file version: %s\n", file)); 649+ SNMP_CFRelease(*prodName); 650+ return -1; 651+ } 652+ 653+ return 0; 654+} 655diff -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 656--- SVN/agent/mibgroup/host/hrSWInstalledTable.c 657+++ APPLE/agent/mibgroup/host/hrSWInstalledTable.c 658@@ -0,0 +1,261 @@ 659+/* 660+ * Note: this file originally auto-generated by mib2c using 661+ * : mib2c.container.conf,v 1.8 2006/07/26 15:58:26 dts12 Exp $ 662+ */ 663+ 664+#include <net-snmp/net-snmp-config.h> 665+#include <net-snmp/net-snmp-includes.h> 666+#include <net-snmp/agent/net-snmp-agent-includes.h> 667+#include <net-snmp/agent/table_container.h> 668+#include <net-snmp/data_access/swinst.h> 669+#include <net-snmp/agent/cache_handler.h> 670+#include "hrSWInstalledTable.h" 671+ 672+#define MYTABLE "hrSWInstalledTable" 673+ 674+static void _cache_free(netsnmp_cache * cache, void *magic); 675+static int _cache_load(netsnmp_cache * cache, void *magic); 676+ 677+/** Initializes the hrSWInstalledTable module */ 678+void 679+init_hrSWInstalledTable(void) 680+{ 681+ /* 682+ * here we initialize all the tables we're planning on supporting 683+ */ 684+ initialize_table_hrSWInstalledTable(); 685+} 686+ 687+/** Initialize the hrSWInstalledTable table by defining its contents and how it's structured */ 688+void 689+initialize_table_hrSWInstalledTable(void) 690+{ 691+ static oid hrSWInstalledTable_oid[] = 692+ { 1, 3, 6, 1, 2, 1, 25, 6, 3 }; 693+ size_t hrSWInstalledTable_oid_len = 694+ OID_LENGTH(hrSWInstalledTable_oid); 695+ netsnmp_handler_registration *reg; 696+ netsnmp_mib_handler *handler; 697+ netsnmp_container *container; 698+ netsnmp_cache *cache; 699+ netsnmp_table_registration_info *table_info; 700+ 701+ DEBUGMSGTL(("hrSWInstalled", "initialize\n")); 702+ 703+ reg = 704+ netsnmp_create_handler_registration("hrSWInstalledTable", 705+ hrSWInstalledTable_handler, 706+ hrSWInstalledTable_oid, 707+ hrSWInstalledTable_oid_len, 708+ HANDLER_CAN_RONLY); 709+ if (NULL == reg) { 710+ snmp_log(LOG_ERR,"error creating handler registration for " 711+ MYTABLE "\n"); 712+ goto bail; 713+ } 714+ 715+ container = netsnmp_container_find("hrSWInstalledTable:table_container"); 716+ if (NULL == container) { 717+ snmp_log(LOG_ERR,"error creating container for " 718+ MYTABLE "\n"); 719+ goto bail; 720+ } 721+ 722+ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info); 723+ if (NULL == table_info) { 724+ snmp_log(LOG_ERR,"error allocating table registration for " 725+ MYTABLE "\n"); 726+ goto bail; 727+ } 728+ 729+ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: hrSWInstalledIndex */ 730+ 0); 731+ table_info->min_column = COLUMN_HRSWINSTALLEDINDEX; 732+ table_info->max_column = COLUMN_HRSWINSTALLEDDATE; 733+ 734+ /************************************************* 735+ * 736+ * inject container_table helper 737+ */ 738+ handler = netsnmp_container_table_handler_get(table_info, container, 739+ TABLE_CONTAINER_KEY_NETSNMP_INDEX); 740+ if (NULL == handler) { 741+ snmp_log(LOG_ERR,"error allocating table registration for " 742+ MYTABLE "\n"); 743+ goto bail; 744+ } 745+ if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { 746+ snmp_log(LOG_ERR,"error injecting container_table handler for " 747+ MYTABLE "\n"); 748+ goto bail; 749+ } 750+ handler = NULL; /* reg has it, will reuse below */ 751+ 752+ /************************************************* 753+ * 754+ * inject cache helper 755+ */ 756+ cache = netsnmp_cache_create(30, /* timeout in seconds */ 757+ _cache_load, _cache_free, 758+ hrSWInstalledTable_oid, 759+ hrSWInstalledTable_oid_len); 760+ 761+ if (NULL == cache) { 762+ snmp_log(LOG_ERR, "error creating cache for " 763+ MYTABLE "\n"); 764+ goto bail; 765+ } 766+ cache->magic = container; 767+ 768+ handler = netsnmp_cache_handler_get(cache); 769+ if (NULL == handler) { 770+ snmp_log(LOG_ERR, "error creating cache handler for " 771+ MYTABLE "\n"); 772+ goto bail; 773+ } 774+ if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) { 775+ snmp_log(LOG_ERR,"error injecting cache handler for " 776+ MYTABLE "\n"); 777+ goto bail; 778+ } 779+ handler = NULL; /* reg has it*/ 780+ 781+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) { 782+ snmp_log(LOG_ERR,"error registering table handler for " 783+ MYTABLE "\n"); 784+ goto bail; 785+ } 786+ 787+ return; /* ok */ 788+ 789+ 790+ bail: /* not ok */ 791+ 792+ if (handler) 793+ netsnmp_handler_free(handler); 794+ 795+ if (cache) 796+ netsnmp_cache_free(cache); 797+ 798+ if (table_info) 799+ netsnmp_table_registration_info_free(table_info); 800+ 801+ if (container) 802+ CONTAINER_FREE(container); 803+ 804+ if (reg) 805+ netsnmp_handler_registration_free(reg); 806+ 807+} 808+ 809+/** handles requests for the hrSWInstalledTable table */ 810+int 811+hrSWInstalledTable_handler(netsnmp_mib_handler *handler, 812+ netsnmp_handler_registration *reginfo, 813+ netsnmp_agent_request_info *reqinfo, 814+ netsnmp_request_info *requests) 815+{ 816+ 817+ netsnmp_request_info *request; 818+ netsnmp_table_request_info *table_info; 819+ netsnmp_swinst_entry *table_entry; 820+ 821+ switch (reqinfo->mode) { 822+ /* 823+ * Read-support (also covers GetNext requests) 824+ */ 825+ case MODE_GET: 826+ for (request = requests; request; request = request->next) { 827+ if (request->processed) 828+ continue; 829+ table_entry = (netsnmp_swinst_entry *) 830+ netsnmp_container_table_extract_context(request); 831+ table_info = netsnmp_extract_table_info(request); 832+ if ((NULL == table_entry) || (NULL == table_info)) { 833+ snmp_log(LOG_ERR, "could not extract table entry or info for " 834+ MYTABLE "\n"); 835+ snmp_set_var_typed_value(request->requestvb, 836+ SNMP_ERR_GENERR, NULL, 0); 837+ continue; 838+ } 839+ 840+ switch (table_info->colnum) { 841+ case COLUMN_HRSWINSTALLEDINDEX: 842+ snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, 843+ table_entry->swIndex); 844+ break; 845+ case COLUMN_HRSWINSTALLEDNAME: { 846+ snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, 847+ (u_char *) table_entry->swName, 848+ table_entry->swName_len); 849+ } break; 850+ case COLUMN_HRSWINSTALLEDID: 851+ snmp_set_var_typed_value(request->requestvb, ASN_OBJECT_ID, 852+ (u_char *) &nullOid, nullOidLen); 853+ break; 854+ case COLUMN_HRSWINSTALLEDTYPE: 855+ snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, 856+ table_entry->swType); 857+ break; 858+ case COLUMN_HRSWINSTALLEDDATE: 859+ snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, 860+ (u_char *) table_entry->swDate, 861+ table_entry->swDate_len); 862+ break; 863+ default: 864+ /* 865+ * An unsupported/unreadable column (if applicable) 866+ */ 867+ snmp_set_var_typed_value(request->requestvb, 868+ SNMP_NOSUCHOBJECT, NULL, 0); 869+ } 870+ } 871+ break; 872+ 873+ } 874+ return SNMP_ERR_NOERROR; 875+} 876+ 877+/*********************************************************************** 878+ * 879+ * DATA ACCESS 880+ * 881+ * The data access mechanism here is rather simple: let newsnmp_swinst_* 882+ * take care of it. 883+ ***********************************************************************/ 884+/** 885+ * @internal 886+ */ 887+static int 888+_cache_load(netsnmp_cache * cache, void *vmagic) 889+{ 890+ DEBUGMSGTL(("hrSWInstalledTable:cache", "load\n")); 891+ 892+ if ((NULL == cache) || (NULL == cache->magic)) { 893+ snmp_log(LOG_ERR, "invalid cache for hrSWInstalledTable_cache_load\n"); 894+ return -1; 895+ } 896+ 897+ /** should only be called for an invalid or expired cache */ 898+ netsnmp_assert((0 == cache->valid) || (1 == cache->expired)); 899+ 900+ cache->magic = 901+ netsnmp_swinst_container_load((netsnmp_container *) cache->magic, 0); 902+ 903+ return 0; 904+} /* _cache_load */ 905+ 906+/** 907+ * @internal 908+ */ 909+static void 910+_cache_free(netsnmp_cache * cache, void *magic) 911+{ 912+ if ((NULL == cache) || (NULL == cache->magic)) { 913+ snmp_log(LOG_ERR, "invalid cache in hrSWInstalledTable_cache_free\n"); 914+ return; 915+ } 916+ DEBUGMSGTL(("hrSWInstalledTable:cache", "free\n")); 917+ 918+ netsnmp_swinst_container_free_items((netsnmp_container *) cache->magic); 919+} /* _cache_free */ 920diff -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 921--- SVN/agent/mibgroup/host/hrSWInstalledTable.h 922+++ APPLE/agent/mibgroup/host/hrSWInstalledTable.h 923@@ -0,0 +1,25 @@ 924+/* 925+ * Note: this file originally auto-generated by mib2c using 926+ * : mib2c.container.conf,v 1.8 2006/07/26 15:58:26 dts12 Exp $ 927+ */ 928+#ifndef HRSWINSTALLEDTABLE_H 929+#define HRSWINSTALLEDTABLE_H 930+ 931+config_require(host/data_access/swinst) 932+ 933+/* 934+ * function declarations 935+ */ 936+void init_hrSWInstalledTable(void); 937+void initialize_table_hrSWInstalledTable(void); 938+Netsnmp_Node_Handler hrSWInstalledTable_handler; 939+ 940+/* 941+ * column number definitions for table hrSWInstalledTable 942+ */ 943+#define COLUMN_HRSWINSTALLEDINDEX 1 944+#define COLUMN_HRSWINSTALLEDNAME 2 945+#define COLUMN_HRSWINSTALLEDID 3 946+#define COLUMN_HRSWINSTALLEDTYPE 4 947+#define COLUMN_HRSWINSTALLEDDATE 5 948+#endif /* HRSWINSTALLEDTABLE_H */ 949diff -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 950--- SVN/include/net-snmp/data_access/swinst.h 951+++ APPLE/include/net-snmp/data_access/swinst.h 952@@ -0,0 +1,67 @@ 953+#ifndef NETSNMP_SWINST_H 954+#define NETSNMP_SWINST_H 955+ 956+#ifdef __cplusplus 957+extern "C" { 958+#endif 959+ 960+ /* 961+ * Data structure for a swinst entry 962+ */ 963+ typedef struct hrSWInstalledTable_entry { 964+ netsnmp_index oid_index; 965+ 966+ /* 967+ * Index values; MIB type is int32, but we use oid so this 968+ * structure can be used directly with a table_container. 969+ */ 970+ oid swIndex; 971+ 972+ /* 973+ * Column values 974+ */ 975+ char swName[64]; 976+ char swDate[11]; 977+#ifdef NETSNMP_HAVE_SWID 978+ oid *swID; 979+ u_char swID_len; 980+#endif 981+ u_char swType; 982+ u_char swName_len; 983+ u_char swDate_len; 984+ } netsnmp_swinst_entry; 985+ 986+#define HRSWINSTALLEDTYPE_UNKNOWN 1 987+#define HRSWINSTALLEDTYPE_OPERATINGSYSTEM 2 988+#define HRSWINSTALLEDTYPE_DEVICEDRIVER 3 989+#define HRSWINSTALLEDTYPE_APPLICATION 4 990+ 991+ 992+#define NETSNMP_SWINST_NOFLAGS 0x00000000 993+ 994+#define NETSNMP_SWINST_ALL_OR_NONE 0x00000001 995+#define NETSNMP_SWINST_DONT_FREE_ITEMS 0x00000002 996+ 997+ netsnmp_container * 998+ netsnmp_swinst_container_load(netsnmp_container *container, int flags ); 999+ 1000+ void netsnmp_swinst_container_free(netsnmp_container *container, 1001+ u_int flags); 1002+ void netsnmp_swinst_container_free_items(netsnmp_container *container); 1003+ 1004+ void netsnmp_swinst_entry_remove(netsnmp_container * container, 1005+ netsnmp_swinst_entry *entry); 1006+ 1007+ netsnmp_swinst_entry * netsnmp_swinst_entry_create(int32_t index); 1008+ void netsnmp_swinst_entry_free(netsnmp_swinst_entry *entry); 1009+ 1010+ int32_t netsnmp_swinst_add_name(const char *name); 1011+ int32_t netsnmp_swinst_get_id(const char *name); 1012+ const char * netsnmp_swinst_get_name(int32_t id); 1013+ 1014+#ifdef __cplusplus 1015+} 1016+#endif 1017+ 1018+ 1019+#endif /* NETSNMP_SWINST_H */ 1020