Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 20db51d70e6b59a061db97ce9b89c771 > files > 56

net-snmp-5.3.2.2-14.el5.src.rpm

595322: hrStorage does not seem to keep track of indexes

taken from upstream, backported to 5.3.2.2

diff -uNr old/agent/mibgroup/hardware/fsys/fsys_getfsstats.c net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_getfsstats.c
--- old/agent/mibgroup/hardware/fsys/fsys_getfsstats.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_getfsstats.c	2011-01-19 14:02:44.453482363 +0100
@@ -0,0 +1,178 @@
+#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/agent/hardware/fsys.h>
+#include "hardware/fsys/hw_fsys.h"
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+
+
+    /*
+     * Handle minor naming differences between statfs/statvfs
+     */
+#if defined(_VFS_NAMELEN)
+#define NSFS_NAMELEN  _VFS_NAMELEN
+#else
+#define NSFS_NAMELEN  MNAMELEN
+#endif
+
+#if defined(HAVE_GETVFSSTAT)
+#define NSFS_GETFSSTAT  getvfsstat
+#define NSFS_STATFS     statvfs
+#define NSFS_FLAGS      f_flag
+#else
+#define NSFS_GETFSSTAT  getfsstat
+#define NSFS_STATFS     statfs
+#define NSFS_FLAGS      f_flags
+#endif
+
+/*
+#if defined(HAVE_STATVFS)
+#define NSFS_STATFS     statvfs
+#define NSFS_FLAGS      f_flag
+#else
+#define NSFS_STATFS     statfs
+#define NSFS_FLAGS      f_flags
+#endif
+*/
+
+/*
+#if defined(HAVE_STATVFS) && defined(__NetBSD__)
+#define NSFS_NAMELEN    _VFS_NAMELEN
+#define NSFS_GETFSSTAT  getvfsstat
+#define NSFS_STATFS     statvfs
+#else
+#define NSFS_FLAGS      f_flags
+#define NSFS_NAMELEN    _VFS_NAMELEN
+#define NSFS_GETFSSTAT  getvfsstat
+#define NSFS_STATFS     statvfs
+#endif
+*/
+
+int
+_fs_type( char *typename )
+{
+    DEBUGMSGTL(("fsys:type", "Classifying %s\n", typename));
+
+    if ( !typename || *typename=='\0' )
+       return NETSNMP_FS_TYPE_UNKNOWN;
+
+#include "mounts.h"
+
+       /*
+        * List of mount types from <sys/mount.h>
+        */
+    else if ( !strcmp(typename, MOUNT_FFS) ||
+              !strcmp(typename, MOUNT_UFS) )
+       return NETSNMP_FS_TYPE_BERKELEY;
+    else if ( !strcmp(typename, MOUNT_NFS) )
+       return NETSNMP_FS_TYPE_NFS;
+    else if ( !strcmp(typename, MOUNT_MFS) )
+       return NETSNMP_FS_TYPE_MFS;
+    else if ( !strcmp(typename, MOUNT_MSDOS) ||
+              !strcmp(typename, MOUNT_MSDOSFS) )
+       return NETSNMP_FS_TYPE_FAT;
+    else if ( !strcmp(typename, MOUNT_AFS) )
+       return NETSNMP_FS_TYPE_AFS;
+    else if ( !strcmp(typename, MOUNT_CD9660) )
+       return NETSNMP_FS_TYPE_ISO9660;
+    else if ( !strcmp(typename, MOUNT_EXT2FS) )
+       return NETSNMP_FS_TYPE_EXT2;
+    else if ( !strcmp(typename, MOUNT_NTFS) )
+       return NETSNMP_FS_TYPE_NTFS;
+
+       /*
+        * NetBSD also recognises the following filesystem types:
+        *     MOUNT_NULL
+        *     MOUNT_OVERLAY
+        *     MOUNT_UMAP
+        *     MOUNT_UNION
+        *     MOUNT_CFS/CODA
+        *     MOUNT_FILECORE
+        *     MOUNT_SMBFS
+        *     MOUNT_PTYFS
+        * OpenBSD also recognises the following filesystem types:
+        *     MOUNT_LOFS
+        *     MOUNT_NCPFS
+        *     MOUNT_XFS
+        *     MOUNT_UDF
+        * Both of them recognise the following filesystem types:
+        *     MOUNT_LFS
+        *     MOUNT_FDESC
+        *     MOUNT_PORTAL
+        *     MOUNT_KERNFS
+        *     MOUNT_PROCFS
+        *     MOUNT_ADOSFS
+        *
+        * All of these filesystems are mapped to NETSNMP_FS_TYPE_OTHER
+        *   so will be picked up by the following default branch.
+        */
+    else
+       return NETSNMP_FS_TYPE_OTHER;
+}
+
+void
+netsnmp_fsys_arch_init( void )
+{
+    return;
+}
+
+void
+netsnmp_fsys_arch_load( void )
+{
+    int n, i;
+    struct NSFS_STATFS *stats;
+    netsnmp_fsys_info *entry;
+
+    /*
+     * Retrieve information about the currently mounted filesystems...
+     */
+    n = NSFS_GETFSSTAT( NULL, 0, 0 );
+    if ( n==0 )
+        return;
+    stats = malloc( n * sizeof( struct NSFS_STATFS ));
+    n = NSFS_GETFSSTAT( stats, n * sizeof( struct NSFS_STATFS ), MNT_NOWAIT );
+
+    /*
+     * ... and insert this into the filesystem container.
+     */
+    for ( i=0; i<n; i++ ) {
+        entry = netsnmp_fsys_by_path( stats[i].f_mntonname,
+                                      NETSNMP_FS_FIND_CREATE );
+        if (!entry)
+            continue;
+
+        memcpy( entry->path,   stats[i].f_mntonname,   sizeof(entry->path)  );
+        entry->path[sizeof(entry->path)-1] = '\0';
+        memcpy( entry->device, stats[i].f_mntfromname, sizeof(entry->device));
+        entry->device[sizeof(entry->device)-1] = '\0';
+        entry->units = stats[i].f_bsize;    /* or f_frsize */
+        entry->size  = stats[i].f_blocks;
+        entry->used  = stats[i].f_bfree;
+        entry->avail = stats[i].f_bavail;
+        entry->inums_total = stats[i].f_files;
+        entry->inums_avail = stats[i].f_ffree;
+
+        entry->type = _fs_type( stats[i].f_fstypename );
+        entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
+
+        if (! stats[i].NSFS_FLAGS & MNT_LOCAL ) {
+            entry->flags |= NETSNMP_FS_FLAG_REMOTE;
+        }
+        if (  stats[i].NSFS_FLAGS & MNT_RDONLY ) {
+            entry->flags |= NETSNMP_FS_FLAG_RONLY;
+        }
+        if (  stats[i].NSFS_FLAGS & MNT_ROOTFS ) {
+            entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;
+        }
+        
+    }
+}
diff -uNr old/agent/mibgroup/hardware/fsys/fsys_mntctl.c net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_mntctl.c
--- old/agent/mibgroup/hardware/fsys/fsys_mntctl.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_mntctl.c	2011-01-19 14:02:44.454482380 +0100
@@ -0,0 +1,179 @@
+#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/agent/hardware/fsys.h>
+
+#include <stdio.h>
+#if HAVE_SYS_MNTCTL_H
+#include <sys/mntctl.h>
+#endif
+#if HAVE_SYS_VMOUNT_H
+#include <sys/vmount.h>
+#endif
+#if HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+
+
+int
+_fsys_remote( char *device, int type, char *host )
+{
+    if (( type == NETSNMP_FS_TYPE_NFS) ||
+        ( type == NETSNMP_FS_TYPE_AFS))
+        return 1;
+    else
+        return 0;
+}
+
+int
+_fsys_type( char *typename )
+{
+    DEBUGMSGTL(("fsys:type", "Classifying %s\n", typename));
+
+    if ( !typename || *typename=='\0' )
+       return NETSNMP_FS_TYPE_UNKNOWN;
+
+/* #include "mnttypes.h" */
+
+    else if ( !strcmp(typename, MNT_AIX) ||
+              !strcmp(typename, MNT_JFS) )
+       return NETSNMP_FS_TYPE_BERKELEY;
+    else if ( !strcmp(typename, MNT_CDROM) )
+       return NETSNMP_FS_TYPE_ISO9660;
+    else if ( !strcmp(typename, MNT_NFS)  ||
+              !strcmp(typename, MNT_NFS3) ||
+              !strcmp(typename, MNT_AUTOFS) )
+       return NETSNMP_FS_TYPE_NFS;
+
+    /*
+     *  The following code covers selected filesystems
+     *    which are not covered by the HR-TYPES enumerations,
+     *    but should still be monitored.
+     *  These are all mapped into type "other"
+     *
+     */    
+    else if ( !strcmp(typename, MNT_SFS) ||
+#ifdef MNT_NAMEFS
+              !strcmp(typename, MNT_NAMEFS) ||
+#endif
+#ifdef MNT_PROCFS
+              !strcmp(typename, MNT_PROCFS) ||
+#endif
+              !strcmp(typename, MNT_CACHEFS))
+       return NETSNMP_FS_TYPE_OTHER;
+
+    /*    
+     *  All other types are silently skipped
+     */
+    else
+       return NETSNMP_FS_TYPE_IGNORE;
+}
+
+void
+netsnmp_fsys_arch_init( void )
+{
+    return;
+}
+
+void
+netsnmp_fsys_arch_load( void )
+{
+    int  ret  = 0;
+    uint size = 0;
+
+    struct vmount *aixmnt, *aixcurr;
+    char          *path;
+    struct statfs  stat_buf;
+    netsnmp_fsys_info *entry;
+    char               tmpbuf[1024];
+
+    /*
+     * Retrieve information about the currently mounted filesystems...
+     */
+    res = mntctl(MCTL_QUERY, sizeof(uint), &size);
+    if ( res != 0 || size<=0 ) {
+        snmp_log_perror( "initial mntctl failed" );
+        return;
+    }
+
+    aixmnt = (struct vmount *)malloc( size );
+    if ( aixmnt == NULL ) {
+        snmp_log_perror( "cannot allocate memory for mntctl data" );
+        return;
+    }
+
+    res = mntctl(MCTL_QUERY, size, aixmnt );
+    if ( res <= 0 ) {
+        free(aixmnt);
+        snmp_log_perror( "main mntctl failed" );
+        return;
+    }
+    aixcurr = aixmnt;
+
+
+    /*
+     * ... and insert this into the filesystem container.
+     */
+
+    for ( aixcurr  = aixmnt;
+         (aixcurr-aixmnt) >= size;
+          aixcurr  = (char*)aixcurr + aixcurr->vmt_length ) {
+
+        path = vmt2dataptr( aixcurr, VMT_OBJECT );
+        entry = netsnmp_fsys_by_path( path, NETSNMP_FS_FIND_CREATE );
+        if (!entry) {
+            continue;
+        }
+
+        strncpy( entry->path,   path,    sizeof( entry->path   ));
+        strncpy( entry->device, vmt2dataptr( aixcurr, VMT_STUB),
+                                         sizeof( entry->device ));
+        entry->type   = _fsys_type( aixcurr->vmt_gfstype );
+
+        if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
+            entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
+
+        if ( _fsys_remote( entry->device, entry->type, vmt2dataptr( aixcurr, VMT_HOST) ))
+            entry->flags |= NETSNMP_FS_FLAG_REMOTE;
+        if ( aixcurr->vmt_flags & MNT_READONLY )
+            entry->flags |= NETSNMP_FS_FLAG_RONLY;
+        /*
+         *  The root device is presumably bootable.
+         *  Other partitions probably aren't!
+         */
+        if ((entry->path[0] == '/') &&
+            (entry->path[1] == '\0'))
+            entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;
+
+        /*
+         *  XXX - identify removeable disks
+         */
+
+        /*
+         *  Optionally skip retrieving statistics for remote mounts
+         */
+        if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) &&
+            netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+                                   NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES))
+            continue;
+
+        if ( statfs( entry->path, &stat_buf ) < 0 ) {
+            snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s\n", entry->path );
+            snmp_log_perror( tmpbuf );
+            continue;
+        }
+        entry->units =  stat_buf.f_bsize;
+        entry->size  =  stat_buf.f_blocks;
+        entry->used  = (stat_buf.f_blocks - stat_buf.f_bfree);
+        entry->avail =  stat_buf.f_bavail;
+        entry->inums_total = stat_buf.f_files;
+        entry->inums_avail = stat_buf.f_ffree;
+    }
+    free(aixmnt);
+    aixmnt  = NULL;
+    aixcurr = NULL;
+}
+
diff -uNr old/agent/mibgroup/hardware/fsys/fsys_mntent.c net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_mntent.c
--- old/agent/mibgroup/hardware/fsys/fsys_mntent.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/fsys_mntent.c	2011-01-19 14:02:44.455482398 +0100
@@ -0,0 +1,244 @@
+#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/agent/hardware/fsys.h>
+
+#include <stdio.h>
+#if HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#if HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#if HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+
+#ifdef solaris2
+#define _NETSNMP_GETMNTENT_TWO_ARGS 1
+#else
+#undef  _NETSNMP_GETMNTENT_TWO_ARGS 
+#endif
+
+    /*
+     * Handle naming differences between getmntent() APIs
+     */
+#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
+    /* Two-argument form (Solaris) */
+#define NSFS_MNTENT   struct mnttab
+#define NSFS_PATH     mnt_mountp
+#define NSFS_DEV      mnt_special
+#define NSFS_TYPE     mnt_fstype
+
+#define NSFS_STATFS   statvfs
+#define NSFS_SIZE     f_frsize
+
+#else
+    /* One-argument form (everything else?) */
+#define NSFS_MNTENT   struct mntent
+#define NSFS_PATH     mnt_dir
+#define NSFS_DEV      mnt_fsname
+#define NSFS_TYPE     mnt_type
+
+#define NSFS_STATFS   statfs
+#define NSFS_SIZE     f_bsize
+
+#endif
+
+int
+_fsys_remote( char *device, int type )
+{
+    if (( type == NETSNMP_FS_TYPE_NFS) ||
+        ( type == NETSNMP_FS_TYPE_AFS))
+        return 1;
+    else
+        return 0;
+}
+
+int
+_fsys_type( char *typename )
+{
+    DEBUGMSGTL(("fsys:type", "Classifying %s\n", typename));
+
+    if ( !typename || *typename=='\0' )
+       return NETSNMP_FS_TYPE_UNKNOWN;
+
+#include "mnttypes.h"
+
+    else if ( !strcmp(typename, MNTTYPE_FFS) )
+       return NETSNMP_FS_TYPE_BERKELEY;
+    else if ( !strcmp(typename, MNTTYPE_UFS) )
+       return _NETSNMP_FS_TYPE_UFS;   /* either N_FS_TYPE_BERKELEY or N_FS_TYPE_SYSV */
+    else if ( !strcmp(typename, MNTTYPE_SYSV) )
+       return NETSNMP_FS_TYPE_SYSV;
+    else if ( !strcmp(typename, MNTTYPE_PC) ||
+              !strcmp(typename, MNTTYPE_MSDOS) )
+       return NETSNMP_FS_TYPE_FAT;
+    else if ( !strcmp(typename, MNTTYPE_HFS) )
+       return NETSNMP_FS_TYPE_HFS;
+    else if ( !strcmp(typename, MNTTYPE_MFS) )
+       return NETSNMP_FS_TYPE_MFS;
+    else if ( !strcmp(typename, MNTTYPE_NTFS) )
+       return NETSNMP_FS_TYPE_NTFS;
+    else if ( !strcmp(typename, MNTTYPE_ISO9660) ||
+              !strcmp(typename, MNTTYPE_CD9660) )
+       return NETSNMP_FS_TYPE_ISO9660;
+    else if ( !strcmp(typename, MNTTYPE_CDFS) )
+       return _NETSNMP_FS_TYPE_CDFS;   /* either N_FS_TYPE_ISO9660 or N_FS_TYPE_ROCKRIDGE */
+    else if ( !strcmp(typename, MNTTYPE_HSFS) )
+       return NETSNMP_FS_TYPE_ROCKRIDGE;
+    else if ( !strcmp(typename, MNTTYPE_NFS)  ||
+              !strcmp(typename, MNTTYPE_NFS3) ||
+              !strcmp(typename, MNTTYPE_NFS4) ||
+              !strcmp(typename, MNTTYPE_CIFS) ||  /* i.e. SMB - ?? */
+              !strcmp(typename, MNTTYPE_SMBFS)    /* ?? */ )
+       return NETSNMP_FS_TYPE_NFS;
+    else if ( !strcmp(typename, MNTTYPE_NCPFS) )
+       return NETSNMP_FS_TYPE_NETWARE;
+    else if ( !strcmp(typename, MNTTYPE_AFS) )
+       return NETSNMP_FS_TYPE_AFS;
+    else if ( !strcmp(typename, MNTTYPE_EXT2) ||
+              !strcmp(typename, MNTTYPE_EXT3) ||
+              !strcmp(typename, MNTTYPE_EXT4) ||
+              !strcmp(typename, MNTTYPE_EXT2FS) ||
+              !strcmp(typename, MNTTYPE_EXT3FS) ||
+              !strcmp(typename, MNTTYPE_EXT4FS) )
+       return NETSNMP_FS_TYPE_EXT2;
+    else if ( !strcmp(typename, MNTTYPE_FAT32) ||
+              !strcmp(typename, MNTTYPE_VFAT) )
+       return NETSNMP_FS_TYPE_FAT32;
+
+    /*
+     *  The following code covers selected filesystems
+     *    which are not covered by the HR-TYPES enumerations,
+     *    but should still be monitored.
+     *  These are all mapped into type "other"
+     *
+     *    (The systems listed are not fixed in stone,
+     *     but are simply here to illustrate the principle!)
+     */    
+    else if ( !strcmp(typename, MNTTYPE_MVFS) ||
+              /*!strcmp(typename, MNTTYPE_TMPFS) || */
+              !strcmp(typename, MNTTYPE_GFS) ||
+              !strcmp(typename, MNTTYPE_GFS2) ||
+              !strcmp(typename, MNTTYPE_JFS) ||
+              !strcmp(typename, MNTTYPE_XFS) ||
+              !strcmp(typename, MNTTYPE_NONE) ||
+              !strcmp(typename, MNTTYPE_LOFS))
+       return NETSNMP_FS_TYPE_OTHER;
+
+    /*    
+     *  All other types are silently skipped
+     */
+    else
+       return NETSNMP_FS_TYPE_IGNORE;
+}
+
+void
+netsnmp_fsys_arch_init( void )
+{
+    return;
+}
+
+void
+netsnmp_fsys_arch_load( void )
+{
+    FILE              *fp=NULL;
+#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
+    struct mnttab      mtmp;
+    struct mnttab     *m = &mtmp;
+#else
+    struct mntent     *m;
+#endif
+    struct NSFS_STATFS stat_buf;
+    netsnmp_fsys_info *entry;
+    char               tmpbuf[1024];
+
+    /*
+     * Retrieve information about the currently mounted filesystems...
+     */
+    fp = fopen( ETC_MNTTAB, "r" );   /* OR setmntent()?? */
+    if ( !fp ) {
+        snprintf( tmpbuf, sizeof(tmpbuf), "Cannot open %s\n", ETC_MNTTAB );
+        snmp_log_perror( tmpbuf );
+        return;
+    }
+
+    /*
+     * ... and insert this into the filesystem container.
+     */
+    while 
+#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
+          ((getmntent(fp, m)) == 0 )
+#else
+          ((m = getmntent(fp)) != NULL )
+#endif
+    {
+        entry = netsnmp_fsys_by_path( m->NSFS_PATH, NETSNMP_FS_FIND_CREATE );
+        if (!entry) {
+            continue;
+        }
+
+        strncpy( entry->path,   m->NSFS_PATH,    sizeof( entry->path   ));
+        entry->path[sizeof(entry->path)-1] = '\0';
+        strncpy( entry->device, m->NSFS_DEV,     sizeof( entry->device ));
+        entry->device[sizeof(entry->device)-1] = '\0';
+        entry->type   = _fsys_type(  m->NSFS_TYPE );
+        if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
+            entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
+
+        if ( _fsys_remote( entry->device, entry->type ))
+            entry->flags |= NETSNMP_FS_FLAG_REMOTE;
+#if HAVE_HASMNTOPT
+        if (hasmntopt( m, "ro" ))
+            entry->flags |= NETSNMP_FS_FLAG_RONLY;
+#endif
+        /*
+         *  The root device is presumably bootable.
+         *  Other partitions probably aren't!
+         *
+         *  XXX - what about /boot ??
+         */
+        if ((entry->path[0] == '/') &&
+            (entry->path[1] == '\0'))
+            entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;
+
+        /*
+         *  XXX - identify removeable disks
+         */
+
+        /*
+         *  Optionally skip retrieving statistics for remote mounts
+         */
+        if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) &&
+            netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+                                   NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES))
+            continue;
+
+        if ( NSFS_STATFS( entry->path, &stat_buf ) < 0 ) {
+            snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s\n", entry->path );
+            snmp_log_perror( tmpbuf );
+            continue;
+        }
+        entry->units =  stat_buf.NSFS_SIZE;
+        entry->size  =  stat_buf.f_blocks;
+        entry->used  = (stat_buf.f_blocks - stat_buf.f_bfree);
+        entry->avail =  stat_buf.f_bavail;
+        entry->inums_total = stat_buf.f_files;
+        entry->inums_avail = stat_buf.f_ffree;
+    }
+    fclose( fp );
+}
+
diff -uNr old/agent/mibgroup/hardware/fsys/hw_fsys.c net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/hw_fsys.c
--- old/agent/mibgroup/hardware/fsys/hw_fsys.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/hw_fsys.c	2011-01-19 14:02:44.458482451 +0100
@@ -0,0 +1,291 @@
+#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/agent/hardware/fsys.h>
+
+
+extern void             netsnmp_fsys_arch_load( void );
+extern void             netsnmp_fsys_arch_init( void );
+static int  _fsys_load( void );
+static void _fsys_free( void );
+
+static int _fsysAutoUpdate = 0;   /* 0 means on-demand caching */
+static void _fsys_update_stats( unsigned int, void* );
+
+netsnmp_cache     *_fsys_cache     = NULL;
+netsnmp_container *_fsys_container = NULL;
+static int         _fsys_idx       = 0;
+static netsnmp_fsys_info * _fsys_create_entry( void );
+
+void init_hw_fsys( void ) {
+
+    if ( _fsys_container )
+        return;   /* Already initialised */
+
+    DEBUGMSGTL(("fsys", "Initialise Hardware FileSystem module\n"));
+
+    /*
+     * Define a container to hold the list of filesystems
+     */
+    _fsys_container = netsnmp_container_find("fsysTable:table_container");
+    if ( NULL == _fsys_container ) {
+        snmp_log( LOG_ERR, "failed to create container for fsysTable");
+        return;
+    }
+    netsnmp_fsys_arch_init( );
+
+    /*
+     * If we're sampling the file system information automatically,
+     *   then arrange for this to be triggered regularly.
+     *
+     * If we're not sampling these values regularly,
+     *   create a suitable cache handler instead.
+     */
+    if ( _fsysAutoUpdate ) {
+        DEBUGMSGTL(("fsys", "Reloading Hardware FileSystems automatically (%d)\n",
+                               _fsysAutoUpdate));
+        snmp_alarm_register( _fsysAutoUpdate, SA_REPEAT,
+                             _fsys_update_stats, NULL );
+    }
+    else {
+        _fsys_cache = netsnmp_cache_create( 5, netsnmp_fsys_load,
+                                               netsnmp_fsys_free, NULL, 0 );
+        DEBUGMSGTL(("fsys", "Reloading Hardware FileSystems on-demand (%p)\n",
+                               _fsys_cache));
+    }
+}
+
+void shutdown_hw_fsys( void ) {
+    _fsys_free();
+}
+
+/*
+ *  Return the main fsys container
+ */
+netsnmp_container *netsnmp_fsys_get_container( void ) { return _fsys_container; }
+
+/*
+ *  Return the main fsys cache control structure (if defined)
+ */
+netsnmp_cache *netsnmp_fsys_get_cache( void ) { return _fsys_cache; }
+
+
+/*
+ * Wrapper routine for automatically updating fsys information
+ */
+void
+_fsys_update_stats( unsigned int clientreg, void *data )
+{
+    _fsys_free();
+    _fsys_load();
+}
+
+/*
+ * Wrapper routine for re-loading filesystem statistics on demand
+ */
+int
+netsnmp_fsys_load( netsnmp_cache *cache, void *data )
+{
+    return _fsys_load();
+}
+
+/*
+ * Wrapper routine for releasing expired filesystem statistics
+ */
+void
+netsnmp_fsys_free( netsnmp_cache *cache, void *data )
+{
+    _fsys_free();
+}
+
+
+/*
+ * Architecture-independent processing of loading filesystem statistics
+ */
+static int
+_fsys_load( void )
+{
+    netsnmp_fsys_arch_load();
+    return 0;
+}
+
+/*
+ * Architecture-independent release of filesystem statistics
+ */
+static void
+_fsys_free( void )
+{
+    netsnmp_fsys_info *sp;
+
+    for (sp = CONTAINER_FIRST( _fsys_container );
+         sp;
+         sp = CONTAINER_NEXT(  _fsys_container, sp )) {
+
+         sp->flags &= ~NETSNMP_FS_FLAG_ACTIVE;
+    }
+}
+
+
+netsnmp_fsys_info *netsnmp_fsys_get_first( void ) {
+    return CONTAINER_FIRST( _fsys_container );
+}
+netsnmp_fsys_info *netsnmp_fsys_get_next( netsnmp_fsys_info *this_ptr ) {
+    return CONTAINER_NEXT( _fsys_container, this_ptr );
+}
+
+/*
+ * Retrieve a filesystem entry based on the path where it is mounted,
+ *  or (optionally) insert a new one into the container
+ */
+netsnmp_fsys_info *
+netsnmp_fsys_by_path( char *path, int create_type )
+{
+    netsnmp_fsys_info *sp;
+
+    DEBUGMSGTL(("fsys:path", "Get filesystem entry (%s)\n", path));
+
+    /*
+     *  Look through the list for a matching entry
+     */
+        /* .. or use a secondary index container ?? */
+    for (sp = CONTAINER_FIRST( _fsys_container );
+         sp;
+         sp = CONTAINER_NEXT(  _fsys_container, sp )) {
+
+        if ( !strcmp( path, sp->path ))
+            return sp;
+    }
+
+    /*
+     * Not found...
+     */
+    if ( create_type == NETSNMP_FS_FIND_EXIST ) {
+        DEBUGMSGTL(("fsys:path", "No such filesystem entry\n"));
+        return NULL;
+    }
+
+    /*
+     * ... so let's create a new one
+     */
+    sp = _fsys_create_entry();
+    if ( sp ) {
+        strncpy( sp->path, path, sizeof(sp->path) );
+    }
+    return sp;
+}
+
+
+/*
+ * Retrieve a filesystem entry based on the hardware device,
+ *   (or exported path for remote mounts).
+ * (Optionally) insert a new one into the container.
+ */
+netsnmp_fsys_info *
+netsnmp_fsys_by_device( char *device, int create_type )
+{
+    netsnmp_fsys_info *sp;
+
+    DEBUGMSGTL(("fsys:device", "Get filesystem entry (%s)\n", device));
+
+    /*
+     *  Look through the list for a matching entry
+     */
+        /* .. or use a secondary index container ?? */
+    for (sp = CONTAINER_FIRST( _fsys_container );
+         sp;
+         sp = CONTAINER_NEXT(  _fsys_container, sp )) {
+
+        if ( !strcmp( device, sp->device ))
+            return sp;
+    }
+
+    /*
+     * Not found...
+     */
+    if ( create_type == NETSNMP_FS_FIND_EXIST ) {
+        DEBUGMSGTL(("fsys:device", "No such filesystem entry\n"));
+        return NULL;
+    }
+
+    /*
+     * ... so let's create a new one
+     */
+    sp = _fsys_create_entry();
+    if ( sp ) {
+        strncpy( sp->device, device, sizeof(sp->device) );
+    }
+    return sp;
+}
+
+
+netsnmp_fsys_info *
+_fsys_create_entry( void )
+{
+    netsnmp_fsys_info *sp;
+
+    sp = SNMP_MALLOC_TYPEDEF( netsnmp_fsys_info );
+    if ( sp ) {
+        /*
+         * Set up the index value.
+         *  
+         * All this trouble, just for a simple integer.
+         * Surely there must be a better way?
+         */
+        sp->idx.len  = 1;
+        sp->idx.oids = SNMP_MALLOC_TYPEDEF( oid );
+        sp->idx.oids[0] = ++_fsys_idx;
+    }
+
+    DEBUGMSGTL(("fsys:new", "Create filesystem entry (index = %d\n", _fsys_idx));
+    CONTAINER_INSERT( _fsys_container, sp );
+    return sp;
+}
+
+
+/*
+ *  Convert fsys size information to 1K units
+ *    (attempting to avoid 32-bit overflow!)
+ */
+unsigned int
+_fsys_to_K( int size, int units )
+{
+    int factor = 1;
+
+    if ( units == 0 ) {
+        return 0;    /* XXX */
+    } else if ( units == 1024 ) {
+        return size;
+    } else if ( units == 512 ) {      /* To avoid unnecessary division */
+        return size/2;
+    } else if ( units < 1024 ) {
+        factor = 1024 / units;   /* Assuming power of two */
+        return (size * factor);
+    } else {
+        factor = units / 1024;   /* Assuming multiple of 1K */
+        return (size / factor);
+    }
+}
+
+unsigned int
+netsnmp_fsys_size( netsnmp_fsys_info *f) {
+    if ( !f ) {
+        return 0;
+    }
+    return _fsys_to_K( f->size, f->units );
+}
+
+unsigned int
+netsnmp_fsys_used( netsnmp_fsys_info *f) {
+    if ( !f ) {
+        return 0;
+    }
+    return _fsys_to_K( f->used, f->units );
+}
+
+unsigned int
+netsnmp_fsys_avail( netsnmp_fsys_info *f) {
+    if ( !f ) {
+        return 0;
+    }
+    return _fsys_to_K( f->avail, f->units );
+}
diff -uNr old/agent/mibgroup/hardware/fsys/hw_fsys.h net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/hw_fsys.h
--- old/agent/mibgroup/hardware/fsys/hw_fsys.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/hw_fsys.h	2011-01-19 14:02:44.461482505 +0100
@@ -0,0 +1,2 @@
+void init_fsys(void);
+void shutdown_hw_fsys( void );
diff -uNr old/agent/mibgroup/hardware/fsys/mnttypes.h net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/mnttypes.h
--- old/agent/mibgroup/hardware/fsys/mnttypes.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/mnttypes.h	2011-01-19 14:02:44.464482556 +0100
@@ -0,0 +1,169 @@
+#ifndef _NETSNMP_FSYS_MNTTYPES_H
+#define _NETSNMP_FSYS_MNTTYPES_H
+/*
+ *  Some mounts can map to one of two hrFS types
+ *    (depending on other characteristics of the system)
+ *  Note which should be used *before* defining any
+ *    type tokens which may be missing.
+ */
+
+#if (defined(BerkelyFS) && !defined(MNTTYPE_HFS)) || defined(solaris2)
+#define  _NETSNMP_FS_TYPE_UFS  NETSNMP_FS_TYPE_BERKELEY
+#else
+#define  _NETSNMP_FS_TYPE_UFS  NETSNMP_FS_TYPE_SYSV
+#endif
+
+#ifdef RockRidge
+#define  _NETSNMP_FS_TYPE_CDFS  NETSNMP_FS_TYPE_ROCKRIDGE
+#else
+#define  _NETSNMP_FS_TYPE_CDFS  NETSNMP_FS_TYPE_ISO9660
+#endif
+
+
+/*
+ *  Ensure all recognised filesystem mount type tokens are
+ *    available (even on systems where they're not used)
+ */
+#ifndef MNTTYPE_AFS
+#define MNTTYPE_AFS      "afs"
+#endif
+#ifndef MNTTYPE_CDFS
+#define MNTTYPE_CDFS     "cdfs"
+#endif
+#ifndef MNTTYPE_CD9660
+#define MNTTYPE_CD9660   "cd9660"
+#endif
+#ifndef MNTTYPE_EXT2
+#define MNTTYPE_EXT2     "ext2"
+#endif
+#ifndef MNTTYPE_EXT3
+#define MNTTYPE_EXT3     "ext3"
+#endif
+#ifndef MNTTYPE_EXT4
+#define MNTTYPE_EXT4     "ext4"
+#endif
+#ifndef MNTTYPE_EXT2FS
+#define MNTTYPE_EXT2FS   "ext2fs"
+#endif
+#ifndef MNTTYPE_EXT3FS
+#define MNTTYPE_EXT3FS   "ext3fs"
+#endif
+#ifndef MNTTYPE_EXT4FS
+#define MNTTYPE_EXT4FS   "ext4fs"
+#endif
+#ifndef MNTTYPE_FAT32
+#define MNTTYPE_FAT32    "fat32"
+#endif
+#ifndef MNTTYPE_FFS
+#define MNTTYPE_FFS      "ffs"
+#endif
+#ifndef MNTTYPE_HFS
+#define MNTTYPE_HFS      "hfs"
+#endif
+#ifndef MNTTYPE_HSFS
+#define MNTTYPE_HSFS     "hsfs"
+#endif
+#ifndef MNTTYPE_ISO9660
+#define MNTTYPE_ISO9660  "iso9660"
+#endif
+#ifndef MNTTYPE_MFS
+#define MNTTYPE_MFS      "mfs"
+#endif
+#ifndef MNTTYPE_MSDOS
+#define MNTTYPE_MSDOS    "msdos"
+#endif
+#ifndef MNTTYPE_NCPFS
+#define MNTTYPE_NCPFS    "ncpfs"
+#endif
+#ifndef MNTTYPE_NFS
+#define MNTTYPE_NFS      "nfs"
+#endif
+#ifndef MNTTYPE_NFS3
+#define MNTTYPE_NFS3     "nfs3"
+#endif
+#ifndef MNTTYPE_NFS4
+#define MNTTYPE_NFS4     "nfs4"
+#endif
+#ifndef MNTTYPE_NTFS
+#define MNTTYPE_NTFS     "ntfs"
+#endif
+#ifndef MNTTYPE_PC
+#define MNTTYPE_PC       "pc"
+#endif
+#ifndef MNTTYPE_REISERFS
+#define MNTTYPE_REISERFS "reiserfs"
+#endif
+#ifndef MNTTYPE_SMBFS
+#define MNTTYPE_SMBFS    "smbfs"
+#endif
+#ifndef MNTTYPE_CIFS
+#define MNTTYPE_CIFS     "cifs"
+#endif
+#ifndef MNTTYPE_SYSV
+#define MNTTYPE_SYSV     "sysv"
+#endif
+#ifndef MNTTYPE_UFS
+#define MNTTYPE_UFS      "ufs"
+#endif
+#ifndef MNTTYPE_VFAT
+#define MNTTYPE_VFAT     "vfat"
+#endif
+#ifndef MNTTYPE_GFS
+#define MNTTYPE_GFS      "gfs"
+#endif
+#ifndef MNTTYPE_GFS2
+#define MNTTYPE_GFS2     "gfs2"
+#endif
+
+/*
+ *  File systems to monitor, but not covered by HR-TYPES enumerations
+ */
+#ifndef MNTTYPE_LOFS
+#define MNTTYPE_LOFS     "lofs"
+#endif
+#ifndef MNTTYPE_APP
+#define MNTTYPE_APP      "app"
+#endif
+#ifndef MNTTYPE_MVFS
+#define MNTTYPE_MVFS     "mvfs"
+#endif
+#ifndef MNTTYPE_JFS
+#define MNTTYPE_JFS      "jfs"
+#endif
+#ifndef MNTTYPE_XFS
+#define MNTTYPE_XFS      "xfs"
+#endif
+#ifndef MNTTYPE_NONE
+#define MNTTYPE_NONE     "none"
+#endif
+
+/*
+ *  File systems to skip
+ *    (Probably not strictly needed)
+ */
+#ifndef MNTTYPE_DEVPTS
+#define MNTTYPE_DEVPTS   "devpts"
+#endif
+#ifndef MNTTYPE_IGNORE
+#define MNTTYPE_IGNORE   "ignore"
+#endif
+#ifndef MNTTYPE_PROC
+#define MNTTYPE_PROC     "proc"
+#endif
+#ifndef MNTTYPE_SYSFS
+#define MNTTYPE_SYSFS    "sysfs"
+#endif
+#ifndef MNTTYPE_TMPFS
+#define MNTTYPE_TMPFS    "tmpfs"
+#endif
+#ifndef MNTTYPE_USBFS
+#define MNTTYPE_USBFS    "usbfs"
+#endif
+#ifndef MNTTYPE_BINFMT
+#define MNTTYPE_BINFMT   "binfmt_misc"
+#endif
+#ifndef MNTTYPE_RPCPIPE
+#define MNTTYPE_RPCPIPE  "rpc_pipefs"
+#endif
+
+#endif /* _NETSNMP_FSYS_MNTTYPES_H */
diff -uNr old/agent/mibgroup/hardware/fsys/mounts.h net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/mounts.h
--- old/agent/mibgroup/hardware/fsys/mounts.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys/mounts.h	2011-01-19 14:02:44.469482644 +0100
@@ -0,0 +1,168 @@
+#ifndef _NETSNMP_FSYS_MOUNTS_H
+#define _NETSNMP_FSYS_MOUNTS_H
+/*
+ *  Some mounts can map to one of two hrFS types
+ *    (depending on other characteristics of the system)
+ *  Note which should be used *before* defining any
+ *    type tokens which may be missing.
+ */
+
+/*
+#if (defined(BerkelyFS) && !defined(MNTTYPE_HFS)) || defined(solaris2)
+#define  _NETSNMP_FS_TYPE_UFS  NETSNMP_FS_TYPE_BERKELEY
+#else
+#define  _NETSNMP_FS_TYPE_UFS  NETSNMP_FS_TYPE_SYSV
+#endif
+
+#ifdef RockRidge
+#define  _NETSNMP_FS_TYPE_CDFS  NETSNMP_FS_TYPE_ROCKRIDGE
+#else
+#define  _NETSNMP_FS_TYPE_CDFS  NETSNMP_FS_TYPE_ISO9660
+#endif
+ */
+
+
+/*
+ *  Ensure all recognised filesystem mount type tokens are
+ *    available (even on systems where they're not used)
+ */
+#ifndef MOUNT_FFS
+#define MOUNT_FFS    "ffs"
+#endif
+#ifndef MOUNT_NFS
+#define MOUNT_NFS    "nfs"
+#endif
+#ifndef MOUNT_MFS
+#define MOUNT_MFS    "mfs"
+#endif
+#ifndef MOUNT_MSDOS
+#define MOUNT_MSDOS  "msdos"
+#endif
+#ifndef MOUNT_MSDOSFS
+#define MOUNT_MSDOSFS "msdosfs"
+#endif
+#ifndef MOUNT_AFS
+#define MOUNT_AFS    "afs"
+#endif
+#ifndef MOUNT_CD9660
+#define MOUNT_CD9660 "cd9660"
+#endif
+#ifndef MOUNT_EXT2FS
+#define MOUNT_EXT2FS "ext2fs"
+#endif
+#ifndef MOUNT_NTFS
+#define MOUNT_NTFS   "ntfs"
+#endif
+#ifndef MOUNT_UFS
+#define MOUNT_UFS    "ufs"
+#endif
+#ifndef MNTTYPE_JFS
+#define MNTTYPE_JFS      "jfs"
+#endif
+#ifndef MNTTYPE_XFS
+#define MNTTYPE_XFS      "xfs"
+#endif
+#ifndef MNTTYPE_NONE
+#define MNTTYPE_NONE     "none"
+#endif
+
+/*
+#ifndef MNTTYPE_AFS
+#define MNTTYPE_AFS      "afs"
+#endif
+#ifndef MNTTYPE_CDFS
+#define MNTTYPE_CDFS     "cdfs"
+#endif
+#ifndef MNTTYPE_CD9660
+#define MNTTYPE_CD9660   "cd9660"
+#endif
+#ifndef MNTTYPE_EXT2
+#define MNTTYPE_EXT2     "ext2"
+#endif
+#ifndef MNTTYPE_EXT3
+#define MNTTYPE_EXT3     "ext3"
+#endif
+#ifndef MNTTYPE_EXT2FS
+#define MNTTYPE_EXT2FS   "ext2fs"
+#endif
+#ifndef MNTTYPE_EXT3FS
+#define MNTTYPE_EXT3FS   "ext3fs"
+#endif
+#ifndef MNTTYPE_FAT32
+#define MNTTYPE_FAT32    "fat32"
+#endif
+#ifndef MNTTYPE_FFS
+#define MNTTYPE_FFS      "ffs"
+#endif
+#ifndef MNTTYPE_HFS
+#define MNTTYPE_HFS      "hfs"
+#endif
+#ifndef MNTTYPE_HSFS
+#define MNTTYPE_HSFS     "hsfs"
+#endif
+#ifndef MNTTYPE_ISO9660
+#define MNTTYPE_ISO9660  "iso9660"
+#endif
+#ifndef MNTTYPE_MFS
+#define MNTTYPE_MFS      "mfs"
+#endif
+#ifndef MNTTYPE_MSDOS
+#define MNTTYPE_MSDOS    "msdos"
+#endif
+#ifndef MNTTYPE_NCPFS
+#define MNTTYPE_NCPFS    "ncpfs"
+#endif
+#ifndef MNTTYPE_NFS
+#define MNTTYPE_NFS      "nfs"
+#endif
+#ifndef MNTTYPE_NFS3
+#define MNTTYPE_NFS3     "nfs3"
+#endif
+#ifndef MNTTYPE_NTFS
+#define MNTTYPE_NTFS     "ntfs"
+#endif
+#ifndef MNTTYPE_PC
+#define MNTTYPE_PC       "pc"
+#endif
+#ifndef MNTTYPE_REISERFS
+#define MNTTYPE_REISERFS "reiserfs"
+#endif
+#ifndef MNTTYPE_SMBFS
+#define MNTTYPE_SMBFS    "smbfs"
+#endif
+#ifndef MNTTYPE_SYSV
+#define MNTTYPE_SYSV     "sysv"
+#endif
+#ifndef MNTTYPE_UFS
+#define MNTTYPE_UFS      "ufs"
+#endif
+#ifndef MNTTYPE_VFAT
+#define MNTTYPE_VFAT     "vfat"
+#endif
+*/
+
+/*
+ *  File systems to skip
+ */
+/*
+#ifndef MNTTYPE_DEVPTS
+#define MNTTYPE_DEVPTS   "devpts"
+#endif
+#ifndef MNTTYPE_IGNORE
+#define MNTTYPE_IGNORE   "ignore"
+#endif
+#ifndef MNTTYPE_PROC
+#define MNTTYPE_PROC     "proc"
+#endif
+#ifndef MNTTYPE_SYSFS
+#define MNTTYPE_SYSFS    "sysfs"
+#endif
+#ifndef MNTTYPE_TMPFS
+#define MNTTYPE_TMPFS    "tmpfs"
+#endif
+#ifndef MNTTYPE_USBFS
+#define MNTTYPE_USBFS    "usbfs"
+#endif
+*/
+
+#endif /* _NETSNMP_FSYS_MOUNTS_H */
diff -uNr old/agent/mibgroup/hardware/fsys.h net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys.h
--- old/agent/mibgroup/hardware/fsys.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/fsys.h	2011-01-19 14:02:44.470482660 +0100
@@ -0,0 +1,8 @@
+config_require(hardware/fsys/hw_fsys)
+#if defined(aix4) || defined(aix5) || defined(aix6)
+config_require(hardware/fsys/fsys_mntctl)
+#elif defined(HAVE_GETVFSSTAT) || defined(HAVE_GETFSSTAT)
+config_require(hardware/fsys/fsys_getfsstat)
+#else
+config_require(hardware/fsys/fsys_mntent)
+#endif
diff -uNr old/agent/mibgroup/hardware/memory/hw_mem.c net-snmp-5.3.2.2/agent/mibgroup/hardware/memory/hw_mem.c
--- old/agent/mibgroup/hardware/memory/hw_mem.c	2006-03-09 19:40:26.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/memory/hw_mem.c	2011-01-19 14:02:44.471482678 +0100
@@ -9,7 +9,9 @@
 netsnmp_cache       *_mem_cache = NULL;
 
 void init_hw_mem( void ) {
-    _mem_cache = netsnmp_cache_create( 5, netsnmp_mem_arch_load, NULL, NULL, 0);
+    oid nsMemory[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 31 };
+    _mem_cache = netsnmp_cache_create( 5, netsnmp_mem_arch_load, NULL,
+                                          nsMemory, OID_LENGTH(nsMemory));
 }
 
 
