/*-------------------------------------------------------------------------- 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); /* strlcpy is wrong here */ 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")) || 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'; }