summaryrefslogtreecommitdiff
path: root/agent/mibgroup/host/hr_filesys.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/host/hr_filesys.c')
-rw-r--r--agent/mibgroup/host/hr_filesys.c1009
1 files changed, 1009 insertions, 0 deletions
diff --git a/agent/mibgroup/host/hr_filesys.c b/agent/mibgroup/host/hr_filesys.c
new file mode 100644
index 0000000..b23d322
--- /dev/null
+++ b/agent/mibgroup/host/hr_filesys.c
@@ -0,0 +1,1009 @@
+/*
+ * Host Resources MIB - File System device group implementation - hr_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-features.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 "host_res.h"
+#include "hr_filesys.h"
+#include "hr_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 HAVE_NBUTIL_H
+#include <nbutil.h>
+#endif
+
+#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+#include <sys/mntctl.h>
+#include <sys/vmount.h>
+#include <sys/statfs.h>
+#endif
+
+netsnmp_feature_require(se_find_free_value_in_slist)
+netsnmp_feature_require(date_n_time)
+netsnmp_feature_require(ctime_to_timet)
+
+#if defined(bsdi4) || defined(freebsd3) || defined(freebsd4) || defined(freebsd5) || defined(darwin)
+#if HAVE_GETFSSTAT && defined(MFSNAMELEN)
+#define MOUNT_NFS "nfs"
+#define MNTTYPE_UFS "ufs"
+#define BerkelyFS
+#define MNTTYPE_FFS "ffs"
+#define MNTTYPE_NFS "nfs"
+#define MNTTYPE_NFS3 "nfs"
+#define MNTTYPE_HFS "hfs"
+#define MNTTYPE_MFS "mfs"
+#define MNTTYPE_MSDOS "msdos"
+#define MNTTYPE_LFS "lfs"
+#define MNTTYPE_FDESC "fdesc"
+#define MNTTYPE_PORTAL "portal"
+#define MNTTYPE_NULL "null"
+#define MNTTYPE_UMAP "umap"
+#define MNTTYPE_KERNFS "kernfs"
+#define MNTTYPE_PROCFS "procfs"
+#define MNTTYPE_AFS "afs"
+#define MNTTYPE_CD9660 "cd9660"
+#define MNTTYPE_UNION "union"
+#define MNTTYPE_ADOSFS "adosfs"
+#define MNTTYPE_EXT2FS "ext2fs"
+#define MNTTYPE_CFS "coda"
+#define MNTTYPE_NTFS "ntfs"
+#endif
+#endif /* freebsd3 */
+
+#define HRFS_MONOTONICALLY_INCREASING
+
+ /*********************
+ *
+ * Kernel & interface information,
+ * and internal forward declarations
+ *
+ *********************/
+
+#ifdef solaris2
+
+struct mnttab HRFS_entry_struct;
+struct mnttab *HRFS_entry = &HRFS_entry_struct;
+#define HRFS_name mnt_special
+#define HRFS_mount mnt_mountp
+#define HRFS_type mnt_fstype
+#define HRFS_statfs statvfs
+
+#elif defined(HAVE_STATVFS) && defined(__NetBSD__)
+
+#if !defined(MFSNAMELEN) && defined(_VFS_NAMELEN)
+#define MFSNAMELEN _VFS_NAMELEN
+#endif
+
+#define getfsstat getvfsstat
+
+static struct statvfs *fsstats = NULL;
+struct statvfs *HRFS_entry;
+static int fscount;
+#define HRFS_mount f_mntonname
+#define HRFS_name f_mntfromname
+#define HRFS_statfs statvfs
+#define HRFS_type f_fstypename
+#elif defined(HAVE_GETFSSTAT) && !defined(HAVE_STATFS) && defined(HAVE_STATVFS)
+
+static struct statfs *fsstats = NULL;
+struct statfs *HRFS_entry;
+static int fscount;
+#define HRFS_mount f_mntonname
+#define HRFS_name f_mntfromname
+#define HRFS_statfs statvfs
+#define HRFS_type f_fstypename
+
+#elif defined(HAVE_GETFSSTAT)
+static struct statfs *fsstats = 0;
+static int fscount;
+struct statfs *HRFS_entry;
+#define HRFS_statfs statfs
+#ifdef MFSNAMELEN
+#define HRFS_type f_fstypename
+#else
+#define HRFS_type f_type
+#endif
+#define HRFS_mount f_mntonname
+#define HRFS_name f_mntfromname
+
+#elif defined(dynix)
+struct mntent *HRFS_entry;
+#define HRFS_name mnt_fsname
+#define HRFS_mount mnt_dir
+#define HRFS_type mnt_type
+#define HRFS_statfs statvfs
+
+#elif defined(WIN32)
+struct win_statfs *HRFS_entry;
+static int fscount;
+#define HRFS_mount f_driveletter
+#define HRFS_name f_fsid
+#define HRFS_statfs win_statfs
+#define HRFS_type f_type
+
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+
+struct vmount *aixmnt, *aixcurr;
+struct HRFS_entry {
+ char *HRFS_name;
+ char *HRFS_mount;
+ int HRFS_type;
+ int HRFS_flags;
+} *HRFS_entry;
+#define HRFS_statfs statfs
+
+#else
+struct mntent *HRFS_entry;
+#define HRFS_name mnt_fsname
+#define HRFS_mount mnt_dir
+#define HRFS_type mnt_type
+#define HRFS_statfs statfs
+
+#ifdef linux
+#define MNTTYPE_CD9660 "iso9660"
+#define MNTTYPE_EXT2FS "ext2"
+#define MNTTYPE_EXT3FS "ext3"
+#define MNTTYPE_SMBFS "smbfs"
+#define MNTTYPE_MSDOS "msdos"
+#define MNTTYPE_FAT32 "vfat"
+#define MNTTYPE_NTFS "ntfs"
+#define MNTTYPE_NFS4 "nfs4"
+#endif /* linux */
+
+#endif
+
+#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_hrfilesys(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, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 1}},
+ {HRFSYS_MOUNT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 2}},
+ {HRFSYS_RMOUNT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 3}},
+ {HRFSYS_TYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 4}},
+ {HRFSYS_ACCESS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 5}},
+ {HRFSYS_BOOT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 6}},
+ {HRFSYS_STOREIDX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 7}},
+ {HRFSYS_FULLDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 8}},
+ {HRFSYS_PARTDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_hrfilesys, 2, {1, 9}},
+};
+oid hrfsys_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 8 };
+
+void
+init_hr_filesys(void)
+{
+ REGISTER_MIB("host/hr_filesys", hrfsys_variables, variable4,
+ hrfsys_variables_oid);
+#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ /* something leaks, make it idiot-safe */
+ aixmnt = NULL;
+ aixcurr = NULL;
+#endif
+}
+
+/*
+ * header_hrfilesys(...
+ * 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_hrfilesys(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_hrfilesys: "));
+ 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 = (WriteMethod*)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_hrfilesys(struct variable *vp,
+ oid * name,
+ size_t * length,
+ int exact, size_t * var_len, WriteMethod ** write_method)
+{
+ int fsys_idx;
+ static char string[1024];
+ char *mnt_type;
+
+ fsys_idx =
+ header_hrfilesys(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:
+ strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string));
+ *var_len = strlen(string);
+ return (u_char *) string;
+ case HRFSYS_RMOUNT:
+ if (Check_HR_FileSys_NFS())
+ strlcpy(string, HRFS_entry->HRFS_name, sizeof(string));
+ else
+ string[0] = '\0';
+ *var_len = strlen(string);
+ return (u_char *) string;
+
+ case HRFSYS_TYPE:
+ if (Check_HR_FileSys_NFS())
+ fsys_type_id[fsys_type_len - 1] = 14;
+ else {
+ /*
+ * Not sufficient to identity the file
+ * type precisely, but it's a start.
+ */
+#if HAVE_GETFSSTAT && !defined(MFSNAMELEN)
+ switch (HRFS_entry->HRFS_type) {
+ case MOUNT_UFS:
+ fsys_type_id[fsys_type_len - 1] = 3;
+ break;
+ case MOUNT_NFS:
+ fsys_type_id[fsys_type_len - 1] = 14;
+ break;
+ case MOUNT_HFS:
+ fsys_type_id[fsys_type_len - 1] = 7;
+ break;
+ case MOUNT_MFS:
+ fsys_type_id[fsys_type_len - 1] = 8;
+ break;
+ case MOUNT_MSDOS:
+ fsys_type_id[fsys_type_len - 1] = 5;
+ break;
+ case MOUNT_LFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_LOFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_FDESC:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_PORTAL:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_NULL:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_UMAP:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_KERNFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_PROCFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_AFS:
+ fsys_type_id[fsys_type_len - 1] = 16;
+ break;
+ case MOUNT_CD9660:
+ fsys_type_id[fsys_type_len - 1] = 12;
+ break;
+ case MOUNT_UNION:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MOUNT_DEVFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+#ifdef MOUNT_EXT2FS
+ case MOUNT_EXT2FS:
+ fsys_type_id[fsys_type_len - 1] = 23;
+ break;
+#endif
+#ifdef MOUNT_TFS
+ case MOUNT_TFS:
+ fsys_type_id[fsys_type_len - 1] = 15;
+ break;
+#endif
+ }
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ switch (HRFS_entry->HRFS_type) {
+ case MNT_AIX:
+ case MNT_JFS:
+ fsys_type_id[fsys_type_len - 1] = 3;
+ break;
+ case MNT_CDROM:
+ fsys_type_id[fsys_type_len - 1] = 12;
+ break;
+#ifdef MNT_NAMEFS
+ case MNT_NAMEFS:
+#endif
+#ifdef MNT_PROCFS
+ case MNT_PROCFS:
+#endif
+ case MNT_SFS:
+ case MNT_CACHEFS:
+ fsys_type_id[fsys_type_len - 1] = 1;
+ break;
+ case MNT_NFS:
+ case MNT_NFS3:
+ case MNT_AUTOFS:
+ fsys_type_id[fsys_type_len - 1] = 14;
+ break;
+ }
+#else
+ mnt_type = HRFS_entry->HRFS_type;
+ if (mnt_type == NULL)
+ fsys_type_id[fsys_type_len - 1] = 2; /* unknown */
+#ifdef MNTTYPE_HFS
+ else if (!strcmp(mnt_type, MNTTYPE_HFS))
+ fsys_type_id[fsys_type_len - 1] = 7;
+#endif
+#ifdef MNTTYPE_UFS
+ else if (!strcmp(mnt_type, MNTTYPE_UFS))
+#if (defined(BerkelyFS) && !defined(MNTTYPE_HFS)) || defined(solaris2)
+ fsys_type_id[fsys_type_len - 1] = 3;
+#else /* SysV */
+ fsys_type_id[fsys_type_len - 1] = 4; /* or 3? XXX */
+#endif
+#endif
+#ifdef MNTTYPE_SYSV
+ else if (!strcmp(mnt_type, MNTTYPE_SYSV))
+ fsys_type_id[fsys_type_len - 1] = 4;
+#endif
+#ifdef MNTTYPE_PC
+ else if (!strcmp(mnt_type, MNTTYPE_PC))
+ fsys_type_id[fsys_type_len - 1] = 5;
+#endif
+#ifdef MNTTYPE_MSDOS
+ else if (!strcmp(mnt_type, MNTTYPE_MSDOS))
+ fsys_type_id[fsys_type_len - 1] = 5;
+#endif
+#ifdef MNTTYPE_FAT32
+ else if (!strcmp(mnt_type, MNTTYPE_FAT32))
+ fsys_type_id[fsys_type_len - 1] = 22;
+#endif
+#ifdef MNTTYPE_CDFS
+ else if (!strcmp(mnt_type, MNTTYPE_CDFS))
+#ifdef RockRidge
+ fsys_type_id[fsys_type_len - 1] = 13;
+#else /* ISO 9660 */
+ fsys_type_id[fsys_type_len - 1] = 12;
+#endif
+#endif
+#ifdef MNTTYPE_HSFS
+ else if (!strcmp(mnt_type, MNTTYPE_HSFS))
+ fsys_type_id[fsys_type_len - 1] = 13;
+#endif
+#ifdef MNTTYPE_ISO9660
+ else if (!strcmp(mnt_type, MNTTYPE_ISO9660))
+ fsys_type_id[fsys_type_len - 1] = 12;
+#endif
+#ifdef MNTTYPE_CD9660
+ else if (!strcmp(mnt_type, MNTTYPE_CD9660))
+ fsys_type_id[fsys_type_len - 1] = 12;
+#endif
+#ifdef MNTTYPE_SMBFS
+ else if (!strcmp(mnt_type, MNTTYPE_SMBFS))
+ fsys_type_id[fsys_type_len - 1] = 14;
+#endif
+#ifdef MNTTYPE_NFS
+ else if (!strcmp(mnt_type, MNTTYPE_NFS))
+ fsys_type_id[fsys_type_len - 1] = 14;
+#endif
+#ifdef MNTTYPE_NFS3
+ else if (!strcmp(mnt_type, MNTTYPE_NFS3))
+ fsys_type_id[fsys_type_len - 1] = 14;
+#endif
+#ifdef MNTTYPE_NFS4
+ else if (!strcmp(mnt_type, MNTTYPE_NFS4))
+ fsys_type_id[fsys_type_len - 1] = 14;
+#endif
+#ifdef MNTTYPE_MFS
+ else if (!strcmp(mnt_type, MNTTYPE_MFS))
+ fsys_type_id[fsys_type_len - 1] = 8;
+#endif
+#ifdef MNTTYPE_EXT2FS
+ else if (!strcmp(mnt_type, MNTTYPE_EXT2FS))
+ fsys_type_id[fsys_type_len - 1] = 23;
+#endif
+#ifdef MNTTYPE_EXT3FS
+ else if (!strcmp(mnt_type, MNTTYPE_EXT3FS))
+ fsys_type_id[fsys_type_len - 1] = 23;
+#endif
+#ifdef MNTTYPE_NTFS
+ else if (!strcmp(mnt_type, MNTTYPE_NTFS))
+ fsys_type_id[fsys_type_len - 1] = 9;
+#endif
+ else
+ fsys_type_id[fsys_type_len - 1] = 1; /* Other */
+#endif /* HAVE_GETFSSTAT */
+ }
+
+ *var_len = sizeof(fsys_type_id);
+ return (u_char *) fsys_type_id;
+
+ case HRFSYS_ACCESS:
+#if defined(HAVE_STATVFS) && defined(__NetBSD__)
+ long_return = HRFS_entry->f_flag & MNT_RDONLY ? 2 : 1;
+#elif defined(HAVE_GETFSSTAT)
+#if HAVE_STRUCT_STATFS_F_FLAGS
+ long_return = HRFS_entry->f_flags & MNT_RDONLY ? 2 : 1;
+#else
+ long_return = HRFS_entry->f_flag & MNT_RDONLY ? 2 : 1;
+#endif
+#elif defined(cygwin)
+ long_return = 1;
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ long_return = (HRFS_entry->HRFS_flags & MNT_READONLY) == 0 ? 1 : 2;
+#else
+#if HAVE_HASMNTOPT
+ if (hasmntopt(HRFS_entry, "ro") != NULL)
+ long_return = 2; /* Read Only */
+ else
+#endif
+ long_return = 1; /* Read-Write */
+#endif
+ return (u_char *) & long_return;
+ case HRFSYS_BOOT:
+ if (HRFS_entry->HRFS_mount[0] == '/' &&
+ HRFS_entry->HRFS_mount[1] == 0)
+ long_return = 1; /* root is probably bootable! */
+ else
+ long_return = 2; /* others probably aren't */
+ 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->HRFS_name, FULL_DUMP, var_len);
+ case HRFSYS_PARTDUMP:
+ return when_dumped(HRFS_entry->HRFS_name, PART_DUMP, var_len);
+ default:
+ DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrfilesys\n",
+ vp->magic));
+ }
+ return NULL;
+}
+
+
+ /*********************
+ *
+ * Internal implementation functions
+ *
+ *********************/
+
+static int HRFS_index;
+#ifndef HAVE_GETFSSTAT
+static FILE *fp;
+#endif
+
+void
+Init_HR_FileSys(void)
+{
+#if HAVE_GETFSSTAT
+#if defined(HAVE_STATVFS) && defined(__NetBSD__)
+ fscount = getvfsstat(NULL, 0, ST_NOWAIT);
+#else
+ fscount = getfsstat(NULL, 0, MNT_NOWAIT);
+#endif
+ if (fsstats)
+ free((char *) fsstats);
+ fsstats = NULL;
+ fsstats = malloc(fscount * sizeof(*fsstats));
+#if defined(HAVE_STATVFS) && defined(__NetBSD__)
+ getvfsstat(fsstats, fscount * sizeof(*fsstats), ST_NOWAIT);
+#else
+ getfsstat(fsstats, fscount * sizeof(*fsstats), MNT_NOWAIT);
+#endif
+ HRFS_index = 0;
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ int ret;
+ uint size;
+ ret = 0;
+ size = 0;
+ if(aixmnt != NULL) free(aixmnt); /* something leaks, make it idiot-safe */
+ aixmnt = NULL;
+ aixcurr = NULL;
+ HRFS_index = 0;
+ ret = mntctl(MCTL_QUERY, sizeof(uint), &size);
+ if(ret == 0 && size > 0) {
+ aixmnt = malloc(size + sizeof(struct HRFS_entry));
+ if(aixmnt != NULL) {
+ HRFS_entry = (char *) aixmnt + size;
+ ret = mntctl(MCTL_QUERY, size, aixmnt);
+ HRFS_index = 1;
+ if(ret <= 0) {
+ free(aixmnt);
+ aixmnt = NULL;
+ HRFS_entry = NULL;
+ } else aixcurr = aixmnt;
+ }
+ }
+#else
+ HRFS_index = 1;
+ if (fp != NULL)
+ fclose(fp);
+ fp = fopen(ETC_MNTTAB, "r");
+ if (!fp) {
+ netsnmp_config_error("Can't open mnttab %s\n", ETC_MNTTAB);
+ }
+#endif
+}
+
+const char *HRFS_ignores[] = {
+#ifdef MNTTYPE_IGNORE
+ MNTTYPE_IGNORE,
+#endif
+#ifdef MNTTYPE_SWAP
+ MNTTYPE_SWAP,
+#endif
+#ifdef MNTTYPE_PROC
+ MNTTYPE_PROC,
+#endif
+#ifdef MNTTYPE_PROCFS
+ MNTTYPE_PROCFS,
+#endif
+#ifdef MNTTYPE_AUTOFS
+ MNTTYPE_AUTOFS,
+#else
+ "autofs",
+#endif
+#ifdef linux
+ "autofs",
+ "bdev",
+ "binfmt_misc",
+ "cpuset",
+ "debugfs",
+ "devfs",
+ "devpts",
+ "eventpollfs",
+ "futexfs",
+ "hugetlbfs",
+ "inotifyfs",
+ "mqueue",
+ "nfsd",
+ "pipefs",
+ "proc",
+ "ramfs",
+ "rootfs",
+ "rpc_pipefs",
+ "securityfs",
+ "shm",
+ "sockfs",
+ "sysfs",
+ "tmpfs",
+ "usbdevfs",
+ "usbfs",
+#endif
+#ifdef solaris2
+ "mntfs",
+ "proc",
+ "fd",
+#endif
+ NULL
+};
+
+int
+Get_Next_HR_FileSys(void)
+{
+#if HAVE_GETFSSTAT
+ if (HRFS_index >= fscount)
+ return -1;
+ HRFS_entry = fsstats + HRFS_index;
+ return ++HRFS_index;
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ if(aixcurr == NULL) {
+ if(aixmnt != NULL) free(aixmnt);
+ aixmnt = NULL;
+ HRFS_entry = NULL;
+ return -1;
+ }
+ HRFS_entry->HRFS_name = vmt2dataptr(aixcurr, VMT_OBJECT);
+ HRFS_entry->HRFS_mount = vmt2dataptr(aixcurr, VMT_STUB);
+ HRFS_entry->HRFS_type = aixcurr->vmt_gfstype;
+ HRFS_entry->HRFS_flags = aixcurr->vmt_flags;
+ aixcurr = (char *) aixcurr + aixcurr->vmt_length;
+ if((char *) aixcurr >= (char *) HRFS_entry) aixcurr = NULL;
+ switch(HRFS_entry->HRFS_type) {
+#ifdef MNT_NAMEFS
+ case MNT_NAMEFS:
+#endif
+#ifdef MNT_PROCFS
+ case MNT_PROCFS:
+#endif
+ case MNT_SFS:
+ return Get_Next_HR_FileSys();
+ break;
+ }
+ return HRFS_index++;
+#else
+ const char **cpp;
+
+ if (fp == NULL)
+ return -1;
+
+#ifdef solaris2
+ if (getmntent(fp, HRFS_entry) != 0)
+ return -1;
+#else
+ HRFS_entry = getmntent(fp);
+ if (HRFS_entry == NULL)
+ return -1;
+#endif /* solaris2 */
+
+ for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
+ if (!strcmp(HRFS_entry->HRFS_type, *cpp))
+ return Get_Next_HR_FileSys();
+
+ /*
+ * Try and ensure that index values are persistent
+ * at least within a single run of the agent
+ */
+ HRFS_index = se_find_value_in_slist("filesys", HRFS_entry->HRFS_name );
+ if (HRFS_index == SE_DNE) {
+ HRFS_index = se_find_free_value_in_slist("filesys");
+ if (HRFS_index == SE_DNE) { HRFS_index = 1; }
+ se_add_pair_to_slist( "filesys",
+ strdup( HRFS_entry->HRFS_name ), HRFS_index);
+ }
+
+ return HRFS_index++;
+#endif /* HAVE_GETFSSTAT */
+}
+
+/*
+ * this function checks whether the current file system (info can be found
+ * in HRFS_entry) is a NFS file system
+ * HRFS_entry must be valid prior to calling this function
+ * returns 1 if NFS file system, 0 otherwise
+ */
+int
+Check_HR_FileSys_NFS (void)
+{
+#if HAVE_GETFSSTAT && !defined(MFSNAMELEN)
+ if ((HRFS_entry->HRFS_type == MOUNT_NFS) ||
+ (HRFS_entry->HRFS_type == MOUNT_AFS))
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ if(HRFS_entry->HRFS_type == MNT_NFS || HRFS_entry->HRFS_type == MNT_NFS3)
+#else /* HAVE_GETFSSTAT */
+ if ( HRFS_entry->HRFS_type != NULL && (
+#if defined(MNTTYPE_NFS)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS) ||
+#else
+ !strcmp( HRFS_entry->HRFS_type, "nfs") ||
+#endif
+#if defined(MNTTYPE_NFS3)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS3) ||
+#endif
+#if defined(MNTTYPE_NFS4)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS4) ||
+#endif
+#if defined(MNTTYPE_SMBFS)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_SMBFS) ||
+#endif
+#if defined(MNTTYPE_LOFS)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_LOFS) ||
+#endif
+#if defined(MNTTYPE_AFP)
+ !strcmp( HRFS_entry->HRFS_type, MNTTYPE_AFP) ||
+#endif
+ !strcmp( HRFS_entry->HRFS_type, "cifs") ||
+ /*
+ * MVFS is Rational ClearCase's view file system
+ * it is similiar to NFS file systems in that it is mounted
+ * locally or remotely from the ClearCase server
+ */
+ !strcmp( HRFS_entry->HRFS_type, "mvfs")))
+#endif /* HAVE_GETFSSTAT */
+ return 1; /* NFS file system */
+
+ return 0; /* no NFS file system */
+}
+
+void
+End_HR_FileSys(void)
+{
+#ifdef HAVE_GETFSSTAT
+ if (fsstats)
+ free((char *) fsstats);
+ fsstats = NULL;
+#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ if(aixmnt != NULL) {
+ free(aixmnt);
+ aixmnt = NULL;
+ aixcurr = NULL;
+ HRFS_entry = NULL;
+ }
+#else
+ if (fp != NULL)
+ fclose(fp);
+ fp = NULL;
+#endif
+}
+
+
+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 & 0xFF))
+ ++cp2; /* Now find the dump level */
+
+ if (level == FULL_DUMP) {
+ if (*(cp2++) != '0')
+ continue; /* Not interested in partial dumps */
+ while (isspace(*cp2 & 0xFF))
+ ++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 & 0xFF))
+ ++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))) {
+ strlcpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev));
+ strlcat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
+ sizeof(cooked_dev));
+ } else {
+ strlcpy(cooked_dev, dev, sizeof(cooked_dev));
+ }
+
+ return cooked_dev;
+}
+
+
+int
+Get_FSIndex(char *dev)
+{
+ int iindex;
+
+ Init_HR_FileSys();
+
+ while ((iindex = Get_Next_HR_FileSys()) != -1)
+ if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
+ End_HR_FileSys();
+ return iindex;
+ }
+
+ End_HR_FileSys();
+ return 0;
+}
+
+long
+Get_FSSize(char *dev)
+{
+ struct HRFS_statfs statfs_buf;
+
+ Init_HR_FileSys();
+
+ while (Get_Next_HR_FileSys() != -1)
+ if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
+ End_HR_FileSys();
+
+ if (HRFS_statfs(HRFS_entry->HRFS_mount, &statfs_buf) != -1)
+ /*
+ * with large file systems the following calculation produces
+ * an overflow:
+ * (statfs_buf.f_blocks*statfs_buf.f_bsize)/1024
+ *
+ * assumption: f_bsize is either 512 or a multiple of 1024
+ * in case of 512 (f_blocks/2) is returned
+ * otherwise (f_blocks*(f_bsize/1024)) is returned
+ */
+#if defined(solaris2) && defined(HAVE_STRUCT_STATVFS_F_FRSIZE)
+ return (statfs_buf.f_blocks*(statfs_buf.f_frsize/1024));
+#else
+ if (statfs_buf.f_bsize == 512)
+ return (statfs_buf.f_blocks/2);
+ else
+ return (statfs_buf.f_blocks*(statfs_buf.f_bsize/1024));
+#endif
+ else
+ return -1;
+ }
+
+ End_HR_FileSys();
+ return 0;
+}