/*
 * disk_hw.c
 */

#include <net-snmp/net-snmp-config.h>


#include <stdio.h>

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <signal.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/hardware/fsys.h>

#include "struct.h"
#include "disk.h"
#include "util_funcs/header_simple_table.h"
#if USING_UCD_SNMP_ERRORMIB_MODULE
#include "errormib.h"
#else
#define setPerrorstatus(x) snmp_log_perror(x)
#endif

/*
 *  * config file parsing routines
 *   */
static void       disk_free_config(void);
static void       disk_parse_config(const char *, char *);
static void       disk_parse_config_all(const char *, char *);

static netsnmp_fsys_info ** _expand_disk_array( char *cptr );

#define MAX_INT_32 0x7fffffff
#define MAX_UINT_32 0xffffffff

int             numdisks;
int             allDisksIncluded = 0;
int             maxdisks = 0;
netsnmp_fsys_info **disks = NULL;

struct variable2 extensible_disk_variables[] = {
  {MIBINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {MIBINDEX}},
  {ERRORNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {ERRORNAME}},
  {DISKDEVICE, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKDEVICE}},
  {DISKMINIMUM, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKMINIMUM}},
  {DISKMINPERCENT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKMINPERCENT}},
  {DISKTOTAL, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKTOTAL}},
  {DISKAVAIL, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKAVAIL}},
  {DISKUSED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKUSED}},
  {DISKPERCENT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKPERCENT}},
  {DISKPERCENTNODE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {DISKPERCENTNODE}},
  {ERRORFLAG, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {ERRORFLAG}},
  {ERRORMSG, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
   var_extensible_disk, 1, {ERRORMSG}},
   {DISKTOTALLOW, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKTOTALLOW}},
   {DISKTOTALHIGH, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKTOTALHIGH}},
   {DISKAVAILLOW, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKAVAILLOW}},
   {DISKAVAILHIGH, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKAVAILHIGH}},
   {DISKUSEDLOW, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKUSEDLOW}},
   {DISKUSEDHIGH, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
    var_extensible_disk, 1, {DISKUSEDHIGH}},
};

/*
 * Define the OID pointer to the top of the mib tree that we're
 * registering underneath 
 */
oid             disk_variables_oid[] = { NETSNMP_UCDAVIS_MIB, NETSNMP_DISKMIBNUM, 1 };

void
init_disk_hw(void)
{
  /*
   * register ourselves with the agent to handle our mib tree 
   */
  REGISTER_MIB("ucd-snmp/disk", extensible_disk_variables, variable2,
	       disk_variables_oid);

  snmpd_register_config_handler("disk", disk_parse_config,
				disk_free_config,
				"path [ minspace | minpercent% ]");
  snmpd_register_config_handler("includeAllDisks", disk_parse_config_all,
				disk_free_config,
				"minpercent%");
  allDisksIncluded = 0;
}

static void
disk_free_config(void)
{
  netsnmp_fsys_info *entry;

  for ( entry  = netsnmp_fsys_get_first();
        entry != NULL;
        entry  = netsnmp_fsys_get_next( entry )) {

      entry->minspace   = -1;
      entry->minpercent = -1;
      entry->flags     &= ~NETSNMP_FS_FLAG_UCD;
  }
  if (disks) {
     free( disks );
     disks = NULL;
     maxdisks = numdisks = 0;
  }
  allDisksIncluded = 0;
}

