- Introducted Arg2Tcl as a replacement for some calls to Arg2Text
- Fixed a memory leak
This commit is contained in:
15
conman.c
15
conman.c
@ -132,7 +132,10 @@ extern pServer pServ;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* This is a serious, very serious error! */
|
||||
@ -1721,7 +1724,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
Item sItem;
|
||||
pCBAction pCB = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
int iMacro;
|
||||
int iMacro;
|
||||
char *script;
|
||||
|
||||
self = (SConnection *)pData;
|
||||
if(!VerifyConnection(self))
|
||||
@ -1781,17 +1785,18 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
return 0;
|
||||
}
|
||||
|
||||
script = Arg2Tcl(argc-4, &argv[4], NULL, 0);
|
||||
|
||||
/* now we can install the callback */
|
||||
pCB = (pCBAction)malloc(sizeof(CBAction));
|
||||
if(!pCB)
|
||||
if(!pCB || !script)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: memory exhausted in SConnection",eError);
|
||||
return 0;
|
||||
}
|
||||
Arg2Text(argc-4, &argv[4],pBueffel,1023);
|
||||
pCB->pCon = pCon;
|
||||
pCB->pSics = pSics;
|
||||
pCB->pAction = strdup(pBueffel);
|
||||
pCB->pAction = script;
|
||||
sItem.pInterface = pInterface;
|
||||
sItem.lID = RegisterCallback(pInterface, SCGetContext(pCB->pCon), iEvent, ConCallBack,
|
||||
pCB, CBKill);
|
||||
|
4
emon.c
4
emon.c
@ -85,8 +85,7 @@
|
||||
|
||||
|
||||
/* remove all the names */
|
||||
/*
|
||||
iRet == LLDnodePtr2First(self->iList);
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDataTo(self->iList,&sEntry);
|
||||
@ -97,7 +96,6 @@
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
*/
|
||||
/* remove list */
|
||||
LLDdelete(self->iList);
|
||||
|
||||
|
@ -1214,12 +1214,11 @@ static void ErrReport(pEVControl self)
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"errorscript") == 0)
|
||||
{
|
||||
Arg2Text(argc-2,&argv[2],pBueffel,255);
|
||||
if(self->errorScript != NULL)
|
||||
{
|
||||
free(self->errorScript);
|
||||
}
|
||||
self->errorScript = strdup(pBueffel);
|
||||
self->errorScript = Arg2Tcl(argc-2,&argv[2],NULL,0);
|
||||
SCSendOK(pCon);
|
||||
SCparChange(pCon);
|
||||
return 1;
|
||||
@ -1542,8 +1541,7 @@ int RemoveEVController(SConnection *pCon, char *name) {
|
||||
return 0;
|
||||
}
|
||||
if (pNew->pDriv->SavePars) {
|
||||
Arg2Text(argc-3, argv+3, pBueffel, sizeof pBueffel);
|
||||
pNew->creationArgs = strdup(pBueffel);
|
||||
pNew->creationArgs = Arg2Tcl(argc-3, argv+3, NULL, 0);
|
||||
pNew->pDes->SaveStatus = EVSaveStatus;
|
||||
} else {
|
||||
pNew->creationArgs = NULL;
|
||||
|
67
macro.c
67
macro.c
@ -174,14 +174,14 @@
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
|
||||
if (pSics->lastUnknown[pSics->iStack]) free(pSics->lastUnknown[pSics->iStack]);
|
||||
pSics->lastUnknown[pSics->iStack] = strdup(comBuffer);
|
||||
|
||||
/* invoke */
|
||||
iMacro = SCinMacro(pCon);
|
||||
SCsetMacro(pCon,1);
|
||||
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
|
||||
SCsetMacro(pCon,iMacro);
|
||||
|
||||
/*
|
||||
lastUnkown gets deeply stacked with each SICS command exec'd.
|
||||
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[])
|
||||
{
|
||||
char pBueffel[1024];
|
||||
char *pCommand;
|
||||
pPubTcl self = NULL;
|
||||
int iRet, length;
|
||||
char *pPtr;
|
||||
@ -864,45 +865,32 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
}
|
||||
|
||||
/* make a string */
|
||||
Arg2Text(argc,argv,pBueffel,1023);
|
||||
|
||||
|
||||
iRet = Tcl_Eval(pTcl,pBueffel);
|
||||
pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
|
||||
if (!pCommand) {
|
||||
SCWrite(pCon, "ERROR: no more memory", eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = Tcl_Eval(pTcl,pCommand);
|
||||
if (pCommand != pBueffel) free(pCommand);
|
||||
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;
|
||||
}
|
||||
memset(pPtr,0,length*sizeof(char));
|
||||
strncpy(pPtr,pTcl->result,length-1);
|
||||
SCWrite(pCon,pPtr,eStatus);
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) == NULL)
|
||||
{
|
||||
pPtr = strdup(pTcl->result);
|
||||
SCWrite(pCon,pPtr,eError);
|
||||
free(pPtr);
|
||||
}
|
||||
else
|
||||
if(Tcl_GetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY) != NULL)
|
||||
{
|
||||
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 1; /* not reached */
|
||||
@ -990,16 +978,21 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
int TransactAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char pCommand[1024], pStart[1024];
|
||||
char pBuffer[1024];
|
||||
char *pCommand;
|
||||
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]);
|
||||
if(strcmp(argv[0],"fulltransact") == 0){
|
||||
snprintf(pStart,1023,"TRANSACTIONSTART %s",pCommand);
|
||||
SCWrite(pCon,pStart,eError);
|
||||
SCPrintf(pCon,eError, "TRANSACTIONSTART %s",pCommand);
|
||||
}
|
||||
iRet = InterpExecute(pSics,pCon,pCommand);
|
||||
if (pCommand != pBuffer) free(pCommand);
|
||||
SCWrite(pCon,"TRANSACTIONFINISHED",eError);
|
||||
return iRet;
|
||||
}
|
||||
|
13
protocol.c
13
protocol.c
@ -171,7 +171,8 @@ void DeleteProtocol(void *self)
|
||||
static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
commandContext comCon;
|
||||
char command[1024];
|
||||
char buffer[1024];
|
||||
char *command;
|
||||
int status;
|
||||
|
||||
if(argc < 3){
|
||||
@ -186,11 +187,15 @@ static int ContextDo(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
strncpy(comCon.deviceID,argv[2],SCDEVIDLEN);
|
||||
memset(command,0,1024*sizeof(char));
|
||||
Arg2Text(argc-2,&argv[2],command,1023);
|
||||
|
||||
memset(buffer,0,sizeof(buffer));
|
||||
command = Arg2Tcl(argc-2,&argv[2],buffer,sizeof buffer);
|
||||
if (!command) {
|
||||
SCWrite(pCon,"ERROR: no more memory",eError);
|
||||
return 0;
|
||||
}
|
||||
SCPushContext2(pCon,comCon);
|
||||
status = InterpExecute(pSics,pCon,command);
|
||||
if (command != buffer) free(command);
|
||||
SCPopContext(pCon);
|
||||
return status;
|
||||
}
|
||||
|
18
remob.c
18
remob.c
@ -534,7 +534,11 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
float fValue;
|
||||
long lID;
|
||||
char *endp;
|
||||
char *argv0;
|
||||
char *cmd;
|
||||
/*
|
||||
char acce[128], inte[128];
|
||||
*/
|
||||
int rights;
|
||||
RemChannel *rc;
|
||||
|
||||
@ -550,16 +554,19 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
if (argc == 1) {
|
||||
iRet = RemTransact(remserver, rc, pCon, argv[0], ">", NULL);
|
||||
} 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(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;
|
||||
} else {
|
||||
pos=snprintf(buf, sizeof(buf), "%s ", remob->name);
|
||||
@ -620,7 +627,6 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
float fValue;
|
||||
long lID;
|
||||
char *endp, *serverport, *thishostname;
|
||||
char acce[128], inte[128];
|
||||
struct sockaddr_in adr;
|
||||
struct hostent *thishost;
|
||||
Remob *p, *next;
|
||||
|
10
script.c
10
script.c
@ -411,6 +411,7 @@
|
||||
char pBueffel[256];
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
int iRet;
|
||||
char *cmd;
|
||||
|
||||
assert(pCon);
|
||||
assert(pSics);
|
||||
@ -425,8 +426,13 @@
|
||||
pTcl = InterpGetTcl(pSics);
|
||||
assert(pTcl);
|
||||
|
||||
Arg2Text(argc-1,&argv[1],pBueffel,255);
|
||||
iRet = Tcl_Eval(pTcl,pBueffel);
|
||||
cmd = Arg2Tcl(argc-1,&argv[1],pBueffel,sizeof 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)
|
||||
{
|
||||
SCWrite(pCon,pTcl->result,eValue);
|
||||
|
10
sicscron.c
10
sicscron.c
@ -83,8 +83,8 @@
|
||||
{
|
||||
pCron pNew = NULL;
|
||||
int iVal, iRet;
|
||||
char pBueffel[512];
|
||||
|
||||
char *cmd;
|
||||
|
||||
/* only managers may do this */
|
||||
if(!SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
@ -108,11 +108,11 @@
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
pNew = (pCron)malloc(sizeof(Cron));
|
||||
if(!pNew)
|
||||
if(!pNew || !cmd)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in sicscron",eError);
|
||||
return 0;
|
||||
@ -124,7 +124,7 @@
|
||||
return 0;
|
||||
}
|
||||
pNew->iIntervall = iVal;
|
||||
pNew->pCommand = strdup(pBueffel);
|
||||
pNew->pCommand = cmd;
|
||||
pNew->tNext = 0;
|
||||
pNew->iEnd = 1;
|
||||
|
||||
|
105
splitter.c
105
splitter.c
@ -11,6 +11,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "tcl.h"
|
||||
#include "splitter.h"
|
||||
|
||||
typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
@ -116,7 +117,7 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
char pBueffel[132];
|
||||
char *pChar;
|
||||
CharType eWhat;
|
||||
int i;
|
||||
int i, n;
|
||||
|
||||
if(!pLine)return NULL;
|
||||
|
||||
@ -142,9 +143,14 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
pChar++;
|
||||
while( (isEnd(*pChar) != 2) && (CheckSpecial(pChar) != eQuote))
|
||||
{
|
||||
pBueffel[i] = *pChar;
|
||||
if (*pChar == '\\') {
|
||||
pBueffel[i] = Tcl_Backslash(pChar, &n);
|
||||
pChar += n;
|
||||
} else {
|
||||
pBueffel[i] = *pChar;
|
||||
pChar++;
|
||||
}
|
||||
i++;
|
||||
pChar++;
|
||||
}
|
||||
pBueffel[i] = '\0';
|
||||
pChar++;
|
||||
@ -226,17 +232,14 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
/* loop through arguments */
|
||||
for( i = 0; i < argc; i++)
|
||||
{
|
||||
/* figure out what we have */
|
||||
for(ii = 0; ii < strlen(argv[i]); ii++)
|
||||
{
|
||||
eWhat = CheckSpecial(argv[i]);
|
||||
|
||||
/* skip whitespace */
|
||||
if(eWhat == eSpace)
|
||||
/* figure out what we have */
|
||||
for(ii = 0; ii < strlen(argv[i]); ii++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
eWhat = CheckSpecial(argv[i]);
|
||||
|
||||
/* skip whitespace */
|
||||
if(eWhat != eSpace) break;
|
||||
}
|
||||
/* Create Token */
|
||||
if(pList == NULL)
|
||||
{
|
||||
@ -253,13 +256,6 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
/* copy text always */
|
||||
pCurrent->text = strdup(argv[i]);
|
||||
|
||||
/* text */
|
||||
if(eWhat == eeText)
|
||||
{
|
||||
pCurrent->Type = eText;
|
||||
break;
|
||||
}
|
||||
|
||||
/* numbers */
|
||||
if(eWhat == eNum)
|
||||
{
|
||||
@ -275,9 +271,11 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
pCurrent->Type = eFloat;
|
||||
sscanf(argv[i],"%f",&(pCurrent->fVal));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* all else is text */
|
||||
pCurrent->Type = eText;
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
}
|
||||
@ -401,6 +399,71 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
|
||||
}
|
||||
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
|
||||
|
15
splitter.h
15
splitter.h
@ -73,4 +73,19 @@ typedef struct _TokenEntry {
|
||||
/*!
|
||||
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
|
||||
|
13
tclintimpl.c
13
tclintimpl.c
@ -135,7 +135,7 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pTclInt self = NULL;
|
||||
char pBuffer[1024];
|
||||
|
||||
char *cmd;
|
||||
|
||||
self = (pTclInt)pData;
|
||||
assert(self);
|
||||
@ -159,11 +159,14 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"backup") == 0){
|
||||
Arg2Text(argc-2, &argv[2],pBuffer,1023);
|
||||
if(self->fd != NULL){
|
||||
fprintf(self->fd,"%s\n",pBuffer);
|
||||
cmd = Arg2Tcl(argc-2, &argv[2],pBuffer,1023);
|
||||
if (cmd) {
|
||||
if(self->fd != NULL){
|
||||
fprintf(self->fd,"%s\n",pBuffer);
|
||||
}
|
||||
if (cmd != pBuffer) free(cmd);
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
sprintf(pBuffer,"ERROR: keyword %s to %s not recognized",
|
||||
|
Reference in New Issue
Block a user