/*
 *  Host Resources MIB - utility functions - hr_utils.c
 *
 */


#include <net-snmp/net-snmp-config.h>
#include <sys/types.h>
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <ctype.h>
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif

#if TIME_WITH_SYS_TIME
#ifdef WIN32
# 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

#include <net-snmp/types.h>
#include <net-snmp/library/snmp-tc.h>   /* for "internal" definitions */
#include <net-snmp/library/snmp_api.h>

/*
  DateAndTime ::= TEXTUAL-CONVENTION
    DISPLAY-HINT "2d-1d-1d,1d:1d:1d.1d,1a1d:1d"
    STATUS       current
    DESCRIPTION
            "A date-time specification.

            field  octets  contents                  range
            -----  ------  --------                  -----
              1      1-2   year*                     0..65536
              2       3    month                     1..12
              3       4    day                       1..31
              4       5    hour                      0..23
              5       6    minutes                   0..59
              6       7    seconds                   0..60
                           (use 60 for leap-second)
              7       8    deci-seconds              0..9
              8       9    direction from UTC        '+' / '-'
              9      10    hours from UTC*           0..13
             10      11    minutes from UTC          0..59

            * Notes:
            - the value of year is in network-byte order
            - daylight saving time in New Zealand is +13

            For example, Tuesday May 26, 1992 at 1:30:15 PM EDT would be
            displayed as:

                             1992-5-26,13:30:15.0,-4:0

            Note that if only local time is known, then timezone
            information (fields 8-10) is not present."
    SYNTAX       OCTET STRING (SIZE (8 | 11))
*/

int
netsnmp_dateandtime_set_buf_from_vars(u_char *buf, size_t *bufsize,
                                      u_short year, u_char month, u_char day,
                                      u_char hour, u_char minutes,
                                      u_char seconds, u_char deci_seconds,
                                      int utc_offset_direction,
                                      u_char utc_offset_hours,
                                      u_char utc_offset_minutes)
{
    u_short tmp_year = htons(year);

    /*
     * if we have a utc offset, need 11 bytes. Otherwise we
     * just need 8 bytes.
     */
    if(utc_offset_direction) {
        if(*bufsize < 11)
            return SNMPERR_RANGE;

        /*
         * set utc offset data
         */
        buf[8] = (utc_offset_direction < 0) ? '-' : '+';
        buf[9] = utc_offset_hours;
        buf[10] = utc_offset_minutes;
        *bufsize = 11;
    }
    else if(*bufsize < 8)
        return SNMPERR_RANGE;
    else
        *bufsize = 8;

    /*
     * set basic date/time data
     */
    memcpy(buf, &tmp_year, sizeof(tmp_year));
    buf[2] = month;
    buf[3] = day;
    buf[4] = hour;
    buf[5] = minutes;
    buf[6] = seconds;
    buf[7] = deci_seconds;

    return SNMPERR_SUCCESS;
}

u_char         *
date_n_time(time_t * when, size_t * length)
{
    struct tm      *tm_p;
    static u_char   string[11];
    unsigned short yauron;

    /*
     * Null time
     */
    if (when == NULL || *when == 0 || *when == (time_t) - 1) {
        string[0] = 0;
        string[1] = 0;
        string[2] = 1;
        string[3] = 1;
        string[4] = 0;
        string[5] = 0;
        string[6] = 0;
        string[7] = 0;
        *length = 8;
        return string;
    }


    /*
     * Basic 'local' time handling
     */
    tm_p = localtime(when);
    yauron = tm_p->tm_year + 1900;
    string[0] = (u_char)(yauron >> 8);
    string[1] = (u_char)yauron;
    string[2] = tm_p->tm_mon + 1;
    string[3] = tm_p->tm_mday;
    string[4] = tm_p->tm_hour;
    string[5] = tm_p->tm_min;
    string[6] = tm_p->tm_sec;
    string[7] = 0;
    *length = 8;

#ifndef cygwin
    /*
     * Timezone offset
     */
    {
#ifdef STRUCT_TM_HAS_TM_GMTOFF
    const int tzoffset = -tm_p->tm_gmtoff;     /* Seconds east of UTC */
#else
    const int tzoffset = timezone;             /* Seconds west of UTC */
#endif
    if (tzoffset > 0)
        string[8] = '-';
    else
        string[8] = '+';
    string[9] = abs(tzoffset) / 3600;
    string[10] = (abs(tzoffset) - string[9] * 3600) / 60;
    *length = 11;
    }
#endif

#ifdef SYSV
    /*
     * Daylight saving time
     */
    if (tm_p->tm_isdst > 0) {
        /*
         * Assume add one hour 
         */
        if (string[8] == '-')
            --string[9];
        else
            ++string[9];

        if (string[9] == 0)
            string[8] = '+';
    }
#endif

    return string;
}