@@ -74,6 +76,16 @@
     return NULL;  /* Shouldn't happen! */
 }
 
+netsnmp_memory_info *netsnmp_memory_get_next_byIdx( int idx, int type ) {
+    netsnmp_memory_info *mem;
+
+    for ( mem=_mem_head; mem; mem=mem->next )
+        if (mem->type == type && mem->idx > idx)    /* Or treat as bits? */
+            return mem;
+    return NULL;
+}
+
+
 
 netsnmp_cache *netsnmp_memory_get_cache( void ) {
     return _mem_cache;
diff -uNr old/agent/mibgroup/hardware/memory/memory_linux.c net-snmp-5.3.2.2/agent/mibgroup/hardware/memory/memory_linux.c
--- old/agent/mibgroup/hardware/memory/memory_linux.c	2005-10-07 00:49:23.000000000 +0200
+++ net-snmp-5.3.2.2/agent/mibgroup/hardware/memory/memory_linux.c	2011-01-19 14:02:44.472482698 +0100
@@ -10,8 +10,11 @@
  * Try to use an initial size that will cover default cases. We aren't talking
  * about huge files, so why fiddle about with reallocs?
  * I checked /proc/meminfo sizes on 3 different systems: 598, 644, 654
+ * 
+ * On newer systems, the size is up to around 930 (2.6.27 kernel)
+ *   or 1160  (2.6.28 kernel)
  */
-#define MEMINFO_INIT_SIZE   768
+#define MEMINFO_INIT_SIZE   1279
 #define MEMINFO_STEP_SIZE   256
 #define MEMINFO_FILE   "/proc/meminfo"
 
@@ -31,20 +34,23 @@
 
     netsnmp_memory_info *mem;
 
+    /*
+     * Retrieve the memory information from the underlying O/S...
+     */
     if ((statfd = open(MEMINFO_FILE, O_RDONLY, 0)) == -1) {
         snmp_log_perror(MEMINFO_FILE);
         return -1;
     }
     if (bsize == 0) {
         bsize = MEMINFO_INIT_SIZE;
-        buff = malloc(bsize);
+        buff = malloc(bsize+1);
         if (NULL == buff) {
             snmp_log(LOG_ERR, "malloc failed\n");
             return -1;
         }
     }
     while ((bytes_read = read(statfd, buff, bsize)) == bsize) {
-        b = realloc(buff, bsize + MEMINFO_STEP_SIZE);
+        b = realloc(buff, bsize + MEMINFO_STEP_SIZE + 1);
         if (NULL == b) {
             snmp_log(LOG_ERR, "malloc failed\n");
             return -1;
@@ -62,12 +68,13 @@
     close(statfd);
     if (bytes_read <= 0) {
         snmp_log_perror(MEMINFO_FILE);
+    } else {
+        buff[bytes_read] = '\0';
     }
 
-        /*
-         * Overall Memory statistics
-         */
-
+    /*
+     * ... parse this into a more useable form...
+     */
     b = strstr(buff, "MemTotal: ");
     if (b) 
         sscanf(b, "MemTotal: %lu", &memtotal);
@@ -118,41 +125,88 @@
         if (first)
             snmp_log(LOG_ERR, "No SwapFree line in /proc/meminfo\n");
     }
+    first = 0;
 
 
-    mem = netsnmp_memory_get_byIdx( -1, 1 );  /* Memory info */
+    /*
+     * ... and save this in a standard form.
+     */
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 );
     if (!mem) {
-        snmp_log_perror("No Memory info entry");
+        snmp_log_perror("No Physical Memory info entry");
     } else {
+        if (!mem->descr)
+             mem->descr = strdup("Physical memory");
         mem->units = 1024;
-        mem->size = memtotal;
-        mem->free = memfree;
-        mem->other = memshared;
+        mem->size  = memtotal;
+        mem->free  = memfree;
+        mem->other = -1;
     }
 
-    mem = netsnmp_memory_get_byIdx( -2, 1 );  /* Swap info */
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 );
     if (!mem) {
-        snmp_log_perror("No Swap info entry");
+        snmp_log_perror("No Virtual Memory info entry");
     } else {
+        if (!mem->descr)
+             mem->descr = strdup("Virtual memory");
         mem->units = 1024;
-        mem->size = swaptotal;
-        mem->free = swapfree;
+        mem->size  = memtotal+swaptotal;
+        mem->free  = memfree +swapfree;
+        mem->other = -1;
     }
 