static void 
disk_parse_config(const char *token, char *cptr)
{
  char            path[STRMAX];
  int             minpercent;
  int             minspace;
  netsnmp_fsys_info *entry;

  /*
   * Ensure there is space for the new entry
   */
  if (numdisks == maxdisks) {
      if (!_expand_disk_array( cptr )) 
          return;
  }

  /*
   * read disk path (eg, /1 or /usr) 
   */
  copy_nword(cptr, path, sizeof(path));
  cptr = skip_not_white(cptr);
  cptr = skip_white(cptr);
	
  /*
   * read optional minimum disk usage spec 
   */
  if(cptr != NULL) {
      if(strchr(cptr, '%') == NULL) {
          minspace = atoi(cptr);
          minpercent = -1;
      }
      else {
          minspace = -1;
          minpercent = atoi(cptr);
      }
  } else {
      minspace = NETSNMP_DEFDISKMINIMUMSPACE;
      minpercent = -1;
  }

  /*
   * check if the disk already exists, if so then modify its
   * parameters. if it does not exist then add it
   */
  entry = netsnmp_fsys_by_path( path, NETSNMP_FS_FIND_CREATE );
  if ( entry ) {
      entry->minspace   = minspace;
      entry->minpercent = minpercent;
      entry->flags     |= NETSNMP_FS_FLAG_UCD;
      disks[numdisks++] = entry;
  }
}

static void 
disk_parse_config_all(const char *token, char *cptr)
{
  int             minpercent = DISKMINPERCENT;
  netsnmp_fsys_info *entry;
    
  /*
   * read the minimum disk usage percent
   */
  if(cptr != NULL) {
      if(strchr(cptr, '%') != NULL) {
          minpercent = atoi(cptr);
      }
  }
  /*
   * if we have already seen the "includeAllDisks" directive
   * then search for the disk in the "disks" array and modify
   * the values. if we havent seen the "includeAllDisks"
   * directive then include this disk
   */
  if(allDisksIncluded) {
      config_perror("includeAllDisks already specified.");
      netsnmp_config_error("\tignoring: includeAllDisks %s", cptr);
  }
  else {

      netsnmp_fsys_load( NULL, NULL );  /* Prime the fsys H/W module */
      for ( entry  = netsnmp_fsys_get_first();
            entry != NULL;
            entry  = netsnmp_fsys_get_next( entry )) {

          if ( !(entry->flags & NETSNMP_FS_FLAG_ACTIVE ))
              continue;
          entry->minspace   = -1;
          entry->minpercent = minpercent;
          entry->flags     |= NETSNMP_FS_FLAG_UCD;
          /*
           * Ensure there is space for the new entry
           */
          if (numdisks == maxdisks) {
              if (!_expand_disk_array( entry->device )) 
                  return;
          }
          disks[numdisks++] = entry;
      }
      allDisksIncluded = 1;
  }
}


static int _percent( unsigned long long value, unsigned long long total ) {
    float v=value, t=total, pct;

    /* avoid division by zero */
    if (total == 0)
        return 0;

    pct  = (v*100)/t;   /* Calculate percentage using floating point
                           arithmetic, to avoid overflow errors */
    pct += 0.5;         /* rounding */
    return (int)pct;
}

static netsnmp_fsys_info **
_expand_disk_array( char *cptr ) {

    if ( maxdisks == 0 )
        maxdisks  = 50;
    else
        maxdisks *= 2;

    disks = realloc( disks, maxdisks * sizeof( netsnmp_fsys_info*));
    if (!disks) {
        config_perror("malloc failed for new disk allocation.");
        netsnmp_config_error("\tignoring: %s", cptr);
        return NULL;
    }

    if ( maxdisks == 50 )
        memset(disks,              0,  maxdisks   * sizeof( netsnmp_fsys_info*));
    else
        memset(disks + maxdisks/2, 0,  maxdisks/2 * sizeof( netsnmp_fsys_info*));

    return disks;
}


/*
 * var_extensible_disk(...
 * 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
 * 
 */