time_t
ctime_to_timet(char *str)
{
    struct tm       tm;

    if (strlen(str) < 24)
        return 0;

    /*
     * Month 
     */
    if (!strncmp(str + 4, "Jan", 3))
        tm.tm_mon = 0;
    else if (!strncmp(str + 4, "Feb", 3))
        tm.tm_mon = 1;
    else if (!strncmp(str + 4, "Mar", 3))
        tm.tm_mon = 2;
    else if (!strncmp(str + 4, "Apr", 3))
        tm.tm_mon = 3;
    else if (!strncmp(str + 4, "May", 3))
        tm.tm_mon = 4;
    else if (!strncmp(str + 4, "Jun", 3))
        tm.tm_mon = 5;
    else if (!strncmp(str + 4, "Jul", 3))
        tm.tm_mon = 6;
    else if (!strncmp(str + 4, "Aug", 3))
        tm.tm_mon = 7;
    else if (!strncmp(str + 4, "Sep", 3))
        tm.tm_mon = 8;
    else if (!strncmp(str + 4, "Oct", 3))
        tm.tm_mon = 9;
    else if (!strncmp(str + 4, "Nov", 3))
        tm.tm_mon = 10;
    else if (!strncmp(str + 4, "Dec", 3))
        tm.tm_mon = 11;
    else
        return 0;

    tm.tm_mday = atoi(str + 8);
    tm.tm_hour = atoi(str + 11);
    tm.tm_min = atoi(str + 14);
    tm.tm_sec = atoi(str + 17);
    tm.tm_year = atoi(str + 20) - 1900;

    /*
     *  Cope with timezone and DST
     */

#ifdef SYSV
    if (daylight)
        tm.tm_isdst = 1;

    tm.tm_sec -= timezone;
#endif

    return (mktime(&tm));
}

/*
 * blatantly lifted from opensmp 
 */
