- Introducted Arg2Tcl as a replacement for some calls to Arg2Text

- Fixed a memory leak
This commit is contained in:
zolliker
2006-04-11 07:26:55 +00:00
parent e25fb68080
commit da3dfd9d76
11 changed files with 184 additions and 92 deletions

View File

@ -132,7 +132,10 @@ extern pServer pServ;
} }
do do
{ /* loop until an unused ident is found */ { /* loop until an unused ident is found. This test needed only for
the case there some object has already the name con<nnn>.
In a live cycle of SICS, no connection ever can get an earlier
used name */
if (lastIdent == LONG_MAX) if (lastIdent == LONG_MAX)
{ {
/* This is a serious, very serious error! */ /* This is a serious, very serious error! */
@ -1722,6 +1725,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
pCBAction pCB = NULL; pCBAction pCB = NULL;
CommandList *pCom = NULL; CommandList *pCom = NULL;
int iMacro; int iMacro;
char *script;
self = (SConnection *)pData; self = (SConnection *)pData;
if(!VerifyConnection(self)) if(!VerifyConnection(self))
@ -1781,17 +1785,18 @@ static void writeToLogFiles(SConnection *self, char *buffer)
return 0; return 0;
} }
script = Arg2Tcl(argc-4, &argv[4], NULL, 0);
/* now we can install the callback */ /* now we can install the callback */
pCB = (pCBAction)malloc(sizeof(CBAction)); pCB = (pCBAction)malloc(sizeof(CBAction));
if(!pCB) if(!pCB || !script)
{ {
SCWrite(pCon,"ERROR: memory exhausted in SConnection",eError); SCWrite(pCon,"ERROR: memory exhausted in SConnection",eError);
return 0; return 0;
} }
Arg2Text(argc-4, &argv[4],pBueffel,1023);
pCB->pCon = pCon; pCB->pCon = pCon;
pCB->pSics = pSics; pCB->pSics = pSics;
pCB->pAction = strdup(pBueffel); pCB->pAction = script;
sItem.pInterface = pInterface; sItem.pInterface = pInterface;
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack, sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
pCB, CBKill); pCB, CBKill);

4
emon.c
View File

@ -85,8 +85,7 @@
/* remove all the names */ /* remove all the names */
/* iRet = LLDnodePtr2First(self->iList);
iRet == LLDnodePtr2First(self->iList);
while(iRet != 0) while(iRet != 0)
{ {
LLDnodeDataTo(self->iList,&sEntry); LLDnodeDataTo(self->iList,&sEntry);
@ -97,7 +96,6 @@
} }
iRet = LLDnodePtr2Next(self->iList); iRet = LLDnodePtr2Next(self->iList);
} }
*/
/* remove list */ /* remove list */
LLDdelete(self->iList); LLDdelete(self->iList);

View File

