/*
 *  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) || defined(aix7)
#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,   NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 1}},
    {HRFSYS_MOUNT,    ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 2}},
    {HRFSYS_RMOUNT,   ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 3}},
    {HRFSYS_TYPE,     ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 4}},
    {HRFSYS_ACCESS,   ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 5}},
    {HRFSYS_BOOT,     ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 6}},
    {HRFSYS_STOREIDX, ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 7}},
    {HRFSYS_FULLDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_hrhfilesys, 2, {1, 8}},
    {HRFSYS_PARTDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_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), "%s", 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), "%s", 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;
    HRFS_index = 0;
}

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 );

    HRFS_index = (HRFS_entry ? HRFS_entry->idx.oids[0] : -1 );
    return HRFS_index;
}



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(0xFF & *cp2))
                ++cp2;          /* Now find the dump level */

            if (level == FULL_DUMP) {
                if (*(cp2++) != '0')
                    continue;   /* Not interested in partial dumps */
                while (isspace(0xFF & *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(0xFF & *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))) {
        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)
{
    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;
}