u_char         *
var_extensible_disk(struct variable *vp,
                    oid * name,
                    size_t * length,
                    int exact,
                    size_t * var_len, WriteMethod ** write_method)
{
    int             disknum = 0;
  netsnmp_fsys_info *entry;
    unsigned long long val;
    static long     long_ret;
    static char     errmsg[300];
    netsnmp_cache  *cache;

    /* Update the fsys H/W module */
    cache = netsnmp_fsys_get_cache();
    netsnmp_cache_check_and_reload(cache);

tryAgain:
    if (header_simple_table
        (vp, name, length, exact, var_len, write_method, numdisks))
        return (NULL);
    disknum = name[*length - 1] - 1;
    entry = disks[disknum];
    if ( !entry ) {
        if (!exact || !(entry->flags & NETSNMP_FS_FLAG_UCD))
            goto tryAgain;
        return NULL;
    }

    switch (vp->magic) {
    case MIBINDEX:
        long_ret = disknum + 1;
        return ((u_char *) (&long_ret));
    case ERRORNAME:            /* DISKPATH */
        *var_len = strlen(entry->path);
        return ((u_char *)entry->path);
    case DISKDEVICE:
        *var_len = strlen(entry->device);
        return ((u_char *)entry->device);
    case DISKMINIMUM:
        long_ret = entry->minspace;
        return ((u_char *) (&long_ret));
    case DISKMINPERCENT:
        long_ret = entry->minpercent;
        return ((u_char *) (&long_ret));

    case DISKTOTAL:
        val = netsnmp_fsys_size_ull(entry);
        if (val > MAX_INT_32)
            long_ret = MAX_INT_32;
        else
            long_ret = (long)val;
        return ((u_char *) (&long_ret));
    case DISKTOTALLOW:
        long_ret = netsnmp_fsys_size_ull(entry) & MAX_UINT_32;
        return ((u_char *) (&long_ret));
    case DISKTOTALHIGH:
        long_ret = netsnmp_fsys_size_ull(entry) >> 32;
        return ((u_char *) (&long_ret));
        
    case DISKAVAIL:
        val = netsnmp_fsys_avail_ull(entry);
        if (val > MAX_INT_32)
            long_ret = MAX_INT_32;
        else
            long_ret = (long)val;
        return ((u_char *) (&long_ret));
    case DISKAVAILLOW:
        long_ret = netsnmp_fsys_avail_ull(entry) & MAX_UINT_32;
        return ((u_char *) (&long_ret));
    case DISKAVAILHIGH:
        long_ret = netsnmp_fsys_avail_ull(entry) >> 32;
        return ((u_char *) (&long_ret));

    case DISKUSED:
        val = netsnmp_fsys_used_ull(entry);
        if (val > MAX_INT_32)
            long_ret = MAX_INT_32;
        else
            long_ret = (long)val;
        return ((u_char *) (&long_ret));
    case DISKUSEDLOW:
        long_ret = netsnmp_fsys_used_ull(entry) & MAX_UINT_32;
        return ((u_char *) (&long_ret));
    case DISKUSEDHIGH:
        long_ret = netsnmp_fsys_used_ull(entry) >> 32;
        return ((u_char *) (&long_ret));

    case DISKPERCENT:
        long_ret = _percent( entry->used, entry->size );
        return ((u_char *) (&long_ret));

    case DISKPERCENTNODE:
        long_ret = _percent( entry->inums_total - entry->inums_avail, entry->inums_total );
        return ((u_char *) (&long_ret));

    case ERRORFLAG:
        long_ret = 0;
        val = netsnmp_fsys_avail_ull(entry);
        if (( entry->minspace >= 0 ) &&
            ( val < entry->minspace ))
            long_ret = 1;
        else if (( entry->minpercent >= 0 ) &&
                 (_percent( entry->avail, entry->size ) < entry->minpercent ))
            long_ret = 1;
        return ((u_char *) (&long_ret));

    case ERRORMSG:
        errmsg[0] = 0;
        val = netsnmp_fsys_avail_ull(entry);
        if (( entry->minspace >= 0 ) &&
            ( val < entry->minspace ))
                snprintf(errmsg, sizeof(errmsg),
                        "%s: less than %d free (= %d)",
                        entry->path, entry->minspace,
                        (int) val);
        else if (( entry->minpercent >= 0 ) &&
                 (_percent( entry->avail, entry->size ) < entry->minpercent ))
                snprintf(errmsg, sizeof(errmsg),
                        "%s: less than %d%% free (= %d%%)",
                        entry->path, entry->minpercent,
                        _percent( entry->avail, entry->size ));
        errmsg[ sizeof(errmsg)-1 ] = 0;
        *var_len = strlen(errmsg);
        return ((u_char *) (errmsg));
    }
    return NULL;
}
