/* wmbObjectLib.c - backplane management library */ /* * Copyright (c) 2001-2010, 2011-2013 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. */ /* modification history -------------------- 02q,21feb13,r_w fix coverity issue(defect WIND00404092) 02p,24jul12,f_f add the int64/uint64 type support in range test (WIND00364418) 02q,16oct12,shi correct Sbyte4 to sbyte4 (WIND00382516) 02p,17sep12,shi Add APIs wmbObjectValueExportAdapt() and wmbObjectValueImportAdapt(). requirement WIND00270285 02o,21mar11,r_w fix defect WIND00237303 02n,30dec10,m_z enable winmark range test CQID: Fix WIND00245970 02m,17dec10,m_z part of APIs changed CQID: Fix WIND00247096 02l,09jul10,m_z remove compile warning 02k,01apr10,f_f VxWorks 64bit support (WIND00193649) 02j,24feb07,msa Correct the apigen comments so they match the actual routines. Also fix any apigen errors. 02i,14jul04,dlr SPR 98759, Added wmbObjectInstanceIsEmpty, to test for 'empty" instances 02h,04jun04,dlr Fix for wmbObjectSetupInstance, don't reset existing instance 02g,19may04,dlr Fix for WM tables, instance length zero but pointer not NULL 02f,12apr04,dlr SPR 92232, fix wmbObjectGet and wmbObjectSet 02e,04apr04,dlr SPR 92292 02d,29apr04,dlr fixed SPR 96708 02c,27apr04,bk fixed SPR 90880 02b,27apr04,adb replaced all buffer size constants with kMagicMarkupBufferSize 02a,11feb04,dlr Added wmbObjectGetNext 01f,22jan04,dlr SPR #93158: Fix 'usrObjectEnum" name to "wmbObjectEnum" 01e,21jan04,adb wmbObjectGet should return variable status 01d,14jan04,dlr SPR #93158: Fix wmbObjectEnum to call handler, explicit/Table Manager instance 01c,22aug03,jws fix compiler warnings, SPR 90282 01b,18apr03,jws instance setting now deletes old instance 01a,01aug01,pns written */ /* DESCRIPTION This module implements all the functions for backplane objects INCLUDE FILES: wm.h wmb.h */ #define __DEBUG_MESSAGES_OFF__ /* undefine to allow debugging messages */ /* includes */ #include "wrn/wm/common/wm.h" #include "wrn/wm/backplane/wmb.h" #include "wrn/wm/common/memPoolLib.h" #include #include #ifndef WM_DELIM_META_K #define WM_DELIM_META_K '^' #endif #ifndef WM_DELIM_INSTANCE_K #define WM_DELIM_INSTANCE_K '.' #endif void wmbObjectNameBufferSet ( WMB_OBJ_T obj, WM_BUFFER_T * pName ); WM_BUFFER_T * wmbObjectValueBufferGet ( WMB_OBJ_T obj ); void wmbObjectNameSet ( WMB_OBJ_T obj, /* object to name */ sbyte * pName /* new name */ ); STATUS wmbObjectInst ( WMB_OBJ_T obj, /* [in] object id */ sbyte * * ppInst, /* [out] instance */ sbyte4 * pLen /* [out] instance length, including zero terminator */ ); STATUS wmbObjectSetupInstance ( WMB_TID_T tid, /* object transaction */ WMB_OBJ_T obj, /* object instance to set up */ void * pInstance, /* [in] Instance pointer of the object */ sbyte4 instanceLength, /* [in] Length of the instance */ DATATYPE_T instanceType, /* [in] Instance Data type in */ BOOL copy /* [in] Copy the pName to newly allocated space */ ); /* globals */ #ifdef __USE_MEMORY_BLOCKS__ extern WM_BLOCK_T * pBlockObjects; #endif extern STATUS lcl_VALID_String ( sbyte *pString, sbyte *pValidStr ); extern STATUS VALID_Length ( sbyte * pString, sbyte * pValidStr ); IMPORT OS_SEM_T g_semObjLock; /* locals */ /************************************************************************** * * wmbObjectNativeSizeGet - return object's maximum direct storage size * * RETURNS: size * */ ssize_t wmbObjectNativeSizeGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; if (wmbObjectBad(obj)) return 0; /* maybe -1? */ if (NULL == (pEntry = wmbObjectEntryGet(obj))) return 0; /* maybe -1? */ return (ssize_t)wmbEntrySizeGet(pEntry); } /************************************************************************** * * wmbObjectNameBufferGet - return object's name as a buffer * * RETURNS: buffer or NULL * */ WM_BUFFER_T * wmbObjectNameBufferGet ( WMB_OBJ_T obj ) { if (wmbObjectFlagIsSet (obj,OBJ_FLAG_NAME_BUFFER_K)) return wmbObject(obj)->pName; return NULL; } /************************************************************************** * * wmbObjectNameBufferSet - set object's name buffer * * Must be empty or dumpable * * RETURNS: N/A * */ void wmbObjectNameBufferSet ( WMB_OBJ_T obj, WM_BUFFER_T * pName ) { WM_BUFFER_T * pOld; /* what if something is already there */ if (NULL != (pOld = wmbObject(obj)->pName)) { if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_BUFFER_K)) wmBufferDelete(pOld); else wmbObjectFlagClear(obj, OBJ_FLAG_NAME_K); } wmbObjectFlagSet(obj, OBJ_FLAG_NAME_BUFFER_K); wmbObject(obj)->pName = pName; } /************************************************************************** * * wmbObjectValueBufferGet - return object's value as a buffer * * RETURNS: buffer or NULL * */ WM_BUFFER_T * wmbObjectValueBufferGet ( WMB_OBJ_T obj ) { if (wmbObjectFlagIsSet(obj, OBJ_FLAG_DATA_BUFFER_K)) return wmbObject(obj)->pValue; DEBUG_MSG_1("wmbObjectValueBufferGet: ERROR! obj: 0x%x has no buffer set", obj); return NULL; } /************************************************************************** * * wmbObjectValueBufferSet - return object's value to be * * RETURNS: N/A * */ void wmbObjectValueBufferSet ( WMB_OBJ_T obj, WM_BUFFER_T * pBuffer ) { wmbObject(obj)->pValue = pBuffer; wmbObjectFlagSet(obj,OBJ_FLAG_DATA_BUFFER_K) ; } /************************************************************************** * * wmbObjectNameClear - free object's name info * * RETURNS: NA * * INTERNAL * * NOMANUAL */ LOCAL void wmbObjectNameClear ( WMB_OBJ_T obj ) { void * pOld; /* deal with prior name */ if (NULL == (pOld = wmbObject(obj)->pName)) return; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_PTR_K) && wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_FREE_K)) { wmFree(pOld); wmbObjectFlagClear(obj, OBJ_FLAG_NAME_PTR_K); wmbObjectFlagClear(obj, OBJ_FLAG_NAME_FREE_K); } else if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_BUFFER_K)) { wmBufferDelete((WM_BUFFER_T *) pOld); wmbObjectFlagClear(obj, OBJ_FLAG_NAME_BUFFER_K); } } /************************************************************************** * * lclObjectInstanceType - return the instance type for the object * * * RETURNS: WMB_TBL_INST_OID if OID attached to WindMark DB entry * WMB_TBL_INST_STR otherwise * * NOMANUAL */ #define WMB_INST_OID 0x00 /* Instance is OID (SNMP) */ #define WMB_INST_STR 0x01 /* Instance is string argument */ LOCAL int lclObjectInstanceType ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL_INVALID, "lclObjectInstanceType: bad entry"); if (wmbDBEntryFlagGet(pEntry, DB_FLAG_OID_COOKIE_K)) return WMB_INST_OID; else return WMB_INST_STR; } /************************************************************************** * * wmbObjectComponentGet - return WindMark's registered component * * RETURNS: component that registered windmark * */ WMB_CID_T wmbObjectComponentGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; if (wmbObjectBad(obj)) return NULL; if (NULL == (pEntry = wmbObjectEntryGet(obj))) return NULL; return wmbEntryIdGet(pEntry); } /************************************************************************** * * wmbObjectNamePtrGet - return object's name as a string * * RETURNS: name or NULL * */ sbyte * wmbObjectNamePtrGet ( WMB_OBJ_T obj ) { WM_BUFFER_T * pBuf; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_PTR_K)) return wmbObject(obj)->pName; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_BUFFER_K)) { pBuf = wmbObject(obj)->pName; return wmBufferDataGet(pBuf); } return NULL; } /************************************************************************** * * wmbObjectNamePtrSet - set object's name to static string * * RETURNS: N/A * */ void wmbObjectNamePtrSet ( WMB_OBJ_T obj, /* object to change */ sbyte * pName /* new name */ ) { /* deal with prior name */ wmbObjectNameClear(obj); wmbObjectFlagSet(obj, OBJ_FLAG_NAME_PTR_K); wmbObject(obj)->pName = pName; } /************************************************************************** * * wmbObjectNameSet - set object's name to string * * May copy buffer or just reference pointer * * RETURNS: N/A * */ void wmbObjectNameSet ( WMB_OBJ_T obj, /* object to name */ sbyte * pName /* new name */ ) { if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_PTR_K)) wmbObject(obj)->pName = pName; else if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_BUFFER_K)) wmBufferUpdate (wmbObject(obj)->pName, pName, 0, DATATYPE_STRING_K, FALSE); else { wmbObjectFlagSet(obj, OBJ_FLAG_NAME_PTR_K); wmbObject(obj)->pName = pName; } } #ifdef __ENABLE_IPC__ /************************************************************************** * * wmbObjectDone - complete object's remote execution * * NOMANUAL * * RETURNS: OK or ERROR * */ STATUS wmbObjectDone ( WMB_CID_T component, /* component replying with object */ sbyte * pMessage, /* text reply */ sbyte4 msgSize /* size of actual reply */ ) { MSG_IPC_T * pIpc; REMOTE_T * pRemote; WMB_OBJ_T obj; DEBUG_MSG_0 ("wmbObjectDone: start\n"); if (NULL == pMessage) return wmError (ERROR, "wmbObjectDone: no message\n"); if (sizeof(*pIpc) > msgSize) return wmError (ERROR, "wmbObjectDone: invalid message\n"); pIpc = (MSG_IPC_T *) pMessage; obj = pIpc->obj; DEBUG_MSG_1 ("wmbObjectDone: object id: 0x%x\n", obj); if (NULL == (pRemote = wmbObjectCookieGet(obj))) return wmError(ERROR, "wmbObjectDone: missing state info!\n"); DEBUG_MSG_1 ("wmbObjectDone: state : 0x%x\n", pRemote); wmosSemGive (pRemote->sem); return OK; } /************************************************************************** * * wmbObjectGoFar - execute object across IPC * * called as remote execution from queue * * RETURNS: validation string or NULL * * * NOMANUAL */ STATUS wmbObjectGoFar ( WMB_CID_T component, /* remote component */ sbyte * pMessage, /* message text */ sbyte4 msgSize /* size of message */ ) { MSG_IPC_T * pIpc; WM_BUFFER_T * pBuffer; sbyte temp[64]; sbyte4 written; DEBUG_MSG_0("wmbObjectGoFar: start\n"); if (NULL == pMessage) return wmError(ERROR_GENERAL_NO_DATA, "wmbObjectFarExec: no message\n"); if (sizeof(*pIpc) > msgSize) return wmError(ERROR_GENERAL_BAD_VALUE, "wmbObjectFarExec: invalid message\n"); pIpc = (MSG_IPC_T *) pMessage; DEBUG_MSG_1 ("wmbObjectGoFar: object id: 0x%x\n", pIpc->remoteObj); pIpc->status = wmbObjectGo (pIpc->remoteTid, pIpc->remoteObj, pIpc->objCmd); pBuffer = wmbObjectValueGet (pIpc->remoteObj); wmBufferExport(pBuffer, temp, sizeof(temp), DATATYPE_STRING_K, &written); DEBUG_MSG_2 ("wmbObjectGoFar: status: 0x%x result: %s.\n", pIpc->status, temp); DEBUG_MSG_2 ("wmbObjectGoFar: buffer: 0x%x exported: %d\n", pBuffer, written); /* return the results to calling domain */ pIpc->msgCmd = WMB_MSG_DONE_K; return wmosQueueSend (pIpc->qid, pMessage, msgSize, 0, 0); } /************************************************************************** * * wmbObjectFound - execute object across IPC * * local function called by remote backplane after resolving remote object * * NOMANUAL * * RETURNS: OK if valid * */ LOCAL STATUS wmbObjectFound ( WMB_CID_T component, /* local component */ sbyte * pMessage, /* text message */ sbyte4 msgSize /* size of message */ ) { WMB_OBJ_T obj; MSG_IPC_T * pFound; REMOTE_T * pRemote; DEBUG_MSG_0 ("wmbObjectFound: start\n"); if (NULL == pMessage) return wmError(ERROR_GENERAL_NO_DATA, "wmbObjectFound: no message\n"); if (sizeof(*pFound) > msgSize) return wmError(ERROR_GENERAL_BAD_VALUE, "wmbObjectFound: invalid message\n"); pFound = (MSG_IPC_T *) pMessage; if (OK != pFound->status) return wmError(pFound->status, "wmbObjectFound: remote failure"); obj = pFound->obj; DEBUG_MSG_1 ("wmbObjectFound: local object: 0x%x\n", obj); if (wmbObjectBad(obj)) return wmError(ERROR_WMB_OBJECT_INVALID, "found: invalid object\n"); if (NULL == (pRemote = wmbObjectCookieGet(obj))) return wmError(ERROR_GENERAL_NOT_FOUND, "wmbObjectFound: no state info!\n"); DEBUG_MSG_1 ("wmbObjectFound: state: 0x%x\n", pRemote); pRemote->obj = pFound->remoteObj; pRemote->tid = pFound->remoteTid; DEBUG_MSG_1 ("wmbObjectFound: remote object: 0x%x\n", pRemote->obj); DEBUG_MSG_1 ("wmbObjectFound: remote tid : 0x%x\n", pRemote->tid); wmbObjectFlagSet(obj, OBJ_FLAG_RESOLVED_K); return wmosSemGive (pRemote->sem); } /************************************************************************** * * wmbObjectResolveFar - name lookup across IPC * * called from remote to resolve obj -- lookup and signal back * * NOMANUAL * * RETURNS: OK if valid * */ LOCAL STATUS wmbObjectResolveFar ( WMB_CID_T component, sbyte * pMessage, sbyte4 msgSize ) { WMB_OBJ_T remoteObj; WMB_ID_T backplane; MSG_IPC_T found; sbyte * pName; WM_BUFFER_T * pValueBuf; OS_MEM_SHARE_T * pMemory; MSG_IPC_T * pIpc; DEBUG_MSG_0 ("wmbObjectResolveFar: start\n"); if (NULL == pMessage) return wmError(ERROR_GENERAL_NO_DATA, "wmbObjectResolveFar: no message\n"); if (sizeof(*pIpc) > msgSize) return wmError(ERROR_GENERAL_INVALID, "wmbObjectResolveFar: invalid message\n"); backplane = wmbBackplaneGet(); if (wmbBackplaneBad(backplane)) return wmError(ERROR_WMB_BACKPLANE_INVALID, "wmbObjectResolveFar: invalid backplane\n"); pMemory = wmbBackplaneSharedGet(backplane); if (NULL == pMemory) return wmError(ERROR_GENERAL_NULL_POINTER, "wmbObjectResolveFar: no memory\n"); pIpc = (MSG_IPC_T *) pMessage; DEBUG_MSG_1 ("wmbObjectResolveFar: local obj: 0x%x\n", pIpc->obj); DEBUG_MSG_1("shared base : 0x%x\n", (int) pMemory->pData); DEBUG_MSG_1("name offset : 0x%x\n", (int) pIpc->name); DEBUG_MSG_1("value offset: 0x%x\n", (int) pIpc->value); pName = (sbyte *) pMemory->pData + pIpc->name; pValueBuf = (WM_BUFFER_T *) ((sbyte *) pMemory->pData + pIpc->value); DEBUG_MSG_1("wmbObjectResolveFar: name = %s\n", pName); if (! wmbObjectNew(remoteObj)) return wmError(ERROR_MEMMGR_NO_MEMORY, "wmbObjectResolveFar: out of memory\n"); wmbObjectBless(remoteObj); wmbObjectNameSet (remoteObj, pName); wmbObjectValueBufferSet (remoteObj, pValueBuf); DEBUG_MSG_1 ("wmbObjectResolveFar: ready to resolve obj: 0x%x\n", remoteObj); DEBUG_MSG_1 ("wmbObjectResolveFar: local obj: 0x%x\n", pIpc->obj); DEBUG_MSG_1 ("wmbObjectResolveFar: value buffer is%s : 0x%x\n", wmBufferShared (pValueBuf) ? "" : " NOT"); wmZero(&found); found.status = wmbObjectResolve (remoteObj); found.obj = pIpc->obj; found.tid = pIpc->tid; found.remoteObj = remoteObj; found.remoteTid = NULL; found.msgCmd = WMB_MSG_FOUND_K; DEBUG_MSG_1 ("wmbObjectResolveFar: resolve status: 0x%x\n", found.status); DEBUG_MSG_1 ("wmbObjectResolveFar: handler : 0x%x\n", wmbObjectHandlerGet(remoteObj)); return wmosQueueSend(pIpc->qid, (sbyte *) &found, sizeof(found), 0, 0); } #endif /* __ENABLE_IPC__ */ /************************************************************************** * * wmbObjectValueCreate - create value buffer for object * * RETURNS: OK or ERROR * */ STATUS wmbObjectValueCreate ( WMB_OBJ_T obj, /* buffer owner */ void * pData, /* data for value */ size_t dataLength, /* size of data */ sbyte4 dataType, /* data type */ BOOL copy /* copy data? */ ) { WM_BUFFER_T * pBuffer; if (wmbObjectBad(obj)) return wmError(ERROR, "bad object"); pBuffer = wmBufferCreate (NULL, dataLength, (sbyte *) pData, dataType, copy); if (NULL == pBuffer) return wmError(ERROR_MEMMGR_NO_MEMORY, "no memory"); wmbObjectValueBufferSet (obj, pBuffer); return OK; } /************************************************************************** * * wmbObjectValidationString - return object's validation string * * RETURNS: validation string or NULL * */ sbyte * wmbObjectValidationString ( WMB_OBJ_T obj /* [in] object id */ ) { DB_ENTRY_T * pDbEntry; if (wmbObjectBad(obj)) return NULL; if (NULL == (pDbEntry = wmbObjectEntryGet(obj))) return NULL; return pDbEntry->pEntry->pValid; } /************************************************************************** * * wmbObjectOid - get object's base OID (if resolved and applicable) * * RETURNS: OK or ERROR * */ STATUS wmbObjectOid ( WMB_OBJ_T obj, /* [in] object id */ ubyte4 * * ppOid, /* [out] oid */ sbyte4 * pLen /* [out] oid length in 4 byte words */ ) { DB_ENTRY_T * pEntry; if (NULL == ppOid || NULL == pLen) return wmError(ERROR_GENERAL_NULL_POINTER, "wmbObjectOid: null ptr"); if (wmbObjectBad(obj)) return wmError(ERROR, "invalid object"); if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL_INVALID, "wmbObjectOid: bad entry"); /* make a copy of root oid */ *ppOid = (ubyte4 *) wmbEntryDataGet(pEntry); *pLen = (sbyte4)(wmbEntrySizeGet(pEntry) / 4); return OK; } /************************************************************************** * * wmbObjectInst - get object's base Instance (if resolved and applicable) * * This apples to string-based instances. Currently, all such WIndMarks * have a zero length base instance, but this may change. * * RETURNS: OK or ERROR * * NOMANUAL */ STATUS wmbObjectInst ( WMB_OBJ_T obj, /* [in] object id */ sbyte * * ppInst, /* [out] instance */ sbyte4 * pLen /* [out] instance length, including zero terminator */ ) { DB_ENTRY_T * pEntry; if (NULL == ppInst || NULL == pLen) return wmError(ERROR_GENERAL_NULL_POINTER, "wmbObjectInst: null ptr"); if (wmbObjectBad(obj)) return wmError(ERROR, "invalid object"); if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL_INVALID, "wmbObjectInst: bad entry"); /* make a copy of root instance */ *ppInst = (sbyte *) ""; *pLen = 1; /* count the zero terminator */ return OK; } /************************************************************************** * * wmbObjectInstanceIsEmpty - is there no actual instance information in this object * * This call will indicate whether the object's instance field is NULL or * effectively empty * * RETURNS: TRUE or FALSE * * * NOMANUAL */ BOOL wmbObjectInstanceIsEmpty ( WMB_OBJ_T obj /* [in] object id */ ) { /* Instance Buffer is NULL */ if (NULL == wmbObjectInstanceGet(obj)) return TRUE; /* OID instance buffer has zero length */ if (WMB_INST_OID == lclObjectInstanceType(obj)) { if (0 == wmBufferUsedGet(wmbObjectInstanceGet(obj))) return TRUE; } /* String instance buffer has zero length (w/o terminator) */ if (WMB_INST_STR == lclObjectInstanceType(obj)) { if (1 >= wmBufferUsedGet(wmbObjectInstanceGet(obj))) return TRUE; if ('\0' == *(char *) (wmBufferDataGet(wmbObjectInstanceGet(obj))) ) return TRUE; } /* There is an instance */ return FALSE; } /************************************************************************** * * wmbObjectLoad - load db data into object data * * Default method to load registered global variables * Strings only load pointer to DB data area, all other types copy the value * * RETURNS: OK or ERROR * */ STATUS wmbObjectLoad ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; size_t size; pEntry = wmbObjectEntryGet (obj); if (0 == (size = wmbEntrySizeGet (pEntry))) size = sizeof(void *); return wmbObjectImport (obj, wmbEntryDataGet (pEntry), size, wmbEntryTypeGet (pEntry)); } /************************************************************************** * * wmbObjectStore - write object data to db data * * Default method to save to registered global variables * * RETURNS: OK or ERROR * */ STATUS wmbObjectStore ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; pEntry = wmbObjectEntryGet (obj); return wmbObjectExport (obj, wmbEntryDataGet (pEntry), wmbEntrySizeGet (pEntry), wmbEntryTypeGet (pEntry), NULL); } /************************************************************************** * * wmbObjectGroup - append to group containing * * This routine appends at the end of the wmbObject list * * RETURNS: N/A * * * NOMANUAL */ void wmbObjectGroup ( WMB_OBJ_T prior, WMB_OBJ_T added ) { WMB_OBJ_T next; for (next = wmbObjectNextGet(prior); wmbObjectGood(next); next = wmbObjectNextGet(prior)) prior = next; wmbObjectNextSet(prior, added); /* sets the group pointer */ } /************************************************************************** * * wmbObjectGroupListSet - append to group containing * * This routine appends at the end of the wmbObject list * * RETURNS: N/A * * * NOMANUAL */ void wmbObjectGroupListSet ( WMB_OBJ_T first, WMB_OBJ_T last ) { WMB_OBJ_T next; while (wmbObjectGood(first) && (first != last)) { next = wmbObjectNextGet(first); wmbObjectGroupNextSet(first, next); first = next; } } /************************************************************************** * * wmbObjectGroupClear - append to group containing * * This routine appends at the end of the wmbObject list * * RETURNS: N/A * * * NOMANUAL */ void wmbObjectGroupClear ( WMB_OBJ_T head ) { WMB_OBJ_T next; while (wmbObjectGood(head)) { next = wmbObjectNextGet (head); wmbObjectGroupNextSet(next, NULL); head = next; } } /************************************************************************** * * wmbObjectAppendByOID - appends a wmbObject based on its OID and instance * * This code works also for string-based instances. * * RETURNS: void. * * * NOMANUAL */ LOCAL void wmbObjectAppendByOID ( WMB_OBJ_T head, /* [in] Start of the link list (in group) */ WMB_OBJ_T added /* [in] New object to be added */ ) { WMB_OBJ_T prior; WMB_OBJ_T matchOID; DB_TABLE_T *addedTable; DB_TABLE_T *priorTable; #if 0 ubyte4 *addedOid, *priorOid; sbyte4 addedLen, priorLen; #endif ubyte4 *pAddedSuffix, *pPriorSuffix; sbyte4 addedSuffixLen, priorSuffixLen; for (prior = head, matchOID = head; wmbObjectGood(wmbObjectNextGet(prior)); prior = wmbObjectNextGet(prior)) { if (wmbObjectInstancePtrGet(prior) == NULL) matchOID = prior; } if (wmbObjectInstancePtrGet(added) != NULL) { addedTable = wmbObjectTableGet(added); if (NULL != addedTable) { wmbObjectInstanceSuffixGet(added, &pAddedSuffix, &addedSuffixLen); for (prior = head; wmbObjectGood(wmbObjectNextGet(prior)); prior = wmbObjectNextGet(prior)) { priorTable = wmbObjectTableGet(prior); if (priorTable == addedTable) { matchOID = prior; if ((NULL != pAddedSuffix) && (OK == wmbObjectInstanceSuffixGet(prior, &pPriorSuffix, &priorSuffixLen))) { if ((priorSuffixLen == addedSuffixLen) && (MEMCMP(pPriorSuffix, pAddedSuffix, (size_t)priorSuffixLen) == 0)) matchOID = prior; } } } } } if (NULL != matchOID) { wmbObjectNextSet(added, wmbObjectNextGet(matchOID)); wmbObjectGroupNextSet(added, wmbObjectGroupNextGet(matchOID)); wmbObjectNextSet(matchOID, added); } } /************************************************************************** * * wmbObjectAppend - appends a wmbObject at end of list containing current wmbObject * * This routine appends at the end of the wmbObject list. Make sure that the * OID of the object is resolved prior to calling this function * * RETURNS: number of objects added. * * * NOMANUAL */ ubyte4 wmbObjectAppend ( WMB_OBJ_T head, WMB_OBJ_T added ) { WMB_OBJ_T prior; ubyte4 count; if (wmbObjectBad(head)) return (ubyte4)wmError(ERROR_WMB_OBJECT_INVALID, "wmbObjectAppend: no object"); count = 0; prior = head; /* start at beginning and work to end */ /* First add to the FLAT LIST... */ while (!wmbObjectBad(wmbObjectListNextGet(prior))) { prior = wmbObjectListNextGet(prior); count++; } wmbObjectListNextSet(prior, added); wmbObjectListNextSet(added, NULL); /* Then add to the GROUP List... */ for (prior = head; wmbObjectGood(prior); prior = wmbObjectGroupNextGet(prior)) { if (wmbObjectHandlerGet(prior) == wmbObjectHandlerGet(added)) { wmbObjectAppendByOID(prior, added); break; } if (wmbObjectBad(wmbObjectGroupNextGet(prior))) { wmbObjectGroupNextSet(prior, added); wmbObjectGroupNextSet(added, NULL); break; } } return count; } /************************************************************************** * * wmbObjectInit - initialize a backplane object * * This routine assigns name and instances to a backplane object * * RETURNS: ERROR or OK. * */ STATUS wmbObjectInit ( WMB_OBJ_T obj, /* object id to initialize */ MEM_POOL_ID pool, /* optional memory pool */ sbyte * pName, /* name of object */ char * pInstance, /* OID or string arg */ sbyte4 instanceLength, /* in bytes */ BOOL copy /* copy the value if true */ ) { WM_OID_T oid; WM_BUFFER_T * pBuffer; wmZero (wmbObject(obj)); DEBUG_MSG_1("wmbObjectInit: obj 0x%x\n", obj); wmbObjectBless (obj); if (copy) { pBuffer = wmBufferCreate(pool, STRLEN(pName) + 1, pName, DATATYPE_STRING_K, TRUE); if (NULL == pBuffer) return wmError(ERROR_MEMMGR_NO_MEMORY, "wmbObjectInit: name buffer failed"); wmbObjectNameBufferSet (obj, pBuffer); } else wmbObjectNamePtrSet(obj, pName); /* OID instance can be given in string or binary form but should internally be binary only */ if (NULL != pInstance) { /* if instance starts with a digit it is an oid, otherwise, a string arg */ if (ISDIGIT((int)*pInstance)) { oid = wmOidFromString (pInstance, 0); if (wmBufferBad(oid)) { return wmError (ERROR_GENERAL, "wmbObjectInit: OID conversion failed"); } } else { if (0 == instanceLength) instanceLength = (sbyte4)STRLEN(pInstance) + 1; oid = wmBufferCreate(pool, (size_t)instanceLength, pInstance, DATATYPE_STRING_K, copy); } } else { /* no value assigned but space requested for later */ if (0 < instanceLength) oid = wmBufferCreate(pool, (size_t)instanceLength, NULL, DATATYPE_OID_K, copy); else oid = NULL; } wmbObjectInstanceSet(obj, oid); return OK; } /************************************************************************** * * wmbObjectNameGet - return name assigned to object * * RETURNS: name or NULL * */ sbyte * wmbObjectNameGet ( WMB_OBJ_T obj ) { WM_BUFFER_T * pBuf; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_PTR_K)) return wmbObject(obj)->pName; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_NAME_BUFFER_K)) { pBuf = wmbObject(obj)->pName; return wmBufferDataGet(pBuf); } return NULL; /* error! */ } /************************************************************************** * * wmbObjectCreate - create a wmbObject * * This routine returns , optionally inserting to * * RETURNS: OK, ERROR * */ STATUS wmbObjectCreate ( WMB_TID_T tid, /* object transaction */ sbyte * pName, /* name of object */ void * pInstance, /* instance or argument */ sbyte4 length, /* length of instance */ WMB_OBJ_T * ppObject /* returned object */ ) { WMB_OBJECT_T * pObject; MEM_POOL_ID pool; /* don't use for now wmbShareCreate(backplane, WMB_SHARE_OBJECT_K, &pObject); */ #ifdef __USE_MEMORY_BLOCKS__ if (NULL == (pObject = wmMemBlockEntryCreate(pBlockObjects))) return wmError(ERROR_MEMMGR_NO_MEMORY, "no memory"); #else if (! wmNew(pObject)) return wmError(ERROR_MEMMGR_NO_MEMORY, "no memory"); #endif if (wmbTransactionBad(tid)) pool = NULL; else pool = wmbTransactionMemGet(tid); if (OK != wmbObjectInit (pObject, pool, pName, pInstance, length, TRUE)) { #ifdef __USE_MEMORY_BLOCKS__ wmMemBlockFree (pBlockObjects, pObject); #else wmFree(pObject); #endif return ERROR; } wmbObjectFlagSet(pObject, OBJ_FLAG_FREE_K); if (wmbTransactionBad(tid)) return OK; if (OK != wmbTransactionObjectAdd(tid, pObject)) { wmbObjectDelete(pObject); if (NULL != ppObject) *ppObject = NULL; return ERROR; } if (NULL != ppObject) *ppObject = pObject; return OK; } /************************************************************************** * * variableGet - Get session handler variable * * RETURNS: OK or ERROR * * NOMANUAL */ LOCAL STATUS variableGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; if (wmbObjectBad(obj)) return wmError(ERROR_WMB_OBJECT_INVALID, "variableGet: bad data"); if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL_INVALID, "variableGet: NULL entry"); return wmbObjectImport(obj, wmbEntryDataGet(pEntry), wmbEntrySizeGet(pEntry), wmbEntryTypeGet(pEntry)); } /************************************************************************** * * variableSet - set session handler variable * * RETURNS: STATUS. * * NOMANUAL */ LOCAL STATUS variableSet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; size_t written; size_t size; void * pDest; if (wmbObjectBad(obj)) return wmError(ERROR_WMB_OBJECT_INVALID, "variableSet: bad data"); if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL_INVALID, "variableSet: NULL entry"); size = wmbEntrySizeGet(pEntry); pDest = wmbEntryDataGet(pEntry); /* just load the buffer */ return wmbObjectExport(obj, pDest, size, DATATYPE_STRING_K, &written); } /************************************************************************** * * wmbObjectVariable - handler for session variables * * RETURNS: STATUS. * * * NOMANUAL */ STATUS wmbObjectVariable ( WMB_TID_T tid, WMB_OBJ_T obj, COMMAND_T cmd ) { switch (cmd) { case CMD_GET_K: return variableGet (obj); case CMD_SET_K: return variableSet (obj); default: break; } return wmError(ERROR_TM_NOT_HANDLED, NULL);; } #ifdef __ENABLE_IPC__ /************************************************************************** * * wmbObjectResolveRemote - find WindMark in foreign backplane * * RETURNS: OK, ERROR_GENERAL_NOT_FOUND * * * NOMANUAL */ STATUS wmbObjectResolveRemote ( WMB_TID_T tid, WMB_OBJ_T obj, sbyte * pName, WMB_CID_T component ) { MSG_IPC_T ipc; OS_MEM_SHARE_T * pMem; REMOTE_T * pRemote; DEBUG_MSG_1 ("wmbObjectResolveRemote: resolving : %s\n", pName); DEBUG_MSG_1 ("wmbObjectResolveRemote: local obj : 0x%x\n", obj); pMem = wmbTransactionSharedGet(tid); ipc.msgCmd = WMB_MSG_RESOLVE_K; ipc.name = wmbShareString (pMem->pool, pName); if (-1 == ipc.name) return wmError(ERROR_GENERAL_INVALID, "wmbObjectResolveRemote: no free shared memory"); if (! wmNew(pRemote)) return wmError(ERROR_MEMMGR_NO_MEMORY, "wmbObjectResolveRemote: not enough memory"); DEBUG_MSG_1 ("wmbObjectResolveRemote: remote info : 0x%x\n", pRemote); pRemote->pValue = wmBufferCreate(pMem->pool, 0, NULL, DATATYPE_INVALID_K, FALSE); if (NULL == pRemote->pValue) { wmPoolFree(pMem->pool, pName); return wmError(ERROR_MEMMGR_NO_MEMORY, "wmbObjectResolveRemote: no free shared memory"); } DEBUG_MSG_2 ("wmbObjectResolveRemote: remote pool : 0x%x value: 0x%x\n", pRemote->pool, pRemote->pValue); ipc.value = (int) pRemote->pValue - (int) pMem->pool; ipc.tid = tid; ipc.qid = wmbTransactionReplyGet(tid); ipc.obj = obj; wmbObjectNameSet (obj, pName); wmbObjectFlagSet (obj, OBJ_FLAG_REMOTE_K); wmbObjectCookieSet (obj, pRemote); /* wmbObject(obj)->pState = pRemote; */ DEBUG_MSG_1 ("wmbObjectResolveRemote: remote info still: 0x%x\n", wmbObjectCookieGet(obj)); pRemote->cid = component; pRemote->qid = wmbComponentQidGet (component); pRemote->pool = pMem->pool; DEBUG_MSG_2 ("wmbObjectResolveRemote: pool: 0x%x value: 0x%x\n", pRemote->pool, pRemote->pValue); if (OK != wmosSemCreate (&pRemote->sem, 1, 0)) return ERROR; if (OK != wmosSemTake (pRemote->sem, WAIT_FOREVER_K)) { wmosSemDestroy (pRemote->sem); return ERROR; } return wmbComponentSend (component, &ipc, sizeof(ipc) - sizeof(int)); } /************************************************************************** * * wmbObjectGoRemote - send message to execute a command for remote wmbObject * * This routine executes the command for , * or the current wmbObject held by * * RETURNS: STATUS. * * * NOMANUAL */ STATUS wmbObjectGoRemote ( WMB_TID_T tid, WMB_OBJ_T obj, COMMAND_T cmd ) { MSG_IPC_T ipc; REMOTE_T * pRemote; DEBUG_MSG_0 ("wmbObjectGoRemote: start\n"); if (NULL == (pRemote = wmbObjectCookieGet (obj))) return wmError (ERROR, "wmbObjectGoRemote: no state info\n"); DEBUG_MSG_1 ("wmbObjectGoRemote: state: 0x%x\n", pRemote); /* are we ready to execute? */ if (! wmbObjectFlagIsSet (obj, OBJ_FLAG_RESOLVED_K)) { DEBUG_MSG_1 ("wmbObjectGoRemote: waiting for resolution of obj: 0x%x\n", obj); wmosSemTake (pRemote->sem, WAIT_FOREVER_K); DEBUG_MSG_1 ("wmbObjectGoRemote: we have resolution of obj: 0x%x\n", obj); } ipc.msgCmd = WMB_MSG_EXEC_K; ipc.qid = wmbTransactionReplyGet (tid); ipc.tid = tid; ipc.obj = obj; ipc.remoteObj = pRemote->obj; ipc.remoteTid = pRemote->tid; ipc.objCmd = cmd; /* make request to remote component */ DEBUG_MSG_1 ("wmbObjectGoRemote: sending to queue: %d\n", pRemote->qid); if (OK != wmbComponentSend (pRemote->cid, (sbyte *) &ipc, sizeof(ipc) - sizeof(int))) return ERROR; /* sit and wait until remote execution is finished */ DEBUG_MSG_1 ("wmbObjectGoRemote: waiting for execution of obj: 0x%x\n", obj); wmosSemTake (pRemote->sem, WAIT_FOREVER_K); DEBUG_MSG_1 ("wmbObjectGoRemote: we have execution of obj: 0x%x\n", obj); wmbObjectValueUpdate (obj, pRemote->pValue); /* we're done. clean up remote data */ wmPoolFree (pRemote->pool, pRemote->pValue); DEBUG_MSG_1 ("wmbObjectGoRemote: state : 0x%x\n", pRemote); wmosSemDestroy (pRemote->sem); DEBUG_MSG_1 ("wmbObjectGoRemote: free remote : 0x%x\n", pRemote); wmFree (pRemote); return OK; } #endif /* __ENABLE_IPC__ */ /************************************************************************** * * wmbObjectInstanceSuffixGet - Return instance suffix. * * RETURNS: Instance Suffix Buffer * * * NOMANUAL */ STATUS wmbObjectInstanceSuffixGet ( WMB_OBJ_T obj, /* [in] object id */ ubyte4 **ppSuffix, /* [out] pointer to the suffix oid */ sbyte4 *suffixLen /* [out] length of the suffix string */ ) { ubyte4 *baseOid; sbyte *baseInst; sbyte4 baseLen; ubyte4 *fullOid; sbyte *fullInst; sbyte4 fullLen; WM_BUFFER_T *pInstance; *ppSuffix = NULL; *suffixLen = 0; if (!wmbObjectBad (obj)) { if (WMB_INST_OID == lclObjectInstanceType(obj)) { if (OK == wmbObjectOid(obj, &baseOid, &baseLen)) { pInstance = wmbObjectInstanceGet(obj); if (!wmBufferBad(pInstance)) { /* * wmbObjectOid() returns base OID length in number of 4 bytes * words. We must be consistent. */ fullLen = (sbyte4)(wmBufferUsedGet(pInstance) / sizeof (ubyte4)); fullOid = wmBufferDataGet(pInstance); /* Make sure (fullLen > baseLen) is true */ if (fullLen > baseLen) { *suffixLen = fullLen - baseLen; *ppSuffix = fullOid + baseLen; } } } } else { if (OK == wmbObjectInst(obj, &baseInst, &baseLen)) { pInstance = wmbObjectInstanceGet(obj); if (!wmBufferBad(pInstance)) { /* * wmbObjectOid() returns base instance length including zero * terminator. */ fullLen = (sbyte4)wmBufferUsedGet(pInstance); fullInst = wmBufferDataGet(pInstance); /* Make sure (fullLen > baseLen) is true */ if (fullLen > baseLen) { /* skip zero terminator in base */ *suffixLen = fullLen - baseLen - 1; /* Return value via the same ppSuffix parameter (cast the pointer) */ *ppSuffix = (ubyte4 *) (fullInst + baseLen); } } } } return OK; } return ERROR; } /************************************************************************** * * wmbObjectResolver - find database entry for WindMark and bind it to Object * * RETURNS: OK, ERROR_GENERAL_NOT_FOUND * * * NOMANUAL */ STATUS wmbObjectResolver ( WMB_SESSION_T * pSession, /* optional session pointer to match */ WMB_CID_T cid, /* optional owner of object to match */ WMB_OBJ_T obj /* already named object */ ) { WM_BUFFER_T * pInstance; WM_BUFFER_T * oid; WMB_ID_T backplane; WMB_CID_T component; WMB_OBJ_T meta; WMB_DB_T * pDB; DB_ENTRY_T * pEntry; sbyte * pName; sbyte * pFull; sbyte * pArg; BOOL absolute; sbyte producer[32]; ubyte4 loop; long size; MEM_POOL_ID pool; sbyte name[kMagicMarkupBufferSize]; ubyte4 argStrLen; if (wmbObjectBad (obj)) return wmError (ERROR, "wmbObjectResolver: invalid object"); DEBUG_MSG_1("wmbObjectResolver: object id: 0x%x\n", obj); /* if we have a handler already we have what we need */ if (wmbObjectFlagIsSet(obj, OBJ_FLAG_HANDLER_K) && NULL != wmbObjectHandlerGet(obj)) return OK; backplane = wmbBackplaneGet(); if (NULL == (pFull = wmbObjectNameGet (obj))) return ERROR; /* default size is full string length */ if (kMagicMarkupBufferSize - 1 < (size = (long)STRLEN(pFull))) return wmError(ERROR_GENERAL_BUFFER_OVERRUN, "buffer overflow"); /* call meta mark first if applicable */ if (NULL == (pName = STRCHR(pFull, WM_DELIM_META_K))) pName = pFull; else { /* put meta in queue before windmark */ size -= ++pName - pFull; STRNCPY(name, pName, (size_t)size); name[size] = 0; /* wmbObjectCreate resolves object and adds to transaction */ if (OK != wmbObjectCreate (wmbSessionTidGet(pSession), name, NULL, 0, &meta)) return ERROR; /* okay, fallthrough andget 'regular' windmark */ pName--; /* move back to meta delimiter */ size = pName - pFull; STRNCPY(name, pFull, (size_t)size); name[size] = 0; /* null terminate truncated name */ pName = name; } /* separate base and possible instance (appended to name) */ pArg = STRCHR(pName, WM_DELIM_INSTANCE_K); if (NULL != pArg) { /* adjust base name */ size = pArg - pName; /* already in buffer we can just truncate */ if (pName == name) pName[size] = 0; else if (pName == pFull) { STRNCPY(name, pFull, (size_t)size); pName = name; pName[size] = 0; } } /* if instanced name we should save instance as well */ absolute = FALSE; pEntry = NULL; pFull = pName; pool = NULL; component = NULL; pDB = NULL; switch (*pName) { case WMB_LOCAL_PREFIX_K: if (OK != wmbDbEntryTempGet(backplane, pSession, ++pName, &pEntry)) return ERROR; break; case WMB_DELIM_K: /* absolute path */ absolute = TRUE; pName++; for (loop = 0; loop < sizeof(producer) - 1; loop++, pName++) { if (WMB_DELIM_K == *pName) break; producer[loop] = *pName; } producer[loop] = 0; if (WMB_DELIM_K == *pName) pName++; /* use registered component ids for namespace separation */ if (NULL == (component = wmbComponentLookup (producer))) return wmError(ERROR_WMB_COMPONENT_INVALID, "invalid component"); #ifdef __ENABLE_IPC__ /* does it belong to another backplane? */ if (! wmbComponentLocal(component)) { /* save name for direct lookup */ DEBUG_MSG_2("wmbObjectResolver: obj 0x%x component 0x%x is remote\n", obj, component); wmbObject(obj)->component = component; wmbObjectCookieSet(obj, pName); return wmError(ERROR_GENERAL_NOT_LOCAL, "not local\n"); } #endif default: /* fall through */ if (NULL == (pDB = wmbBackplaneDBGet(backplane))) return wmError(ERROR_DB_NO_DATABASE, "no database!"); pEntry = wmbDBEntryGet(pDB, pName, component, FALSE); break; } /* * Normally we would throw the error because the return value is static. * Because not finding an objejct is sometimes ok we let the caller decide. */ if ((NULL == pEntry) || (NULL == pDB)) return wmError(ERROR_GENERAL_NOT_FOUND, "WindMark Not Found"); DEBUG_MSG_1("wmbObjectResolve: FOUND! object id: 0x%x\n", obj); /* bind object to this database */ wmbObjectDBSet (obj, pDB); wmbObjectEntrySet(obj, pEntry); wmbObjectHandlerSet(obj, wmbEntryHandlerGet(pEntry)); wmbObjectTypeNativeSet(obj, wmbEntryTypeGet(pEntry)); wmbObjectPathlenSet(obj, (unsigned int) (pName - pFull)); wmbObjectLocalSet(obj, (ubyte4)wmbEntryLocalGet(pEntry)); if (wmbDBEntryFlagGet(pEntry,DB_FLAG_OID_COOKIE_K)) { oid = wmBufferCreate(NULL, 256, NULL, DATATYPE_OID_K, TRUE); if (NULL != oid) wmBufferUpdate (oid, wmbEntryDataGet(pEntry), (size_t)wmbEntrySizeGet(pEntry), DATATYPE_OID_K, TRUE); pInstance = wmbObjectInstanceGet(obj); if (!wmBufferBad(pInstance) && (0 != wmBufferUsedGet(pInstance))) { wmOidAppend (oid, pInstance); } wmbObjectInstanceSet(obj, oid); } if (NULL != pArg) { pInstance = wmbObjectInstanceGet(obj); if (wmBufferBad(pInstance)) { argStrLen = (ubyte4)STRLEN(pArg++); pInstance = wmBufferCreate (NULL, argStrLen, pArg, DATATYPE_STRING_K, FALSE); wmbObjectInstanceSet (obj, pInstance); } else { pInstance = wmOidFromString (++pArg, 0); if (wmBufferBad(pInstance)) { return wmError (ERROR_GENERAL, "wmbObjectResolver: OID conversion failed"); } wmOidAppend (wmbObjectInstanceGet(obj), pInstance); wmBufferDelete (pInstance); } } /* untyped objects default to native type at instantiation */ if (DATATYPE_INVALID_K == wmbObjectTypeLocalGet(obj)) wmbObjectTypeLocalSet(obj, wmbEntryTypeGet(pEntry)); return OK; } /************************************************************************** * * wmbObjectLock - Lock all objects * * RETURNS: STATUS. * * NOMANUAL */ STATUS wmbObjectLock ( WMB_TID_T tid, WMB_OBJ_T obj, COMMAND_T cmd ) { WMB_LOCK_MODE_T mode; if ((cmd == CMD_GET_K) || (cmd == CMD_GET_NEXT_K)) mode = WMB_MODE_SHARED; else mode = WMB_MODE_EXCLUSIVE; wmosSemTake(g_semObjLock, WAIT_FOREVER_K); while (wmbObjectGood(obj)) { if (wmbObjectHandlerLocked(obj)) break; if (OK != wmbLock(obj, tid, mode)) { wmosSemGive(g_semObjLock); return ERROR; } obj = wmbObjectNextGet (obj); } return OK; } /************************************************************************** * * wmbObjectUnlock - Unlock all objects * * RETURNS: none. * * NOMANUAL */ void wmbObjectUnlock ( WMB_TID_T tid, WMB_OBJ_T obj ) { while (! wmbObjectBad (obj)) { if (wmbObjectHandlerLocked (obj)) break; if (OK != wmbUnlock (obj, tid)) break; obj = wmbObjectNextGet (obj); } wmosSemGive(g_semObjLock); } /************************************************************************** * * wmbObjectGo - execute a command associated with a wmbObject * * This routine executes the command for , * or the current wmbObject held by * * RETURNS: STATUS. * * * NOMANUAL */ STATUS wmbObjectGo ( WMB_TID_T tid, WMB_OBJ_T obj, COMMAND_T cmd ) { STATUS status = OK; #if 0 DB_ENTRY_T * pEntry; WM_BUFFER_T * pTemp; #endif #ifdef __ENABLE_IPC__ if (wmbObjectFlagIsSet(obj, OBJ_FLAG_REMOTE_K)) { return wmbObjectGoRemote (tid, obj, cmd); } #endif while (wmbObjectGood(obj)) { switch (cmd) { case CMD_GET_K: status = wmbObjectLoad(obj); break; case CMD_GET_NEXT_K: status = wmError(ERROR_TM_NOT_HANDLED, "not handled"); break; case CMD_COMMIT_K: status = wmbObjectStore(obj); break; case CMD_COMPLETE_K: wmbObjectSavedFree(obj); break; case CMD_TEST_K: /* backup data */ status = wmbObjectRedo(obj); break; case CMD_UNDO_K: status = wmbObjectUndo(obj); break; default: status = wmError(ERROR, "wmbObjectGo: no handler"); break; } if (OK != status) break; obj = wmbObjectNextGet(obj); } return status; } /*************************************************************************** * * wmbObjectEnumeration - lookup up 's enumerated value * * This function expects a WindMark to be named and have enumerated values * in its validation string (generated by the Integration Tool). * * NOTE: This handler currently only supports GET requests. * * NOMANUAL * * RETURNS: ERROR or OK. */ LOCAL STATUS wmbObjectEnumeration ( WMB_TID_T tid, /* transaction id */ WMB_OBJ_T metaObj, /* the meta WM (named "enum") */ WMB_OBJ_T enumObj, /* the enumerated WM */ COMMAND_T cmd /* handler command */ ) { sbyte Name[128]; sbyte temp[32]; sbyte * pTableName; sbyte tblInstance[128]; sbyte * pValidation; sbyte * pEnum; sbyte4 length; sbyte * pInstance; size_t instanceLength; ssize_t nValueSize = 0; sbyte * pTemp; /* get the name of the enumerated object */ if (NULL == wmbObjectInstancePtrGet(metaObj)) return ERROR; else { length = (sbyte4)strlen(wmbObjectInstancePtrGet(metaObj)); if (length > (sbyte4)(sizeof(Name)-1)) length = (sbyte4)sizeof(Name)-1; strncpy(Name,wmbObjectInstancePtrGet(metaObj),(size_t)length); /* length safe copy */ Name[length] = '\0'; } /* extract any instance/argument/table_instance from WindMark name */ if (NULL != (pInstance = strchr (Name, '('))) /* explicit '()' argument ? */ { *pInstance++ = '\0'; /* remove closing paren, using szValue as temp pointer */ if (NULL !=(pTemp = strrchr (pInstance, ')'))) *pTemp = '\0'; instanceLength = strlen(pInstance); /* Note, presumable any extra table parameter would have been truncated after the ')' */ /* Also, doing this test first allows for '.' and ',' characters that may be in the argument */ } else if (NULL != (pInstance = strchr (Name, '.'))) /* explicit '.' instance ? */ { *pInstance++ = '\0'; if (NULL != (pTemp = strchr (pInstance, ','))) /* Toss any table parameter */ *pTemp = '\0'; instanceLength = strlen(pInstance); } else if (NULL != (pTableName = strchr (Name, ','))) /* dynamic table instance ? */ { *pTableName++ = '\0'; if (OK != wmbTableInstanceGet(wmbTransactionSessionGet(tid), pTableName, tblInstance, sizeof(tblInstance), &instanceLength)) return ERROR; pInstance = tblInstance; } else /* no instance */ { pInstance = NULL; instanceLength = 0; } /* set up enumerated object and get validation string */ if (OK != wmbObjectMake (tid, enumObj, Name, NULL, 0, temp, sizeof(temp), DATATYPE_STRING_K, FALSE)) { return ERROR; } if (NULL == (pValidation = wmbObjectValidationString(enumObj))) return wmError(ERROR_GENERAL_NO_DATA, "no validation string"); /* get enumerated object's value (getting a string value means no byte count issue) */ if (OK !=wmbDataStringGet (wmbTransactionSessionGet(tid), Name, pInstance, (sbyte4)instanceLength, temp, sizeof(temp), &nValueSize)) return ERROR; /* convert the value into its enumeration */ if (OK != wmConvertEnum(pValidation, atoi(temp), &pEnum, &length)) return ERROR; /* load enumerated value into meta object's value buffer */ return wmbObjectImport(metaObj, pEnum, (size_t)length, DATATYPE_STRING_K); } /*************************************************************************** * * wmbObjectEnum - enum Meta WindMark handler * * This function is the enum WindMark handler (the Meta WM). * * Usage: * enum(windmark) : No instance (or custom/RC instancing done by handler) * enum(windmark.1.2.3) : Explicit instance * enum(windmark(argument)) : Explicit argument * enum(windmark,tablename) : Instance from Table Manager (createTable) * * The Enum WindMark should have enumerated values in its validation string * (generated by the Integration Tool). * * This function will retrieve the value of the Enum WM and convert that value * into an enumeration string (as set above). * * NOTE: This handler currently only supports GET requests. * * RETURNS: ERROR or OK. */ STATUS wmbObjectEnum ( WMB_TID_T tid, /* transaction id */ WMB_OBJ_T metaObj, /* the meta WM (named "enum") */ COMMAND_T cmd /* handler command */ ) { WMB_OBJECT_T enumObject; /* currently only support gets on enums -- should add sets later */ if (CMD_GET_K != cmd) return wmError (ERROR_GENERAL_READ_ONLY, "enums are read only"); while (wmbObjectGood (metaObj)) { if (OK != wmbObjectEnumeration (tid, metaObj, &enumObject, cmd)) break; /* loop through other (optional) enum meta objects in transaction */ metaObj = wmbObjectNextGet (metaObj); } /* clean up our working object */ wmbTransactionObjectRemove(tid, &enumObject); wmbObjectDelete (&enumObject); return OK; } /************************************************************************** * * wmbObjectDelete - delete a wmbObject * * RETURNS: N/A. * */ void wmbObjectDelete ( WMB_OBJ_T obj /* object to delete */ ) { WM_BUFFER_T * pBuffer; DB_ENTRY_T * pEntry; DEBUG_MSG_1 ("wmbObjectDelete: start obj: 0x%x\n", obj); if (wmbObjectBad(obj)) { wmError(ERROR, "wmbObjectDelete: invalid object"); return; } pBuffer = wmbObjectNameBufferGet(obj); if (! wmBufferBad(pBuffer)) wmBufferDelete(pBuffer); pBuffer = wmbObjectValueGet(obj); if (! wmBufferBad(pBuffer)) wmBufferDelete(pBuffer); if (NULL != (pEntry = wmbObjectEntryGet(obj))) { if (wmbEntryFlagGet(pEntry, DB_FLAG_WRITE_LOCK)) wmbEntryWriteUnlock(wmbObjectDBGet(obj), pEntry); else wmbEntryReadUnlock(wmbObjectDBGet(obj), pEntry); } pBuffer = wmbObjectInstanceGet(obj); if (! wmBufferBad (pBuffer)) wmBufferDelete (pBuffer); /* wmbShareFree (wmbBackplaneGet(), WMB_SHARE_OBJECT_K, obj); */ if (FLAG_SET(wmbObject(obj), OBJ_FLAG_FREE_K)) { #ifdef __USE_MEMORY_BLOCKS__ wmMemBlockFree (pBlockObjects, obj); /* wmMemBlockFree (wmbBackplaneObjectsGet(backplane), obj) */ #else wmFree(obj); #endif } } /************************************************************************** * * wmbObjectImport - assign object value * * Updates the "working value", the data buffer * * RETURNS: OK or ERROR * */ STATUS wmbObjectImport ( WMB_OBJ_T obj, /* object to update */ void * pSrc, /* source of new working data */ size_t srcSize, /* size of new data */ DATATYPE_T srcType /* data type of new data */ ) { WM_BUFFER_T * pBuf; if (NULL == (pBuf = wmbObjectValueBufferGet(obj))) { if (NULL == (pBuf = wmBufferCreate(NULL, srcSize, pSrc, srcType, TRUE))) return wmError(ERROR, "wmbObjectImport: no memory"); wmbObjectValueBufferSet(obj, pBuf); return OK; } return wmBufferUpdate (wmbObjectValueBufferGet(obj), pSrc, srcSize, srcType, TRUE); } /************************************************************************** * * wmbObjectExport - copy object value to buffer * * Updates the "working value", the data buffer * * RETURNS: OK or ERROR * */ STATUS wmbObjectExport ( WMB_OBJ_T obj, /* object to export from */ void * pDest, /* buffer to receive data */ size_t destSize, /* size of buffer */ DATATYPE_T destType, /* type of data */ size_t * pWritten /* amount of bytes written */ ) { WM_BUFFER_T * pValue; pValue = wmbObjectValueGet(obj); if (NULL == pValue) return wmError(ERROR_WMB_OBJECT_INVALID, "wmObjectExport"); return wmBufferExport (pValue, pDest, destSize, destType, pWritten); } ubyte4 wmbObjectTypeLocalGet ( WMB_OBJ_T obj ) { WM_BUFFER_T * pBuf; pBuf = wmbObjectValueGet(obj); if (wmBufferBad(pBuf)) return DATATYPE_INVALID_K; return (ubyte4)wmBufferLocalGet(pBuf); } void wmbObjectTypeLocalSet ( WMB_OBJ_T obj, ubyte4 type ) { WM_BUFFER_T * pBuf; pBuf = wmbObjectValueGet(obj); if (! wmBufferBad(pBuf)) wmBufferLocalSet(pBuf, type); #if __WM_DEBUUG__ else DEBUG_MSG_1("wmbObjectTypeLocalSet for obj: 0x%x has no value buffer\n", obj); #endif } ubyte4 wmbObjectTypeNativeGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pDbEntry; if (wmbObjectBad(obj)) return DATATYPE_INVALID_K; if (NULL == (pDbEntry = wmbObjectEntryGet(obj))) return DATATYPE_INVALID_K; return wmbEntryTypeGet(pDbEntry); } void wmbObjectTypeNativeSet ( WMB_OBJ_T obj, ubyte4 type ) { WM_BUFFER_T * pBuf; pBuf = wmbObjectValueGet(obj); if (! wmBufferBad(pBuf)) wmBufferTypeSet(pBuf, type); } /*************** toolkit commands **************/ /* load native to object value */ #ifdef __ENABLE_IPC__ LOCAL STATUS wmbObjectExecRemote ( WMB_CMD_T command, WMB_OBJ_T object, sbyte * pBuffer, long length, ubyte4 type ) { OS_SEM_T sem; MSG_IPC_T ipc; WMB_CID_T component; STATUS status; BOOL copy; sbyte * pName; size_t written; MEM_POOL_ID pool; WM_BUFFER_T * pValue; DEBUG_MSG_1("wmbObjectExecRemote: obj: 0x%x\n", object); if (NULL == (pName = wmbObjectCookieGet(object))) return wmError(ERROR, "wmbObjectExecRemote: no name"); if (NULL == (pool = wmbSharedPool())) return wmError(ERROR, "wmbObjectExecRemote: no shared pool"); component = wmbObject(object)->component; if (wmbComponentBad(component)) return wmError(ERROR, "wmbObjectExecRemote: no component"); if (OK != wmosSemCreate(&sem, 1, 0)) return ERROR; copy = (CMD_SET_K == command); if (NULL == (pValue = wmBufferCreate(pool, pBuffer, (size_t)length, type, copy))) return wmError(ERROR, "wmbObjectExecRemote: no value"); if (OK != wmbObjectValueCreate (&object, pBuffer, length, type, copy)) return wmError(ERROR, "wmbObjectExecRemote: no value"); wmbObjectValueBufferSet (&object, pValue); DEBUG_MSG_2 ("wmbObjectExecRemote: value: 0x%x pool: 0x%x\n", pValue, pool); wmZero(&ipc); ipc.msgCmd = WMB_MSG_COMMAND_K; ipc.objCmd = command; ipc.sem = sem; ipc.name = wmbShareString(pool, pName); ipc.value = (int) wmPtrSet(pool, pValue); DEBUG_MSG_2 ("wmbObjectExecRemote: sending to component: 0x%x cmd: %d\n", component, command); DEBUG_MSG_3 ("wmbObjectExecRemote: ipc value: 0x%x value: 0x%x pool: 0x%x\n", ipc.value, pValue, pool); if (OK == (status = wmbComponentSend(component, &ipc, sizeof(ipc) - sizeof(int)))) { DEBUG_MSG_2 ("wmbObjectExecRemote: waiting for obj: 0x%x cmd: %d\n", object, command); wmosSemTake(sem, WAIT_FOREVER_K); wmosSemTake(sem, WAIT_FOREVER_K); DEBUG_MSG_2 ("wmbObjectExecRemote: finished obj: 0x%x cmd: %d\n", object, command); /* get results */ switch (command) { case CMD_GET_K: /* fallthrough */ case CMD_GET_NEXT_K: /* fallthrough */ case CMD_EXEC_K: /* fallthrough */ wmBufferExport(pValue, pBuffer, length, type, &written); break; } status = ipc.status; } wmosSemDestroy (sem); wmPoolFree(pool, (sbyte *) pool + ipc.name); return status; } /* far end of execution of remote command */ STATUS wmbObjectExecFar ( WMB_CID_T component, MSG_IPC_T * pIpc ) { WMB_OBJECT_T object; MEM_POOL_ID pool; WM_BUFFER_T * pValue; DEBUG_MSG_1("wmbObjectExecFar: obj: 0x%x\n", &object); if (NULL == (pool = wmbSharedPool())) return wmError(ERROR, "wmbObjectExecFar: no shared pool"); DEBUG_MSG_1("wmbObjectExecFar: pool: 0x%x\n", pool); DEBUG_MSG_1("wmbObjectExecFar: raw value: 0x%x\n", pIpc->value); pValue = wmPtrGet (pool, pIpc->value); if (wmBufferBad (pValue)) return wmError (ERROR, "wmbObjectExecFar: no shared value buffer"); wmbObjectInit (&object, NULL, wmPtrGet(pool, pIpc->name), NULL, 0); wmbObjectValueBufferSet (&object, pValue); DEBUG_MSG_2 ("wmbObjectExecFar: obj: 0x%x buf: 0x%x\n", &object, pValue); if (OK != wmbObjectResolveComponent (component, &object)) return wmError(ERROR, "wmbObjectExecFar: no resolve"); pIpc->status = wmbObjectGo (NULL, &object, pIpc->objCmd); DEBUG_MSG_2 ("wmbObjectExecFar: obj: 0x%x status: 0x%x\n", &object, pIpc->status); return pIpc->status; } #endif /************************************************************************** * * wmbObjectMake - initialize and lookup object * * Helper constructor. Does not execute command * * RETURNS: * \is * * \i OK * Data successfully retrieved * * \i ERROR * Windmark doesn't exist * \ie */ STATUS wmbObjectMake ( WMB_TID_T tid, WMB_OBJ_T obj, sbyte * pName, void * pInstance, sbyte4 instanceLen, sbyte * pBuffer, ssize_t bufferLen, ubyte4 bufferType, BOOL copy ) { WMB_SESSION_T * pSession; if (wmbTransactionBad(tid)) return wmError(ERROR_TM_TID_NOT_FOUND, "wmbObjectMake"); pSession = wmbTransactionSessionGet(tid); if (OK != wmbObjectInit (obj, NULL, pName, pInstance, instanceLen, copy)) return ERROR; if (OK != wmbTransactionObjectAdd(tid, obj)) { wmbObjectDelete(obj); return ERROR; } if (DATATYPE_INVALID_K == bufferType) bufferType = wmbObjectTypeNativeGet (obj); wmbObjectTypeLocalSet (obj, bufferType); return wmbObjectValueCreate (obj, pBuffer, (size_t)bufferLen, (sbyte4)bufferType, copy); } /************************************************************************** * * wmbObjectPermission - verify user can access object * * * RETURNS: * \is * * \i OK * Data accessible * * \i ERROR * Access denied * \ie */ STATUS wmbObjectPermission ( WMB_SESSION_T * pSession, WMB_OBJ_T obj, COMMAND_T command ) { DB_ENTRY_T * pEntry; WM_ACCESS_T user; BOOL allowed; /* if no session, then they don't care about permissions */ if (wmbSessionBad(pSession)) return OK; if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR, "wmbObjectPermission: no db entry!"); user = wmbSessionAccessGet(pSession); switch (command) { case CMD_SET_K: /* fallthrough */ case CMD_COMMIT_K: case CMD_TEST_K: if (wmbDBEntryFlagGet(pEntry, DB_FLAG_READONLY_K)) allowed = FALSE; else allowed = wmAccessWriteAllowed(user.write, (Access)wmbEntryWriteAccessGet(pEntry)); break; case CMD_GET_K: case CMD_GET_NEXT_K: allowed = wmAccessReadAllowed(user.read, (Access)wmbEntryReadAccessGet(pEntry)); break; default: allowed = TRUE; break; } if (allowed) return OK; return wmError(ERROR_GENERAL_ACCESS_DENIED, "access denied"); } /************************************************************************** * * wmbObjectSetupInstance - Set up the instance value for on object record * * * RETURNS: OK or ERROR * * NOMANUAL */ STATUS wmbObjectSetupInstance ( WMB_TID_T tid, /* object transaction */ WMB_OBJ_T obj, /* object instance to set up */ void * pInstance, /* [in] Instance pointer of the object */ sbyte4 instanceLength, /* [in] Length of the instance */ DATATYPE_T instanceType, /* [in] Instance Data type in */ BOOL copy /* [in] Copy the pName to newly allocated space */ ) { WM_OID_T oid; WM_INSTANCE_T inst; MEM_POOL_ID pool; if (wmbTransactionBad(tid)) pool = NULL; else pool = wmbTransactionMemGet(tid); if (WMB_INST_OID == lclObjectInstanceType(obj)) { /* OID instance can be given in string or binary form but should internally be binary only */ if ((NULL != pInstance) && (0 != instanceLength)) { /* if instance starts with a digit it is an oid, otherwise, a string arg */ if (DATATYPE_OID_K == instanceType) { oid = wmBufferCreate(pool, (size_t)instanceLength, pInstance, DATATYPE_OID_K, copy); } else if (ISDIGIT( (int) *((char *)pInstance ) ) ) { oid = wmOidFromString (pInstance, 0); if (wmBufferBad(oid)) { return wmError (ERROR_GENERAL, "wmbObjectInit: OID conversion failed"); } } else { if (0 == instanceLength) instanceLength = (sbyte4)STRLEN(pInstance) + 1; oid = wmBufferCreate(pool, (size_t)instanceLength, pInstance, DATATYPE_STRING_K, copy); } wmOidAppend(wmbObjectInstanceGet(obj), oid); /* we are done with oid */ wmBufferDelete(oid); } else if (NULL == wmbObjectInstanceGet(obj)) { /* no value assigned but space requested for later */ if (0 < instanceLength) oid = wmBufferCreate(pool, (size_t)instanceLength, NULL, DATATYPE_OID_K, copy); else { oid = wmBufferCreate(pool, 0, NULL, DATATYPE_OID_K, FALSE); /* oid = NULL; */ } wmbObjectInstanceSet(obj, oid); } } else { /* string-based instance */ if ((NULL != pInstance) && (0 != instanceLength)) { inst = wmBufferCreate(pool, (size_t)instanceLength, pInstance, DATATYPE_STRING_K, copy); wmbObjectInstanceSet(obj, inst); } else if (NULL == wmbObjectInstanceGet(obj)) { /* no value assigned but space requested for later */ if (0 < instanceLength) { inst = wmBufferCreate(pool, (size_t)instanceLength, NULL, DATATYPE_STRING_K, FALSE); } else inst = wmBufferCreate(pool, 1, "", DATATYPE_STRING_K, TRUE); wmbObjectInstanceSet(obj, inst); } else { /* protect against existing zero length string instance (missing terminator) */ inst = wmbObjectInstanceGet(obj); if (0 == wmBufferUsedGet(inst)) wmbObjectInstanceSet(obj, NULL); } } return OK; } /************************************************************************** * * wmbObjectGet - Get value for a single object * * * RETURNS: OK or ERROR * * NOMANUAL */ STATUS wmbObjectGet ( WMB_SESSION_T * pSession, /* [in] Session pointer for the current session */ COMMAND_T command, /* [in] Command to execute CMD_GET_K */ sbyte * pName, /* [in] Name of the Object */ void * pInstance, /* [in] Instance pointer of the object */ sbyte4 instanceLength, /* [in] Length of the instance */ sbyte * pBuffer, /* [in] Buffer that holds the new, or returned value */ long bufferLength, /* [in] Length of the buffer */ DATATYPE_T bufferType, /* [in] Buffer type: Data type in the buffer. */ /* DATA_TYPE_INVALID_K: Use Object native type (no conversion) */ BOOL copy, /* [in] Copy the pName to newly allocated space */ long * pWritten /* [out] Actual number of bytes returned */ ) { STATUS status; WMB_TID_T tid; WMB_OBJECT_T object; WMB_HANDLER_T handler; tid = wmbSessionTidGet (pSession); /* Initialize the object, but defer the instance init */ if (OK != wmbObjectMake(tid, &object, pName, NULL, 0, pBuffer, bufferLength, bufferType, copy)) return ERROR; /* Explicitly set up the instance; only string-form instances supported here */ if (OK != wmbObjectSetupInstance(tid, &object, pInstance, instanceLength, DATATYPE_STRING_K, copy)) return ERROR; /* make sure user has permission to access object */ if (OK != wmbObjectPermission(pSession, &object, command)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } if (!wmbObjectHandlerLocked(&object)) { if (OK != wmbObjectLock(tid, &object, command)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } } handler = wmbObjectHandlerGet(&object); if (NULL == handler) handler = wmbObjectGo; status = handler(tid, &object, command); if (OK != status) { #ifdef __ENABLE_IPC__ if (ERROR_GENERAL_NOT_LOCAL != wmErrNo()) { /* TO DO: Rewrite the IPC portion */ DEBUG_MSG_1 ("wmbObjectExec: attempting remote for obj:0x%x\n", &object); status = wmbObjectExecRemote (set[i], &object, pBuffer, bufferLength, (ubyte4)bufferType); } #endif /* __ENABLE_IPC__ */ } if (!wmbObjectHandlerLocked(&object)) wmbObjectUnlock(tid, &object); if (NULL != pWritten) *pWritten = (long)wmbObjectSizeGet(&object); /* the object itself may be static but this will free assocated buffers */ wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return (status); } /* wmbObjectGet */ /************************************************************************** * * wmbObjectGetNext - Get value for a single object, update instance * * This routine will fetch the next value for a given WindMark. It will update * the instance data with the new instance, in the indicated data type (which * is expected to be OID or STRING) * * RETURNS: OK or ERROR * * NOMANUAL */ STATUS wmbObjectGetNext ( WMB_SESSION_T * pSession, /* [in] Session pointer for the current session */ sbyte * pName, /* [in] Name of the Object */ void * pInstance, /* [in] Instance pointer of the object */ sbyte4* pInstanceLength,/* [in] Length of the instance */ sbyte4 maxInstanceLength,/* [in] Maximum Length of the instance buffer */ DATATYPE_T instanceType, /* [in] Instance Data type in and next */ sbyte * pBuffer, /* [in] Buffer that holds the new, or returned value */ long bufferLength, /* [in] Length of the buffer */ DATATYPE_T bufferType, /* [in] Buffer type: Data type in the buffer. */ /* DATA_TYPE_INVALID_K: Use Object native type (no conversion) */ BOOL copy, /* [in] Copy the pName to newly allocated space */ long * pWritten /* [out] Actual number of bytes returned */ ) { STATUS status; WMB_TID_T tid; WMB_OBJECT_T object; WMB_HANDLER_T handler; WM_BUFFER_T * pInstBuffer; size_t instLenTmp; tid = wmbSessionTidGet (pSession); /* Initialize the object, but defer the instance init */ if (OK != wmbObjectMake(tid, &object, pName, NULL , 0, pBuffer, bufferLength, bufferType, copy)) return ERROR; /* Explicitly set up the instance; only string-form instances supported here */ if (OK != wmbObjectSetupInstance(tid, &object, pInstance, *pInstanceLength, instanceType, copy)) return ERROR; /* make sure user has permission to access object */ if (OK != wmbObjectPermission(pSession, &object, CMD_GET_NEXT_K)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } if (!wmbObjectHandlerLocked(&object)) { if (OK != wmbObjectLock(tid, &object, CMD_GET_NEXT_K)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } } handler = wmbObjectHandlerGet(&object); if (NULL == handler) handler = wmbObjectGo; status = handler(tid, &object, CMD_GET_NEXT_K); if (OK != status) { #ifdef __ENABLE_IPC__ if (ERROR_GENERAL_NOT_LOCAL != wmErrNo()) { /* TO DO: Rewrite the IPC portion */ DEBUG_MSG_1 ("wmbObjectExec: attempting remote for obj:0x%x\n", &object); status = wmbObjectExecRemote (set[i], &object, pBuffer, bufferLength, bufferType); } #endif /* __ENABLE_IPC__ */ } if (!wmbObjectHandlerLocked(&object)) wmbObjectUnlock(tid, &object); if (NULL != pWritten) *pWritten = (OK == status) ? (long)wmbObjectSizeGet(&object) : 0; /* update the instance information */ if (OK == status) { pInstBuffer = wmbObjectInstanceGet(&object); *pInstanceLength = (sbyte4)wmBufferUsedGet(pInstBuffer); status = wmBufferExport (pInstBuffer, pInstance, (size_t)maxInstanceLength, instanceType, &instLenTmp); *pInstanceLength = (sbyte4)instLenTmp; if (OK != status) { wmError(0, "Buffer for new instance too small!"); status = ERROR_GENERAL_WRONG_LENGTH; } } /* the object itself may be static but this will free assocated buffers */ wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return (status); } /* wmbObjectGetNext */ /************************************************************************** * * wmbObjectSet - set an object's value * * RETURNS: * OK or ERROR * * NOMANUAL */ STATUS wmbObjectSet ( WMB_SESSION_T * pSession, /* [in] Session pointer for the current session */ sbyte * pName, /* [in] Name of the Object */ void * pInstance, /* [in] Instance pointer of the object */ sbyte4 instanceLength, /* [in] Length of the instance */ sbyte * pBuffer, /* [in] Buffer that holds the new value */ long bufferLength, /* [in] Length of the buffer */ DATATYPE_T bufferType /* [in] Buffer type: Data type in the buffer. */ /* DATA_TYPE_INVALID_K: Use Object native type (no conversion) */ ) { STATUS status; WMB_TID_T tid; WMB_OBJECT_T object; WMB_HANDLER_T handler; tid = wmbSessionTidGet (pSession); /* Initialize the object, but defer the instance init */ if (OK != wmbObjectMake(tid, &object, pName, NULL, 0, pBuffer, bufferLength, bufferType, FALSE)) return ERROR; /* Explicitly set up the instance; ONLY string-form instances supported here */ if (OK != wmbObjectSetupInstance(tid, &object, pInstance, instanceLength, DATATYPE_STRING_K, FALSE)) return ERROR; /* make sure user has permission to access object */ if (OK != wmbObjectPermission(pSession, &object, CMD_COMMIT_K)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } if (!wmbObjectHandlerLocked(&object)) { if (OK != wmbObjectLock(tid, &object, CMD_TEST_K)) { wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return ERROR; } } handler = wmbObjectHandlerGet(&object); if (NULL == handler) handler = wmbObjectGo; status = handler(tid, &object, CMD_TEST_K); if (OK != status) { #ifdef __ENABLE_IPC__ if (ERROR_GENERAL_NOT_LOCAL != wmErrNo()) { /* TO DO: Rewrite the IPC portion */ DEBUG_MSG_1 ("wmbObjectExec: attempting remote for obj:0x%x\n", &object); status = wmbObjectExecRemote (set[i], &object, pBuffer, bufferLength, bufferType); } #endif /* __ENABLE_IPC__ */ } else { status = handler(tid, &object, CMD_COMMIT_K); if (OK != status) { wmbObjectStatusSet(&object, status); } handler(tid, &object, CMD_COMPLETE_K); } if (!wmbObjectHandlerLocked(&object)) wmbObjectUnlock(tid, &object); /* the object itself may be static but this will free assocated buffers */ wmbTransactionObjectRemove(tid, &object); wmbObjectDelete (&object); return status; } WM_BUFFER_T * wmbObjectValueGet ( WMB_OBJ_T obj ) { if (wmbObjectBad(obj)) return NULL; return wmbObject(obj)->pValue; } /************************************************************************** * * wmbObjectInstancePtrGet - get data pointer of object instance * * * RETURNS: data ptr or NULL. * */ void * wmbObjectInstancePtrGet ( WMB_OBJ_T obj ) { WM_BUFFER_T * pInstance; if (wmbObjectFlagIsSet(obj, OBJ_FLAG_INST_BUFFER_K)) { pInstance = wmbObject(obj)->pInstance; return wmBufferDataGet(pInstance); } if (wmbObjectFlagIsSet(obj, OBJ_FLAG_INST_PTR_K)) return wmbObject(obj)->pInstance; return NULL; } sbyte4 wmbObjectLocalGet ( WMB_OBJ_T obj ) { return (sbyte4)(wmbObject(obj)->localId); } void * wmbObjectCookieGet ( WMB_OBJ_T obj ) { return wmbObject(obj)->pCookie; } void wmbObjectCookieSet ( WMB_OBJ_T obj, void * pState ) { if (NULL != wmbObject(obj)->pCookie && NULL != pState) wmError(ERROR_GENERAL, "wmbObjectCookieSet: overwriting cookie!"); wmbObject(obj)->pCookie = pState; } /************************************************************************** * * wmbObjectUndo - restore original native data * * RETURNS: * \is * * \i OK * \i ERROR * No undo * \ie */ STATUS wmbObjectUndo ( WMB_OBJ_T obj ) { WM_BUFFER_T * pBuffer; size_t written; DB_ENTRY_T * pEntry; if (! wmbObjectFlagIsSet(obj, OBJ_FLAG_COOKIE_UNDO_K)) return OK; if (NULL == (pEntry = wmbObjectEntryGet(obj))) return wmError(ERROR_GENERAL, "wmbObjectUndo: no db entry"); if (NULL == (pBuffer = wmbObjectCookieGet(obj))) return wmError(ERROR_GENERAL, "wmbObjectUndo: no buffer"); wmBufferExport(pBuffer, wmbEntryDataGet(pEntry), wmbEntrySizeGet(pEntry), wmbEntryTypeGet(pEntry), &written); wmbObjectSavedFree(obj); return OK; } /************************************************************************** * * wmbObjectRedo - save original native data * * RETURNS: * \is * * \i OK * \i ERROR * No undo * \ie */ STATUS wmbObjectRedo ( WMB_OBJ_T obj ) { if (NULL != wmbObjectCookieGet(obj)) return wmError(ERROR_GENERAL, "wmbObjectRedo: overwriting cookie"); wmbObjectCookieSet(obj, wmbObjectStoredGet(obj)); wmbObjectFlagSet(obj, OBJ_FLAG_COOKIE_UNDO_K); return OK; } /************************************************************************** * * wmbObjectSavedGet - return saved COPY of original native data * * * RETURNS: * \is * * \i Buffer pointer * \i NULL * No database entry * \ie */ STATUS wmbObjectSavedGet ( WMB_OBJ_T obj, void * pData, size_t size, sbyte4 type ) { WM_BUFFER_T * pBuffer; size_t written; if (NULL == (pBuffer = wmbObjectCookieGet(obj))) return wmError(ERROR_GENERAL, "wmbObjectSavedGet: no buffer"); return wmBufferExport(pBuffer, pData, size, (ubyte4)type, &written); } /************************************************************************** * * wmbObjectSavedSet - make COPY of original native data * * * RETURNS: * \is * * \i Buffer pointer * \i NULL * No database entry * \ie */ STATUS wmbObjectSavedSet ( WMB_OBJ_T obj, void * pData, size_t size, sbyte4 type ) { WM_BUFFER_T * pBuffer; if (NULL == (pBuffer = wmBufferCreate(NULL, size, pData, type, TRUE))) return wmError(ERROR_GENERAL, "wmbObjectBackup: can't make buffer"); wmbObjectCookieSet(obj, pBuffer); return OK; } /************************************************************************** * * wmbObjectStoredGet - return a buffer with a COPY of stored data * * * RETURNS: * \is * * \i Buffer pointer * \i NULL * No database entry * \ie */ WM_BUFFER_T * wmbObjectStoredGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; if (NULL == (pEntry = wmbObjectEntryGet(obj))) return NULL; return wmBufferCreate(NULL, wmbEntrySizeGet(pEntry), wmbEntryDataGet(pEntry), wmbEntryTypeGet(pEntry), TRUE); } /************************************************************************** * * wmbObjectSavedFree - free the cookie buffer * * * RETURNS: * \is * * \i Buffer pointer * \i NULL * No database entry * \ie * * NOMANUAL */ void wmbObjectSavedFree ( WMB_OBJ_T obj ) { WM_BUFFER_T * pBuffer; if (NULL == (pBuffer = wmbObjectCookieGet(obj))) return; wmBufferDelete(pBuffer); wmbObjectCookieSet(obj, NULL); } /************************************************************************** * * wmbObjectInstanceSet - set instance * * This routine first frees up any instance info currently defined. * * * * RETURNS: * \is * * \i Buffer pointer * \i NULL * No database entry * \ie */ void wmbObjectInstanceSet ( WMB_OBJ_T obj, WM_BUFFER_T * pInstance ) { if (obj->pInstance != NULL) wmBufferDelete(obj->pInstance); wmbObjectFlagSet(obj, OBJ_FLAG_INST_BUFFER_K); obj->pInstance = pInstance; } /************************************************************************** * * wmbObjectEntryGet - get database entry associated with object * * * RETURNS: DB_ENTRY_T * */ DB_ENTRY_T * wmbObjectEntryGet ( WMB_OBJ_T obj /* [in] Object Pointer */ ) { return wmbObject(obj)->pEntry; } /************************************************************************** * * wmbObjectTableGet - return table object is a member of * * RETURNS: * \is * * \i table pointer * \i NULL * No table * \ie */ DB_TABLE_T * wmbObjectTableGet ( WMB_OBJ_T obj /* [in] Object for which the table pointer is returned */ ) { DB_ENTRY_T *pEntry; pEntry = wmbObjectEntryGet(obj); return (NULL != pEntry ? wmbEntryTableGet(pEntry) : NULL); } /************************************************************************** * * wmbObjectStatusSet - set status of object * * RETURNS: N/A */ void wmbObjectStatusSet ( WMB_OBJ_T obj, sbyte4 status ) { wmbObject(obj)->status = status; } /************************************************************************** * * wmbObjectStatusGet - get status of processed object * * RETURNS: object status */ sbyte4 wmbObjectStatusGet ( WMB_OBJ_T obj ) { return wmbObject(obj)->status; } /************************************************************************** * * wmbObjectHandlerGet - return object handler * * * RETURNS: object handler */ WMB_HANDLER_T wmbObjectHandlerGet ( WMB_OBJ_T obj ) { return wmbObject(obj)->handler; } /************************************************************************** * * wmbObjectHandlerLocked - is object locked? * * RETURNS: TRUE if locked */ BOOL wmbObjectHandlerLocked ( WMB_OBJ_T obj ) { return wmbEntryFlagGet(wmbObjectEntryGet(obj), DB_FLAG_LOCK_SELF_K); } /************************************************************************** * * wmbObjectLevelGet - return lock level of object * * RETURNS: lock level */ sbyte4 wmbObjectLevelGet ( WMB_OBJ_T obj ) { DB_ENTRY_T * pEntry; pEntry = wmbObjectEntryGet(obj); if (wmbDBEntryFlagGet(pEntry, DB_FLAG_LEVEL_TABLE_K)) return WMB_LOCK_LEVEL_TABLE_K; return wmbDBEntryFlagGet(wmbObjectEntryGet(obj), DB_FLAG_LEVEL_COMP_K) ? WMB_LOCK_LEVEL_COMP_K : WMB_LOCK_LEVEL_OBJECT_K; } /************************************************************************** * * wmbObjectNameBaseGet - return base name of object (no path prepended) * * RETURNS: name */ sbyte * wmbObjectNameBaseGet ( WMB_OBJ_T obj ) { sbyte * pName; pName = wmbObjectNamePtrGet(obj); return pName + wmbObjectPathlenGet(obj); } /************************************************************************** * * wmbObjectSetRangeTest - check the oject value range * * RETURNS: OK if valid, Error if not */ STATUS wmbObjectSetRangeTest ( WMB_OBJ_T obj ) { STATUS status = OK; char * pBuf = NULL; char * pValidStr = NULL; char * pString = NULL; DB_ENTRY_T * pDBEntry = NULL; WMB_ENTRY_T * pWMBEntry = NULL; WM_BUFFER_T * pValue = NULL; pDBEntry = wmbObjectEntryGet (obj); if (NULL != pDBEntry) pWMBEntry = pDBEntry->pEntry; if ((NULL == pWMBEntry) || (NULL == pWMBEntry->pValid)) return OK; pValidStr = pWMBEntry->pValid; pValue = wmbObjectValueGet(obj); if(NULL != pValue) pString = pValue->data; switch (pWMBEntry->type) { case DATATYPE_INTEGER_K: case DATATYPE_UINTEGER_K: case DATATYPE_CHAR_K: case DATATYPE_UCHAR_K: case DATATYPE_SHORT_K: case DATATYPE_USHORT_K: case DATATYPE_LONG_K: case DATATYPE_ULONG_K: case DATATYPE_INT64_K: case DATATYPE_UINT64_K: if (! wmConvertIsNumber(pString)) return ERROR_CONVERSION_INCORRECT_TYPE; /* Check lower bound */ if (NULL == (pBuf = strstr(pValidStr,"L="))) break; if (-1 == wmConvertStrNumCmp(pString , &pBuf[2])) return ERROR_GENERAL_OUT_OF_RANGE; /* Check upper bound */ if (NULL == (pBuf = strstr(pValidStr,"U="))) break; if (1 == wmConvertStrNumCmp(pString , &pBuf[2])) return ERROR_GENERAL_OUT_OF_RANGE; break; case DATATYPE_STRING_K: /* evaluate string contents and length */ if (NULL == pString) return OK; if (OK != (status = lcl_VALID_String(pString, pValidStr))) return status; if (NULL == pString) return OK; /* Check string length */ if (OK != (status = VALID_Length(pString, pValidStr))) return status; break; case DATATYPE_IPV4_K: /* evaulate 256.256.256.256 format */ case DATATYPE_IPV6_K: case DATATYPE_MACADDR_K: /* evaulate xx:xx:xx:xx:xx:xx format */ case DATATYPE_ENUM_K: /* find if string is in enum list */ case DATATYPE_LIST_K: /* find if strings are in enum list */ case DATATYPE_ACCESS_K: /* find if strings are in enum list */ break; default: /* if other type, assume it is OK for now */ break; } return status; } /*********************************************************************** * * wmbObjectValueExportAdapt - convert object value in setting process. * * convert the object value from export type(DATATYPE_ENUM_K) to expect type * (DATATYPE_STRING_K: numeric string) before calling wmbObjectStore() or * wmbObjectExport() if necessary. * * NOTE: This handler currently only support enumerated string to numeric * string. exportType should be DATATYPE_ENUM_K. * * RETURNS: ERROR or OK */ STATUS wmbObjectValueExportAdapt (WMB_OBJ_T obj, DATATYPE_T exportType) { WM_BUFFER_T * pBuf; sbyte tempBuf[128]={0}; DATATYPE_T bufType; sbyte4 enumVal; if (exportType != DATATYPE_ENUM_K) return OK; if(NULL == (pBuf=wmbObjectValueBufferGet(obj))) return ERROR; bufType = wmBufferTypeGet(pBuf); if(bufType != DATATYPE_STRING_K) return OK; if (OK != wmConvertEnumFromStr(wmbObjectValidationString(obj),(sbyte *)wmBufferDataGet(pBuf),&enumVal)) return ERROR; if (OK != wmConvertIntToStr(enumVal,tempBuf)) return ERROR; if (OK != wmBufferDelete(pBuf)) return ERROR; if (NULL == (pBuf = wmBufferCreate(NULL,STRLEN(tempBuf)+1,tempBuf,DATATYPE_STRING_K, TRUE))) return ERROR; wmbObjectValueBufferSet(obj,pBuf); return OK; } /*********************************************************************** * * wmbObjectValueImportAdapt - convert object value in getting process. * * convert the object value to import type(DATATYPE_ENUM_K) after calling * wmbObjectLoad() or wmbObjectImport() if necessary. * * NOTE: This handler currently only support numeric string to enumerated * string. importType should be DATATYPE_ENUM_K. * * RETURNS: ERROR or OK */ STATUS wmbObjectValueImportAdapt (WMB_OBJ_T obj, DATATYPE_T importType) { WM_BUFFER_T * pBuf; DATATYPE_T bufType; sbyte4 enumVal; sbyte4 length; sbyte *pEnumStr; if (importType != DATATYPE_ENUM_K) return OK; if(NULL == (pBuf=wmbObjectValueBufferGet(obj))) return ERROR; bufType = wmBufferTypeGet(pBuf); if (bufType != DATATYPE_STRING_K) return OK; enumVal = ATOI((sbyte *)(wmBufferDataGet(pBuf))); if (OK != wmConvertEnum(wmbObjectValidationString(obj),enumVal,&pEnumStr, &length)) return ERROR; return wmBufferUpdate(pBuf, pEnumStr, length, DATATYPE_STRING_K, TRUE); } /* eof wmbObjectLib.c */