Files
sics/sinfox.c
koennecke 45fd50265f - Added SicsList
- 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
2006-01-16 08:32:07 +00:00

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';
}