/*
 *  Host Resources MIB - storage group implementation - hrh_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, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {1}},
    {HRSTORE_TYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {2}},
    {HRSTORE_DESCR, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {3}},
    {HRSTORE_UNITS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {4}},
    {HRSTORE_SIZE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {5}},
    {HRSTORE_USED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_hrstore, 1, {6}},
    {HRSTORE_FAILS, ASN_COUNTER, NETSNMP_OLDAPI_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) {
            strlcpy(string, HRFS_entry->path, sizeof(string));
            *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;
		}	
	}
}

