1456 lines
38 KiB
C
1456 lines
38 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 "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] == '/') {
|
|
strlcat(buffer, argv[2], sizeof buffer);
|
|
SCWrite(pCon, buffer, eValue);
|
|
return 1;
|
|
}
|
|
pPtr = self->batchPath;
|
|
pPtr = stptok(pPtr, pPath, 131, ":");
|
|
strlcat(buffer, pPath, sizeof buffer);
|
|
strlcat(buffer, "/", sizeof buffer);
|
|
strlcat(buffer, argv[2], sizeof 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);
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
int isBatchRunning()
|
|
{
|
|
pExeMan self = (pExeMan) FindCommandData(pServ->pSics, "exe", "ExeManager");
|
|
if(self != NULL && self->exeStackPtr > 0){
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
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;
|
|
}
|
|
|
|
if (self->runCon != NULL && self->runCon != pCon) {
|
|
SCWrite(pCon, "ERROR: another batch buffer is already runnig", eError);
|
|
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) {
|
|
Log(ERROR,"sys","%s", "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;
|
|
SConnection *conCon = NULL;
|
|
|
|
/*
|
|
* 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);
|
|
conCon = SCCopyConnection(pCon);
|
|
if (conCon == NULL) {
|
|
SCWrite(pCon, "ERROR: out of memory in exehdbNode", eError);
|
|
return 0;
|
|
}
|
|
strlcpy(conCon->deviceID, name, 255);
|
|
strlcpy(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);
|
|
|
|
strlcpy(bufferNode, name, 511);
|
|
SCSetWriteFunc(conCon, SCHdbWrite);
|
|
status = exeBufProcess(buffer, pServ->pSics, conCon, NULL, 0);
|
|
SCDeleteConnection(conCon);
|
|
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;
|
|
SConnection *conCon = NULL;
|
|
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
|
|
if (self->runCon != NULL && self->runCon != pCon) {
|
|
SCWrite(pCon, "ERROR: another bacth buffer is still running", eError);
|
|
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
|
|
*/
|
|
conCon = SCCopyConnection(pCon);
|
|
strlcpy(conCon->deviceID, pBueffel,255);
|
|
|
|
/*
|
|
* 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);
|
|
|
|
strlcpy(bufferNode, name, 511);
|
|
SCSetWriteFunc(conCon, SCHdbWrite);
|
|
self->exeStackPtr++;
|
|
self->runCon = conCon;
|
|
DynarPut(self->exeStack, self->exeStackPtr, buffer);
|
|
status = exeBufProcess(buffer, pSics, conCon, self->pCall, self->echo);
|
|
self->exeStackPtr--;
|
|
self->runCon = NULL;
|
|
SCDeleteConnection(conCon);
|
|
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 (strcasecmp(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]);
|
|
if(self->batchPath[0] != '/'){
|
|
SCPrintf(pCon,eLog, "WARNING: batchpath %s not an absolute path", argv[2]);
|
|
} else {
|
|
SCSendOK(pCon);
|
|
}
|
|
SCparChange(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBuffer, 1023, "%s.batchpath = %s", argv[0],
|
|
self->batchPath);
|
|
SCWrite(pCon, pBuffer, eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
if (strcasecmp(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->pCon != NULL) {
|
|
SCDeleteConnection(self->pCon);
|
|
}
|
|
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;
|
|
}
|
|
memset(pNew, 0, sizeof(exeInfo));
|
|
pNew->pCon = SCCopyConnection(pCon);
|
|
if (pNew->pCon == NULL) {
|
|
SCWrite(pCon,
|
|
"ERROR: failed to allocate info structure for registering callbacks",
|
|
eError);
|
|
return NULL;
|
|
}
|
|
pNew->exe = self;
|
|
return pNew;
|
|
}
|
|
|
|
/*------------------------------------------------------------------*/
|
|
static int BufferCallback(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
pExeInfo self = (pExeInfo) pUser;
|
|
char *name = (char *) pEvent;
|
|
char pBueffel[132];
|
|
|
|
if (!SCisConnected(self->pCon)) {
|
|
return -1;
|
|
}
|
|
|
|
if (iEvent == BATCHSTART) {
|
|
snprintf(pBueffel, 131, "BATCHSTART=%s", name);
|
|
SCWrite(self->pCon, pBueffel, eLog);
|
|
return 1;
|
|
}
|
|
if (iEvent == BATCHEND) {
|
|
snprintf(pBueffel, 131, "BATCHEND=%s", name);
|
|
SCWrite(self->pCon, pBueffel, eLog);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
static int LineCallBack(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
pExeInfo self = (pExeInfo) pUser;
|
|
char pBueffel[256];
|
|
int start, end, lineno;
|
|
void *pPtr = NULL;
|
|
pExeBuf buf = NULL;
|
|
|
|
assert(self);
|
|
|
|
if (!SCisConnected(self->pCon)) {
|
|
return -1;
|
|
}
|
|
|
|
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);
|
|
SCWrite(self->pCon, pBueffel, eLog);
|
|
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, BATCHSTART, BufferCallback,
|
|
info, killExeInfo);
|
|
lID = RegisterCallback(self->pCall, BATCHEND, BufferCallback,
|
|
info, NULL);
|
|
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack, info, NULL);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*========================= 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;
|
|
}
|
|
memset(pLine,0,sizeof(pLine));
|
|
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) {
|
|
strlcat(pPath, "/",255);
|
|
strlcat(pPath, argv[2],255);
|
|
} else {
|
|
strlcpy(pPath, argv[2], 255);
|
|
}
|
|
} else {
|
|
strlcpy(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 {
|
|
strlcpy(pPath, argv[2], 255);
|
|
}
|
|
} else {
|
|
strlcpy(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
|
|
(void)*stringToCheck++;
|
|
(void)*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)
|
|
(void)*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 {
|
|
/*
|
|
argv must no be modifed, use strcasecmp instead M.Z.
|
|
strtolower(argv[2]);
|
|
*/
|
|
if (strcasecmp(argv[2], "stack") == 0) {
|
|
printExeStack(self, pCon);
|
|
return 1;
|
|
} else if (strcasecmp(argv[2], "range") == 0) {
|
|
printExeRange(self, pCon, argc, argv);
|
|
return 1;
|
|
} else if (strcasecmp(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);
|
|
filePath = CreateDynString(256,256);
|
|
if(filePath == NULL){
|
|
SCWrite(pCon,"ERROR: out of memory printing buffer",eError);
|
|
return 0;
|
|
}
|
|
while (fgets(pLine, 511, fd) != NULL) {
|
|
DynStringConcat(filePath, pLine);
|
|
if(strrchr(pLine,(int)'\n') == NULL){
|
|
DynStringConcatChar(filePath,'\n');
|
|
}
|
|
}
|
|
fclose(fd);
|
|
SCWrite(pCon, GetCharArray(filePath), eValue);
|
|
DeleteDynString(filePath);
|
|
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
|
|
|| (self->runCon != NULL && self->runCon != pCon)) {
|
|
SCWrite(pCon,
|
|
"ERROR: cannot start queue while batch buffers are still running",
|
|
eError);
|
|
return 0;
|
|
}
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
|
|
self->runCon = pCon;
|
|
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);
|
|
self->runCon = NULL;
|
|
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);
|
|
self->runCon = NULL;
|
|
return 0;
|
|
}
|
|
}
|
|
self->runCon = 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) {
|
|
strlcpy(pBufferName, argv[1], 255);
|
|
/*
|
|
argv must no be modifed, use strcasecmp instead M.Z.
|
|
strtolower(argv[1]);
|
|
*/
|
|
status = handleBatchPath(self, pCon, argc, argv);
|
|
if (status >= 0) {
|
|
return status;
|
|
}
|
|
if (strcasecmp(argv[1], "interest") == 0) {
|
|
registerCallbacks(pCon, pSics, self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcasecmp(argv[1], "uninterest") == 0) {
|
|
unregisterCallbacks(pCon, self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcasecmp(argv[1], "upload") == 0) {
|
|
status = startUpload(self, pCon);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "append") == 0) {
|
|
status = appendLine(self, pCon, argc, argv);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "save") == 0) {
|
|
status = uploadSave(self, pCon, argc, argv);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "forcesave") == 0) {
|
|
status = uploadForceSave(self, pCon, argc, argv);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "clearupload") == 0) {
|
|
status = clearUpload(self, pCon);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "info") == 0) {
|
|
status = infoHandler(self, pCon, argc, argv);
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "print") == 0) {
|
|
status = printBuffer(self, pCon, argc, argv);
|
|
return status;
|
|
} else if (strcasecmp(argv[1], "enqueue") == 0) {
|
|
status = enqueueBuffer(self, pCon, argc, argv);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(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 (strcasecmp(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 (strcasecmp(argv[1], "makepath") == 0) {
|
|
return makeExePath(self, pCon, argc, argv);
|
|
} else if (strcasecmp(argv[1], "clear") == 0) {
|
|
clearQueue(self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcasecmp(argv[1], "queue") == 0) {
|
|
printQueue(self, pCon);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcasecmp(argv[1], "run") == 0) {
|
|
status = execQueue(self, pCon, pSics);
|
|
if (status) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return status;
|
|
} else if (strcasecmp(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 (strcasecmp(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;
|
|
}
|