-    mem = netsnmp_memory_get_byIdx( -3, 1 );  /* Buffer info */
+   /* Shared memory is not reported by Linux 2.6 kernel */
+   if (0 != netsnmp_os_prematch("Linux","2.6")) {
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 1 );
     if (!mem) {
-        snmp_log_perror("No Buffer info entry");
+        snmp_log_perror("No Shared Memory info entry");
     } else {
+        if (!mem->descr)
+             mem->descr = strdup("Shared memory");
         mem->units = 1024;
-        mem->size = buffers;
-        mem->other = cached;
+        mem->size  = memshared;
+        mem->free  = -1;
+        mem->other = -1;
     }
+   }
 
-    /*
-     * XXX - TODO: extract individual memory/swap information
-     *    (Into separate netsnmp_memory_info data structures)
-     */
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 1 );
+    if (!mem) {
+        snmp_log_perror("No Cached Memory info entry");
+    } else {
+        if (!mem->descr)
+             mem->descr = strdup("Cached memory");
+        mem->units = 1024;
+        mem->size  = cached;
+        mem->free  = 0;     /* Report cached size/used as equal */
+        mem->other = -1;
+    }
+
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 );
+    if (!mem) {
+        snmp_log_perror("No Swap info entry");
+    } else {
+        if (!mem->descr)
+             mem->descr = strdup("Swap space");
+        mem->units = 1024;
+        mem->size  = swaptotal;
+        mem->free  = swapfree;
+        mem->other = -1;
+    }
+
+    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 1 );
+    if (!mem) {
+        snmp_log_perror("No Buffer, etc info entry");
+    } else {
+        if (!mem->descr)
+             mem->descr = strdup("Memory buffers");
+        mem->units = 1024;
+        mem->size  = memtotal;  /* Traditionally we've always regarded
+                                   all memory as potentially available
+                                   for memory buffers. */
+        mem->free  = memtotal - buffers;
+        mem->other = -1;
+    }
 
