/*-------------------------------------------------------------------------- ANSTO Server Info Command Object Paul Hathaway, January, 2005 Copyright: See copyright.txt ----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include /* incl. SCWrite */ #include #include #include #include #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;iRetpName); Tcl_ListObjAppendElement(tTcl,tList, Tcl_NewStringObj(pBuf,strlen(pBuf))); } pCurrent = pCurrent->pNext; } break; case 5: /* deviceType */ for(iRet=0;iRetpData); 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;iRetpCList; 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;itTcl,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;ipTcl); /* 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'; }