char
check_rowstatus_transition(int oldValue, int newValue)
{
    /*
     * From the SNMPv2-TC MIB:
     *                                          STATE
     *               +--------------+-----------+-------------+-------------
     *               |      A       |     B     |      C      |      D
     *               |              |status col.|status column|
     *               |status column |    is     |      is     |status column
     *     ACTION    |does not exist|  notReady | notInService|  is active
     * --------------+--------------+-----------+-------------+-------------
     * set status    |noError    ->D|inconsist- |inconsistent-|inconsistent-
     * column to     |       or     |   entValue|        Value|        Value
     * createAndGo   |inconsistent- |           |             |
     *               |         Value|           |             |
     * --------------+--------------+-----------+-------------+-------------
     * set status    |noError  see 1|inconsist- |inconsistent-|inconsistent-
     * column to     |       or     |   entValue|        Value|        Value
     * createAndWait |wrongValue    |           |             |
     * --------------+--------------+-----------+-------------+-------------
     * set status    |inconsistent- |inconsist- |noError      |noError
     * column to     |         Value|   entValue|             |
     * active        |              |           |             |
     *               |              |     or    |             |
     *               |              |           |             |
     *               |              |see 2   ->D|see 8     ->D|          ->D
     * --------------+--------------+-----------+-------------+-------------
     * set status    |inconsistent- |inconsist- |noError      |noError   ->C
     * column to     |         Value|   entValue|             |
     * notInService  |              |           |             |
     *               |              |     or    |             |      or
     *               |              |           |             |
     *               |              |see 3   ->C|          ->C|see 6
     * --------------+--------------+-----------+-------------+-------------
     * set status    |noError       |noError    |noError      |noError   ->A
     * column to     |              |           |             |      or
     * destroy       |           ->A|        ->A|          ->A|see 7
     * --------------+--------------+-----------+-------------+-------------
     * set any other |see 4         |noError    |noError      |see 5
     * column to some|              |           |             |
     * value         |              |      see 1|          ->C|          ->D
     * --------------+--------------+-----------+-------------+-------------
     
     *             (1) goto B or C, depending on information available to the
     *             agent.
     
     *             (2) if other variable bindings included in the same PDU,
     *             provide values for all columns which are missing but
     *             required, and all columns have acceptable values, then
     *             return noError and goto D.
     
     *             (3) if other variable bindings included in the same PDU,
     *             provide legal values for all columns which are missing but
     *             required, then return noError and goto C.
     
     *             (4) at the discretion of the agent, the return value may be
     *             either:
     
     *                  inconsistentName:  because the agent does not choose to
     *                  create such an instance when the corresponding
     *                  RowStatus instance does not exist, or
     
     *                  inconsistentValue:  if the supplied value is
     *                  inconsistent with the state of some other MIB object's
     *                  value, or
     
     *                  noError: because the agent chooses to create the
     *                  instance.
     
     *             If noError is returned, then the instance of the status
     *             column must also be created, and the new state is B or C,
     *             depending on the information available to the agent.  If
     *             inconsistentName or inconsistentValue is returned, the row
     *             remains in state A.
     
     *             (5) depending on the MIB definition for the column/table,
     *             either noError or inconsistentValue may be returned.
     
     *             (6) the return value can indicate one of the following
     *             errors:
     
     *                  wrongValue: because the agent does not support
     *                  notInService (e.g., an agent which does not support
     *                  createAndWait), or
     
     *                  inconsistentValue: because the agent is unable to take
     *                  the row out of service at this time, perhaps because it
     *                  is in use and cannot be de-activated.
     
     *             (7) the return value can indicate the following error:
     
     *                  inconsistentValue: because the agent is unable to
     *                  remove the row at this time, perhaps because it is in
     *                  use and cannot be de-activated.
     
     *             (8) the transition to D can fail, e.g., if the values of the
     *             conceptual row are inconsistent, then the error code would
     *             be inconsistentValue.
     
     *             NOTE: Other processing of (this and other varbinds of) the
     *             set request may result in a response other than noError
     *             being returned, e.g., wrongValue, noCreation, etc.
     */

    switch (newValue) {
        /*
         * these two end up being equivelent as far as checking the 
         */
        /*
         * status goes, although the final states are based on the 
         */
        /*
         * newValue. 
         */
    case RS_ACTIVE:
    case RS_NOTINSERVICE:
        if (oldValue == RS_NOTINSERVICE || oldValue == RS_ACTIVE);
        else
            return SNMP_ERR_INCONSISTENTVALUE;
        break;

    case RS_NOTREADY:
        /*
         * Illegal set value. 
         */
        return SNMP_ERR_WRONGVALUE;
        break;

    case RS_CREATEANDGO:
        if (oldValue != RS_NONEXISTENT)
            /*
             * impossible, we already exist. 
             */
            return SNMP_ERR_INCONSISTENTVALUE;
        break;

    case RS_CREATEANDWAIT:
        if (oldValue != RS_NONEXISTENT)
            /*
             * impossible, we already exist. 
             */
            return SNMP_ERR_INCONSISTENTVALUE;
        break;

    case RS_DESTROY:
        break;

    default:
        return SNMP_ERR_WRONGVALUE;
        break;
    }

    return SNMP_ERR_NOERROR;
}

char
check_storage_transition(int oldValue, int newValue)
{
    /*
     * From the SNMPv2-TC MIB:
     
     *             "Describes the memory realization of a conceptual row.  A
     *             row which is volatile(2) is lost upon reboot.  A row which
     *             is either nonVolatile(3), permanent(4) or readOnly(5), is
     *             backed up by stable storage.  A row which is permanent(4)
     *             can be changed but not deleted.  A row which is readOnly(5)
     *             cannot be changed nor deleted.
     
     *             If the value of an object with this syntax is either
     *             permanent(4) or readOnly(5), it cannot be written.
     *             Conversely, if the value is either other(1), volatile(2) or
     *             nonVolatile(3), it cannot be modified to be permanent(4) or
     *             readOnly(5).  (All illegal modifications result in a
     *             'wrongValue' error.)
     
     *             Every usage of this textual convention is required to
     *             specify the columnar objects which a permanent(4) row must
     *             at a minimum allow to be writable."
     */
    switch (oldValue) {
    case SNMP_STORAGE_PERMANENT:
    case SNMP_STORAGE_READONLY:
        return SNMP_ERR_INCONSISTENTVALUE;

    case SNMP_STORAGE_NONE:
    case SNMP_STORAGE_OTHER:
    case SNMP_STORAGE_VOLATILE:
    case SNMP_STORAGE_NONVOLATILE:
        if (newValue == SNMP_STORAGE_PERMANENT ||
            newValue == SNMP_STORAGE_READONLY)
            return SNMP_ERR_INCONSISTENTVALUE;
    }

    return SNMP_ERR_NOERROR;
}