-    first = 0;
     return 0;
 }
diff -uNr old/agent/mibgroup/host/hrh_filesys.c net-snmp-5.3.2.2/agent/mibgroup/host/hrh_filesys.c
--- old/agent/mibgroup/host/hrh_filesys.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/host/hrh_filesys.c	2011-01-19 14:02:44.473482718 +0100
@@ -0,0 +1,427 @@
+/*
+ *  Host Resources MIB - File System device group implementation (HAL rewrite) - hrh_filesys.c
+ *
+ */
+/* Portions of this file are subject to the following copyright(s).  See
+ * the Net-SNMP's COPYING file for more details and other copyrights
+ * that may apply:
+ */
+/*
+ * Portions of this file are copyrighted by:
+ * 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/agent/hardware/memory.h>
+#include <net-snmp/agent/hardware/fsys.h>
+#include "host_res.h"
+#include "hrh_filesys.h"
+#include "hrh_storage.h"
+#include "hr_disk.h"
+#include <net-snmp/utilities.h>
+
+#if HAVE_MNTENT_H
+#include <mntent.h>
+#endif
+#if HAVE_SYS_MNTENT_H
+#include <sys/mntent.h>
+#endif
+#if HAVE_SYS_MNTTAB_H
+#include <sys/mnttab.h>
+#endif
+#if HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#if HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+
+#include <ctype.h>
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if defined(aix4) || defined(aix5) || defined(aix6)
+#include <sys/mntctl.h>
+#include <sys/vmount.h>
+#include <sys/statfs.h>
+#endif
+
+
+#define HRFS_MONOTONICALLY_INCREASING
+
+        /*********************
+	 *
+	 *  Kernel & interface information,
+	 *   and internal forward declarations
+	 *
+	 *********************/
+netsnmp_fsys_info *HRFS_entry;
+
+#define	FULL_DUMP	0
+#define	PART_DUMP	1
+
+extern void     Init_HR_FileSys(void);
+extern int      Get_Next_HR_FileSys(void);
+char           *cook_device(char *);
+static u_char  *when_dumped(char *filesys, int level, size_t * length);
+int             header_hrhfilesys(struct variable *, oid *, size_t *, int,
+                                 size_t *, WriteMethod **);
+
+        /*********************
+	 *
+	 *  Initialisation & common implementation functions
+	 *
+	 *********************/
+
+#define HRFSYS_INDEX		1
+#define HRFSYS_MOUNT		2
+#define HRFSYS_RMOUNT		3
+#define HRFSYS_TYPE		4
+#define HRFSYS_ACCESS		5
+#define HRFSYS_BOOT		6
+#define HRFSYS_STOREIDX		7
+#define HRFSYS_FULLDUMP		8
+#define HRFSYS_PARTDUMP		9
+
+struct variable4 hrfsys_variables[] = {
+    {HRFSYS_INDEX,    ASN_INTEGER,   RONLY,
+     var_hrhfilesys, 2, {1, 1}},
+    {HRFSYS_MOUNT,    ASN_OCTET_STR, RONLY,
+     var_hrhfilesys, 2, {1, 2}},
+    {HRFSYS_RMOUNT,   ASN_OCTET_STR, RONLY,
+     var_hrhfilesys, 2, {1, 3}},
+    {HRFSYS_TYPE,     ASN_OBJECT_ID, RONLY,
+     var_hrhfilesys, 2, {1, 4}},
+    {HRFSYS_ACCESS,   ASN_INTEGER,   RONLY,
+     var_hrhfilesys, 2, {1, 5}},
+    {HRFSYS_BOOT,     ASN_INTEGER,   RONLY,
+     var_hrhfilesys, 2, {1, 6}},
+    {HRFSYS_STOREIDX, ASN_INTEGER,   RONLY,
+     var_hrhfilesys, 2, {1, 7}},
+    {HRFSYS_FULLDUMP, ASN_OCTET_STR, RONLY,
+     var_hrhfilesys, 2, {1, 8}},
+    {HRFSYS_PARTDUMP, ASN_OCTET_STR, RONLY,
+     var_hrhfilesys, 2, {1, 9}},
+};
+oid             hrfsys_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 8 };
+
+void
+init_hrh_filesys(void)
+{
+    REGISTER_MIB("host/hr_filesys", hrfsys_variables, variable4,
+                 hrfsys_variables_oid);
+}
+
+/*
+ * header_hrhfilesys(...
+ * Arguments:
+ * vp     IN      - pointer to variable entry that points here
+ * name    IN/OUT  - IN/name requested, OUT/name found
+ * length  IN/OUT  - length of IN/OUT oid's 
+ * exact   IN      - TRUE if an exact match was requested
+ * var_len OUT     - length of variable or 0 if function returned
+ * write_method
+ * 
+ */
+
+int
+header_hrhfilesys(struct variable *vp,
+                 oid * name,
+                 size_t * length,
+                 int exact, size_t * var_len, WriteMethod ** write_method)
+{
+#define HRFSYS_ENTRY_NAME_LENGTH	11
+    oid             newname[MAX_OID_LEN];
+    int             fsys_idx, LowIndex = -1;
+    int             result;
+
+    DEBUGMSGTL(("host/hr_filesys", "var_hrhfilesys: "));
+    DEBUGMSGOID(("host/hr_filesys", name, *length));
+    DEBUGMSG(("host/hr_filesys", " %d\n", exact));
+
+    memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
+    /*
+     * Find "next" file system entry 
+     */
+
+    Init_HR_FileSys();
+    for (;;) {
+        fsys_idx = Get_Next_HR_FileSys();
+        if (fsys_idx == -1)
+            break;
+        newname[HRFSYS_ENTRY_NAME_LENGTH] = fsys_idx;
+        result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
+        if (exact && (result == 0)) {
+            LowIndex = fsys_idx;
+            break;
+        }
+        if ((!exact && (result < 0)) &&
+            (LowIndex == -1 || fsys_idx < LowIndex)) {
+            LowIndex = fsys_idx;
+#ifdef HRFS_MONOTONICALLY_INCREASING
+            break;
+#endif
+        }
+    }
+
+    if (LowIndex == -1) {
+        DEBUGMSGTL(("host/hr_filesys", "... index out of range\n"));
+        return (MATCH_FAILED);
+    }
+
+    memcpy((char *) name, (char *) newname,
+           (vp->namelen + 1) * sizeof(oid));
+    *length = vp->namelen + 1;
+    *write_method = 0;
+    *var_len = sizeof(long);    /* default to 'long' results */
+
+    DEBUGMSGTL(("host/hr_filesys", "... get filesys stats "));
+    DEBUGMSGOID(("host/hr_filesys", name, *length));
+    DEBUGMSG(("host/hr_filesys", "\n"));
+
+    return LowIndex;
+}
+
+
+oid             fsys_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 3, 9, 1 };     /* hrFSOther */
+int             fsys_type_len =
+    sizeof(fsys_type_id) / sizeof(fsys_type_id[0]);
+
+
+
+        /*********************
+	 *
+	 *  System specific implementation functions
+	 *
+	 *********************/
+
+
+u_char         *
+var_hrhfilesys(struct variable *vp,
+              oid * name,
+              size_t * length,
+              int exact, size_t * var_len, WriteMethod ** write_method)
+{
+    int             fsys_idx;
+    static char     string[1024];
+
+    fsys_idx =
+        header_hrhfilesys(vp, name, length, exact, var_len, write_method);
+    if (fsys_idx == MATCH_FAILED)
+        return NULL;
+
+    switch (vp->magic) {
+    case HRFSYS_INDEX:
+        long_return = fsys_idx;
+        return (u_char *) & long_return;
+    case HRFSYS_MOUNT:
+        snprintf(string, sizeof(string), HRFS_entry->path);
+        string[ sizeof(string)-1 ] = 0;
+        *var_len = strlen(string);
+        return (u_char *) string;
+    case HRFSYS_RMOUNT:
+        if (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOTE) {
+            snprintf(string, sizeof(string), HRFS_entry->device);
+            string[ sizeof(string)-1 ] = 0;
+        } else
+            string[0] = '\0';
+        *var_len = strlen(string);
+        return (u_char *) string;
+
+    case HRFSYS_TYPE:
+        fsys_type_id[fsys_type_len - 1] = 
+            (HRFS_entry->type > _NETSNMP_FS_TYPE_LOCAL ?
+                                 NETSNMP_FS_TYPE_OTHER : HRFS_entry->type);
+        *var_len = sizeof(fsys_type_id);
+        return (u_char *) fsys_type_id;
+
+    case HRFSYS_ACCESS:
+	long_return = HRFS_entry->flags & NETSNMP_FS_FLAG_RONLY ? 2 : 1;
+        return (u_char *) & long_return;
+    case HRFSYS_BOOT:
+	long_return = HRFS_entry->flags & NETSNMP_FS_FLAG_BOOTABLE ? 1 : 2;
+        return (u_char *) & long_return;
+    case HRFSYS_STOREIDX:
+        long_return = fsys_idx + NETSNMP_MEM_TYPE_MAX;
+        return (u_char *) & long_return;
+    case HRFSYS_FULLDUMP:
+        return when_dumped(HRFS_entry->path, FULL_DUMP, var_len);
+    case HRFSYS_PARTDUMP:
+        return when_dumped(HRFS_entry->path, PART_DUMP, var_len);
+    default:
+        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrhfilesys\n",
+                    vp->magic));
+    }
+    return NULL;
+}
+
+
+        /*********************
+	 *
+	 *  Internal implementation functions
+	 *
+	 *********************/
+static int      HRFS_index;
+
+void
+Init_HR_FileSys(void)
+{
+    netsnmp_cache *c = netsnmp_fsys_get_cache();
+    netsnmp_cache_check_and_reload( c );
+
+    HRFS_entry = NULL;
+}
+
+int
+Get_Next_HR_FileSys(void)
+{
+    if ( HRFS_entry ) {
+        HRFS_entry = netsnmp_fsys_get_next( HRFS_entry );
+    } else {     
+        HRFS_entry = netsnmp_fsys_get_first();
+    }
+    /* Skip "inactive" entries */
+    while ( HRFS_entry && !(HRFS_entry->flags & NETSNMP_FS_FLAG_ACTIVE))
+        HRFS_entry = netsnmp_fsys_get_next( HRFS_entry );
+
+    return (HRFS_entry ? HRFS_entry->idx.oids[0] : -1 );
+}
+
+
+
+static u_char  *
+when_dumped(char *filesys, int level, size_t * length)
+{
+    time_t          dumpdate = 0, tmp;
+    FILE           *dump_fp;
+    char            line[1024];
+    char           *cp1, *cp2, *cp3;
+
+    /*
+     * Look for the relevent entries in /etc/dumpdates
+     *
+     * This is complicated by the fact that disks are
+     *   mounted using block devices, but dumps are
+     *   done via the raw character devices.
+     * Thus the device names in /etc/dumpdates and
+     *   /etc/mnttab don't match.
+     *   These comparisons are therefore made using the
+     *   final portion of the device name only.
+     */
+
+    if (*filesys == '\0')       /* No filesystem name? */
+        return date_n_time(NULL, length);
+    cp1 = strrchr(filesys, '/');        /* Find the last element of the current FS */
+
+    if (cp1 == NULL)
+        cp1 = filesys;
+
+    if ((dump_fp = fopen("/etc/dumpdates", "r")) == NULL)
+        return date_n_time(NULL, length);
+
+    while (fgets(line, sizeof(line), dump_fp) != NULL) {
+        cp2 = strchr(line, ' ');        /* Start by looking at the device name only */
+        if (cp2 != NULL) {
+            *cp2 = '\0';
+            cp3 = strrchr(line, '/');   /* and find the last element */
+            if (cp3 == NULL)
+                cp3 = line;
+
+            if (strcmp(cp1, cp3) != 0)  /* Wrong FS */
+                continue;
+
+            ++cp2;
+            while (isspace(*cp2))
+                ++cp2;          /* Now find the dump level */
+
+            if (level == FULL_DUMP) {
+                if (*(cp2++) != '0')
+                    continue;   /* Not interested in partial dumps */
+                while (isspace(*cp2))
+                    ++cp2;
+
+                dumpdate = ctime_to_timet(cp2);
+                fclose(dump_fp);
+                return date_n_time(&dumpdate, length);
+            } else {            /* Partial Dump */
+                if (*(cp2++) == '0')
+                    continue;   /* Not interested in full dumps */
+                while (isspace(*cp2))
+                    ++cp2;
+
+                tmp = ctime_to_timet(cp2);
+                if (tmp > dumpdate)
+                    dumpdate = tmp;     /* Remember the 'latest' partial dump */
+            }
+        }
+    }
+
+    fclose(dump_fp);
+
+    return date_n_time(&dumpdate, length);
+}
+
+
+#define RAW_DEVICE_PREFIX	"/dev/rdsk"
+#define COOKED_DEVICE_PREFIX	"/dev/dsk"
+
+char           *
+cook_device(char *dev)
+{
+    static char     cooked_dev[SNMP_MAXPATH+1];
+
+    if (!strncmp(dev, RAW_DEVICE_PREFIX, strlen(RAW_DEVICE_PREFIX))) {
+        strncpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev)-1);
+        cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
+        strncat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
+                sizeof(cooked_dev)-strlen(cooked_dev)-1);
+        cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
+    } else {
+        strncpy(cooked_dev, dev, sizeof(cooked_dev)-1);
+        cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
+    }
+
+    return (cooked_dev);
+}
+
+
+int
+Get_FSIndex(char *dev)
+{
+    netsnmp_fsys_info *fsys;
+
+    fsys = netsnmp_fsys_by_device( dev, NETSNMP_FS_FIND_EXIST );
+    return (fsys ? fsys->idx.oids[0] : -1 );
+}
+
+long
+Get_FSSize(char *dev)
+{
+    netsnmp_fsys_info *fsys;
+
+    fsys = netsnmp_fsys_by_device( dev, NETSNMP_FS_FIND_EXIST );
+    if ( fsys )       
+        return netsnmp_fsys_size( fsys );
+    else
+        return -1;
+}
+
+int
+Check_HR_FileSys_NFS (void)
+{
+    return (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOTE) ? 1 : 0;
+}
diff -uNr old/agent/mibgroup/host/hrh_filesys.h net-snmp-5.3.2.2/agent/mibgroup/host/hrh_filesys.h
--- old/agent/mibgroup/host/hrh_filesys.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/host/hrh_filesys.h	2011-01-19 14:02:44.505483279 +0100
@@ -0,0 +1,19 @@
+/*
+ *  Host Resources MIB - file system device group interface (HAL rewrite) - hrh_filesys.h
+ *
+ */
+#ifndef _MIBGROUP_HRFSYS_H
+#define _MIBGROUP_HRFSYS_H
+
+extern void     init_hrh_filesys(void);
+extern void     Init_HR_FileSys(void);
+extern FindVarMethod var_hrhfilesys;
+extern int      Get_Next_HR_FileSys(void);
+extern int      Check_HR_FileSys_NFS(void);
+
+extern int      Get_FSIndex(char *);
+extern long     Get_FSSize(char *);     /* Temporary */
+
+config_exclude( host/hr_filesys )
+
+#endif                          /* _MIBGROUP_HRFSYS_H */
diff -uNr old/agent/mibgroup/host/hrh_storage.c net-snmp-5.3.2.2/agent/mibgroup/host/hrh_storage.c
--- old/agent/mibgroup/host/hrh_storage.c	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/host/hrh_storage.c	2011-01-19 14:02:44.507483316 +0100
@@ -0,0 +1,505 @@
+/*
+ *  Host Resources MIB - storage group implementation - hr_storage.c
+ *
+ */
+
+#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/agent/hardware/memory.h>
+#include <net-snmp/agent/hardware/fsys.h>
+#include "host_res.h"
+#include "hrh_filesys.h"
+#include "hrh_storage.h"
+#include "hr_disk.h"
+#include <net-snmp/utilities.h>
+
+
+#include <sys/types.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if TIME_WITH_SYS_TIME
+# ifdef WIN32
+#  include <windows.h>
+#  include <errno.h>
+#  include <sys/timeb.h>
+# else
+#  include <sys/time.h>
+# endif
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if HAVE_STRING_H
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#include <net-snmp/output_api.h>
+
+#include <net-snmp/agent/agent_read_config.h>
+#include <net-snmp/library/read_config.h>
+
+#define HRSTORE_MONOTONICALLY_INCREASING
+
+        /*********************
+	 *
+	 *  Kernel & interface information,
+	 *   and internal forward declarations
+	 *
+	 *********************/
+
+
+extern netsnmp_fsys_info *HRFS_entry;
+
+static void parse_storage_config(const char *, char *);
+
+        /*********************
+	 *
+	 *  Initialisation & common implementation functions
+	 *
+	 *********************/
+int             Get_Next_HR_Store(void);
+void            Init_HR_Store(void);
+int             header_hrstore(struct variable *, oid *, size_t *, int,
+                               size_t *, WriteMethod **);
+void*           header_hrstoreEntry(struct variable *, oid *, size_t *,
+                                    int, size_t *, WriteMethod **);
+Netsnmp_Node_Handler handle_memsize;
+
+
+#define	HRSTORE_MEMSIZE		1
+#define	HRSTORE_INDEX		2
+#define	HRSTORE_TYPE		3
+#define	HRSTORE_DESCR		4
+#define	HRSTORE_UNITS		5
+#define	HRSTORE_SIZE		6
+#define	HRSTORE_USED		7
+#define	HRSTORE_FAILS		8
+
+struct variable2 hrstore_variables[] = {
+    {HRSTORE_INDEX, ASN_INTEGER, RONLY,
+     var_hrstore, 1, {1}},
+    {HRSTORE_TYPE, ASN_OBJECT_ID, RONLY,
+     var_hrstore, 1, {2}},
+    {HRSTORE_DESCR, ASN_OCTET_STR, RONLY,
+     var_hrstore, 1, {3}},
+    {HRSTORE_UNITS, ASN_INTEGER, RONLY,
+     var_hrstore, 1, {4}},
+    {HRSTORE_SIZE, ASN_INTEGER, RONLY,
+     var_hrstore, 1, {5}},
+    {HRSTORE_USED, ASN_INTEGER, RONLY,
+     var_hrstore, 1, {6}},
+    {HRSTORE_FAILS, ASN_COUNTER, RONLY,
+     var_hrstore, 1, {7}}
+};
+oid             hrstore_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2 };
+oid             hrMemorySize_oid[]   = { 1, 3, 6, 1, 2, 1, 25, 2, 2 };
+oid             hrStorageTable_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2, 3, 1 };
+
+
+void
+init_hrh_storage(void)
+{
+    char *appname;
+
+    netsnmp_register_scalar(
+        netsnmp_create_handler_registration("host/hrMemorySize", handle_memsize,
+                           hrMemorySize_oid, OID_LENGTH(hrMemorySize_oid),
+                                             HANDLER_CAN_RONLY));
+    REGISTER_MIB("host/hr_storage", hrstore_variables, variable2,
+                 hrStorageTable_oid);
+
+    appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+                                    NETSNMP_DS_LIB_APPTYPE);
+    netsnmp_ds_register_config(ASN_BOOLEAN, appname, "skipNFSInHostResources", 
+			       NETSNMP_DS_APPLICATION_ID,
+			       NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES);
+
+    snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL,
+	"1 | 2\t\t(1 = enable, 2 = disable)");
+}
+
+static int storageUseNFS = 1;	/* Default to reporting NFS mounts as NetworkDisk */
+
+static void
+parse_storage_config(const char *token, char *cptr)
+{
+    char *val;
+    int ival;
+    char *st;
+
+    val = strtok_r(cptr, " \t", &st);
+    if (!val) {
+        config_perror("Missing FLAG parameter in storageUseNFS");
+        return;
+    }
+    ival = atoi(val);
+    if (ival < 1 || ival > 2) {
+        config_perror("storageUseNFS must be 1 or 2");
+        return;
+    }
+    storageUseNFS = (ival == 1) ? 1 : 0;
+}
+
+/*
+ * header_hrstoreEntry(...
+ * Arguments:
+ * vp     IN      - pointer to variable entry that points here
+ * name    IN/OUT  - IN/name requested, OUT/name found
+ * length  IN/OUT  - length of IN/OUT oid's 
+ * exact   IN      - TRUE if an exact match was requested
+ * var_len OUT     - length of variable or 0 if function returned
+ * write_method
+ * 
+ */
+
+void *
+header_hrstoreEntry(struct variable *vp,
+                    oid * name,
+                    size_t * length,
+                    int exact,
+                    size_t * var_len, WriteMethod ** write_method)
+{
+#define HRSTORE_ENTRY_NAME_LENGTH	11
+    oid             newname[MAX_OID_LEN];
+    int             storage_idx, LowIndex = -1;
+    int             result;
+    int                  idx = -1;
+    netsnmp_memory_info *mem  = NULL;
+
+    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: request "));
+    DEBUGMSGOID(("host/hr_storage", name, *length));
+    DEBUGMSG(("host/hr_storage", " exact=%d\n", exact));
+
+    memcpy((char *) newname, (char *) vp->name,
+           (int) vp->namelen * sizeof(oid));
+    result = snmp_oid_compare(name, *length, vp->name, vp->namelen);
+
+    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: compare "));
+    DEBUGMSGOID(("host/hr_storage", vp->name, vp->namelen));
+    DEBUGMSG(("host/hr_storage", " => %d\n", result));
+
+
+    if (result < 0 ||
+        *length <= HRSTORE_ENTRY_NAME_LENGTH ) {
+       /*
+        * Requested OID too early or too short to refer
+        *   to a valid row (for the current column object).
+        * GET requests should fail, GETNEXT requests
+        *   should use the first row.
+        */
+        if ( exact )
+            return NULL;
+        netsnmp_memory_load();
+        mem = netsnmp_memory_get_first( 0 );
+    }
+    else {
+        /*
+         * Otherwise, retrieve the requested
+         *  (or following) row as appropriate.
+         */
+        if ( exact && *length > HRSTORE_ENTRY_NAME_LENGTH+1 )
+            return NULL;   /* Too long for a valid instance */
+        idx = name[ HRSTORE_ENTRY_NAME_LENGTH ];
+        if ( idx < NETSNMP_MEM_TYPE_MAX ) {
+            netsnmp_memory_load();
+            mem = ( exact ? netsnmp_memory_get_byIdx( idx, 0 ) :
+                       netsnmp_memory_get_next_byIdx( idx, 0 ));
+        }
+    }
+
+    /*
+     * If this matched a memory-based entry, then
+     *    update the OID parameter(s) for GETNEXT requests.
+     */
+    if ( mem ) {
+        if ( !exact ) {
+            newname[ HRSTORE_ENTRY_NAME_LENGTH ] = mem->idx;
+            memcpy((char *) name, (char *) newname,
+                   ((int) vp->namelen + 1) * sizeof(oid));
+            *length = vp->namelen + 1;
+        }
+    }
+    /*
+     * If this didn't match a memory-based entry,
+     *   then consider the disk-based storage.
+     */
+    else {
+        Init_HR_Store();
+        for (;;) {
+            storage_idx = Get_Next_HR_Store();
+            DEBUGMSG(("host/hr_storage", "(index %d ....", storage_idx));
+            if (storage_idx == -1)
+                break;
+            newname[HRSTORE_ENTRY_NAME_LENGTH] = storage_idx;
+            DEBUGMSGOID(("host/hr_storage", newname, *length));
+            DEBUGMSG(("host/hr_storage", "\n"));
+            result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
+            if (exact && (result == 0)) {
+                LowIndex = storage_idx;
+                /*
+                 * Save storage status information 
+                 */
+                break;
+            }
+            if ((!exact && (result < 0)) &&
+                (LowIndex == -1 || storage_idx < LowIndex)) {
+                LowIndex = storage_idx;
+                /*
+                 * Save storage status information 
+                 */
+#ifdef HRSTORE_MONOTONICALLY_INCREASING
+                break;
+#endif
+            }
+        }
+        if ( LowIndex != -1 ) {
+            if ( !exact ) {
+                newname[ HRSTORE_ENTRY_NAME_LENGTH ] = LowIndex;
+                memcpy((char *) name, (char *) newname,
+                       ((int) vp->namelen + 1) * sizeof(oid));
+                *length = vp->namelen + 1;
+            }
+            mem = (netsnmp_memory_info*)0xffffffff;   /* To indicate 'success' */
+        }
+    }
+
+    *write_method = (WriteMethod*)0;
+    *var_len = sizeof(long);    /* default to 'long' results */
+
+    /*
+     *  ... and return the appropriate row
+     */
+    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: process "));
+    DEBUGMSGOID(("host/hr_storage", name, *length));
+    DEBUGMSG(("host/hr_storage", " (%p)\n", mem));
+    return (void*)mem;
+}
+
+oid             storage_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 2, 1, 1 };  /* hrStorageOther */
+int             storage_type_len =
+    sizeof(storage_type_id) / sizeof(storage_type_id[0]);
+
+        /*********************
+	 *
+	 *  System specific implementation functions
+	 *
+	 *********************/
+
+int
+handle_memsize(netsnmp_mib_handler *handler,
+                netsnmp_handler_registration *reginfo,
+                netsnmp_agent_request_info *reqinfo,
+                netsnmp_request_info *requests)
+{
+    netsnmp_memory_info *mem_info;
+    int val;
+
+    /*
+     * We just need to handle valid GET requests, as invalid instances
+     *   are rejected automatically, and (valid) GETNEXT requests are
+     *   converted into the appropriate GET request.
+     *
+     * We also only ever receive one request at a time.
+     */
+    switch (reqinfo->mode) {
+    case MODE_GET:
+        netsnmp_memory_load();
+        mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 );
+        if ( !mem_info || mem_info->size == -1 || mem_info->units == -1 )
+            netsnmp_set_request_error( reqinfo, requests, SNMP_NOSUCHOBJECT );
+	else {
+            val  =  mem_info->size;     /* memtotal */
+            val *= (mem_info->units/1024);
+            snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
+                                     (u_char *)&val, sizeof(val));
+        }
+        return SNMP_ERR_NOERROR;
+
+    default:
+        /*
+         * we should never get here, so this is a really bad error 
+         */
+        snmp_log(LOG_ERR, "unknown mode (%d) in handle_memsize\n",
+                 reqinfo->mode);
+        return SNMP_ERR_GENERR;
+    }
+
+    return SNMP_ERR_NOERROR;
+}
+
+
+u_char         *
+var_hrstore(struct variable *vp,
+            oid * name,
+            size_t * length,
+            int exact, size_t * var_len, WriteMethod ** write_method)
+{
+    int             store_idx = 0;
+    static char     string[1024];
+    void                *ptr;
+    netsnmp_memory_info *mem = NULL;
+
+really_try_next:
+	ptr = header_hrstoreEntry(vp, name, length, exact, var_len,
+					write_method);
+	if (ptr == NULL)
+	    return NULL;
+
+        store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ];
+        if (HRFS_entry &&
+	    store_idx > NETSNMP_MEM_TYPE_MAX &&
+            netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+                                   NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) &&
+            Check_HR_FileSys_NFS())
+            return NULL;
+        if (store_idx <= NETSNMP_MEM_TYPE_MAX ) {
+	    mem = (netsnmp_memory_info*)ptr;
+        }
+
+
+
+    switch (vp->magic) {
+    case HRSTORE_INDEX:
+        long_return = store_idx;
+        return (u_char *) & long_return;
+    case HRSTORE_TYPE:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX)
+            if (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOTE )
+                storage_type_id[storage_type_len - 1] = 10;     /* Network Disk */
+            else if (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOVE )
+                storage_type_id[storage_type_len - 1] = 5;      /* Removable Disk */
+            else
+                storage_type_id[storage_type_len - 1] = 4;      /* Assume fixed */
+        else
+            switch (store_idx) {
+            case NETSNMP_MEM_TYPE_PHYSMEM:
+            case NETSNMP_MEM_TYPE_USERMEM:
+                storage_type_id[storage_type_len - 1] = 2;      /* RAM */
+                break;
+            case NETSNMP_MEM_TYPE_VIRTMEM:
+            case NETSNMP_MEM_TYPE_SWAP:
+                storage_type_id[storage_type_len - 1] = 3;      /* Virtual Mem */
+                break;
+            default:
+                storage_type_id[storage_type_len - 1] = 1;      /* Other */
+                break;
+            }
+        *var_len = sizeof(storage_type_id);
+        return (u_char *) storage_type_id;
+    case HRSTORE_DESCR:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX) {
+            strncpy(string, HRFS_entry->path, sizeof(string)-1);
+            string[ sizeof(string)-1 ] = 0;
+            *var_len = strlen(string);
+            return (u_char *) string;
+        } else {
+            if ( !mem || !mem->descr )
+                goto try_next;
+            *var_len = strlen(mem->descr);
+            return (u_char *) mem->descr;
+        }
+    case HRSTORE_UNITS:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX)
+            long_return = HRFS_entry->units;
+        else {
+            if ( !mem || mem->units == -1 )
+                goto try_next;
+            long_return = mem->units;
+        }
+        return (u_char *) & long_return;
+    case HRSTORE_SIZE:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX)
+            long_return = HRFS_entry->size;
+        else {
+            if ( !mem || mem->size == -1 )
+                goto try_next;
+            long_return = mem->size;
+        }
+        return (u_char *) & long_return;
+    case HRSTORE_USED:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX)
+            long_return = HRFS_entry->used;
+        else {
+            if ( !mem || mem->size == -1 || mem->free == -1 )
+                goto try_next;
+            long_return = mem->size - mem->free;
+        }
+        return (u_char *) & long_return;
+    case HRSTORE_FAILS:
+        if (store_idx > NETSNMP_MEM_TYPE_MAX)
+#if NETSNMP_NO_DUMMY_VALUES
+	    goto try_next;
+#else
+            long_return = 0;
+#endif
+        else {
+            if ( !mem || mem->other == -1 )
+                goto try_next;
+            long_return = mem->other;
+        }
+        return (u_char *) & long_return;
+    default:
+        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrstore\n",
+                    vp->magic));
+    }
+    return NULL;
+
+  try_next:
+    if (!exact)
+        goto really_try_next;
+
+    return NULL;
+}
+
+
+        /*********************
+	 *
+	 *  Internal implementation functions
+	 *
+	 *********************/
+
+static int      HRS_index;
+
+void
+Init_HR_Store(void)
+{
+    HRS_index = 0;
+    Init_HR_FileSys();
+}
+
+int
+Get_Next_HR_Store(void)
+{
+    /*
+     * File-based storage 
+     */
+	for (;;) {
+    	HRS_index = Get_Next_HR_FileSys();
+		if (HRS_index >= 0) {
+			if (!(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
+							NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && 
+						Check_HR_FileSys_NFS())) {
+				return HRS_index + NETSNMP_MEM_TYPE_MAX;	
+			}
+		} else {
+			return -1;
+		}	
+	}
+}
+
diff -uNr old/agent/mibgroup/host/hrh_storage.h net-snmp-5.3.2.2/agent/mibgroup/host/hrh_storage.h
--- old/agent/mibgroup/host/hrh_storage.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/agent/mibgroup/host/hrh_storage.h	2011-01-19 14:02:44.509483353 +0100
@@ -0,0 +1,23 @@
+/*
+ *  Host Resources MIB - storage group interface (HAL rewrite) - hrh_storage.h
+ *
+ */
+#ifndef _MIBGROUP_HRSTORAGE_H
+#define _MIBGROUP_HRSTORAGE_H
+
+config_require(hardware/memory)
+config_require(hardware/fsys)
+config_require(host/hrh_filesys)
+
+config_exclude( host/hr_storage )
+
+extern void     init_hrh_storage(void);
+extern FindVarMethod var_hrstore;
+
+
+#define	HRS_TYPE_MBUF		1
+#define	HRS_TYPE_MEM		2
+#define	HRS_TYPE_SWAP		3
+#define	HRS_TYPE_FIXED_MAX	3     /* the largest fixed type */
+
+#endif                          /* _MIBGROUP_HRSTORAGE_H */
diff -uNr old/agent/mibgroup/host.h net-snmp-5.3.2.2/agent/mibgroup/host.h
--- old/agent/mibgroup/host.h	2002-04-20 09:30:29.000000000 +0200
+++ net-snmp-5.3.2.2/agent/mibgroup/host.h	2011-01-19 14:02:44.510483370 +0100
@@ -2,9 +2,18 @@
  *  Host Resources 'wrapper' interface
  *	calls the per-group interfaces from 'hr_*.h'
  */
