- Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
This commit is contained in:
898
sicsobj.c
898
sicsobj.c
@ -17,438 +17,474 @@
|
||||
#include "initializer.h"
|
||||
#include "splitter.h"
|
||||
|
||||
extern int decodeSICSPriv(char *txt); /* from access.c */
|
||||
extern int decodeSICSPriv(char *txt); /* from access.c */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DefaultKill(void *data){
|
||||
return;
|
||||
void DefaultKill(void *data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DefaultFree(void *data)
|
||||
{
|
||||
if (data != NULL) {
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void DefaultFree(void *data){
|
||||
if(data != NULL){
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void saveSICSNode(pHdb node, char *prefix, FILE *fd){
|
||||
char newprefix[1024], val[20];
|
||||
pHdb child;
|
||||
hdbValue v;
|
||||
pDynString data = NULL;
|
||||
|
||||
if(GetHdbProperty(node,"__save",val,20) == 1){
|
||||
GetHipadabaPar(node,&v,NULL);
|
||||
data = formatValue(v,node);
|
||||
if(data != NULL){
|
||||
fprintf(fd,"%s %s\n", prefix, GetCharArray(data));
|
||||
DeleteDynString(data);
|
||||
}
|
||||
child = node->child;
|
||||
while(child != NULL){
|
||||
snprintf(newprefix,1024,"%s/%s", prefix,child->name);
|
||||
saveSICSNode(child,newprefix,fd);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int SaveSICSOBJ(void *data, char *name, FILE *fd){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
char prefix[1024];
|
||||
pHdb node;
|
||||
|
||||
if(self != NULL && self->objectNode != NULL){
|
||||
node = self->objectNode->child;
|
||||
while(node != NULL){
|
||||
snprintf(prefix, 1024,"%s %s", name, node->name);
|
||||
saveSICSNode(node, prefix, fd);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ MakeSICSOBJv(char *name, char *class, int type, int priv){
|
||||
pSICSOBJ pNew = NULL;
|
||||
hdbValue val;
|
||||
|
||||
pNew = (pSICSOBJ)malloc(sizeof(SICSOBJ));
|
||||
if(pNew == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew,0,sizeof(SICSOBJ));
|
||||
pNew->pDes = CreateDescriptor(class);
|
||||
pNew->pDes->SaveStatus = SaveSICSOBJ;
|
||||
if (type == HIPNONE) {
|
||||
pNew->objectNode = MakeHipadabaNode(name, HIPNONE, 1);
|
||||
} else {
|
||||
val = makeHdbValue(type,0);
|
||||
pNew->objectNode = MakeSICSHdbPar(name, priv, val);
|
||||
ReleaseHdbValue(&val);
|
||||
}
|
||||
if(pNew->pDes == NULL || pNew->objectNode == NULL){
|
||||
free(pNew);
|
||||
return(NULL);
|
||||
}
|
||||
pNew->pDes->parNode = pNew->objectNode;
|
||||
pNew->KillPrivate = DefaultKill;
|
||||
return pNew;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ MakeSICSOBJ(char *name, char *class){
|
||||
return MakeSICSOBJv(name, class, HIPNONE, 0);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void KillSICSOBJ(void *data){
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
if(self->KillPrivate != NULL && self->pPrivate != NULL){
|
||||
self->KillPrivate(self->pPrivate);
|
||||
}
|
||||
RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon);
|
||||
if(self->pDes != NULL){
|
||||
DeleteDescriptor(self->pDes); /* kill descriptor including node */
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*===========================================================================*/
|
||||
static int assignPar(pHdb node, SConnection *pCon, char *data){
|
||||
char error[132], buffer[256];
|
||||
int status;
|
||||
|
||||
status = readHdbValue(&node->value,data, error, 132);
|
||||
if(status != 1){
|
||||
snprintf(buffer,255,"ERROR: error parsing %s: %s",
|
||||
node->name, error);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCon,
|
||||
int argc, char *argv[]){
|
||||
int status, i, count = 0;
|
||||
pHdb currentPar = NULL;
|
||||
SICSOBJFunc pFunc = NULL;
|
||||
pHdb parArray[64];
|
||||
char buffer[1024];
|
||||
|
||||
/*
|
||||
* If the first argument has the special name args, concatenate all arguments
|
||||
* and put the result as text into this parameter. This allows for the
|
||||
* object function to parse and interpret the arguments itself.
|
||||
*/
|
||||
if(commandNode->child != NULL && strcmp(commandNode->child->name,"args") == 0) {
|
||||
Arg2Text(argc,argv,buffer,1024);
|
||||
assignPar(commandNode->child,pCon,buffer);
|
||||
parArray[0] = commandNode->child;
|
||||
count = 1;
|
||||
goto invoke;
|
||||
}
|
||||
|
||||
/*
|
||||
* assign parameters and fill parameter array for function at the same
|
||||
* time. Be lenient about missing parameters: Then the old values will
|
||||
* be used.
|
||||
*/
|
||||
for(i = 0, currentPar = commandNode->child;
|
||||
i < argc && currentPar != NULL;
|
||||
i++, currentPar = currentPar->next){
|
||||
if(argv[i] != NULL){
|
||||
status = assignPar(currentPar,pCon, argv[i]);
|
||||
}
|
||||
if(status != 1){
|
||||
return status;
|
||||
}
|
||||
parArray[i] = currentPar;
|
||||
count++;
|
||||
}
|
||||
|
||||
invoke: pFunc = (SICSOBJFunc)commandNode->value.v.func;
|
||||
if(pFunc == NULL){
|
||||
SCWrite(pCon,"ERROR: internal error, function not found",eError);
|
||||
return 0;
|
||||
}
|
||||
SendHdbStatusMessage(commandNode,"start");
|
||||
status = pFunc(object, pCon, commandNode, parArray,count);
|
||||
SendHdbStatusMessage(commandNode,"stop");
|
||||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int ScriptObjFunc(pSICSOBJ obj, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nCount){
|
||||
int status, i;
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
Tcl_DString com;
|
||||
char value[256];
|
||||
pDynString val = NULL;
|
||||
char *pPtr = NULL;
|
||||
|
||||
memset(value,0,256);
|
||||
GetHdbProperty(commandNode,"priv",value,256);
|
||||
status = decodeSICSPriv(value);
|
||||
if(!SCMatchRights(pCon,status)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(GetHdbProperty(commandNode,"script",value,256) != 1){
|
||||
SCWrite(pCon,"ERROR: script property not configured on this node",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Tcl_DStringInit(&com);
|
||||
Tcl_DStringAppend(&com,value,strlen(value));
|
||||
for(i = 0; i < nCount; i++){
|
||||
val = formatValue(par[i]->value, par[i]);
|
||||
if(val != NULL){
|
||||
Tcl_DStringAppend(&com," ", 1);
|
||||
pPtr = GetCharArray(val);
|
||||
Tcl_DStringAppend(&com,pPtr,strlen(pPtr));
|
||||
DeleteDynString(val);
|
||||
}
|
||||
}
|
||||
|
||||
MacroPush(pCon);
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
status = Tcl_Eval(pTcl,Tcl_DStringValue(&com));
|
||||
Tcl_DStringFree(&com);
|
||||
MacroPop();
|
||||
|
||||
if(status == TCL_OK){
|
||||
SCWrite(pCon,Tcl_GetStringResult(pTcl),eValue);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,Tcl_GetStringResult(pTcl),eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int MakeScriptFunc(pSICSOBJ self, SConnection *pCon,
|
||||
int argc, char *argv[]){
|
||||
char path[512], *pPtr = NULL;
|
||||
pHdb parent = NULL, node = NULL;
|
||||
hdbValue func;
|
||||
|
||||
if(argc < 5){
|
||||
SCWrite(pCon,
|
||||
"ERROR: not enough arguments: obj makescriptfunc path script priv",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!SCMatchRights(pCon,usMugger)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
strncpy(path,argv[2],511);
|
||||
pPtr = strrchr(path,'/');
|
||||
if(pPtr == NULL){
|
||||
/* no hierarchy */
|
||||
parent = self->objectNode;
|
||||
node = MakeHipadabaNode(path,HIPFUNC,1);
|
||||
} else {
|
||||
/* hierarchy */
|
||||
*pPtr = '\0';
|
||||
parent = GetHipadabaNode(self->objectNode,path);
|
||||
pPtr++;
|
||||
node = MakeHipadabaNode(pPtr,HIPFUNC,1);
|
||||
}
|
||||
if(parent == NULL || node == NULL){
|
||||
SCWrite(pCon,"ERROR: root path error or out of memory",eError);
|
||||
return 0;
|
||||
}
|
||||
node->value = MakeSICSFunc(ScriptObjFunc);
|
||||
SetHdbProperty(node,"script",argv[3]);
|
||||
SetHdbProperty(node,"priv",argv[4]);
|
||||
AppendHipadabaCallback(node,MakeSICSFuncCallback(self));
|
||||
AddHipadabaChild(parent,node,pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int isNodePrintable(pHdb node){
|
||||
switch(node->value.dataType){
|
||||
case HIPNONE:
|
||||
case HIPFUNC:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void objFormatNode(pHdb node, pDynString data){
|
||||
char par[40];
|
||||
pDynString val = NULL;
|
||||
|
||||
snprintf(par,40,"%-20s = ",node->name);
|
||||
DynStringConcat(data,par);
|
||||
val = formatValue(node->value,node);
|
||||
if(val != NULL){
|
||||
DynStringConcat(data,GetCharArray(val));
|
||||
DynStringConcatChar(data,'\n');
|
||||
DeleteDynString(val);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int ListObj(pSICSOBJ self, SConnection *pCon, int argc, char *argv[]){
|
||||
pHdb node = NULL;
|
||||
pDynString data;
|
||||
|
||||
data = CreateDynString(128,128);
|
||||
if(data == NULL){
|
||||
return 0;
|
||||
}
|
||||
node = self->pDes->parNode;
|
||||
if(node != NULL){
|
||||
objFormatNode(node,data);
|
||||
node = node->child;
|
||||
while(node != NULL){
|
||||
objFormatNode(node,data);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(data),eValue);
|
||||
DeleteDynString(data);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pSICSOBJ self = NULL;
|
||||
int status;
|
||||
pHdb parNode;
|
||||
char buffer[132];
|
||||
hdbValue data;
|
||||
pDynString parData;
|
||||
|
||||
self = (pSICSOBJ)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
if (argc == 1) {
|
||||
parNode = self->objectNode;
|
||||
if(parNode != NULL && isNodePrintable(parNode) ){
|
||||
status = GetHipadabaPar(parNode,&data,pCon);
|
||||
if(status != 1){
|
||||
return 0;
|
||||
}
|
||||
parData = formatValue(data, parNode);
|
||||
if(parData == NULL){
|
||||
SCWrite(pCon,"ERROR: failed to format data", eError);
|
||||
return 0;
|
||||
}
|
||||
SCPrintf(pCon,eValue,"%s = %s", argv[0], GetCharArray(parData));
|
||||
DeleteDynString(parData);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: nothing to print", eError);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
parNode = GetHipadabaNode(self->objectNode,argv[1]);
|
||||
}
|
||||
if(parNode != NULL && parNode->value.dataType == HIPFUNC){
|
||||
status = invokeOBJFunction(self, parNode, pCon, argc-2, &argv[2]);
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "%s ", argv[0]);
|
||||
status = ProcessSICSHdbPar(self->objectNode,pCon, buffer,
|
||||
argc-1,&argv[1]);
|
||||
}
|
||||
if(status == -1){
|
||||
if(strcmp(argv[1],"makescriptfunc") == 0) {
|
||||
return MakeScriptFunc(self,pCon,argc,argv);
|
||||
} else if(strcmp(argv[1],"list") == 0){
|
||||
return ListObj(self,pCon,argc,argv);
|
||||
}
|
||||
SCPrintf(pCon, eError, "ERROR: %s %s not found", argv[0], argv[1]);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InterInvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
int status;
|
||||
char buffer[132];
|
||||
|
||||
status = InvokeSICSOBJ(pCon,pSics,pData,argc,argv);
|
||||
if(status == -1){
|
||||
status = 0;
|
||||
if(argc > 1){
|
||||
snprintf(buffer,131,"ERROR: no command or parameter found for key: %s",
|
||||
argv[1]);
|
||||
} else {
|
||||
snprintf(buffer,131,"ERROR: no argument found");
|
||||
}
|
||||
SCWrite(pCon,buffer,eError);
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pSICSOBJ pNew = NULL;
|
||||
int status;
|
||||
int type;
|
||||
int priv;
|
||||
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError);
|
||||
return NULL;
|
||||
}
|
||||
if (argc < 5) {
|
||||
type = HIPNONE;
|
||||
priv = usInternal;
|
||||
} else {
|
||||
/* convert privilege */
|
||||
priv = decodeSICSPriv(argv[3]);
|
||||
/* convert datatype */
|
||||
strtolower(argv[4]);
|
||||
type = convertHdbType(argv[4]);
|
||||
if(type > HIPFLOAT){
|
||||
SCWrite(pCon,
|
||||
"ERROR: invalid type requested: none, int, float supported",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pNew = MakeSICSOBJv(argv[1], argv[2], type, priv);
|
||||
if(pNew == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError);
|
||||
return NULL;
|
||||
}
|
||||
if (strcasecmp(argv[0],"DynSicsObj") == 0) {
|
||||
/* make object dynamic by defining a descriptor command */
|
||||
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
|
||||
}
|
||||
|
||||
status = AddCommand(pSics,
|
||||
argv[1],
|
||||
InterInvokeSICSOBJ,
|
||||
KillSICSOBJ,
|
||||
pNew);
|
||||
if(status != 1){
|
||||
KillSICSOBJ(pNew);
|
||||
SCPrintf(pCon,eError,"ERROR: failed create duplicate command %s", argv[1]);
|
||||
return NULL;
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InstallSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pSICSOBJ pNew = NULL;
|
||||
|
||||
pNew = SetupSICSOBJ(pCon, pSics, pData, argc, argv);
|
||||
if(pNew == NULL){
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
|
||||
{
|
||||
char newprefix[1024], val[20];
|
||||
pHdb child;
|
||||
hdbValue v;
|
||||
pDynString data = NULL;
|
||||
|
||||
if (GetHdbProperty(node, "__save", val, 20) == 1) {
|
||||
GetHipadabaPar(node, &v, NULL);
|
||||
data = formatValue(v, node);
|
||||
if (data != NULL) {
|
||||
fprintf(fd, "%s %s\n", prefix, GetCharArray(data));
|
||||
DeleteDynString(data);
|
||||
}
|
||||
child = node->child;
|
||||
while (child != NULL) {
|
||||
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
|
||||
saveSICSNode(child, newprefix, fd);
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int SaveSICSOBJ(void *data, char *name, FILE * fd)
|
||||
{
|
||||
pSICSOBJ self = (pSICSOBJ) data;
|
||||
char prefix[1024];
|
||||
pHdb node;
|
||||
|
||||
if (self != NULL && self->objectNode != NULL) {
|
||||
node = self->objectNode->child;
|
||||
while (node != NULL) {
|
||||
snprintf(prefix, 1024, "%s %s", name, node->name);
|
||||
saveSICSNode(node, prefix, fd);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ MakeSICSOBJv(char *name, char *class, int type, int priv)
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
hdbValue val;
|
||||
|
||||
pNew = (pSICSOBJ) malloc(sizeof(SICSOBJ));
|
||||
if (pNew == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(pNew, 0, sizeof(SICSOBJ));
|
||||
pNew->pDes = CreateDescriptor(class);
|
||||
pNew->pDes->SaveStatus = SaveSICSOBJ;
|
||||
if (type == HIPNONE) {
|
||||
pNew->objectNode = MakeHipadabaNode(name, HIPNONE, 1);
|
||||
} else {
|
||||
val = makeHdbValue(type, 0);
|
||||
pNew->objectNode = MakeSICSHdbPar(name, priv, val);
|
||||
ReleaseHdbValue(&val);
|
||||
}
|
||||
if (pNew->pDes == NULL || pNew->objectNode == NULL) {
|
||||
free(pNew);
|
||||
return (NULL);
|
||||
}
|
||||
pNew->pDes->parNode = pNew->objectNode;
|
||||
pNew->KillPrivate = DefaultKill;
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ MakeSICSOBJ(char *name, char *class)
|
||||
{
|
||||
return MakeSICSOBJv(name, class, HIPNONE, 0);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void KillSICSOBJ(void *data)
|
||||
{
|
||||
pSICSOBJ self = (pSICSOBJ) data;
|
||||
if (self == NULL) {
|
||||
return;
|
||||
}
|
||||
if (self->KillPrivate != NULL && self->pPrivate != NULL) {
|
||||
self->KillPrivate(self->pPrivate);
|
||||
}
|
||||
RemoveHdbNodeFromParent(self->objectNode, pServ->dummyCon);
|
||||
if (self->pDes != NULL) {
|
||||
DeleteDescriptor(self->pDes); /* kill descriptor including node */
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
static int assignPar(pHdb node, SConnection * pCon, char *data)
|
||||
{
|
||||
char error[132], buffer[256];
|
||||
int status;
|
||||
|
||||
status = readHdbValue(&node->value, data, error, 132);
|
||||
if (status != 1) {
|
||||
snprintf(buffer, 255, "ERROR: error parsing %s: %s",
|
||||
node->name, error);
|
||||
SCWrite(pCon, buffer, eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode,
|
||||
SConnection * pCon, int argc, char *argv[])
|
||||
{
|
||||
int status, i, count = 0;
|
||||
pHdb currentPar = NULL;
|
||||
SICSOBJFunc pFunc = NULL;
|
||||
pHdb parArray[64];
|
||||
char buffer[1024];
|
||||
|
||||
/*
|
||||
* If the first argument has the special name args, concatenate all arguments
|
||||
* and put the result as text into this parameter. This allows for the
|
||||
* object function to parse and interpret the arguments itself.
|
||||
*/
|
||||
if (commandNode->child != NULL
|
||||
&& strcmp(commandNode->child->name, "args") == 0) {
|
||||
Arg2Text(argc, argv, buffer, 1024);
|
||||
assignPar(commandNode->child, pCon, buffer);
|
||||
parArray[0] = commandNode->child;
|
||||
count = 1;
|
||||
goto invoke;
|
||||
}
|
||||
|
||||
/*
|
||||
* assign parameters and fill parameter array for function at the same
|
||||
* time. Be lenient about missing parameters: Then the old values will
|
||||
* be used.
|
||||
*/
|
||||
for (i = 0, currentPar = commandNode->child;
|
||||
i < argc && currentPar != NULL;
|
||||
i++, currentPar = currentPar->next) {
|
||||
if (argv[i] != NULL) {
|
||||
status = assignPar(currentPar, pCon, argv[i]);
|
||||
}
|
||||
if (status != 1) {
|
||||
return status;
|
||||
}
|
||||
parArray[i] = currentPar;
|
||||
count++;
|
||||
}
|
||||
|
||||
invoke:pFunc = (SICSOBJFunc) commandNode->value.v.func;
|
||||
if (pFunc == NULL) {
|
||||
SCWrite(pCon, "ERROR: internal error, function not found", eError);
|
||||
return 0;
|
||||
}
|
||||
SendHdbStatusMessage(commandNode, "start");
|
||||
status = pFunc(object, pCon, commandNode, parArray, count);
|
||||
SendHdbStatusMessage(commandNode, "stop");
|
||||
return status;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int ScriptObjFunc(pSICSOBJ obj, SConnection * pCon,
|
||||
pHdb commandNode, pHdb par[], int nCount)
|
||||
{
|
||||
int status, i;
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
Tcl_DString com;
|
||||
char value[256];
|
||||
pDynString val = NULL;
|
||||
char *pPtr = NULL;
|
||||
|
||||
memset(value, 0, 256);
|
||||
GetHdbProperty(commandNode, "priv", value, 256);
|
||||
status = decodeSICSPriv(value);
|
||||
if (!SCMatchRights(pCon, status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GetHdbProperty(commandNode, "script", value, 256) != 1) {
|
||||
SCWrite(pCon, "ERROR: script property not configured on this node",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Tcl_DStringInit(&com);
|
||||
Tcl_DStringAppend(&com, value, strlen(value));
|
||||
for (i = 0; i < nCount; i++) {
|
||||
val = formatValue(par[i]->value, par[i]);
|
||||
if (val != NULL) {
|
||||
Tcl_DStringAppend(&com, " ", 1);
|
||||
pPtr = GetCharArray(val);
|
||||
Tcl_DStringAppend(&com, pPtr, strlen(pPtr));
|
||||
DeleteDynString(val);
|
||||
}
|
||||
}
|
||||
|
||||
MacroPush(pCon);
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
status = Tcl_Eval(pTcl, Tcl_DStringValue(&com));
|
||||
Tcl_DStringFree(&com);
|
||||
MacroPop();
|
||||
|
||||
if (status == TCL_OK) {
|
||||
SCWrite(pCon, Tcl_GetStringResult(pTcl), eValue);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon, Tcl_GetStringResult(pTcl), eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int MakeScriptFunc(pSICSOBJ self, SConnection * pCon,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char path[512], *pPtr = NULL;
|
||||
pHdb parent = NULL, node = NULL;
|
||||
hdbValue func;
|
||||
|
||||
if (argc < 5) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: not enough arguments: obj makescriptfunc path script priv",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SCMatchRights(pCon, usMugger)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
strncpy(path, argv[2], 511);
|
||||
pPtr = strrchr(path, '/');
|
||||
if (pPtr == NULL) {
|
||||
/* no hierarchy */
|
||||
parent = self->objectNode;
|
||||
node = MakeHipadabaNode(path, HIPFUNC, 1);
|
||||
} else {
|
||||
/* hierarchy */
|
||||
*pPtr = '\0';
|
||||
parent = GetHipadabaNode(self->objectNode, path);
|
||||
pPtr++;
|
||||
node = MakeHipadabaNode(pPtr, HIPFUNC, 1);
|
||||
}
|
||||
if (parent == NULL || node == NULL) {
|
||||
SCWrite(pCon, "ERROR: root path error or out of memory", eError);
|
||||
return 0;
|
||||
}
|
||||
node->value = MakeSICSFunc(ScriptObjFunc);
|
||||
SetHdbProperty(node, "script", argv[3]);
|
||||
SetHdbProperty(node, "priv", argv[4]);
|
||||
AppendHipadabaCallback(node, MakeSICSFuncCallback(self));
|
||||
AddHipadabaChild(parent, node, pCon);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int isNodePrintable(pHdb node)
|
||||
{
|
||||
switch (node->value.dataType) {
|
||||
case HIPNONE:
|
||||
case HIPFUNC:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void objFormatNode(pHdb node, pDynString data)
|
||||
{
|
||||
char par[40];
|
||||
pDynString val = NULL;
|
||||
|
||||
snprintf(par, 40, "%-20s = ", node->name);
|
||||
DynStringConcat(data, par);
|
||||
val = formatValue(node->value, node);
|
||||
if (val != NULL) {
|
||||
DynStringConcat(data, GetCharArray(val));
|
||||
DynStringConcatChar(data, '\n');
|
||||
DeleteDynString(val);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int ListObj(pSICSOBJ self, SConnection * pCon, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
pHdb node = NULL;
|
||||
pDynString data;
|
||||
|
||||
data = CreateDynString(128, 128);
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
node = self->pDes->parNode;
|
||||
if (node != NULL) {
|
||||
objFormatNode(node, data);
|
||||
node = node->child;
|
||||
while (node != NULL) {
|
||||
objFormatNode(node, data);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
SCWrite(pCon, GetCharArray(data), eValue);
|
||||
DeleteDynString(data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pSICSOBJ self = NULL;
|
||||
int status;
|
||||
pHdb parNode;
|
||||
char buffer[132];
|
||||
hdbValue data;
|
||||
pDynString parData;
|
||||
|
||||
self = (pSICSOBJ) pData;
|
||||
assert(self != NULL);
|
||||
|
||||
if (argc == 1) {
|
||||
parNode = self->objectNode;
|
||||
if (parNode != NULL && isNodePrintable(parNode)) {
|
||||
status = GetHipadabaPar(parNode, &data, pCon);
|
||||
if (status != 1) {
|
||||
return 0;
|
||||
}
|
||||
parData = formatValue(data, parNode);
|
||||
if (parData == NULL) {
|
||||
SCWrite(pCon, "ERROR: failed to format data", eError);
|
||||
return 0;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "%s = %s", argv[0], GetCharArray(parData));
|
||||
DeleteDynString(parData);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon, "ERROR: nothing to print", eError);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
parNode = GetHipadabaNode(self->objectNode, argv[1]);
|
||||
}
|
||||
if (parNode != NULL && parNode->value.dataType == HIPFUNC) {
|
||||
status = invokeOBJFunction(self, parNode, pCon, argc - 2, &argv[2]);
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "%s ", argv[0]);
|
||||
status = ProcessSICSHdbPar(self->objectNode, pCon, buffer,
|
||||
argc - 1, &argv[1]);
|
||||
}
|
||||
if (status == -1) {
|
||||
if (strcmp(argv[1], "makescriptfunc") == 0) {
|
||||
return MakeScriptFunc(self, pCon, argc, argv);
|
||||
} else if (strcmp(argv[1], "list") == 0) {
|
||||
return ListObj(self, pCon, argc, argv);
|
||||
}
|
||||
SCPrintf(pCon, eError, "ERROR: %s %s not found", argv[0], argv[1]);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InterInvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int status;
|
||||
char buffer[132];
|
||||
|
||||
status = InvokeSICSOBJ(pCon, pSics, pData, argc, argv);
|
||||
if (status == -1) {
|
||||
status = 0;
|
||||
if (argc > 1) {
|
||||
snprintf(buffer, 131,
|
||||
"ERROR: no command or parameter found for key: %s",
|
||||
argv[1]);
|
||||
} else {
|
||||
snprintf(buffer, 131, "ERROR: no argument found");
|
||||
}
|
||||
SCWrite(pCon, buffer, eError);
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
pSICSOBJ SetupSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
int status;
|
||||
int type;
|
||||
int priv;
|
||||
|
||||
if (argc < 3) {
|
||||
SCWrite(pCon, "ERROR: not enough arguments to InstallSICSOBJ", eError);
|
||||
return NULL;
|
||||
}
|
||||
if (argc < 5) {
|
||||
type = HIPNONE;
|
||||
priv = usInternal;
|
||||
} else {
|
||||
/* convert privilege */
|
||||
priv = decodeSICSPriv(argv[3]);
|
||||
/* convert datatype */
|
||||
strtolower(argv[4]);
|
||||
type = convertHdbType(argv[4]);
|
||||
if (type > HIPFLOAT) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: invalid type requested: none, int, float supported",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
pNew = MakeSICSOBJv(argv[1], argv[2], type, priv);
|
||||
if (pNew == NULL) {
|
||||
SCWrite(pCon, "ERROR: out of memory creating new SICS object", eError);
|
||||
return NULL;
|
||||
}
|
||||
if (strcasecmp(argv[0], "DynSicsObj") == 0) {
|
||||
/* make object dynamic by defining a descriptor command */
|
||||
SetDescriptorKey(pNew->pDes, "creationCommand", "0");
|
||||
}
|
||||
|
||||
status = AddCommand(pSics,
|
||||
argv[1], InterInvokeSICSOBJ, KillSICSOBJ, pNew);
|
||||
if (status != 1) {
|
||||
KillSICSOBJ(pNew);
|
||||
SCPrintf(pCon, eError, "ERROR: failed create duplicate command %s",
|
||||
argv[1]);
|
||||
return NULL;
|
||||
}
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int InstallSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
|
||||
pNew = SetupSICSOBJ(pCon, pSics, pData, argc, argv);
|
||||
if (pNew == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user