@ -1214,12 +1214,11 @@ static void ErrReport(pEVControl self)
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"errorscript") == 0) if(strcmp(argv[1],"errorscript") == 0)
{ {
Arg2Text(argc-2,&argv[2],pBueffel,255);
if(self->errorScript != NULL) if(self->errorScript != NULL)
{ {
free(self->errorScript); free(self->errorScript);
} }
self->errorScript = strdup(pBueffel); self->errorScript = Arg2Tcl(argc-2,&argv[2],NULL,0);
SCSendOK(pCon); SCSendOK(pCon);
SCparChange(pCon); SCparChange(pCon);
return 1; return 1;
@ -1542,8 +1541,7 @@ int RemoveEVController(SConnection *pCon, char *name) {
return 0; return 0;
} }
if (pNew->pDriv->SavePars) { if (pNew->pDriv->SavePars) {
Arg2Text(argc-3, argv+3, pBueffel, sizeof pBueffel); pNew->creationArgs = Arg2Tcl(argc-3, argv+3, NULL, 0);
pNew->creationArgs = strdup(pBueffel);
pNew->pDes->SaveStatus = EVSaveStatus; pNew->pDes->SaveStatus = EVSaveStatus;
} else { } else {
pNew->creationArgs = NULL; pNew->creationArgs = NULL;

63
macro.c
View File

@ -174,6 +174,7 @@
return TCL_ERROR; return TCL_ERROR;
} }
} }
if (pSics->lastUnknown[pSics->iStack]) free(pSics->lastUnknown[pSics->iStack]);
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer); pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
/* invoke */ /* invoke */
@ -181,7 +182,6 @@
SCsetMacro(pCon,1); SCsetMacro(pCon,1);
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg); iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
SCsetMacro(pCon,iMacro); SCsetMacro(pCon,iMacro);
/* /*
lastUnkown gets deeply stacked with each SICS command exec'd. lastUnkown gets deeply stacked with each SICS command exec'd.
This is not reflected in code. However, lastUnknown has already This is not reflected in code. However, lastUnknown has already
@ -844,6 +844,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
int argc, char *argv[]) int argc, char *argv[])
{ {
char pBueffel[1024]; char pBueffel[1024];
char *pCommand;
pPubTcl self = NULL; pPubTcl self = NULL;
int iRet, length; int iRet, length;
char *pPtr; char *pPtr;
@ -864,45 +865,32 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
} }
/* make a string */ /* make a string */
Arg2Text(argc,argv,pBueffel,1023); pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
if (!pCommand) {
SCWrite(pCon, "ERROR: no more memory", eError);
iRet = Tcl_Eval(pTcl,pBueffel);
if(iRet == TCL_OK)
{ length = strlen(pTcl->result);
if(length < 1024){
strncpy(pBueffel,pTcl->result,1023);
SCWrite(pCon,pBueffel,eStatus);
} else {
length += 10;
pPtr = (char *)malloc(length*sizeof(char));
if(pPtr == NULL){
SCWrite(pCon,
"ERROR: out of memory in TclAction",
eError);
return 0; return 0;
} }
memset(pPtr,0,length*sizeof(char)); iRet = Tcl_Eval(pTcl,pCommand);
strncpy(pPtr,pTcl->result,length-1); if (pCommand != pBueffel) free(pCommand);
SCWrite(pCon,pPtr,eStatus); if(iRet == TCL_OK)
free(pPtr); {
} /* we do not now why, but at some time it was found that
we need a copy, and can not use pTcl->result directly
SCWrite(pCon,pTcl->result,eStatus);
let us use SCPrintf, which maked always a copy
*/
SCPrintf(pCon, eStatus, "%s", pTcl->result);
return 1; return 1;
} }
else else
{ {
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) == NULL) if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) != NULL)
{
pPtr = strdup(pTcl->result);
SCWrite(pCon,pPtr,eError);
free(pPtr);
}
else
{ {
Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY); Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY);
strncpy(pBueffel,pTcl->result,1023);
SCWrite(pCon,pBueffel,eError);
} }
SCPrintf(pCon,eError,"%s",pTcl->result);
return 0; return 0;
} }
return 1; /* not reached */ return 1; /* not reached */
@ -990,16 +978,21 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData, int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
{ {
char pCommand[1024], pStart[1024]; char pBuffer[1024];
char *pCommand;
int iRet; int iRet;
Arg2Text(argc-1,&argv[1],pCommand,1023); pCommand = Arg2Tcl(argc-1,&argv[1],pBuffer, sizeof(pBuffer));
if (!pCommand) {
SCWrite(pCon,"ERROR: no memory", eError);
return 0;
}
strtolower(argv[0]); strtolower(argv[0]);
if(strcmp(argv[0],"fulltransact") == 0){ if(strcmp(argv[0],"fulltransact") == 0){
snprintf(pStart,1023,"TRANSACTIONSTART %s",pCommand); SCPrintf(pCon,eError, "TRANSACTIONSTART %s",pCommand);
SCWrite(pCon,pStart,eError);
} }
iRet = InterpExecute(pSics,pCon,pCommand); iRet = InterpExecute(pSics,pCon,pCommand);
if (pCommand != pBuffer) free(pCommand);
SCWrite(pCon,"TRANSACTIONFINISHED",eError); SCWrite(pCon,"TRANSACTIONFINISHED",eError);
return iRet; return iRet;
} }

