- 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
1325 lines
36 KiB
C
1325 lines
36 KiB
C
/**
|
|
* Implementation file for the exe buffer buffer manager.
|
|
*
|
|
* copyright: see file COPYRIGHT
|
|
*
|
|
* More information in exe.tex
|
|
*
|
|
* Mark Koennecke, November 2004
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <tcl.h>
|
|
#include <dirent.h>
|
|
#include <ctype.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "sdynar.h"
|
|
#include "dynstring.h"
|
|
#include "lld.h"
|
|
#include "splitter.h"
|
|
#include "exebuf.h"
|
|
#include "exeman.i"
|
|
#include "exeman.h"
|
|
#include "sicshipadaba.h"
|
|
#include "commandlog.h"
|
|
#include "protocol.h"
|
|
/*-------------------------------------------------------------------*/
|
|
static void KillExeMan(void *data){
|
|
pExeMan self = (pExeMan)data;
|
|
if(!self){
|
|
return;
|
|
}
|
|
if(self->pDes){
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
if(self->pCall){
|
|
DeleteCallBackInterface(self->pCall);
|
|
}
|
|
if(self->batchPath){
|
|
free(self->batchPath);
|
|
}
|
|
if(self->sysPath){
|
|
free(self->sysPath);
|
|
}
|
|
if(self->exeStack){
|
|
DeleteDynar(self->exeStack);
|
|
}
|
|
LLDdelete(self->runList);
|
|
free(self);
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static int SaveExeMan(void *data, char *name, FILE *fd){
|
|
pExeMan self = (pExeMan)data;
|
|
|
|
if(!self){
|
|
return 0;
|
|
}
|
|
fprintf(fd,"%s batchpath %s\n",name,self->batchPath);
|
|
fprintf(fd,"%s syspath %s\n",name,self->sysPath);
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static void *ExeManInterface(void *data, int interfaceID){
|
|
pExeMan self = (pExeMan)data;
|
|
|
|
if(self == NULL){
|
|
return NULL;
|
|
}
|
|
if(interfaceID == CALLBACKINTERFACE){
|
|
return self->pCall;
|
|
}
|
|
return NULL;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
int MakeExeManager(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pExeMan pNew = NULL;
|
|
int status;
|
|
|
|
pNew = (pExeMan)malloc(sizeof(ExeMan));
|
|
if(!pNew){
|
|
SCWrite(pCon,"ERROR: out of memory creating exe Manager",eError);
|
|
return 0;
|
|
}
|
|
|
|
memset(pNew,0,sizeof(ExeMan));
|
|
pNew->pDes = CreateDescriptor("ExeManager");
|
|
pNew->pCall = CreateCallBackInterface();
|
|
pNew->sysPath = strdup("./");
|
|
pNew->batchPath = strdup("./");
|
|
pNew->exeStack = CreateDynar(1,10,10,exeBufKill);
|
|
pNew->exeStackPtr = -1;
|
|
pNew->runList = LLDcreate(sizeof(pExeBuf));
|
|
if(!pNew->pDes || !pNew->pCall || ! pNew->batchPath ||
|
|
!pNew->exeStack || pNew->runList < 0){
|
|
SCWrite(pCon,"ERROR: out of memory creating exe Manager",eError);
|
|
return 0;
|
|
}
|
|
pNew->pDes->SaveStatus = SaveExeMan;
|
|
pNew->pDes->GetInterface = ExeManInterface;
|
|
|
|
if(argc > 1){
|
|
status = AddCommand(pSics,
|
|
argv[1],
|
|
ExeManagerWrapper,
|
|
KillExeMan,
|
|
pNew);
|
|
} else {
|
|
status = AddCommand(pSics,
|
|
"exe",
|
|
ExeManagerWrapper,
|
|
KillExeMan,
|
|
pNew);
|
|
}
|
|
if(status != 1) {
|
|
SCWrite(pCon,"ERROR: duplicate exe manager not created",eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*======================== buffer execution ==========================*/
|
|
static int fileExists(char *path){
|
|
FILE *fd = NULL;
|
|
int status = 0;
|
|
|
|
fd = fopen(path,"r");
|
|
if(fd != NULL){
|
|
fclose(fd);
|
|
status = 1;
|
|
}
|
|
return status;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
extern char *stptok(char *s, char *t, int len, char *brk);
|
|
|
|
static pDynString locateBatchBuffer(pExeMan self, char *name){
|
|
pDynString result = NULL;
|
|
char pPath[132], *pPtr = NULL;
|
|
|
|
result = CreateDynString(256,256);
|
|
if(!result){
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
do not try to convert absolute paths
|
|
*/
|
|
if(name[0] == '/'){
|
|
DynStringCopy(result,name);
|
|
if(fileExists(GetCharArray(result))){
|
|
return result;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
pPtr = self->batchPath;
|
|
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
|
|
DynStringCopy(result,pPath);
|
|
DynStringConcatChar(result,'/');
|
|
DynStringConcat(result,name);
|
|
if(fileExists(GetCharArray(result))){
|
|
return result;
|
|
}
|
|
}
|
|
|
|
pPtr = self->sysPath;
|
|
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
|
|
DynStringCopy(result,pPath);
|
|
DynStringConcatChar(result,'/');
|
|
DynStringConcat(result,name);
|
|
if(fileExists(GetCharArray(result))){
|
|
return result;
|
|
}
|
|
}
|
|
DeleteDynString(result);
|
|
return NULL;
|
|
}
|
|
/*-------------------------------------------------------------------
|
|
* Generate a full path name for the argument in the first
|
|
* directory of batch path
|
|
* -------------------------------------------------------------------*/
|
|
static int makeExePath(pExeMan self, SConnection *pCon, int argc, char *argv[]){
|
|
char buffer[512], *pPtr = NULL, pPath[132];
|
|
|
|
if(argc < 3) {
|
|
SCWrite(pCon,"ERROR: require a file name for makepath",eError);
|
|
return 0;
|
|
}
|
|
strcpy(buffer,"exe.makepath = ");
|
|
/*
|
|
* do nothing to absolute path
|
|
*/
|
|
if(argv[2][0] == '/'){
|
|
strncat(buffer,argv[2],511-strlen(buffer));
|
|
SCWrite(pCon,buffer,eValue);
|
|
return 1;
|
|
}
|
|
pPtr = self->batchPath;
|
|
pPtr = stptok(pPtr,pPath,131,":");
|
|
strncat(buffer,pPath,511-strlen(buffer));
|
|
strncat(buffer,"/",511-strlen(buffer));
|
|
strncat(buffer,argv[2],511-strlen(buffer));
|
|
SCWrite(pCon,buffer,eValue);
|
|
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
pDynString findBatchFile(SicsInterp *pSics, char *name){
|
|
pExeMan self = (pExeMan)FindCommandData(pSics,"exe","ExeManager");
|
|
if(self == NULL){
|
|
return NULL;
|
|
}
|
|
return locateBatchBuffer(self,name);
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int runBatchBuffer(pExeMan self, SConnection *pCon,
|
|
SicsInterp *pSics, char *name){
|
|
pDynString filePath = NULL;
|
|
char pBueffel[256];
|
|
pExeBuf buffer = NULL;
|
|
int status;
|
|
|
|
if(!SCMatchRights(pCon,usUser)) {
|
|
return 0;
|
|
}
|
|
filePath = locateBatchBuffer(self,name);
|
|
if(filePath == NULL){
|
|
snprintf(pBueffel,255,"ERROR: batch buffer %s not found in path",
|
|
name);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
buffer = exeBufCreate(name);
|
|
if(!buffer){
|
|
DeleteDynString(filePath);
|
|
SCWrite(pCon,"ERROR: out of memory creating batch buffer",eError);
|
|
return 0;
|
|
}
|
|
status = exeBufLoad(buffer,GetCharArray(filePath));
|
|
if(!status){
|
|
DeleteDynString(filePath);
|
|
SCWrite(pCon,"ERROR: failed to load batch buffer",eError);
|
|
return 0;
|
|
}
|
|
DeleteDynString(filePath);
|
|
|
|
self->exeStackPtr++;
|
|
DynarPut(self->exeStack,self->exeStackPtr,buffer);
|
|
status = exeBufProcess(buffer,pSics,pCon,self->pCall,self->echo);
|
|
self->exeStackPtr--;
|
|
return status;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static char bufferNode[512];
|
|
|
|
static int SCHdbWrite(SConnection *self, char *message, int outCode){
|
|
pHdb node = NULL;
|
|
char pBueffel[512];
|
|
commandContext cc;
|
|
hdbValue v;
|
|
pDynString val = NULL;
|
|
writeFunc defWrite = NULL;
|
|
|
|
|
|
cc = SCGetContext(self);
|
|
node = GetHipadabaNode(GetHipadabaRoot(),cc.deviceID);
|
|
if(node == NULL || strstr(cc.deviceID,bufferNode) == NULL){
|
|
/*
|
|
* this means the deviceId is wrong and the output is for another
|
|
* operation.
|
|
*/
|
|
defWrite = GetProtocolWriteFunc(self);
|
|
if(defWrite == NULL){
|
|
defWrite = SCNormalWrite;
|
|
}
|
|
defWrite(self,message,outCode);
|
|
return 1;
|
|
}
|
|
|
|
SCFileWrite(self,message,outCode);
|
|
|
|
if(SCinMacro(self) && (outCode != eError && outCode != eWarning) ){
|
|
return 1;
|
|
}
|
|
|
|
v = MakeHdbText(strdup(""));
|
|
GetHipadabaPar(node,&v,NULL);
|
|
v.dataType = HIPTEXT;
|
|
val = CreateDynString(128,128);
|
|
if(val == NULL){
|
|
WriteToCommandLog("INTERNAL ERROR>>",
|
|
"No memory to append to log in SCHdbWrite");
|
|
return 0;
|
|
}
|
|
if(v.v.text != NULL){
|
|
DynStringConcat(val,v.v.text);
|
|
if(strrchr(v.v.text,(int)'\n') == NULL && strlen(v.v.text) > 1){
|
|
DynStringConcatChar(val,'\n');
|
|
}
|
|
}
|
|
DynStringConcat(val,message);
|
|
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 1){
|
|
DynStringConcatChar(val,'\n');
|
|
}
|
|
if(v.v.text != NULL){
|
|
free(v.v.text);
|
|
}
|
|
v.v.text = GetCharArray(val);
|
|
UpdateHipadabaPar(node,v,NULL);
|
|
DeleteDynString(val);
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
int exeHdbNode(pHdb exeNode, SConnection *pCon){
|
|
char pBueffel[512], *name = NULL;
|
|
pHdb node = NULL, log = NULL;
|
|
pExeBuf buffer = NULL;
|
|
hdbValue v;
|
|
int status;
|
|
commandContext cc;
|
|
writeFunc oldWrite;
|
|
|
|
/*
|
|
* clear log buffer
|
|
*/
|
|
log = GetHipadabaNode(exeNode,"log");
|
|
if(log == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
|
return 0;
|
|
}
|
|
v = MakeHdbText(strdup(""));
|
|
UpdateHipadabaPar(log,v,pCon);
|
|
/*
|
|
* prepare context
|
|
*/
|
|
name = GetHipadabaPath(log);
|
|
cc = SCGetContext(pCon);
|
|
strncpy(cc.deviceID, name,255);
|
|
strncpy(bufferNode,name,511);
|
|
|
|
/*
|
|
* load commands into buffer
|
|
*/
|
|
node = GetHipadabaNode(exeNode,"commands");
|
|
if(node == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
|
return 0;
|
|
}
|
|
|
|
GetHipadabaPar(node,&v,pCon);
|
|
if(v.dataType != HIPTEXT || v.v.text == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node is of wrong type or contains no data",eError);
|
|
return 0;
|
|
|
|
}
|
|
|
|
buffer = exeBufCreate(name);
|
|
if(!buffer){
|
|
SCWrite(pCon,"ERROR: out of memory creating batch buffer",eError);
|
|
return 0;
|
|
}
|
|
exeBufAppend(buffer,v.v.text);
|
|
|
|
strncpy(bufferNode,name,511);
|
|
oldWrite = SCGetWriteFunc(pCon);
|
|
SCSetWriteFunc(pCon,SCHdbWrite);
|
|
SCPushContext2(pCon,cc);
|
|
status = exeBufProcess(buffer,pServ->pSics,pCon,NULL,0);
|
|
SCSetWriteFunc(pCon,oldWrite);
|
|
SCPopContext(pCon);
|
|
exeBufDelete(buffer);
|
|
free(name);
|
|
if(strlen(log->value.v.text) < 2){
|
|
v = MakeHdbText(strdup("OK\n"));
|
|
UpdateHipadabaPar(log,v,pCon);
|
|
ReleaseHdbValue(&v);
|
|
}
|
|
return status;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int runHdbBuffer(pExeMan self, SConnection *pCon,
|
|
SicsInterp *pSics, char *name){
|
|
char pBueffel[512];
|
|
pExeBuf buffer = NULL;
|
|
pHdb node = NULL;
|
|
hdbValue v;
|
|
int status;
|
|
commandContext cc;
|
|
writeFunc oldWrite;
|
|
|
|
if(!SCMatchRights(pCon,usUser)) {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* clear log buffer
|
|
*/
|
|
snprintf(pBueffel,511,"%s/log",name);
|
|
node = GetHipadabaNode(GetHipadabaRoot(),pBueffel);
|
|
if(node == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
|
return 0;
|
|
}
|
|
v = MakeHdbText(strdup(""));
|
|
UpdateHipadabaPar(node,v,pCon);
|
|
/*
|
|
* prepare context
|
|
*/
|
|
cc = SCGetContext(pCon);
|
|
strcpy(cc.deviceID, pBueffel);
|
|
|
|
/*
|
|
* load commands into buffer
|
|
*/
|
|
snprintf(pBueffel,511,"%s/commands",name);
|
|
node = GetHipadabaNode(GetHipadabaRoot(),pBueffel);
|
|
if(node == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
|
return 0;
|
|
}
|
|
|
|
GetHipadabaPar(node,&v,pCon);
|
|
if(v.dataType != HIPTEXT || v.v.text == NULL){
|
|
SCWrite(pCon,"ERROR: Hdb node is of wrong type or contains no data",eError);
|
|
return 0;
|
|
|
|
}
|
|
|
|
buffer = exeBufCreate(name);
|
|
if(!buffer){
|
|
SCWrite(pCon,"ERROR: out of memory creating batch buffer",eError);
|
|
return 0;
|
|
}
|
|
exeBufAppend(buffer,v.v.text);
|
|
|
|
strncpy(bufferNode,name,511);
|
|
oldWrite = SCGetWriteFunc(pCon);
|
|
SCSetWriteFunc(pCon,SCHdbWrite);
|
|
SCPushContext2(pCon,cc);
|
|
self->exeStackPtr++;
|
|
DynarPut(self->exeStack,self->exeStackPtr,buffer);
|
|
status = exeBufProcess(buffer,pSics,pCon,self->pCall,self->echo);
|
|
self->exeStackPtr--;
|
|
SCSetWriteFunc(pCon,oldWrite);
|
|
SCPopContext(pCon);
|
|
return status;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
int exeHdbBuffer(SConnection *pCon,
|
|
SicsInterp *pSics, char *name){
|
|
pExeMan self = (pExeMan)FindCommandData(pSics,"exe","ExeManager");
|
|
if(self != NULL){
|
|
return runHdbBuffer(self,pCon,pSics,name);
|
|
}
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
int runExeBatchBuffer(void *pData, SConnection *pCon,
|
|
SicsInterp *pSics, char *name){
|
|
int status, oldEcho;
|
|
pExeMan self = (pExeMan)pData;
|
|
oldEcho = self->echo;
|
|
self->echo = 1;
|
|
status = runBatchBuffer(self,pCon,pSics,name);
|
|
self->echo = oldEcho;
|
|
return status;
|
|
}
|
|
/*========================== path management ========================*/
|
|
static int handleBatchPath(pExeMan self, SConnection *pCon, int argc,
|
|
char *argv[]){
|
|
char pBuffer[1024];
|
|
|
|
if(strcmp(argv[1],"batchpath") == 0) {
|
|
if(argc > 2) {
|
|
if(!SCMatchRights(pCon,usUser)){
|
|
return 0;
|
|
}
|
|
if(self->batchPath != NULL){
|
|
free(self->batchPath);
|
|
}
|
|
self->batchPath = strdup(argv[2]);
|
|
SCSendOK(pCon);
|
|
SCparChange(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBuffer,1023,"%s.batchpath = %s", argv[0],self->batchPath);
|
|
SCWrite(pCon,pBuffer,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
if(strcmp(argv[1],"syspath") == 0) {
|
|
if(argc > 2) {
|
|
if(!SCMatchRights(pCon,usMugger)){
|
|
return 0;
|
|
}
|
|
if(self->sysPath != NULL){
|
|
free(self->sysPath);
|
|
}
|
|
self->sysPath = strdup(argv[2]);
|
|
SCSendOK(pCon);
|
|
SCparChange(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBuffer,1023,"%s.syspath = %s", argv[0],self->sysPath);
|
|
SCWrite(pCon,pBuffer,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
/*=========================== callbacks ==============================*/
|
|
typedef struct {
|
|
SConnection *pCon;
|
|
pExeMan exe;
|
|
}exeInfo, *pExeInfo;
|
|
/*------------------------------------------------------------------*/
|
|
static void killExeInfo(void *pData){
|
|
pExeInfo self = (pExeInfo)pData;
|
|
if(self != NULL){
|
|
free(self);
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static pExeInfo makeExeInfo(SConnection *pCon, pExeMan self){
|
|
pExeInfo pNew = NULL;
|
|
pNew = malloc(sizeof(exeInfo));
|
|
if(pNew == NULL){
|
|
SCWrite(pCon,
|
|
"ERROR: failed to allocate info structure for registering callbacks",
|
|
eError);
|
|
return NULL;
|
|
}
|
|
pNew->pCon = pCon;
|
|
pNew->exe = self;
|
|
return pNew;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static int BufferCallback(int iEvent, void *pEvent, void *pUser,
|
|
commandContext cc){
|
|
pExeInfo self = (pExeInfo)pUser;
|
|
char *name = (char *)pEvent;
|
|
char pBueffel[132];
|
|
|
|
if(iEvent == BATCHSTART){
|
|
snprintf(pBueffel,131,"BATCHSTART=%s",name);
|
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
|
return 1;
|
|
}
|
|
if(iEvent == BATCHEND){
|
|
snprintf(pBueffel,131,"BATCHEND=%s",name);
|
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static int LineCallBack(int iEvent, void *pEvent, void *pUser,
|
|
commandContext cc){
|
|
pExeInfo self = (pExeInfo)pUser;
|
|
char pBueffel[256];
|
|
int start, end, lineno;
|
|
void *pPtr = NULL;
|
|
pExeBuf buf = NULL;
|
|
|
|
assert(self);
|
|
if(iEvent == BATCHAREA){
|
|
DynarGet(self->exe->exeStack,self->exe->exeStackPtr,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
assert(buf);
|
|
exeBufRange(buf,&start,&end,&lineno);
|
|
snprintf(pBueffel,255,"%s.range = %d = %d",exeBufName(buf),
|
|
start,end);
|
|
SCWriteInContext(self->pCon,pBueffel,eWarning,cc);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
|
|
pExeMan self){
|
|
pExeInfo info = NULL;
|
|
long lID;
|
|
|
|
info = makeExeInfo(pCon,self);
|
|
if(info == NULL){
|
|
return;
|
|
}
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHSTART, BufferCallback,
|
|
info, killExeInfo);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHEND, BufferCallback,
|
|
info, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),BATCHAREA, LineCallBack,
|
|
info, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static void unregisterCallbacks(SConnection *pCon, pExeMan self){
|
|
long lID;
|
|
int i;
|
|
|
|
for(i = 0; i < 3; i++){
|
|
lID = SCgetCallbackID(pCon,self->pCall);
|
|
if(lID >= 0){
|
|
RemoveCallback(self->pCall,lID);
|
|
SCUnregisterID(pCon,lID);
|
|
}
|
|
}
|
|
}
|
|
/*========================= uploading ===============================*/
|
|
static int startUpload(pExeMan self, SConnection *pCon){
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to upload buffers",eError);
|
|
return 0;
|
|
}
|
|
if(self->uploadBuffer != NULL){
|
|
SCWrite(pCon,"ERRO: another upload is still in progress",eError);
|
|
return 0;
|
|
}
|
|
self->uploadBuffer = exeBufCreate("upload");
|
|
if(self->uploadBuffer == NULL){
|
|
SCWrite(pCon,"ERROR: failed to create upload buffer",eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static int clearUpload(pExeMan self, SConnection *pCon){
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to clear buffer upload",eError);
|
|
return 0;
|
|
}
|
|
if(self->uploadBuffer != NULL){
|
|
exeBufDelete(self->uploadBuffer);
|
|
self->uploadBuffer = NULL;
|
|
}
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
static int appendLine(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
char pLine[1024];
|
|
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to upload buffers",eError);
|
|
return 0;
|
|
}
|
|
if(self->uploadBuffer == NULL){
|
|
SCWrite(pCon,"ERROR: no upload in operation",eError);
|
|
return 0;
|
|
}
|
|
Arg2Text(argc-2,&argv[2],pLine,1023);
|
|
exeBufAppend(self->uploadBuffer,pLine);
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int uploadForceSave(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
int status;
|
|
char pPath[256], *pPtr;
|
|
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to save buffers",eError);
|
|
return 0;
|
|
}
|
|
if(argc < 3) {
|
|
SCWrite(pCon,"ERROR: no file given to save upload buffer to",eError);
|
|
return 0;
|
|
}
|
|
if(self->uploadBuffer == NULL){
|
|
SCWrite(pCon,"ERROR: no upload buffer to save exists",eError);
|
|
return 0;
|
|
}
|
|
if(argv[2][0] != '/') {
|
|
pPtr = self->batchPath;
|
|
pPtr = stptok(pPtr,pPath,131,":");
|
|
if(strlen(pPath) + 1 + strlen(argv[2]) <= 256){
|
|
strcat(pPath,"/");
|
|
strcat(pPath,argv[2]);
|
|
} else {
|
|
strncpy(pPath,argv[2],255);
|
|
}
|
|
} else {
|
|
strncpy(pPath,argv[2],131);
|
|
}
|
|
|
|
status = exeBufSave(self->uploadBuffer,pPath);
|
|
if(status == 0){
|
|
SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError);
|
|
}
|
|
exeBufDelete(self->uploadBuffer);
|
|
self->uploadBuffer = NULL;
|
|
return status;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int uploadSave(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
int status;
|
|
char pPath[256], *pPtr;
|
|
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to save buffers",eError);
|
|
return 0;
|
|
}
|
|
if(argc < 3) {
|
|
SCWrite(pCon,"ERROR: no file given to save upload buffer to",eError);
|
|
return 0;
|
|
}
|
|
if(self->uploadBuffer == NULL){
|
|
SCWrite(pCon,"ERROR: no upload buffer to save exists",eError);
|
|
return 0;
|
|
}
|
|
if(argv[2][0] != '/') {
|
|
pPtr = self->batchPath;
|
|
pPtr = stptok(pPtr,pPath,131,":");
|
|
if(strlen(pPath) + 1 + strlen(argv[2]) <= 256){
|
|
strcat(pPath,"/");
|
|
strcat(pPath,argv[2]);
|
|
} else {
|
|
strncpy(pPath,argv[2],255);
|
|
}
|
|
} else {
|
|
strncpy(pPath,argv[2],131);
|
|
}
|
|
if(fileExists(pPath)) {
|
|
SCWrite(pCon,"ERROR: file exists",eError);
|
|
return 0;
|
|
}
|
|
|
|
status = exeBufSave(self->uploadBuffer,pPath);
|
|
if(status == 0){
|
|
SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError);
|
|
}
|
|
exeBufDelete(self->uploadBuffer);
|
|
self->uploadBuffer = NULL;
|
|
return status;
|
|
}
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* See if a string matches a wildcard specification that uses * or ?
|
|
(like "*.txt"), and return TRUE or FALSE, depending on the result.
|
|
There's also a TRUE/FALSE parameter you use to indicate whether
|
|
the match should be case-sensitive or not.
|
|
*/
|
|
#ifndef TRUE
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#endif
|
|
/*--------------------------------------------------------------------------------*/
|
|
static int IsWildcardMatch (char *wildcardString, char *stringToCheck, int caseSensitive)
|
|
{
|
|
char wcChar;
|
|
char strChar;
|
|
// use the starMatchesZero variable to determine whether an asterisk
|
|
// matches zero or more characters (TRUE) or one or more characters
|
|
// (FALSE)
|
|
int starMatchesZero = TRUE;
|
|
|
|
|
|
while ((strChar = *stringToCheck) && (wcChar = *wildcardString))
|
|
{
|
|
// we only want to advance the pointers if we successfully assigned
|
|
// both of our char variables, so we'll do it here rather than in the
|
|
// loop condition itself
|
|
*stringToCheck++;
|
|
*wildcardString++;
|
|
|
|
// if this isn't a case-sensitive match, make both chars uppercase
|
|
// (thanks to David John Fielder (Konan) at http://innuendo.ev.ca
|
|
// for pointing out an error here in the original code)
|
|
if (!caseSensitive)
|
|
{
|
|
wcChar = toupper(wcChar);
|
|
strChar = toupper(strChar);
|
|
}
|
|
|
|
// check the wcChar against our wildcard list
|
|
switch (wcChar)
|
|
{
|
|
// an asterisk matches zero or more characters
|
|
case '*' :
|
|
// do a recursive call against the rest of the string,
|
|
// until we've either found a match or the string has
|
|
// ended
|
|
if (starMatchesZero)
|
|
*stringToCheck--;
|
|
|
|
while (*stringToCheck)
|
|
{
|
|
if (IsWildcardMatch(wildcardString, stringToCheck++, caseSensitive))
|
|
return TRUE;
|
|
}
|
|
|
|
break;
|
|
|
|
// a question mark matches any single character
|
|
case '?' :
|
|
break;
|
|
|
|
// if we fell through, we want an exact match
|
|
default :
|
|
if (wcChar != strChar)
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// if we have any asterisks left at the end of the wildcard string, we can
|
|
// advance past them if starMatchesZero is TRUE (so "blah*" will match "blah")
|
|
while ((*wildcardString) && (starMatchesZero))
|
|
{
|
|
if (*wildcardString == '*')
|
|
wildcardString++;
|
|
else
|
|
break;
|
|
}
|
|
|
|
// if we got to the end but there's still stuff left in either of our strings,
|
|
// return false; otherwise, we have a match
|
|
if ((*stringToCheck) || (*wildcardString))
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
|
|
}
|
|
/*----------------------------------------------------------------------------*/
|
|
static int wwmatch(char *pattern, char *name){
|
|
return IsWildcardMatch(pattern,name,1);
|
|
}
|
|
/*--------------------------------------------------------------------
|
|
search the directory pPath for file matching pattern. Successfull
|
|
files will be appended to result
|
|
-----------------------------------------------------------------------*/
|
|
static void searchDir(char *pPath, char *pattern, pDynString result){
|
|
DIR *currentdir = NULL;
|
|
struct dirent *currentFile = NULL;
|
|
|
|
currentdir = opendir(pPath);
|
|
if(currentdir == NULL){
|
|
return;
|
|
}
|
|
currentFile = readdir(currentdir);
|
|
while(currentFile != NULL){
|
|
if(wwmatch(pattern, currentFile->d_name)){
|
|
DynStringConcat(result,currentFile->d_name);
|
|
DynStringConcatChar(result,'\n');
|
|
}
|
|
currentFile = readdir(currentdir);
|
|
}
|
|
closedir(currentdir);
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static pDynString findDirEntries(pExeMan self, char *pattern){
|
|
pDynString result = NULL;
|
|
char pPath[132], *pPtr = NULL;
|
|
|
|
result = CreateDynString(256,256);
|
|
if(!result){
|
|
return NULL;
|
|
}
|
|
|
|
pPtr = self->batchPath;
|
|
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
|
|
searchDir(pPath,pattern,result);
|
|
}
|
|
|
|
pPtr = self->sysPath;
|
|
while((pPtr = stptok(pPtr,pPath,131,":")) != NULL){
|
|
searchDir(pPath,pattern,result);
|
|
}
|
|
return result;
|
|
}
|
|
/*=========================== info ===================================*/
|
|
static void printExeStack(pExeMan self, SConnection *pCon){
|
|
int i, j;
|
|
pDynString txt = NULL;
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
|
|
txt = CreateDynString(80,80);
|
|
if(txt == NULL){
|
|
SCWrite(pCon,"ERROR: failed to allocate memory in printExeStack",eError);
|
|
return;
|
|
}
|
|
for(i = 0; i <= self->exeStackPtr; i++){
|
|
DynarGet(self->exeStack,i,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
assert(buf);
|
|
for(j = 0; j < i; j++){
|
|
DynStringConcat(txt," ");
|
|
}
|
|
DynStringConcat(txt,exeBufName(buf));
|
|
DynStringConcatChar(txt,'\n');
|
|
}
|
|
SCWrite(pCon,GetCharArray(txt),eValue);
|
|
DeleteDynString(txt);
|
|
}
|
|
/*-----------------------------------------------------------------*/
|
|
static int locateBuffer(pExeMan self, char *name){
|
|
int i;
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
|
|
for(i = 0; i <= self->exeStackPtr; i++){
|
|
DynarGet(self->exeStack,i,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
if(strcmp(name,exeBufName(buf)) == 0) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static void printExeRange(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
int start, end, lineno, bufNo;
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
char pBueffel[256];
|
|
|
|
if(argc > 3) {
|
|
bufNo = locateBuffer(self,argv[3]);
|
|
} else {
|
|
bufNo = self->exeStackPtr;
|
|
}
|
|
if(bufNo < 0){
|
|
SCWrite(pCon,"ERROR: named buffer not found",eError);
|
|
return;
|
|
}
|
|
DynarGet(self->exeStack,bufNo,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
assert(buf);
|
|
exeBufRange(buf,&start,&end,&lineno);
|
|
snprintf(pBueffel,255,"%s.range = %d = %d = %d",exeBufName(buf),
|
|
start,end,lineno);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static void printExeText(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
int start, end, lineno, bufNo;
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
pDynString txt;
|
|
|
|
if(argc > 3) {
|
|
bufNo = locateBuffer(self,argv[3]);
|
|
} else {
|
|
bufNo = self->exeStackPtr;
|
|
}
|
|
if(bufNo < 0){
|
|
SCWrite(pCon,"ERROR: named buffer not found",eError);
|
|
return;
|
|
}
|
|
DynarGet(self->exeStack,bufNo,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
assert(buf);
|
|
exeBufRange(buf,&start,&end,&lineno);
|
|
txt = exeBufText(buf,start,end);
|
|
if(txt != NULL){
|
|
SCWrite(pCon,GetCharArray(txt),eValue);
|
|
DeleteDynString(txt);
|
|
} else {
|
|
SCWrite(pCon,"ERROR: failed to allocate text buffer for operation",eError);
|
|
}
|
|
}
|
|
/*------------------------------------------------------------------*/
|
|
static void printQueue(pExeMan self, SConnection *pCon){
|
|
pExeBuf buf= NULL;
|
|
pDynString text = NULL;
|
|
int status;
|
|
|
|
text = CreateDynString(80,80);
|
|
if(text == NULL){
|
|
SCWrite(pCon,"ERROR: out of memory",eError);
|
|
return;
|
|
}
|
|
|
|
status = LLDnodePtr2First(self->runList);
|
|
while(status != 0) {
|
|
LLDnodeDataTo(self->runList,&buf);
|
|
if(buf != NULL){
|
|
DynStringConcat(text,exeBufName(buf));
|
|
DynStringConcatChar(text,'\n');
|
|
}
|
|
status = LLDnodePtr2Next(self->runList);
|
|
}
|
|
SCWrite(pCon,GetCharArray(text),eValue);
|
|
DeleteDynString(text);
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
static int infoHandler(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
char pBueffel[256];
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
|
|
if(self->exeStackPtr < 0){
|
|
SCWrite(pCon,"Idle",eValue);
|
|
return 1;
|
|
}
|
|
|
|
if(argc < 3){
|
|
if(self->exeStackPtr >= 0){
|
|
DynarGet(self->exeStack,self->exeStackPtr,&pPtr);
|
|
buf = (pExeBuf)pPtr;
|
|
if(buf != NULL){
|
|
snprintf(pBueffel,255,"Executing %s",exeBufName(buf));
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
SCWrite(pCon,"Nothing to execute",eValue);
|
|
return 1;
|
|
} else {
|
|
strtolower(argv[2]);
|
|
if(strcmp(argv[2],"stack") == 0){
|
|
printExeStack(self,pCon);
|
|
return 1;
|
|
} else if(strcmp(argv[2],"range") == 0){
|
|
printExeRange(self,pCon,argc,argv);
|
|
return 1;
|
|
} else if(strcmp(argv[2],"text") == 0){
|
|
printExeText(self,pCon,argc,argv);
|
|
return 1;
|
|
} else {
|
|
SCWrite(pCon,"ERROR: subcommand to info unknown",eError);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
/*=========================== print ==================================*/
|
|
static int printBuffer(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
pDynString filePath = NULL;
|
|
char pLine[512];
|
|
pExeBuf buf;
|
|
void *pPtr = NULL;
|
|
FILE *fd = NULL;
|
|
|
|
if(argc < 3){
|
|
if(self->exeStackPtr >= 0) {
|
|
DynarGet(self->exeStack,self->exeStackPtr,&pPtr);
|
|
buf = (pExeBuf) pPtr;
|
|
if(buf != NULL){
|
|
filePath = locateBatchBuffer(self,exeBufName(buf));
|
|
}
|
|
} else {
|
|
SCWrite(pCon,"ERROR: no default buffer to print, argument required",eError);
|
|
return 0;
|
|
}
|
|
} else {
|
|
filePath = locateBatchBuffer(self,argv[2]);
|
|
}
|
|
if(filePath == NULL){
|
|
snprintf(pLine,255,"ERROR: batch buffer %s not found in path",
|
|
argv[2]);
|
|
SCWrite(pCon,pLine,eError);
|
|
return 0;
|
|
}
|
|
|
|
fd = fopen(GetCharArray(filePath),"r");
|
|
if(fd == NULL){
|
|
SCWrite(pCon,"ERROR: failed to open file for printing",eError);
|
|
DeleteDynString(filePath);
|
|
return 0;
|
|
}
|
|
DeleteDynString(filePath);
|
|
SCStartBuffering(pCon);
|
|
while(fgets(pLine,511,fd) != NULL){
|
|
SCWrite(pCon,pLine,eValue);
|
|
}
|
|
fclose(fd);
|
|
filePath = SCEndBuffering(pCon);
|
|
SCWrite(pCon,GetCharArray(filePath),eValue);
|
|
return 1;
|
|
}
|
|
/*========================== run stack ===============================*/
|
|
static int enqueueBuffer(pExeMan self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
pExeBuf buf = NULL;
|
|
int status;
|
|
pDynString filePath = NULL;
|
|
|
|
if(SCGetRights(pCon) > usUser){
|
|
SCWrite(pCon,"ERROR: no permission to enque buffers",eError);
|
|
return 0;
|
|
}
|
|
if(argc < 3) {
|
|
SCWrite(pCon,"ERROR: no buffer file given to enqueue ",eError);
|
|
return 0;
|
|
}
|
|
|
|
filePath = locateBatchBuffer(self,argv[2]);
|
|
if(filePath == NULL){
|
|
SCWrite(pCon,"ERROR: failed to locate buffer to enqueue",eError);
|
|
return 0;
|
|
}
|
|
|
|
buf = exeBufCreate("enqueue");
|
|
if(buf == NULL){
|
|
SCWrite(pCon,"ERROR: out of memory",eError);
|
|
return 0;
|
|
}
|
|
status = exeBufLoad(buf,GetCharArray(filePath));
|
|
DeleteDynString(filePath);
|
|
if(status != 1) {
|
|
SCWrite(pCon,"ERROR: failed to load buffer",eError);
|
|
return 0;
|
|
}
|
|
LLDnodeAppendFrom(self->runList,&buf);
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static void clearQueue(pExeMan self){
|
|
pExeBuf buf = NULL;
|
|
int status;
|
|
|
|
status = LLDnodePtr2First(self->runList);
|
|
while(status != 0) {
|
|
LLDnodeDataTo(self->runList,&buf);
|
|
if(buf != NULL){
|
|
exeBufDelete(buf);
|
|
}
|
|
LLDnodeDelete(self->runList);
|
|
status = LLDnodePtr2Next(self->runList);
|
|
}
|
|
/*
|
|
A second time round. This is a workaround for some
|
|
dodgy behaviour of the list system.
|
|
*/
|
|
status = LLDnodePtr2First(self->runList);
|
|
while(status != 0) {
|
|
LLDnodeDataTo(self->runList,&buf);
|
|
if(buf != NULL){
|
|
exeBufDelete(buf);
|
|
}
|
|
LLDnodeDelete(self->runList);
|
|
status = LLDnodePtr2Next(self->runList);
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static int execQueue(pExeMan self, SConnection *pCon, SicsInterp *pSics){
|
|
pExeBuf buf = NULL;
|
|
int status;
|
|
|
|
if(self->exeStackPtr >= 0){
|
|
SCWrite(pCon,
|
|
"ERROR: cannot start queue while batch buffers are still running",eError);
|
|
return 0;
|
|
}
|
|
if(!SCMatchRights(pCon,usUser)){
|
|
return 0;
|
|
}
|
|
|
|
while(LLDnodePtr2First(self->runList) != 0){
|
|
LLDnodeDataTo(self->runList,&buf);
|
|
LLDnodeDelete(self->runList);
|
|
self->exeStackPtr++;
|
|
if(buf == NULL){
|
|
SCWrite(pCon,
|
|
"ERROR: serious trouble, buffer not in queue, inform programmer",eError);
|
|
return 0;
|
|
}
|
|
DynarPut(self->exeStack,self->exeStackPtr,buf);
|
|
status = exeBufProcess(buf,pSics,pCon,self->pCall,self->echo);
|
|
self->exeStackPtr--;
|
|
if(SCGetInterrupt(pCon) >= eAbortBatch){
|
|
SCWrite(pCon,"ERROR: queue processing interrupted",eError);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*========================== interpreter action =======================*/
|
|
int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pExeMan self = NULL;
|
|
char pBufferName[256];
|
|
int status;
|
|
pDynString dirList = NULL;
|
|
pDynString fullPath = NULL;
|
|
|
|
self = (pExeMan)pData;
|
|
assert(self != NULL);
|
|
|
|
|
|
if(argc > 1){
|
|
strncpy(pBufferName,argv[1],255);
|
|
strtolower(argv[1]);
|
|
status = handleBatchPath(self,pCon,argc,argv);
|
|
if(status >= 0){
|
|
return status;
|
|
}
|
|
if(strcmp(argv[1],"interest") == 0){
|
|
registerCallbacks(pCon,pSics,self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if(strcmp(argv[1],"uninterest") == 0){
|
|
unregisterCallbacks(pCon,self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}else if(strcmp(argv[1],"upload") == 0){
|
|
status = startUpload(self,pCon);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"append") == 0){
|
|
status = appendLine(self,pCon,argc,argv);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"save") == 0){
|
|
status = uploadSave(self,pCon,argc,argv);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"forcesave") == 0){
|
|
status = uploadForceSave(self,pCon,argc,argv);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"clearupload") == 0){
|
|
status = clearUpload(self,pCon);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"info") == 0){
|
|
status = infoHandler(self,pCon,argc,argv);
|
|
return status;
|
|
}else if(strcmp(argv[1],"print") == 0){
|
|
status = printBuffer(self,pCon,argc,argv);
|
|
return status;
|
|
}else if(strcmp(argv[1],"enqueue") == 0){
|
|
status = enqueueBuffer(self,pCon,argc,argv);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if(strcmp(argv[1],"dir") == 0){
|
|
if(argc <= 2){
|
|
dirList = findDirEntries(self,"*");
|
|
} else {
|
|
dirList = findDirEntries(self,argv[2]);
|
|
}
|
|
if(dirList != NULL){
|
|
SCWrite(pCon,GetCharArray(dirList),eValue);
|
|
DeleteDynString(dirList);
|
|
} else {
|
|
SCWrite(pCon,"Nothing found",eValue);
|
|
}
|
|
return 1;
|
|
}else if(strcmp(argv[1],"fullpath") == 0){
|
|
if(argc < 2){
|
|
SCWrite(pCon,"ERROR: not enough arguments to exe fullpath",eError);
|
|
return 0;
|
|
}
|
|
fullPath = locateBatchBuffer(self,argv[2]);
|
|
if(fullPath == NULL){
|
|
SCWrite(pCon,"ERROR: buffer NOT found",eError);
|
|
return 0;
|
|
} else {
|
|
DynStringInsert(fullPath,"exe.fullpath=",0);
|
|
SCWrite(pCon,GetCharArray(fullPath),eValue);
|
|
DeleteDynString(fullPath);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}else if(strcmp(argv[1],"makepath") == 0){
|
|
return makeExePath(self,pCon,argc,argv);
|
|
}else if(strcmp(argv[1],"clear") == 0){
|
|
clearQueue(self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}else if(strcmp(argv[1],"queue") == 0){
|
|
printQueue(self,pCon);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}else if(strcmp(argv[1],"run") == 0){
|
|
status = execQueue(self,pCon,pSics);
|
|
if(status){
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
}else if(strcmp(argv[1],"echo") == 0){
|
|
if (argc > 2) {
|
|
self->echo = atoi(argv[2]) != 0;
|
|
SCSendOK(pCon);
|
|
} else {
|
|
SCPrintf(pCon, eValue, "exe echo = %d", self->echo);
|
|
}
|
|
return 1;
|
|
}else if(strcmp(argv[1],"runhdb") == 0){
|
|
if (argc < 2) {
|
|
SCWrite(pCon,"ERROR: require path to root of queue node",eError);
|
|
SCSendOK(pCon);
|
|
}
|
|
status = runHdbBuffer(self,pCon,pSics,argv[2]);
|
|
if(self->exeStackPtr < 0){
|
|
SCWrite(pCon,"EXE TERMINATED",eWarning);
|
|
}
|
|
return status;
|
|
} else {
|
|
status = runBatchBuffer(self,pCon,pSics,pBufferName);
|
|
if(self->exeStackPtr < 0){
|
|
SCWrite(pCon,"EXE TERMINATED",eWarning);
|
|
}
|
|
return status;
|
|
}
|
|
} else {
|
|
SCWrite(pCon,"ERROR: need argument to manage batch buffers",eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|