+/* Portions of this file are subject to the following copyright(s).  See
+ * the Net-SNMP's COPYING file for more details and other copyrights
+ * that may apply:
+ */
+/*
+ * Portions of this file are copyrighted by:
+ * 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.
+ */
 
 	config_require(host/hr_system)
-	config_require(host/hr_storage)
 	config_require(host/hr_device)
 	config_require(host/hr_other)
 	config_require(host/hr_proc)
@@ -12,7 +21,10 @@
 	config_require(host/hr_print)
 	config_require(host/hr_disk)
 	config_require(host/hr_partition)
-	config_require(host/hr_filesys)
+
+	config_require(host/hrh_storage)
+	config_require(host/hrh_filesys)
+
 	config_require(host/hr_swrun)
 	config_require(host/hr_swinst)
 
diff -uNr old/include/net-snmp/agent/hardware/fsys.h net-snmp-5.3.2.2/include/net-snmp/agent/hardware/fsys.h
--- old/include/net-snmp/agent/hardware/fsys.h	1970-01-01 01:00:00.000000000 +0100
+++ net-snmp-5.3.2.2/include/net-snmp/agent/hardware/fsys.h	2011-01-19 14:02:44.512483401 +0100
@@ -0,0 +1,93 @@
+typedef struct netsnmp_fsys_info_s netsnmp_fsys_info;
+
+#define _NETSNMP_FS_TYPE_SKIP_BIT   0x2000
+#define _NETSNMP_FS_TYPE_LOCAL      0x1000
+
+   /*
+    * Enumeration from HOST-RESOURCES-TYPES mib
+    */
+#define NETSNMP_FS_TYPE_OTHER	   1
+#define NETSNMP_FS_TYPE_UNKNOWN	   2
+#define NETSNMP_FS_TYPE_BERKELEY   3
+#define NETSNMP_FS_TYPE_SYSV	   4
+#define NETSNMP_FS_TYPE_FAT	   5
+#define NETSNMP_FS_TYPE_HPFS	   6
+#define NETSNMP_FS_TYPE_HFS	   7
+#define NETSNMP_FS_TYPE_MFS	   8
+#define NETSNMP_FS_TYPE_NTFS	   9
+#define NETSNMP_FS_TYPE_VNODE	   10
+#define NETSNMP_FS_TYPE_JFS	   11
+#define NETSNMP_FS_TYPE_ISO9660	   12
+#define NETSNMP_FS_TYPE_ROCKRIDGE  13
+#define NETSNMP_FS_TYPE_NFS	   14
+#define NETSNMP_FS_TYPE_NETWARE	   15
+#define NETSNMP_FS_TYPE_AFS	   16
+#define NETSNMP_FS_TYPE_DFS	   17
+#define NETSNMP_FS_TYPE_APPLESHARE 18
+#define NETSNMP_FS_TYPE_RFS	   19
+#define NETSNMP_FS_TYPE_DGCS	   20
+#define NETSNMP_FS_TYPE_BOOTFS	   21
+#define NETSNMP_FS_TYPE_FAT32	   22
+#define NETSNMP_FS_TYPE_EXT2	   23
+
+   /*
+    * Additional enumerationis - not listed in that MIB
+    */
+#define NETSNMP_FS_TYPE_IGNORE	   1 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT
+
+#define NETSNMP_FS_TYPE_PROC	   2 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT
+
+#define NETSNMP_FS_TYPE_DEVPTS	   3 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT
+#define NETSNMP_FS_TYPE_SYSFS	   4 | _NETSNMP_FS_TYPE_LOCAL | _NETSNMP_FS_TYPE_SKIP_BIT
+#define NETSNMP_FS_TYPE_TMPFS	   5 | _NETSNMP_FS_TYPE_LOCAL
+#define NETSNMP_FS_TYPE_USBFS	   6 | _NETSNMP_FS_TYPE_LOCAL
+
+#define NETSNMP_FS_FLAG_ACTIVE   0x01
+#define NETSNMP_FS_FLAG_REMOTE   0x02
+#define NETSNMP_FS_FLAG_RONLY    0x04
+#define NETSNMP_FS_FLAG_BOOTABLE 0x08
+#define NETSNMP_FS_FLAG_REMOVE   0x10
+
+#define NETSNMP_FS_FIND_CREATE     1   /* or use one of the type values */
+#define NETSNMP_FS_FIND_EXIST      0
+
+struct netsnmp_fsys_info_s {
+     netsnmp_index  idx;
+  /* int  idx; */
+ 
+     char path[  SNMP_MAXPATH+1];
+     char device[SNMP_MAXPATH+1];
+     int  type;
+
+     long size;
+     long used;
+     long avail;
+     long units;
+
+     long inums_total;
+     long inums_avail;
+
+     long flags;
+
+     netsnmp_fsys_info *next;
+};
+
+
+    /*
+     * Possibly not all needed ??
+     */
+netsnmp_fsys_info *netsnmp_fsys_get_first( void );
+netsnmp_fsys_info *netsnmp_fsys_get_next( netsnmp_fsys_info* );
+netsnmp_fsys_info *netsnmp_fsys_get_byIdx(  int,   int );
+netsnmp_fsys_info *netsnmp_fsys_get_next_byIdx(int,int );
+
+netsnmp_fsys_info *netsnmp_fsys_by_device(  char*, int );
+netsnmp_fsys_info *netsnmp_fsys_by_path(    char*, int );
+
+netsnmp_cache *netsnmp_fsys_get_cache( void );
+int  netsnmp_fsys_load( netsnmp_cache *cache, void *data );
+void netsnmp_fsys_free( netsnmp_cache *cache, void *data );
+
+unsigned int netsnmp_fsys_size( netsnmp_fsys_info* );
+unsigned int netsnmp_fsys_used( netsnmp_fsys_info* );
+unsigned int netsnmp_fsys_avail(netsnmp_fsys_info* );
diff -uNr old/include/net-snmp/agent/hardware/memory.h net-snmp-5.3.2.2/include/net-snmp/agent/hardware/memory.h
--- old/include/net-snmp/agent/hardware/memory.h	2005-06-27 10:57:52.000000000 +0200
+++ net-snmp-5.3.2.2/include/net-snmp/agent/hardware/memory.h	2011-01-19 14:02:44.513483419 +0100
@@ -1,12 +1,22 @@
 typedef struct netsnmp_memory_info_s netsnmp_memory_info;
 