View File

@ -171,7 +171,8 @@ void DeleteProtocol(void *self)
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData, static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){ int argc, char *argv[]){
commandContext comCon; commandContext comCon;
char command[1024]; char buffer[1024];
char *command;
int status; int status;
if(argc < 3){ if(argc < 3){
@ -186,11 +187,15 @@ static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0; return 0;
} }
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN); strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
memset(command,0,1024*sizeof(char)); memset(buffer,0,sizeof(buffer));
Arg2Text(argc-2,&argv[2],command,1023); command = Arg2Tcl(argc-2,&argv[2],buffer,sizeof buffer);
if (!command) {
SCWrite(pCon,"ERROR: no more memory",eError);
return 0;
}
SCPushContext2(pCon,comCon); SCPushContext2(pCon,comCon);
status = InterpExecute(pSics,pCon,command); status = InterpExecute(pSics,pCon,command);
if (command != buffer) free(command);
SCPopContext(pCon); SCPopContext(pCon);
return status; return status;
} }

18
remob.c
View File

@ -534,7 +534,11 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
float fValue; float fValue;
long lID; long lID;
char *endp; char *endp;
char *argv0;
char *cmd;
/*
char acce[128], inte[128]; char acce[128], inte[128];
*/
int rights; int rights;
RemChannel *rc; RemChannel *rc;
@ -550,16 +554,19 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
if (argc == 1) { if (argc == 1) {
iRet = RemTransact(remserver, rc, pCon, argv[0], ">", NULL); iRet = RemTransact(remserver, rc, pCon, argv[0], ">", NULL);
} else if (strcasecmp(argv[1],"list") == 0) { } else if (strcasecmp(argv[1],"list") == 0) {
snprintf(buf, sizeof(buf), "%s ", remob->name);
i = strlen(buf);
Arg2Text(argc-1, argv+1, buf + i, sizeof buf - i);
/* /*
snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name); snprintf(acce, sizeof(acce), "!%s.accesscode", remob->name);
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name); snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
*/ */
RemTransact(remserver, rc, pCon, buf, ">", NULL); argv0 = argv[0];
argv[0] = remob->name;
cmd = Arg2Tcl(argc, argv, buf, sizeof buf);
argv[0] = argv0;
if (cmd) {
RemTransact(remserver, rc, pCon, cmd, ">", NULL);
if (cmd != buf) free(cmd);
}
iRet=1; iRet=1;
} else { } else {
pos=snprintf(buf, sizeof(buf), "%s ", remob->name); pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
@ -620,7 +627,6 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
float fValue; float fValue;
long lID; long lID;
char *endp, *serverport, *thishostname; char *endp, *serverport, *thishostname;
char acce[128], inte[128];
struct sockaddr_in adr; struct sockaddr_in adr;
struct hostent *thishost; struct hostent *thishost;
Remob *p, *next; Remob *p, *next;

View File

@ -411,6 +411,7 @@
char pBueffel[256]; char pBueffel[256];
Tcl_Interp *pTcl = NULL; Tcl_Interp *pTcl = NULL;
int iRet; int iRet;
char *cmd;
assert(pCon); assert(pCon);
assert(pSics); assert(pSics);
@ -425,8 +426,13 @@
pTcl = InterpGetTcl(pSics); pTcl = InterpGetTcl(pSics);
assert(pTcl); assert(pTcl);
Arg2Text(argc-1,&argv[1],pBueffel,255); cmd = Arg2Tcl(argc-1,&argv[1],pBueffel,sizeof pBueffel);
iRet = Tcl_Eval(pTcl,pBueffel); if (!cmd) {
SCWrite(pCon,"ERROR: no more memory",eError);
return 0;
}
iRet = Tcl_Eval(pTcl,cmd);
if (cmd != pBueffel) free(cmd);
if(strlen(pTcl->result) > 1) if(strlen(pTcl->result) > 1)
{ {
SCWrite(pCon,pTcl->result,eValue); SCWrite(pCon,pTcl->result,eValue);

View File

@ -83,7 +83,7 @@
{ {
pCron pNew = NULL; pCron pNew = NULL;
int iVal, iRet; int iVal, iRet;
char pBueffel[512]; char *cmd;
/* only managers may do this */ /* only managers may do this */
if(!SCMatchRights(pCon,usMugger)) if(!SCMatchRights(pCon,usMugger))
@ -108,11 +108,11 @@
} }
/* concatenate the rest to the command */ /* concatenate the rest to the command */
Arg2Text(argc-2,&argv[2],pBueffel,511); cmd = Arg2Tcl(argc-2,&argv[2],NULL,0);
/* create data structure and install task */ /* create data structure and install task */
pNew = (pCron)malloc(sizeof(Cron)); pNew = (pCron)malloc(sizeof(Cron));
if(!pNew) if(!pNew || !cmd)
{ {
SCWrite(pCon,"ERROR: out of memory in sicscron",eError); SCWrite(pCon,"ERROR: out of memory in sicscron",eError);
return 0; return 0;
@ -124,7 +124,7 @@
return 0; return 0;
} }
pNew->iIntervall = iVal; pNew->iIntervall = iVal;
pNew->pCommand = strdup(pBueffel); pNew->pCommand = cmd;
pNew->tNext = 0; pNew->tNext = 0;
pNew->iEnd = 1; pNew->iEnd = 1;

View File

@ -11,6 +11,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include "tcl.h"
#include "splitter.h" #include "splitter.h"
typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType; typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
@ -116,7 +117,7 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
char pBueffel[132]; char pBueffel[132];
char *pChar; char *pChar;
CharType eWhat; CharType eWhat;
int i; int i, n;
if(!pLine)return NULL; if(!pLine)return NULL;
@ -142,10 +143,15 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
pChar++; pChar++;
while( (isEnd(*pChar) != 2) && (CheckSpecial(pChar) != eQuote)) while( (isEnd(*pChar) != 2) && (CheckSpecial(pChar) != eQuote))
{ {
if (*pChar == '\\') {
pBueffel[i] = Tcl_Backslash(pChar, &n);
pChar += n;
} else {
pBueffel[i] = *pChar; pBueffel[i] = *pChar;
i++;
pChar++; pChar++;
} }
i++;
}
pBueffel[i] = '\0'; pBueffel[i] = '\0';
pChar++; pChar++;
eWhat = eeText; eWhat = eeText;
@ -232,11 +238,8 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
eWhat = CheckSpecial(argv[i]); eWhat = CheckSpecial(argv[i]);
/* skip whitespace */ /* skip whitespace */
if(eWhat == eSpace) if(eWhat != eSpace) break;
{
continue;
} }
/* Create Token */ /* Create Token */
if(pList == NULL) if(pList == NULL)
{ {
@ -253,13 +256,6 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
/* copy text always */ /* copy text always */
pCurrent->text = strdup(argv[i]); pCurrent->text = strdup(argv[i]);
/* text */
if(eWhat == eeText)
{
pCurrent->Type = eText;
break;
}
/* numbers */ /* numbers */
if(eWhat == eNum) if(eWhat == eNum)
{ {
@ -275,8 +271,10 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
pCurrent->Type = eFloat; pCurrent->Type = eFloat;
sscanf(argv[i],"%f",&(pCurrent->fVal)); sscanf(argv[i],"%f",&(pCurrent->fVal));
} }
break;
} }
else
{ /* all else is text */
pCurrent->Type = eText;
} }
} }
return pList; return pList;
@ -401,6 +399,71 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
} }
return 1; return 1;
} }
/*--------------------------------------------------------------------------*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
int i, l, firstArgToQuote, quote;
char ch;
char *res, *arg;
l = 0;
firstArgToQuote = argc;
quote = 0;
for (i=0; i<argc; i++) {
arg = argv[i];
if (arg == NULL) return NULL;
ch = *arg++;
if (ch == '\0') quote=1;
while (ch != '\0') {
switch (ch) {
case '\\':
l += 2; quote = 1; break;
case '"':
l += 2; quote = 1; break;
case ' ':
case '\t':
case '\v':
case '\f':
case '\r':
case '\n':
l++; quote = 1; break;
default:
l++; break;
}
ch = *arg++;
}
if (quote == 0) {
firstArgToQuote = i+1;
l += 1;
} else {
l += 3;
}
}
if (l > buffersize) {
buffer = calloc(l,1);
if (buffer == NULL) return NULL;
}
res = buffer;
for (i=0; i<argc; i++) {
if (i >= firstArgToQuote) *res++ = '"';
arg = argv[i];
ch = *arg++;
while (ch != '\0') {
switch (ch) {
case '"': *res++ = '\\'; *res++ = '"'; break;
case '\\': *res++ = '\\'; *res++ = '\\'; break;
case '\r': *res++ = '\\'; *res++ = 'r'; break;
case '\n': *res++ = '\\'; *res++ = 'n'; break;
default: *res++ = ch; break;
}
ch = *arg++;
}
if (i >= firstArgToQuote) *res++ = '"';
*res++ = ' ';
}
if (res > buffer) res--; /* remove trailing space */
*res='\0';
return buffer;
}
/*============================================================================ /*============================================================================
Testprogram, can be activated by defining MAIN Testprogram, can be activated by defining MAIN

View File

@ -73,4 +73,19 @@ typedef struct _TokenEntry {
/*! /*!
isNumeric test if pText is a number isNumeric test if pText is a number
!*/ !*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize);
/*!
Arg2Tcl converts an argc, argv[] pair into a line of
text. Args are quoted if needed, in order to be interpreted as
proper tcl command. If buffer is NULL or the result longer than
buffersize, the result is allocated by Arg2Tcl.
If the results fits the buffer, buffer is returned.
If no memory is available or any element of argv is NULL, NULL is
returned.
The result has to be freed by the caller after use be something like:
if (result != NULL && result != buffer) free(result);
!*/
#endif #endif

View File

@ -135,7 +135,7 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){ int argc, char *argv[]){
pTclInt self = NULL; pTclInt self = NULL;
char pBuffer[1024]; char pBuffer[1024];
char *cmd;
self = (pTclInt)pData; self = (pTclInt)pData;
assert(self); assert(self);
@ -159,11 +159,14 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon); SCSendOK(pCon);
return 1; return 1;
} else if(strcmp(argv[1],"backup") == 0){ } else if(strcmp(argv[1],"backup") == 0){
Arg2Text(argc-2, &argv[2],pBuffer,1023); cmd = Arg2Tcl(argc-2, &argv[2],pBuffer,1023);
if (cmd) {
if(self->fd != NULL){ if(self->fd != NULL){
fprintf(self->fd,"%s\n",pBuffer); fprintf(self->fd,"%s\n",pBuffer);
} }
if (cmd != pBuffer) free(cmd);
SCSendOK(pCon); SCSendOK(pCon);
}
return 1; return 1;
} else { } else {
sprintf(pBuffer,"ERROR: keyword %s to %s not recognized", sprintf(pBuffer,"ERROR: keyword %s to %s not recognized",