- Fixed a massive memory leak in Hipadaba

- Extended the Hdb adapter to support SICSdata
- Made the simulated histogram memory driver work properly when
  data has been set.
- Implemented the hfactory command
- Removed hdbcommand which was never finsihed
This commit is contained in:
koennecke
2008-05-08 09:27:48 +00:00
parent 7d2b0c5104
commit e46334eddf
20 changed files with 1167 additions and 901 deletions

348
sicshdbfactory.c Normal file
View File

@ -0,0 +1,348 @@
/**
* This implements the hfactory command which is used to create
* hipadaba nodes.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2008,
* reusing code from former separate node creation functions.
*/
#include <sicshipadaba.h>
#include "statusfile.h"
#define MAX_HDB_PATH 1024
/*-------------------------------------------------------------------------*/
static int MakePlainNode(pHdb parent, char *name, SConnection *pCon,
int argc, char *argv[]){
pHdb child = NULL;
int type = 0, length = 0, priv = -1;
hdbValue val;
if(argc < 5){
SCWrite(pCon,"ERROR: not enough arguments to create plain node",
eError);
return 0;
}
/*
* convert privilege
*/
priv = decodeSICSPriv(argv[3]);
if(priv < 0){
SCPrintf(pCon,eError,"ERROR: %s is no valid privilege code", argv[3]);
return 0;
}
/*
* convert datatype
*/
strtolower(argv[4]);
type = convertHdbType(argv[4]);
if(type > HIPFLOATVARAR){
SCWrite(pCon,
"ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported",
eError);
return 0;
}
if(type >= HIPINTAR){
if( argc < 6){
SCWrite(pCon,"ERROR: array length missing for array data type",
eError);
return 0;
} else {
length = atoi(argv[5]);
}
}
if(type != HIPNONE){
val = makeHdbValue(type,length);
child = MakeSICSHdbPar(name, priv, val);
ReleaseHdbValue(&val);
} else {
child = MakeHipadabaNode(name,type,length);
}
if(child == NULL){
SCWrite(pCon,"ERROR: out of memory creating node",eError);
return 0;
}
AddHipadabaChild(parent,child,pCon);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
static int MakeScriptNode(pHdb parent, char *name, SConnection *pCon,
int argc, char *argv[]){
int type, length;
pHdb child = NULL;
hdbValue v;
if(argc < 5){
SCWrite(pCon,
"ERROR: not enough arguments to create script parameter node",
eError);
return 0;
}
/*
* convert datatype
*/
strtolower(argv[5]);
type = convertHdbType(argv[5]);
if(type >= 7){
SCWrite(pCon,
"ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported",
eError);
return 0;
}
if(type > 2){
if( argc < 7){
SCWrite(pCon,"ERROR: array length missing for array data type",
eError);
return 0;
} else {
length = atoi(argv[6]);
}
}
v = makeHdbValue(type,length);
child = MakeSICSScriptPar(name, argv[4], argv[3], v);
ReleaseHdbValue(&v);
if(child == NULL){
SCWrite(pCon,"ERROR: out of memory creating node",eError);
return 0;
}
AddHipadabaChild(parent,child,pCon);
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------------*/
static int MakeLinkNode(pHdb parent, char *name, SConnection *pCon,
int argc, char *argv[]){
pHdb node = NULL;
pObjectDescriptor pDes = NULL;
char buffer[256];
if(argc < 4){
SCWrite(pCon,"ERROR: not enough arguments to create script node",
eError);
return 0;
}
pDes = FindCommandDescriptor(pServ->pSics,argv[3]);
if(pDes == NULL){
snprintf(buffer,255,"ERROR: failed to find object %s", argv[3]);
SCWrite(pCon,buffer,eError);
return 0;
}
if(pDes->parNode == NULL){
snprintf(buffer,255,
"ERROR: Object %s does not use Hipadaba natively and thus cannot be linked",
argv[3]);
SCWrite(pCon,buffer,eError);
return 0;
}
if(pDes->parNode->mama != NULL){
snprintf(buffer,255,
"ERROR: Object %s is already linked somewhere else",
argv[3]);
SCWrite(pCon,buffer,eError);
return 0;
}
AddHipadabaChild(parent,pDes->parNode,pCon);
if(pDes->parNode->name != NULL){
free(pDes->parNode->name);
}
pDes->parNode->name = strdup(name);
SCSendOK(pCon);
return 1;
}
/* --------------------------------------------------------------------------
* This is actually SCInvoke but without advancing the context. I think this
* is only of local use. It makes sure that commands executed as Hipadaba
* commands get logged properly.
---------------------------------------------------------------------------*/
static int HDBInvoke(SConnection *self, SicsInterp *pInter, char *pCommand)
{
int iRet;
long lLen;
const char *pResult = NULL;
char *pBuffer = NULL, *pFile = NULL;
char pBueffel[80];
int i, iSpace;
assert(pInter);
/* print command to log files */
for( i = 0; i < self->iFiles; i++)
{
if(self->pFiles[i])
{
fprintf(self->pFiles[i],"SICS>> %s\n",pCommand);
}
}
/* print to command log if user or manager */
if(SCGetRights(self) <= usUser)
{
if(self->pSock != NULL)
{
sprintf(pBueffel,"sock %d>>",self->pSock->sockid);
}
}
/* invoke */
self->inUse++;
self->eInterrupt = eContinue;
/*
get first word of command
*/
iRet = InterpExecute(pInter,self,pCommand);
StatusFileTask(NULL); /* save changed parameters */
self->inUse--;
return iRet;
}
/*---------------------------------------------------------------------------*/
static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData,
pHdbMessage message){
SConnection *pCon = NULL;
pDynString cmd = NULL, par = NULL;
pHdb current = NULL;
int status;
pHdbDataMessage mm = NULL;
hdbValue v;
if((mm = GetHdbSetMessage(message)) == NULL){
return hdbContinue;
}
pCon = (SConnection *)pCon;
v = *(mm->v);
if(pCon == NULL){
printf("Cannot invoke command without connection\n");
return hdbAbort;
}
if(v.dataType == HIPTEXT){
if(strstr(v.v.text,"start") != NULL) {
cmd = CreateDynString(64,64);
if(cmd == 0){
SCWrite(pCon,"ERROR: out of memory in CommandSetCallback",eError);
return 0;
}
DynStringCopy(cmd, node->value.v.text);
DynStringConcat(cmd," ");
current = node->child;
while(current != NULL){
par = formatValue(current->value, current);
if(par != NULL){
DynStringConcat(cmd, GetCharArray(par));
DynStringConcat(cmd," ");
DeleteDynString(par);
}
current = current->next;
}
status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
DeleteDynString(cmd);
if(status == 1){
return hdbContinue;
} else {
return hdbAbort;
}
} else {
SCWrite(pCon,"ERROR: this node only understands start as value",eError);
return hdbAbort;
}
}
return hdbContinue;
}
/*---------------------------------------------------------------------------*/
static hdbCallbackReturn CommandGetCallback(pHdb node, void *userData,
pHdbMessage message){
pHdbDataMessage mm = NULL;
if((mm = GetHdbGetMessage(message)) == NULL){
return hdbContinue;
}
hdbValue v2 = MakeHdbText("Nothing to get");
*(mm->v) = v2;
return hdbContinue;
}
/*--------------------------------------------------------------------------*/
static int MakeCommandNode(pHdb parent, char *name, SConnection *pCon,
int argc, char *argv[]){
pHdb node = NULL;
pHdbCallback kalle = NULL;
if(argc < 4){
SCWrite(pCon,"ERROR: not enough arguments to create command node",
eError);
return 0;
}
node = MakeHipadabaNode(name, HIPTEXT, 1);
if(node == NULL){
SCWrite(pCon,"ERROR: out of memory in hcommand",eError);
return 0;
}
node->value.v.text = strdup(argv[3]);
node->value.arrayLength = strlen(argv[3]);
SetHdbProperty(node,"sicscommand", argv[3]);
kalle = MakeHipadabaCallback(CommandSetCallback,NULL, NULL);
if(kalle == NULL){
SCWrite(pCon,"ERROR: out of memory in hcommand",eError);
return 0;
}
AppendHipadabaCallback(node,kalle);
kalle = MakeHipadabaCallback(CommandGetCallback,NULL, NULL);
if(kalle == NULL){
SCWrite(pCon,"ERROR: out of memory in hcommand",eError);
return 0;
}
AppendHipadabaCallback(node,kalle);
AddHipadabaChild(parent,node,pCon);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
int HdbNodeFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
char *name = NULL;
pHdb parent = NULL;
if(!SCMatchRights(pCon,usMugger)){
return 0;
}
if(argc < 3) {
SCWrite(pCon,"ERROR: not enough arguments to hfactory",eError);
return 0;
}
parent = FindHdbParent(NULL, argv[1], &name, pCon);
if (parent == NULL) {
return 0; /* error messages written inside FindHdbParent */
}
strtolower(argv[2]);
if(strcmp(argv[2],"plain") == 0){
return MakePlainNode(parent,name,pCon,argc,argv);
} else if(strcmp(argv[2],"script") == 0){
return MakeScriptNode(parent,name,pCon,argc,argv);
} else if(strcmp(argv[2],"link") == 0){
return MakeLinkNode(parent,name,pCon,argc,argv);
} else if(strcmp(argv[2],"command") == 0){
return MakeCommandNode(parent,name,pCon,argc,argv);
} else {
SCWrite(pCon,"ERROR: node type not recognised", eError);
return 0;
}
return 0;
}