496 lines
14 KiB
C
496 lines
14 KiB
C
/* usrGetNextSetCode.c - common support code for artibrary Get, Next, and Set */
|
|
|
|
/* Copyright 2004 Wind River Systems, Inc. */
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01c,21apr10,m_z VxWorks 64-bit support
|
|
(WIND00193649)
|
|
01b,04may04,dlr Added error codes, use wmbTableLib instead of wmbDataXxx for SNMP data.
|
|
01a,24mar04,dlr written.
|
|
*/
|
|
|
|
/*
|
|
DESCRIPTION
|
|
This sample user code provides uniform access to arbitrary WindMarks with arbitrary
|
|
argument/instance information as part of the name.
|
|
|
|
It can access data in purely string format or as native data.
|
|
|
|
It updates the instance/argument part of the WindMark name when using getnext.
|
|
|
|
This sample code will use the wmbTableLib for SNMP WindMark access, to better capture
|
|
and report errors. In particular, in WM 4.3 GetNext for SNMP objects must use wmbTableLib
|
|
for access through MIBWay.
|
|
|
|
This code provides support for the sample demonstration CLI commands wmget, wmnext, and wmset.
|
|
|
|
NOMANUAL
|
|
*/
|
|
|
|
#include "wm.h"
|
|
#include "wmb.h"
|
|
#include "usrGetNextSetCode.h"
|
|
#include "wrn/wm/backplane/wmbTableLib.h"
|
|
|
|
#include "errnoLib.h"
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* usrWindMarkIsWmbTable - Set flag if registered WindMark is controled by wmbTableLib
|
|
* - i.e. DB_FLAG_OID_COOKIE_K flag is set
|
|
*
|
|
* NOMANUAL
|
|
*
|
|
* RETURNS: OK if successful, or
|
|
* ERROR if WindMark could not be found
|
|
*/
|
|
|
|
STATUS usrWindMarkIsWmbTable
|
|
(
|
|
char * szName, /* WindMark name */
|
|
BOOL * bIsWmbTable,/* Pointer to type variable to set */
|
|
BOOL * bIsOidTable,/* Pointer to type variable to set */
|
|
DATATYPE_T *wmType /* Data type of object */
|
|
)
|
|
{
|
|
DB_ENTRY_T * pDBEntry;
|
|
char *pInstance;
|
|
char ch = '\0';
|
|
|
|
*bIsWmbTable = FALSE;
|
|
*bIsOidTable = FALSE;
|
|
*wmType = DATATYPE_STRING_K;
|
|
|
|
/* strip off existing instance, if any */
|
|
if (NULL == (pInstance = strchr (szName, '(')))
|
|
pInstance = strchr (szName, '.');
|
|
if (NULL != pInstance)
|
|
{
|
|
ch = *pInstance;
|
|
*pInstance = '\0';
|
|
}
|
|
|
|
/* Get the DB entry for this WindMark, any component */
|
|
pDBEntry = wmbDBEntryGet (wmbBackplaneDBGet (wmbBackplaneGet()), szName, NULL, FALSE);
|
|
if (NULL == pDBEntry)
|
|
{
|
|
wmError (ERROR_GENERAL_NOT_FOUND, "usrWindMarkIsWmbTable: no such WindMark");
|
|
return ERROR;
|
|
}
|
|
|
|
*bIsWmbTable = (wmbEntry(pDBEntry)->table) != NULL;
|
|
*bIsOidTable = (wmbDBEntryFlagGet(pDBEntry,DB_FLAG_OID_COOKIE_K));
|
|
*wmType = (wmbEntryTypeGet(pDBEntry));
|
|
|
|
/* restore instance separater, if any */
|
|
if (NULL != pInstance)
|
|
*pInstance = ch;
|
|
|
|
return OK;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* usrParseAndRequest - fetch value of a WindMark, GET/GETNEXT/SET, Scalar/Table Object
|
|
*
|
|
* This routine will fetch a context-less WindMark name. It will determine if it
|
|
* member of an SNMP table (and thus require the instance in binary OID form),
|
|
* a WindMark table member, or a simple SNMP/WindMark scalar.
|
|
*
|
|
* It will work for both native and string types and instances/arguments.
|
|
*
|
|
* Instances are extracted and restored to the string WindMark name.
|
|
*
|
|
* In addtion to a basic GET request, it can process a GETNEXT updating the
|
|
* returned instance information as appropriate. An End-Of-Table is indicated
|
|
* by the instance not changing.
|
|
*
|
|
* NOTE: processing GETNEXT on a SNMP table object requires using the wmbTableLib API
|
|
*
|
|
* NOMANUAL
|
|
*
|
|
* RETURNS: OK if the object has been fetched successfully, or
|
|
* ERROR if illegal name or instance.
|
|
*/
|
|
|
|
STATUS usrParseAndRequest
|
|
(
|
|
WMB_SESSION_T * pSession, /* WMB Session used by this request */
|
|
char * szName, /* Original WindMark name */
|
|
void * szValue, /* WindMark value buffer */
|
|
ubyte4 nValueMax, /* WindMark value buffer max size */
|
|
ubyte4* pValueSize, /* size of new value */
|
|
ubyte4 nCmnd, /* CMD_GET_K | CMD_GET_NEXT_K | CMD_SET_K */
|
|
BOOL bIsString /* TRUE=string, FALSE=native: value&inst */
|
|
)
|
|
{
|
|
/* Local value fetch */
|
|
sbyte *pInstance,*pTemp;
|
|
sbyte4 instanceLength;
|
|
sbyte4 instanceMaxLength;
|
|
char instanceSep;
|
|
char *szNameBf;
|
|
BOOL bIsTableObject = FALSE;
|
|
BOOL bIsSNMPObject = FALSE;
|
|
BOOL bIsRootInstance = FALSE;
|
|
BOOL bInstanceInOidForm = FALSE;
|
|
char * pStrInstance = NULL;
|
|
sbyte4 nStrInstanceLen = 0;
|
|
sbyte4 nStrInstanceMax = 0;
|
|
DATATYPE_T wmType = DATATYPE_STRING_K;
|
|
STATUS status = OK;
|
|
#ifdef _WRS_CONFIG_LP64
|
|
sbyte8 valueSize64;
|
|
#endif
|
|
|
|
/* Got to have a name to work with */
|
|
if ( szName == NULL )
|
|
{
|
|
return ERROR;
|
|
}
|
|
|
|
/* Create temp and modifiable name buffer */
|
|
if (NULL == (szNameBf = wmMalloc(kMagicMarkupBufferSize)))
|
|
{
|
|
return ERROR;
|
|
}
|
|
|
|
/* Make safe local copy of name */
|
|
strcpy(szNameBf,szName);
|
|
|
|
/* If this is a table WindMark with no instance, attach appropriate */
|
|
if (OK != usrWindMarkIsWmbTable(szNameBf, &bIsTableObject, &bIsSNMPObject,&wmType))
|
|
{
|
|
return ERROR;
|
|
}
|
|
|
|
/* A name without instance may be a root name of a table member */
|
|
if (bIsTableObject && (NULL == strchr (szNameBf, '(')) && (NULL == strchr (szNameBf, '.')))
|
|
{
|
|
bIsRootInstance = TRUE;
|
|
strcat(szNameBf,(bIsSNMPObject) ? ".":"()");
|
|
}
|
|
|
|
|
|
/* Extract any instance/argument field */
|
|
pInstance = NULL;
|
|
/* extract any instance/argument from WindMark name */
|
|
if (NULL != (pInstance = strchr (szNameBf, '(')))
|
|
{
|
|
*pInstance++ = '\0';
|
|
|
|
/* remove closing paren */
|
|
if (NULL !=(pTemp = strrchr (pInstance, ')')))
|
|
*pTemp = '\0';
|
|
|
|
instanceLength = (sbyte4)strlen(pInstance) + 1;
|
|
instanceSep = '(';
|
|
}
|
|
else if (NULL != (pInstance = strchr (szNameBf, '.')))
|
|
{
|
|
*pInstance++ = '\0';
|
|
instanceLength = (sbyte4)strlen(pInstance) + 1;
|
|
instanceMaxLength = kMagicMarkupBufferSize - (sbyte4)strlen(szNameBf) - 1;
|
|
instanceSep = '.';
|
|
|
|
/* The pInstance is really the string OID buffer. If GetNext transaction, Swap in binary version. */
|
|
|
|
bInstanceInOidForm = (CMD_GET_NEXT_K == nCmnd);
|
|
|
|
if (bInstanceInOidForm)
|
|
{
|
|
pStrInstance = pInstance;
|
|
nStrInstanceLen = instanceLength;
|
|
nStrInstanceMax = instanceMaxLength;
|
|
|
|
instanceMaxLength = 128*4;
|
|
pInstance = wmMalloc((ubyte4)instanceMaxLength);
|
|
|
|
if (NULL != pInstance)
|
|
{
|
|
if ((0 == nStrInstanceLen) ||
|
|
(OK != wmConvertStrToOid(pStrInstance, (ubyte4 *) pInstance, instanceMaxLength, &instanceLength)) )
|
|
{
|
|
instanceLength = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
instanceMaxLength = 0;
|
|
instanceLength = 0;
|
|
}
|
|
|
|
if (OK != wmbTableCreate(pSession, szNameBf, (0 != instanceLength) ? pStrInstance:NULL, szNameBf))
|
|
{
|
|
DEBUG_MSG_1("usrParseAndRequest: wmbTableCreate(%s) ERROR! =========\n",szNameBf);
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
/* the buffer after the name is available for a new instance */
|
|
pInstance = &szNameBf[strlen(szNameBf) + 1];
|
|
memset(pInstance,0,4);
|
|
instanceLength = 0;
|
|
instanceSep = '\0';
|
|
}
|
|
instanceMaxLength = kMagicMarkupBufferSize - (sbyte4)strlen(szNameBf) - 1;
|
|
|
|
/* Time to do the transaction */
|
|
if (!bIsString)
|
|
{
|
|
if (CMD_SET_K == nCmnd)
|
|
{
|
|
status = wmbDataNativeSet (pSession, szNameBf,
|
|
pInstance, instanceLength,
|
|
szValue, nValueMax);
|
|
}
|
|
else if ((CMD_GET_NEXT_K == nCmnd) && bIsSNMPObject)
|
|
{
|
|
/* GETNEXT for bIsSNMPObject objects are managed by wmbTableLib */
|
|
void *table = wmbSessionTableGet(pSession);
|
|
|
|
/* If Root Instance, then we have the first row data already */
|
|
if (!bIsRootInstance)
|
|
status = wmbTableRowNext(table);
|
|
|
|
if (OK == status)
|
|
{
|
|
WM_BUFFER_T * oidSfx;
|
|
|
|
/* Extract the GETNEXT string value !Use second half of value buffer! */
|
|
wmbTableGet(pSession,szNameBf, ((char*)szValue)+(nValueMax/2),nValueMax/2);
|
|
*pValueSize = (ubyte4)strlen( (char *)(((char*)szValue)+(nValueMax/2)) )+1;
|
|
/* Convert to native type */
|
|
#ifndef _WRS_CONFIG_LP64
|
|
wmConvert( (((char*)szValue)+(nValueMax/2)) ,*pValueSize,DATATYPE_STRING_K,
|
|
szValue,nValueMax,wmType,(sbyte4 *) pValueSize);
|
|
#else
|
|
wmConvert( (((char*)szValue)+(nValueMax/2)) ,*pValueSize,DATATYPE_STRING_K,
|
|
szValue,nValueMax,wmType, &valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
#endif
|
|
/* Extract the new GETNEXT instance */
|
|
oidSfx = wmbTableInstanceSfxGet (pSession, szNameBf);
|
|
instanceLength = (sbyte4)wmBufferUsedGet(oidSfx);
|
|
memcpy(pInstance,wmBufferDataGet(oidSfx),(ubyte4)instanceLength);
|
|
}
|
|
else
|
|
{
|
|
if (wmErrNo()!=ERROR_TABLE_END_OF_TABLE)
|
|
{
|
|
errnoSet(ERROR_TABLE_END_OF_TABLE);
|
|
}
|
|
}
|
|
}
|
|
else if ((CMD_GET_K == nCmnd) && bIsSNMPObject)
|
|
{
|
|
/* This GET for bIsSNMPObject objects are managed by wmbTableLib */
|
|
|
|
/* Extract the GET string value !Use second half of value buffer! */
|
|
status = wmbTableGet(pSession,szNameBf,((char*)szValue)+(nValueMax/2),nValueMax/2);
|
|
*pValueSize = (ubyte4)strlen( (char *)(((char*)szValue)+(nValueMax/2)) )+1;
|
|
/* Convert to native type */
|
|
#ifndef _WRS_CONFIG_LP64
|
|
wmConvert( (&((char*)szValue)[nValueMax/2]) ,*pValueSize ,DATATYPE_STRING_K,
|
|
szValue,nValueMax,wmType, (sbyte4 *) pValueSize);
|
|
#else
|
|
wmConvert( (&((char*)szValue)[nValueMax/2]) ,*pValueSize ,DATATYPE_STRING_K,
|
|
szValue,nValueMax,wmType, &valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
#endif
|
|
}
|
|
else if (CMD_GET_NEXT_K == nCmnd)
|
|
#ifndef _WRS_CONFIG_LP64
|
|
status = wmbDataNativeGetNext (pSession, szNameBf,
|
|
pInstance, &instanceLength, instanceMaxLength,DATATYPE_STRING_K,
|
|
szValue, nValueMax,
|
|
(sbyte4 *) pValueSize);
|
|
#else
|
|
{
|
|
status = wmbDataNativeGetNext (pSession, szNameBf,
|
|
pInstance, &instanceLength, instanceMaxLength,DATATYPE_STRING_K,
|
|
szValue, nValueMax,
|
|
&valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
}
|
|
#endif
|
|
else
|
|
#ifndef _WRS_CONFIG_LP64
|
|
status = wmbDataNativeGet (pSession, szNameBf,
|
|
pInstance, instanceLength,
|
|
szValue, nValueMax,
|
|
(sbyte4 *) pValueSize);
|
|
#else
|
|
{
|
|
status = wmbDataNativeGet (pSession, szNameBf,
|
|
pInstance, instanceLength,
|
|
szValue, nValueMax,
|
|
&valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
}
|
|
#endif
|
|
if (OK != status)
|
|
{
|
|
/* Handler Errors here */
|
|
DEBUG_MSG_1("usrParseAndRequest: wmbDataNativeGet(%s) ERROR! =========\n",szNameBf);
|
|
memset(szValue,0,4);
|
|
*pValueSize = 4;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (CMD_SET_K == nCmnd)
|
|
{
|
|
status = wmbDataStringSet (pSession, szNameBf,
|
|
pInstance, instanceLength,
|
|
szValue, (sbyte4)STRLEN(szValue));
|
|
}
|
|
else if ((CMD_GET_NEXT_K == nCmnd) && bIsSNMPObject)
|
|
{
|
|
/* GETNEXT for bIsSNMPObject objects are managed by wmbTableLib */
|
|
void *table = wmbSessionTableGet(pSession);
|
|
/* If Root Instance, then we have the first row data already */
|
|
if (!bIsRootInstance)
|
|
status = wmbTableRowNext(table);
|
|
|
|
if (OK == status)
|
|
{
|
|
WM_BUFFER_T * oidSfx;
|
|
|
|
/* Extract the GETNEXT string value */
|
|
wmbTableGet(pSession,szNameBf,szValue,nValueMax);
|
|
*pValueSize = (ubyte4)strlen(szValue)+1;
|
|
|
|
/* Extract the new GETNEXT instance */
|
|
oidSfx = wmbTableInstanceSfxGet (pSession, szNameBf);
|
|
instanceLength = (sbyte4)wmBufferUsedGet(oidSfx);
|
|
memcpy(pInstance,wmBufferDataGet(oidSfx),(ubyte4)instanceLength);
|
|
}
|
|
else
|
|
{
|
|
if (wmErrNo()!=ERROR_TABLE_END_OF_TABLE)
|
|
{
|
|
errnoSet(ERROR_TABLE_END_OF_TABLE);
|
|
}
|
|
}
|
|
}
|
|
else if ((CMD_GET_K == nCmnd) && bIsSNMPObject)
|
|
{
|
|
/* This GET for bIsSNMPObject objects are managed by wmbTableLib */
|
|
|
|
/* Extract the GET string value */
|
|
status = wmbTableGet(pSession,szNameBf,szValue,nValueMax);
|
|
*pValueSize = (ubyte4)strlen(szValue)+1;
|
|
}
|
|
else if (CMD_GET_NEXT_K == nCmnd)
|
|
#ifndef _WRS_CONFIG_LP64
|
|
status = wmbDataStringGetNext (pSession, szNameBf,
|
|
pInstance, &instanceLength, instanceMaxLength,DATATYPE_STRING_K,
|
|
szValue, nValueMax,
|
|
(sbyte4 *) pValueSize);
|
|
#else
|
|
{
|
|
status = wmbDataStringGetNext (pSession, szNameBf,
|
|
pInstance, &instanceLength, instanceMaxLength,DATATYPE_STRING_K,
|
|
szValue, nValueMax,
|
|
&valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
}
|
|
#endif
|
|
else
|
|
#ifndef _WRS_CONFIG_LP64
|
|
status = wmbDataStringGet (pSession, (sbyte *) szNameBf,
|
|
pInstance, instanceLength,
|
|
(sbyte *) szValue, kMagicMarkupBufferSize,
|
|
(sbyte4 *) pValueSize);
|
|
#else
|
|
{
|
|
status = wmbDataStringGet (pSession, (sbyte *) szNameBf,
|
|
pInstance, instanceLength,
|
|
(sbyte *) szValue, kMagicMarkupBufferSize,
|
|
&valueSize64);
|
|
*pValueSize = (ubyte4)valueSize64;
|
|
}
|
|
#endif
|
|
|
|
if (OK != status)
|
|
{
|
|
/* Handler Errors here */
|
|
DEBUG_MSG_1("usrParseAndRequest: wmbDataStringGet(%s) ERROR! =========\n",szNameBf);
|
|
strcpy(szValue,(wmErrNo()==ERROR_TABLE_END_OF_TABLE) ? "<EndTable>":"<NoValue>");
|
|
*pValueSize = (ubyte4)strlen(szValue);
|
|
}
|
|
|
|
/* insure actual string length from wmbDataStringGet !!! */
|
|
if (((ubyte4)strlen(szValue)+1) != *pValueSize)
|
|
{
|
|
*pValueSize = (ubyte4)strlen(szValue) + 1;
|
|
}
|
|
}
|
|
|
|
/* Put any binary OID back to string OID */
|
|
if (bInstanceInOidForm)
|
|
{
|
|
char *temp;
|
|
|
|
if ((NULL == pInstance) || (0 == instanceLength) ||
|
|
(OK != wmConvertOidToString(
|
|
(ubyte4 *) pInstance,
|
|
instanceLength,
|
|
pStrInstance,
|
|
nStrInstanceMax,
|
|
&nStrInstanceLen))
|
|
)
|
|
{
|
|
*pStrInstance = '\0';
|
|
}
|
|
|
|
/* swap, so that pInstance is string OID ptr, and pStrInstance is temp buffer */
|
|
temp = pInstance;
|
|
pInstance = pStrInstance;
|
|
pStrInstance = temp;
|
|
instanceLength = nStrInstanceLen; /* we do not care about nStrInstanceLen after this */
|
|
}
|
|
|
|
/* The new GETNEXT instance needs some propagation */
|
|
if (CMD_GET_NEXT_K == nCmnd)
|
|
{
|
|
/* remember that pInstance is one (delim) character past end of name */
|
|
if ('\0' == instanceSep)
|
|
{
|
|
/* Force an instance delim if this base base instance (i.e. no instance) */
|
|
instanceSep = (char)((bIsSNMPObject) ? '.':'(');
|
|
}
|
|
|
|
pInstance--;
|
|
*pInstance = instanceSep;
|
|
if ('(' == instanceSep)
|
|
strcat(pInstance,")");
|
|
|
|
/* UPDATE INPUT NAME BUFFER WITH NEW NAME*/
|
|
strcpy(szName,szNameBf);
|
|
}
|
|
|
|
/* Release any wmbTable structure for this object */
|
|
if (bIsSNMPObject && (NULL != wmbSessionTableGet(pSession)) )
|
|
{
|
|
wmbTableDestroy(pSession);
|
|
}
|
|
|
|
/* if pStrInstance buffer at large, free it */
|
|
if (NULL != pStrInstance)
|
|
wmFree(pStrInstance);
|
|
|
|
if (NULL != szNameBf)
|
|
wmFree(szNameBf);
|
|
|
|
return( (OK == status) ? OK:ERROR);
|
|
}
|
|
|
|
|