- Removed group and description attributes from ObjectDescriptor SKIPPED: psi/dornier2.c psi/libpsi.a psi/make_gen psi/makefile_linux psi/pimotor.c psi/pipiezo.c psi/psi.c psi/serial.c psi/sinqhttp.c psi/sinqhttp.h psi/tcpdornier.c psi/velodornier.c
1224 lines
38 KiB
C
1224 lines
38 KiB
C
/*--------------------------------------------------------------------------
|
|
ANSTO Server Info Command Object
|
|
Paul Hathaway, January, 2005
|
|
Copyright: See copyright.txt
|
|
----------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <conman.h>
|
|
#include <obdes.h>
|
|
#include <ctype.h>
|
|
#include <sics.h>
|
|
#include <sicsvar.h>
|
|
#include <conman.h> /* incl. SCWrite */
|
|
#include <fupa.h>
|
|
#include <splitter.h>
|
|
#include <outcode.c>
|
|
#include <protocol.h>
|
|
#include "sinfox.h"
|
|
|
|
/*-----------------------------------------------------------------------
|
|
* External Interface defined in sinfox.h includes
|
|
* struct pSinfox
|
|
* int InstallSinfox(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
* int argc, char *argv[]);
|
|
* void DeleteSinfox(void *pSelf);
|
|
* int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
* int argc, char *argv[]);
|
|
* and lists of option keys
|
|
*-----------------------------------------------------------------------*/
|
|
|
|
/* Core module functions */
|
|
static pSinfox CreateSinfox(void);
|
|
static int SinfoxInit(SicsInterp *pSics, char *infofile);
|
|
static int SinfoxHelp(pSinfox pSin, SicsInterp* pSics);
|
|
static int SinfoxReset(pSinfox pSin, SicsInterp* pSics);
|
|
static int SinfoxSetDesc(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *pDesc);
|
|
static int SinfoxSetGrp(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *pGrp);
|
|
static int SinfoxSetKey(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *keyName, char *eltValue);
|
|
static int SinfoxReadKey(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *fileName);
|
|
static int SinfoxList(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *pObjName, char *pKeyName, char *pEltName);
|
|
static int SinfoxEnumerate(pSinfox pSin, SicsInterp* pSics,
|
|
SConnection *pCon, char *keyName);
|
|
static int SinfoxShow(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *keyName, char *eltName);
|
|
static int SinfoxDevice(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *devName, char *keyName, char *eltName);
|
|
static int SinfoxGetGrp(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName);
|
|
|
|
/* Utility functions */
|
|
static int EnumChoice(char *pList[], int iLength, char *pInput);
|
|
static int LinkVar(char *tcl_var_name, char *pAddress, int link_flags);
|
|
static void setOKE(char *obj, char *key, char *elt,
|
|
char *oVal, char *kVal, char *eVal);
|
|
static int isNameDevice(char *name);
|
|
static int isNameCommand(char *name);
|
|
static int isObjectDevice(CommandList *pObj);
|
|
static int isObjectCommand(CommandList *pObj);
|
|
static void addToList(Tcl_Interp *tTcl, Tcl_Obj *tList, char *prefix, char *sVal);
|
|
static void addPairsToList(Tcl_Interp *tTcl, Tcl_Obj *tList, IPair *pList);
|
|
static void RemoveWhiteSpace(char *pText);
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
pSinfox CreateSinfox(void)
|
|
{
|
|
int i;
|
|
pSinfox pNew = NULL;
|
|
SicsInterp *pSics;
|
|
Tcl_Interp *tTcl;
|
|
|
|
pNew = (pSinfox)malloc(sizeof(Sinfox));
|
|
if(!pNew)
|
|
{
|
|
return NULL;
|
|
}
|
|
pNew->pDes = CreateDescriptor("sinfox");
|
|
if(!pNew->pDes)
|
|
{
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
pSics = GetInterpreter();
|
|
tTcl = (Tcl_Interp *)(pSics->pTcl);
|
|
pNew->tTcl = tTcl;
|
|
/* LinkVar("server::configName",pNew->configName,TCL_LINK_STRING); */
|
|
pNew->buildVersion = Tcl_GetVar(tTcl,
|
|
"::server::buildVersion",TCL_GLOBAL_ONLY);
|
|
pNew->configName = Tcl_GetVar(tTcl,
|
|
"::server::configName",TCL_GLOBAL_ONLY);
|
|
pNew->configVersion = Tcl_GetVar(tTcl,
|
|
"::server::configVersion",TCL_GLOBAL_ONLY);
|
|
pNew->description = Tcl_GetVar(tTcl,
|
|
"::server::description",TCL_GLOBAL_ONLY);
|
|
pNew->instrument = Tcl_GetVar(tTcl,
|
|
"::server::instrument",TCL_GLOBAL_ONLY);
|
|
pNew->schemaVersion = Tcl_GetVar(tTcl,
|
|
"::server::schemaVersion",TCL_GLOBAL_ONLY);
|
|
pNew->pDes->pKeys = NULL;
|
|
return pNew;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void DeleteSinfox(void *self)
|
|
{
|
|
int i;
|
|
pSinfox pOld = (pSinfox)self;
|
|
|
|
if(NULL==pOld)
|
|
{
|
|
return;
|
|
}
|
|
if(pOld->buildVersion)
|
|
{
|
|
free((void *)(pOld->buildVersion));
|
|
}
|
|
if(pOld->configName)
|
|
{
|
|
free((void *)(pOld->configName));
|
|
}
|
|
if(pOld->configVersion)
|
|
{
|
|
free((void *)(pOld->configVersion));
|
|
}
|
|
if(pOld->description)
|
|
{
|
|
free((void *)(pOld->description));
|
|
}
|
|
if(pOld->instrument)
|
|
{
|
|
free((void *)(pOld->instrument));
|
|
}
|
|
if(pOld->schemaVersion)
|
|
{
|
|
free((void *)(pOld->schemaVersion));
|
|
}
|
|
if(pOld->pDes)
|
|
{
|
|
DeleteDescriptor(pOld->pDes);
|
|
}
|
|
free(pOld);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int InstallSinfox(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pSinfox pNew = NULL;
|
|
pNew = CreateSinfox();
|
|
if(NULL==pNew)
|
|
{
|
|
SCWrite(pCon,"No memory to create Sinfox",eError);
|
|
return 0;
|
|
}
|
|
AddCommand(pSics,"sinfox",SinfoxAction,DeleteSinfox,pNew);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int SinfoxInit(SicsInterp *pSics, char *infofile)
|
|
{
|
|
SConnection *pCon = NULL;
|
|
char pBuf[1024];
|
|
int iRet;
|
|
|
|
/* create a connection */
|
|
pCon = SCCreateDummyConnection(pSics);
|
|
if(!pCon)
|
|
{
|
|
return 0;
|
|
}
|
|
pCon->iFiles = 1;
|
|
pCon->pFiles[0] = stdout;
|
|
|
|
/* evaluate the file */
|
|
sprintf(pBuf,"fileeval %s",infofile);
|
|
iRet = InterpExecute(pSics,pCon,pBuf);
|
|
pCon->iFiles = 0;
|
|
SCDeleteConnection(pCon);
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxHelp(pSinfox pSin, SicsInterp* pSics)
|
|
{
|
|
Tcl_SetResult((Tcl_Interp *)(pSics->pTcl),"Sinfox Help",TCL_VOLATILE);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxReset(pSinfox pSin, SicsInterp* pSics)
|
|
{
|
|
int i;
|
|
|
|
pSin->buildVersion = Tcl_GetVar(pSin->tTcl,
|
|
"::server::buildVersion",TCL_GLOBAL_ONLY);
|
|
pSin->configName = Tcl_GetVar(pSin->tTcl,
|
|
"::server::configName",TCL_GLOBAL_ONLY);
|
|
pSin->configVersion = Tcl_GetVar(pSin->tTcl,
|
|
"::server::configVersion",TCL_GLOBAL_ONLY);
|
|
pSin->description = Tcl_GetVar(pSin->tTcl,
|
|
"::server::description",TCL_GLOBAL_ONLY);
|
|
pSin->instrument = Tcl_GetVar(pSin->tTcl,
|
|
"::server::instrument",TCL_GLOBAL_ONLY);
|
|
pSin->schemaVersion = Tcl_GetVar(pSin->tTcl,
|
|
"::server::schemaVersion",TCL_GLOBAL_ONLY);
|
|
|
|
Tcl_SetResult(pSin->tTcl,"{Sinfox Reset}",TCL_VOLATILE);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxSetDesc(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *pDesc)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
char pBuf[256];
|
|
|
|
memset(pBuf,0,256);
|
|
pCurrent = pSics->pCList;
|
|
|
|
pCurrent = FindCommand(pSics,objName);
|
|
if(NULL != pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
SetDescriptorDescription(pDes,pDesc);
|
|
sprintf(pBuf,"description=%s",pDesc);
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 1;
|
|
}
|
|
}
|
|
sprintf(pBuf,"error=unable to set %s.description to %s",objName,pDesc);
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxSetGrp(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *pGrp)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
char pBuf[256];
|
|
|
|
memset(pBuf,0,256);
|
|
pCurrent = pSics->pCList;
|
|
|
|
pCurrent = FindCommand(pSics,objName);
|
|
if(NULL!=pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
SetDescriptorGroup(pDes,pGrp);
|
|
sprintf(pBuf,"group=%s",pGrp);
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 1;
|
|
}
|
|
}
|
|
sprintf(pBuf,"error=unable to set %s.group to %s",objName,pGrp);
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 0;
|
|
}
|
|
|
|
static int SinfoxGetGrp(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
char pBuf[256];
|
|
|
|
pBuf[0]='\0';
|
|
pCurrent = pSics->pCList;
|
|
|
|
pCurrent = FindCommand(pSics,objName);
|
|
if(NULL==pCurrent) {
|
|
sprintf(pBuf,"%s.group=none",objName);
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 1;
|
|
} else {
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
sprintf(pBuf,"%s.group=%s",objName, GetDescriptorGroup(pDes));
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxSetKey(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *keyName, char *eltValue)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
int bOK = 0;
|
|
char *obj;
|
|
char pBuf[256];
|
|
memset(pBuf,0,256);
|
|
|
|
obj = strdup(objName);
|
|
strtolower(obj);
|
|
|
|
if(0==strcmp(obj,"server"))
|
|
{ /* sinfox object is surrogate for server object inside SICS */
|
|
free(obj);
|
|
obj = strdup("sinfox");
|
|
}
|
|
else
|
|
{
|
|
free(obj);
|
|
obj = strdup(objName);
|
|
}
|
|
|
|
pCurrent = pSics->pCList;
|
|
pCurrent = FindCommand(pSics,obj);
|
|
|
|
if(NULL != pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
strtolower(keyName);
|
|
strtolower(eltValue);
|
|
pDes->pKeys = IFSetOption(pDes->pKeys,keyName,eltValue);
|
|
if(NULL != pDes->pKeys)
|
|
{
|
|
bOK=1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bOK==1)
|
|
{
|
|
sprintf(pBuf,"%s.%s=%s",
|
|
pCurrent->pName,pDes->pKeys->name,pDes->pKeys->value);
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBuf,"error=unable to set %s.%s to %s",
|
|
obj,keyName,eltValue);
|
|
}
|
|
|
|
Tcl_SetObjResult(pSin->tTcl,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
return bOK;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxReadKey(pSinfox pSin, SicsInterp *pSics,
|
|
char *objName, char *fileName)
|
|
{
|
|
static FILE *fKeyFile = NULL;
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
char pBuf[256];
|
|
char pName[132];
|
|
char pValue[132];
|
|
char *pPos;
|
|
int iLen;
|
|
|
|
memset(pBuf,0,256);
|
|
|
|
pCurrent = pSics->pCList;
|
|
pCurrent = FindCommand(pSics,objName);
|
|
|
|
if(NULL != pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
fKeyFile = fopen(fileName,"r");
|
|
if(NULL == fKeyFile)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
while(!feof(fKeyFile))
|
|
{
|
|
fgets(pBuf,255,fKeyFile);
|
|
if(feof(fKeyFile)) continue;
|
|
|
|
if(pBuf[0] == '#') continue;
|
|
|
|
pPos = strchr(pBuf,'=');
|
|
if(!pPos) continue;
|
|
|
|
iLen = pPos - pBuf;
|
|
strncpy(pName,pBuf,iLen);
|
|
pName[iLen] = '\0';
|
|
strcpy(pValue,(pPos+1));
|
|
RemoveWhiteSpace(pName);
|
|
RemoveWhiteSpace(pValue);
|
|
strtolower(pName);
|
|
strtolower(pValue);
|
|
|
|
pDes->pKeys = IFAddOption(pDes->pKeys,pName,pValue);
|
|
if(NULL==pDes->pKeys) return 0;
|
|
}
|
|
|
|
fclose(fKeyFile);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxList(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *pObjName, char *pKeyName, char *pEltName)
|
|
{
|
|
int iRet;
|
|
char *objName;
|
|
char *keyName = NULL;
|
|
char *eltName = NULL;
|
|
CommandList *pObj = NULL;
|
|
|
|
objName = strdup(pObjName); strtolower(objName);
|
|
if (NULL!=pKeyName)
|
|
{
|
|
keyName = strdup(pKeyName); strtolower(keyName);
|
|
}
|
|
if (NULL!=pEltName)
|
|
{
|
|
eltName = strdup(pEltName); strtolower(eltName);
|
|
}
|
|
|
|
/* check if objName is an interfaceName */
|
|
iRet = EnumChoice(pIFaces,iNumIFaces,objName);
|
|
if(-1 < iRet)
|
|
{
|
|
if((0==strcmp(keyName,"device")) || (0==strcmp(keyName,NULL)))
|
|
{ /* format as sinfox list server interface interfaceName */
|
|
setOKE(objName,keyName,eltName,"server","interface",objName);
|
|
} else if(0==strcmp(keyName,"command"))
|
|
{ /* todo: not yet implemented */
|
|
return SinfoxHelp(pSin,pSics);
|
|
}
|
|
}
|
|
|
|
/* check if objName is commandName */
|
|
/* check if objName is a deviceName */
|
|
pObj = FindCommand(pSics,objName);
|
|
if(NULL != pObj)
|
|
{
|
|
if(1==isObjectDevice(pObj))
|
|
{
|
|
return SinfoxDevice(pSin,pSics,pCon,objName,keyName,eltName);
|
|
}
|
|
else /* command */
|
|
{ return 0;
|
|
iRet = EnumChoice(pCommandKeys,iNumCommandKeys,keyName);
|
|
switch(iRet)
|
|
{
|
|
case 1: /* argument */
|
|
/* todo: not yet implemented */
|
|
case 2: /* device */
|
|
/* todo: secondary: not yet implemented */
|
|
case 3: /* interface */
|
|
/* todo: secondary: not yet implemented */
|
|
default: /* sinfox list server command commandName */
|
|
setOKE(objName,keyName,eltName,"server","command",objName);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(0 == strcmp(objName,"server"))
|
|
{
|
|
iRet = EnumChoice(pServerKeys,iNumServerKeys,keyName);
|
|
/* if invalid (iRet < 0) then default to "help" command */
|
|
switch(iRet)
|
|
{
|
|
/* cases that have no eltName argument */
|
|
case 1: /* list */
|
|
case 3: /* connection */
|
|
case 6: /* experiment */
|
|
case 9: /* key */
|
|
return SinfoxEnumerate(pSin,pSics,pCon,keyName);
|
|
break;
|
|
/* cases that are not fully implemented */
|
|
case 2: /* command */
|
|
case 4: /* device */
|
|
case 5: /* deviceType */
|
|
case 7: /* group */
|
|
case 8: /* interface */
|
|
return SinfoxShow(pSin,pSics,pCon,keyName,eltName);
|
|
break;
|
|
/* fully functional cases */
|
|
case 0: /* help */
|
|
default:
|
|
return SinfoxHelp(pSin,pSics);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
/* Retrieve a list of elements from CommandList matching criteria */
|
|
static int SinfoxEnumerate(pSinfox pSin, SicsInterp* pSics,
|
|
SConnection *pCon, char *keyName)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
Tcl_Interp *tTcl;
|
|
Tcl_Obj *tList;
|
|
IPair *pOption = NULL;
|
|
IPair *pGroups = NULL;
|
|
pSicsVariable pSVar = NULL;
|
|
int iRet;
|
|
char pBuf[256], *pPtr = NULL;
|
|
int checkDeviceTypes[iNumDeviceTypes];
|
|
|
|
pCurrent = pSics->pCList;
|
|
tTcl = (Tcl_Interp *)(pSics->pTcl);
|
|
tList = Tcl_NewListObj(0,NULL);
|
|
memset(pBuf,0,256);
|
|
|
|
iRet = EnumChoice(pServerKeys,iNumServerKeys,keyName);
|
|
/* if invalid (iRet < 0) then default to "help" command */
|
|
switch(iRet)
|
|
{
|
|
/* cases that have no eltName argument - not fully implemented */
|
|
case 1: /* list */
|
|
addToList(tTcl,tList,"buildVersion",(char *)(pSin->buildVersion));
|
|
addToList(tTcl,tList,"configName",(char *)(pSin->configName));
|
|
addToList(tTcl,tList,"configVersion",(char *)(pSin->configVersion));
|
|
addToList(tTcl,tList,"description",(char *)(pSin->description));
|
|
addToList(tTcl,tList,"instrument",(char *)(pSin->instrument));
|
|
addToList(tTcl,tList,"schemaVersion",(char *)(pSin->schemaVersion));
|
|
addPairsToList(tTcl,tList,pSin->pDes->pKeys);
|
|
addPairsToList(tTcl,tList,pSICSOptions);
|
|
break;
|
|
case 2: /* command */
|
|
while(pCurrent)
|
|
{
|
|
if(1==isObjectCommand(pCurrent))
|
|
{
|
|
strcpy(pBuf,pCurrent->pName);
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
break;
|
|
case 3: /* connection */
|
|
sprintf(pBuf,"%d",SCGetRights(pCon));
|
|
addToList(tTcl,tList,"userAccessLevel",pBuf);
|
|
addToList(tTcl,tList,"protocol",GetProtocolName(pCon));
|
|
break;
|
|
case 6: /* experiment */
|
|
while(pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
strcpy(pBuf,pDes->name);
|
|
strtolower(pBuf);
|
|
if(0==strcmp(pBuf,"sicsvariable"))
|
|
{
|
|
pSVar=FindVariable(pSics,pCurrent->pName);
|
|
addToList(tTcl,tList,pCurrent->pName,pSVar->text);
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
break;
|
|
case 9: /* key */
|
|
for(iRet=0;iRet<iNumServerKeys;iRet++)
|
|
{
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pServerKeys[iRet],
|
|
strlen(pServerKeys[iRet])));
|
|
}
|
|
break;
|
|
/* cases that have not specified eltName */
|
|
case 4: /* device */
|
|
while(pCurrent)
|
|
{
|
|
if(1==isObjectDevice(pCurrent))
|
|
{
|
|
strcpy(pBuf,pCurrent->pName);
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
break;
|
|
case 5: /* deviceType */
|
|
for(iRet=0;iRet<iNumDeviceTypes;iRet++)
|
|
{
|
|
checkDeviceTypes[iRet] = 0;
|
|
}
|
|
while(pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
strcpy(pBuf,pDes->name);
|
|
strtolower(pBuf);
|
|
iRet = EnumChoice(pDeviceTypes,iNumDeviceTypes,pBuf);
|
|
if(-1 < iRet)
|
|
{
|
|
if(1!=checkDeviceTypes[iRet])
|
|
{
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
checkDeviceTypes[iRet] = 1;
|
|
}
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
break;
|
|
case 7: /* group */
|
|
pCurrent = pSics->pCList;
|
|
/* Always add default group "none" */
|
|
pGroups = IFAddOption(pGroups,"none","OK");
|
|
Tcl_ListObjAppendElement(tTcl,tList,Tcl_NewStringObj("none",4));
|
|
while(pCurrent)
|
|
{
|
|
if(1==isObjectDevice(pCurrent))
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if((pPtr = IFindOption(pDes->pKeys,"group")) != NULL)
|
|
{
|
|
strcpy(pBuf,pPtr);
|
|
strtolower(pBuf);
|
|
if(NULL==IFindOption(pGroups,pBuf))
|
|
{
|
|
pGroups = IFAddOption(pGroups,pBuf,"OK");
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
if(NULL!=pGroups)
|
|
{
|
|
IFDeleteOptions(pGroups);
|
|
}
|
|
break;
|
|
case 8: /* interface */
|
|
for(iRet=0;iRet<iNumIFaces;iRet++)
|
|
{
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pIFaces[iRet],
|
|
strlen(pIFaces[iRet])));
|
|
}
|
|
break;
|
|
/* special cases */
|
|
case 0: /* help */
|
|
default:
|
|
return SinfoxHelp(pSin,pSics);
|
|
break;
|
|
}
|
|
Tcl_SetObjResult(tTcl,tList);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SinfoxShow(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *keyName, char *eltName)
|
|
{
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
Tcl_Interp *tTcl;
|
|
Tcl_Obj *tList;
|
|
int iRet, iType;
|
|
char pBuf[256];
|
|
char *pTmp;
|
|
char *pElt;
|
|
|
|
pCurrent = pSics->pCList;
|
|
tTcl = (Tcl_Interp *)(pSics->pTcl);
|
|
tList = Tcl_NewListObj(0,NULL);
|
|
memset(pBuf,0,256);
|
|
|
|
if (NULL==eltName)
|
|
{
|
|
return SinfoxEnumerate(pSin,pSics,pCon,keyName);
|
|
}
|
|
pElt = strdup(eltName);
|
|
strtolower(pElt);
|
|
|
|
iRet = EnumChoice(pServerKeys,iNumServerKeys,keyName);
|
|
/* if invalid (iRet < 0) then default to "help" command */
|
|
switch(iRet)
|
|
{
|
|
case 2: /* command */
|
|
case 4: /* device - list deviceName {attribute|command|interface} */
|
|
//addToList(tTcl,tList,pElt,"is being searched for");
|
|
pCurrent = FindCommand(pSics,pElt);
|
|
if(NULL!=pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
//addToList(tTcl,tList,"debug2","descriptor found");
|
|
if(1==isObjectDevice(pCurrent))
|
|
{
|
|
if(NULL!=pDes->name)
|
|
{
|
|
strcpy(pBuf,pDes->name);
|
|
strtolower(pBuf);
|
|
addToList(tTcl,tList,"devicetype",pBuf);
|
|
}
|
|
if((pTmp = IFindOption(pDes->pKeys,"group")) != NULL)
|
|
{
|
|
strcpy(pBuf,pTmp);
|
|
strtolower(pBuf);
|
|
addToList(tTcl,tList,"group",pBuf);
|
|
}
|
|
}
|
|
if((pTmp = IFindOption(pDes->pKeys,"description")) != NULL)
|
|
{
|
|
strcpy(pBuf,pTmp);
|
|
strtolower(pBuf);
|
|
addToList(tTcl,tList,"description",pBuf);
|
|
}
|
|
//addToList(tTcl,tList,"debug3","default fields processed");
|
|
if(NULL!=pDes->pKeys)
|
|
{
|
|
addPairsToList(tTcl,tList,pDes->pKeys);
|
|
}
|
|
}
|
|
}
|
|
//addToList(tTcl,tList,"debug4","device show finished");
|
|
break;
|
|
case 5: /* devicetype */
|
|
iRet = EnumChoice(pDeviceTypes,iNumDeviceTypes,pElt);
|
|
if (0 > iRet)
|
|
{
|
|
if((0==strcmp(pElt,"all"))||(0==strcmp(pElt,"*")))
|
|
{
|
|
Tcl_SetVar(tTcl,"name",keyName,0);
|
|
return SinfoxEnumerate(pSin,pSics,pCon,keyName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while(pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
strcpy(pBuf,pDes->name);
|
|
strtolower(pBuf);
|
|
if(0==strcmp(pElt,pBuf))
|
|
{
|
|
strcpy(pBuf,pCurrent->pName);
|
|
strtolower(pBuf);
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
}
|
|
break;
|
|
case 7: /* group */
|
|
if((0==strcmp(pElt,"all"))||(0==strcmp(pElt,"*")))
|
|
{
|
|
Tcl_SetVar(tTcl,"name",keyName,0);
|
|
return SinfoxEnumerate(pSin,pSics,pCon,keyName);
|
|
}
|
|
while(NULL!=pCurrent)
|
|
{
|
|
if(1==isObjectDevice(pCurrent))
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
if((pTmp = IFindOption(pDes->pKeys,"group")) == NULL)
|
|
{
|
|
strcpy(pBuf,"none");
|
|
}
|
|
else
|
|
{
|
|
strcpy(pBuf,pTmp);
|
|
strtolower(pBuf);
|
|
}
|
|
if(0==strcmp(pElt,pBuf))
|
|
{
|
|
strcpy(pBuf,pCurrent->pName);
|
|
strtolower(pBuf);
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
break;
|
|
case 8: /* interface */
|
|
iRet = EnumChoice(pIFaces,iNumIFaces,pElt);
|
|
if (0 > iRet)
|
|
{
|
|
if((0==strcmp(pElt,"all"))||(0==strcmp(pElt,"*")))
|
|
{
|
|
Tcl_SetVar(tTcl,"name",keyName,0);
|
|
return SinfoxEnumerate(pSin,pSics,pCon,keyName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch(iRet)
|
|
{
|
|
case 0: /* callback */
|
|
iType = CALLBACKINTERFACE; break;
|
|
case 1: /* countable */
|
|
iType = COUNTID; break;
|
|
case 2: /* drivable */
|
|
iType = DRIVEID; break;
|
|
case 3: /* environment */
|
|
iType = ENVIRINTERFACE; break;
|
|
default: /* interface not recognised */
|
|
Tcl_SetObjResult(tTcl,tList);
|
|
return 1;
|
|
break;
|
|
}
|
|
while(pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
if(NULL != pDes->GetInterface(pDes,iType))
|
|
{
|
|
strcpy(pBuf,pCurrent->pName);
|
|
strtolower(pBuf);
|
|
Tcl_ListObjAppendElement(tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
addToList(tTcl,tList,"error","unknown key");
|
|
break;
|
|
}
|
|
Tcl_SetObjResult(tTcl,tList);
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SinfoxDevice(pSinfox pSin, SicsInterp* pSics, SConnection *pCon,
|
|
char *devName, char *keyName, char *eltName)
|
|
{
|
|
int i,iRet,iType;
|
|
Tcl_Obj *tList;
|
|
char pBuf[256];
|
|
char *pTmp;
|
|
CommandList *pCurrent;
|
|
pObjectDescriptor pDes = NULL;
|
|
|
|
memset(pBuf,0,256);
|
|
pCurrent = pSics->pCList;
|
|
tList = Tcl_NewListObj(0,NULL);
|
|
pCurrent = FindCommand(pSics,devName);
|
|
/* debug */
|
|
addToList(pSin->tTcl,tList,"dev",devName);
|
|
addToList(pSin->tTcl,tList,"key",keyName);
|
|
addToList(pSin->tTcl,tList,"elt",eltName);
|
|
/*-------*/
|
|
iRet = EnumChoice(pDeviceKeys,iNumDeviceKeys,keyName);
|
|
switch(iRet)
|
|
{
|
|
case 2: /* interface */
|
|
if(NULL!=pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
for(i=0;i<iNumIFaces;i++)
|
|
{
|
|
switch(i)
|
|
{
|
|
case 0: /* callback */
|
|
iType = CALLBACKINTERFACE; break;
|
|
case 1: /* countable */
|
|
iType = COUNTID; break;
|
|
case 2: /* drivable */
|
|
iType = DRIVEID; break;
|
|
case 3: /* environment */
|
|
iType = ENVIRINTERFACE; break;
|
|
default: /* interface not recognised */
|
|
Tcl_SetObjResult(pSin->tTcl,tList);
|
|
return 0;
|
|
break;
|
|
}
|
|
if(NULL != pDes->GetInterface(pDes,iType))
|
|
{
|
|
strcpy(pBuf,pIFaces[i]);
|
|
Tcl_ListObjAppendElement(pSin->tTcl,tList,
|
|
Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 0: /* attribute */
|
|
if(NULL==eltName)
|
|
{
|
|
return SinfoxShow(pSin,pSics,pCon,"device",devName);
|
|
}
|
|
else
|
|
{
|
|
if(NULL!=pCurrent)
|
|
{
|
|
pDes = FindDescriptor(pCurrent->pData);
|
|
if(NULL != pDes)
|
|
{
|
|
pTmp = IFindOption(pDes->pKeys,eltName);
|
|
if(NULL!=pTmp)
|
|
{
|
|
strcpy(pBuf,pTmp);
|
|
addToList(pSin->tTcl,tList,eltName,pTmp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 1: /* command */
|
|
/* todo: secondary: not yet implemented */
|
|
default: /* sinfox list server device deviceName */
|
|
return SinfoxShow(pSin,pSics,pCon,"device",devName);
|
|
break;
|
|
}
|
|
Tcl_SetObjResult(pSin->tTcl,tList);
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
int iRet;
|
|
char **argx;
|
|
FuPaResult PaRes;
|
|
pSinfox pSin = NULL;
|
|
|
|
const int iNumCmds = 8;
|
|
FuncTemplate CommandTemplate[] = {
|
|
{"help",0,{0,0}},
|
|
{"list",3,{FUPATEXT,FUPATEXT,FUPAOPT}},
|
|
{"setdesc",2,{FUPATEXT,FUPATEXT}},
|
|
{"setgrp",2,{FUPATEXT,FUPATEXT}},
|
|
{"setkey",3,{FUPATEXT,FUPATEXT,FUPATEXT}},
|
|
{"reset",0,{0,0}},
|
|
{"readkey",2,{FUPATEXT,FUPATEXT}},
|
|
{"getgrp",1,{FUPATEXT}},
|
|
{NULL}
|
|
};
|
|
|
|
assert(pCon);
|
|
assert(pSics);
|
|
pSin = (pSinfox)pData;
|
|
assert(pSin);
|
|
|
|
/* You need to have User level access rights to use this facility */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* parse function args */
|
|
argtolower(argc,argv);
|
|
argx = &argv[1];
|
|
iRet = EvaluateFuPa((pFuncTemplate)&CommandTemplate,iNumCmds,argc-1,argx,&PaRes);
|
|
/* if invalid (iRet < 0) then default to "help" command */
|
|
switch(iRet)
|
|
{
|
|
case 1: /* list */
|
|
if(1==PaRes.Arg[2].iVal)
|
|
{
|
|
iRet = SinfoxList(pSin,pSics,pCon,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text,PaRes.Arg[2].text);
|
|
}
|
|
else
|
|
{
|
|
iRet = SinfoxList(pSin,pSics,pCon,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text,NULL);
|
|
}
|
|
return iRet;
|
|
break;
|
|
case 2: /* setdesc */
|
|
return SinfoxSetDesc(pSin,pSics,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text);
|
|
break;
|
|
case 3: /* setgrp */
|
|
return SinfoxSetGrp(pSin,pSics,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text);
|
|
break;
|
|
case 4: /* setkey */
|
|
return SinfoxSetKey(pSin,pSics,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text,PaRes.Arg[2].text);
|
|
break;
|
|
case 5: /* reset */
|
|
return SinfoxReset(pSin,pSics);
|
|
break;
|
|
case 6: /* readkey */
|
|
return SinfoxReadKey(pSin,pSics,
|
|
PaRes.Arg[0].text,PaRes.Arg[1].text);
|
|
break;
|
|
case 7: /*getgrp */
|
|
return SinfoxGetGrp(pSin, pSics, PaRes.Arg[0].text);
|
|
break;
|
|
case 0: /* help */
|
|
default:
|
|
return SinfoxHelp(pSin,pSics);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int EnumChoice(char *pList[], int iLength, char *pInput)
|
|
{
|
|
int i;
|
|
int iRet = -1;
|
|
|
|
for(i=0;i<iLength;i++)
|
|
{
|
|
if(0==strcmp(pInput,pList[i]))
|
|
{
|
|
iRet = i;
|
|
break;
|
|
}
|
|
}
|
|
return iRet;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int LinkVar(char *tcl_var_name, char *pAddress, int link_flags)
|
|
{
|
|
SicsInterp *pSics = NULL;
|
|
Tcl_Interp *pTcl = NULL;
|
|
int tcl_flags = TCL_LINK_INT;
|
|
|
|
pSics = GetInterpreter();
|
|
pTcl = (Tcl_Interp *)(pSics->pTcl);
|
|
/* tcl_flags = f(link_flags)*/
|
|
switch(link_flags)
|
|
{
|
|
case TCL_LINK_INT :
|
|
break;
|
|
case TCL_LINK_DOUBLE:
|
|
case TCL_LINK_BOOLEAN:
|
|
case TCL_LINK_STRING:
|
|
tcl_flags = link_flags;
|
|
break;
|
|
default : return 0;
|
|
}
|
|
Tcl_LinkVar(pTcl,tcl_var_name,pAddress,tcl_flags);
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static void setOKE(char *obj, char *key, char *elt, char *oVal, char *kVal, char *eVal)
|
|
{
|
|
char *eBuf;
|
|
char *kBuf;
|
|
char *oBuf;
|
|
eBuf = strdup(eVal);
|
|
kBuf = strdup(kVal);
|
|
oBuf = strdup(oVal);
|
|
free(elt); elt = eBuf;
|
|
free(key); key = kBuf;
|
|
free(obj); obj = oBuf;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int isNameDevice(char *name)
|
|
{
|
|
SicsInterp *pSics;
|
|
CommandList *pObj = NULL;
|
|
Dummy *pDum = NULL;
|
|
|
|
pSics = GetInterpreter();
|
|
pObj = FindCommand(pSics,name);
|
|
if(NULL != pObj)
|
|
{
|
|
pDum = (Dummy *)pObj->pData;
|
|
if(NULL != pDum)
|
|
{
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,DRIVEID)) return 1;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,COUNTID)) return 1;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,ENVIRINTERFACE)) return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int isNameCommand(char *name)
|
|
{
|
|
SicsInterp *pSics;
|
|
CommandList *pObj = NULL;
|
|
Dummy *pDum = NULL;
|
|
|
|
pSics = GetInterpreter();
|
|
pObj = FindCommand(pSics,name);
|
|
if(NULL != pObj)
|
|
{
|
|
pDum = (Dummy *)pObj->pData;
|
|
if(NULL != pDum)
|
|
{
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,DRIVEID)) return 0;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,COUNTID)) return 0;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,ENVIRINTERFACE)) return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int isObjectDevice(CommandList *pObj)
|
|
{
|
|
Dummy *pDum = NULL;
|
|
if(NULL != pObj)
|
|
{
|
|
pDum = (Dummy *)pObj->pData;
|
|
if(NULL != pDum)
|
|
{
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,DRIVEID)) return 1;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,COUNTID)) return 1;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,ENVIRINTERFACE))
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int isObjectCommand(CommandList *pObj)
|
|
{
|
|
Dummy *pDum = NULL;
|
|
if(NULL != pObj)
|
|
{
|
|
pDum = (Dummy *)pObj->pData;
|
|
if(NULL != pDum)
|
|
{
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,DRIVEID)) return 0;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,COUNTID)) return 0;
|
|
if(NULL != pDum->pDescriptor->GetInterface(pDum,ENVIRINTERFACE)) return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static void addToList(Tcl_Interp *tTcl, Tcl_Obj *tList, char *prefix, char *sVal)
|
|
{
|
|
char pBuf[256];
|
|
if(NULL!=sVal)
|
|
{
|
|
memset(pBuf,0,256);
|
|
sprintf(pBuf,"%s=%s",prefix,sVal);
|
|
Tcl_ListObjAppendElement(tTcl,tList,Tcl_NewStringObj(pBuf,strlen(pBuf)));
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static void addPairsToList(Tcl_Interp *tTcl, Tcl_Obj *tList, IPair *pList)
|
|
{
|
|
IPair *pCurrent;
|
|
if(NULL!=pList)
|
|
{
|
|
pCurrent = pList;
|
|
while(NULL!=pCurrent)
|
|
{
|
|
addToList(tTcl,tList,pCurrent->name,pCurrent->value);
|
|
pCurrent = pCurrent->pNext;
|
|
}
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static void RemoveWhiteSpace(char *pText)
|
|
{
|
|
int i, ii, i3;
|
|
char *pPtr;
|
|
|
|
if(NULL==pText) return;
|
|
|
|
/* find start */
|
|
i = 0;
|
|
while(isspace(pText[i]))
|
|
{
|
|
i++;
|
|
}
|
|
|
|
/* find end */
|
|
ii = strlen(pText);
|
|
ii--;
|
|
while( (isspace(pText[ii])) || (pText[ii] == '\n') )
|
|
{
|
|
ii--;
|
|
}
|
|
|
|
/* copy it */
|
|
pPtr = pText;
|
|
for(i3 = i; i3 < (ii+1); i3++)
|
|
{
|
|
*pPtr = pText[i3];
|
|
pPtr++;
|
|
}
|
|
*pPtr = '\0';
|
|
}
|