blob: d1e3943eb307093d0cc38a9e1feed5702db4cd92 [file] [log] [blame]
/*
* 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
# 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/types.h>
#include <net-snmp/library/snmp-tc.h> /* for "internal" definitions */
#include <net-snmp/library/snmp_api.h>
u_char *
date_n_time ( time_t *when, size_t *length)
{
struct tm *tm_p;
static u_char string[11];
/*
* 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 );
* (short *)string = htons( tm_p->tm_year+1900 );
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
*/
#ifndef SYSV
#ifndef aix
#define timezone tm_p->tm_gmtoff
#endif
#endif
if ( timezone > 0 )
string[8] = '-';
else
string[8] = '+';
string[9] = abs(timezone)/3600;
string[10] = (abs(timezone) - 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* string )
{
struct tm tm;
if ( strlen(string) < 24 )
return 0;
/* Month */
if ( !strncmp( string+4, "Jan", 3 )) tm.tm_mon = 0;
else if ( !strncmp( string+4, "Feb", 3 )) tm.tm_mon = 1;
else if ( !strncmp( string+4, "Mar", 3 )) tm.tm_mon = 2;
else if ( !strncmp( string+4, "Apr", 3 )) tm.tm_mon = 3;
else if ( !strncmp( string+4, "May", 3 )) tm.tm_mon = 4;
else if ( !strncmp( string+4, "Jun", 3 )) tm.tm_mon = 5;
else if ( !strncmp( string+4, "Jul", 3 )) tm.tm_mon = 6;
else if ( !strncmp( string+4, "Aug", 3 )) tm.tm_mon = 7;
else if ( !strncmp( string+4, "Sep", 3 )) tm.tm_mon = 8;
else if ( !strncmp( string+4, "Oct", 3 )) tm.tm_mon = 9;
else if ( !strncmp( string+4, "Nov", 3 )) tm.tm_mon = 10;
else if ( !strncmp( string+4, "Dec", 3 )) tm.tm_mon = 11;
else return 0;
tm.tm_mday = atoi(string+8);
tm.tm_hour = atoi(string+11);
tm.tm_min = atoi(string+14);
tm.tm_sec = atoi(string+17);
tm.tm_year = atoi(string+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, int storage_type )
{
/*
// 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_INCONSISTENTVALUE;
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_INCONSISTENTVALUE;
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_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;
}