-#define NETSNMP_MEM_TYPE_MEMORY  1
-#define NETSNMP_MEM_TYPE_SWAP    2
-#define NETSNMP_MEM_TYPE_BUFFERS 3
+#define NETSNMP_MEM_TYPE_PHYSMEM  1
+#define NETSNMP_MEM_TYPE_USERMEM  2
+#define NETSNMP_MEM_TYPE_VIRTMEM  3
+#define NETSNMP_MEM_TYPE_STEXT    4
+#define NETSNMP_MEM_TYPE_RTEXT    5
+#define NETSNMP_MEM_TYPE_MBUF     6
+#define NETSNMP_MEM_TYPE_CACHED   7
+#define NETSNMP_MEM_TYPE_SHARED   8
+#define NETSNMP_MEM_TYPE_SHARED2  9
+#define NETSNMP_MEM_TYPE_SWAP    10
+    /* Leave space for individual swap devices */
+#define NETSNMP_MEM_TYPE_MAX     30
 
 struct netsnmp_memory_info_s {
      int  idx;
      int  type;
+     char *descr;
 
      long units;
      long size;
@@ -23,6 +33,7 @@
 netsnmp_memory_info *netsnmp_memory_get_first(  int );
 netsnmp_memory_info *netsnmp_memory_get_next( netsnmp_memory_info*, int );
 netsnmp_memory_info *netsnmp_memory_get_byIdx(  int,   int );
+netsnmp_memory_info *netsnmp_memory_get_next_byIdx(int,int );
 
 netsnmp_cache *netsnmp_memory_get_cache( void );
 int netsnmp_memory_load( void );