Merge branch 'develop' of ssh://gitlab.psi.ch/sinqdev/sics into develop
This commit is contained in:
19
SCinter.c
19
SCinter.c
@ -72,14 +72,12 @@
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "splitter.h"
|
||||
#include "servlog.h"
|
||||
#include "macro.h"
|
||||
#include "interface.h"
|
||||
#include "motor.h"
|
||||
#include "obdes.h"
|
||||
#include "lld.h"
|
||||
#include "dynstring.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
/* M.Z. */
|
||||
#include "definealias.h"
|
||||
@ -101,7 +99,7 @@ SicsInterp *InitInterp(void)
|
||||
|
||||
pInter = (SicsInterp *) malloc(sizeof(SicsInterp));
|
||||
if (!pInter) {
|
||||
SICSLogWrite("Error allocating memory for Interpreter", eInternal);
|
||||
Log(FATAL,"sys","Error allocating memory for Interpreter");
|
||||
return NULL;
|
||||
}
|
||||
memset(pInter, 0, sizeof(SicsInterp));
|
||||
@ -140,7 +138,7 @@ int AddCommandWithFlag(SicsInterp * pInterp, char *pName, ObjectFunc pFunc,
|
||||
pNew = (CommandList *) malloc(sizeof(CommandList));
|
||||
if (!pNew) {
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "Out of memory creating command - %s -", pName);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
Log(ERROR,"sys","%s",pBueffel);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew, 0, sizeof(CommandList));
|
||||
@ -296,15 +294,6 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText)
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
|
||||
/* write info to Log */
|
||||
if (pCon->sockHandle >= 0) {
|
||||
snprintf(pBueffel,1023, "Executing -> %s <- from socket %d", pText,
|
||||
pCon->sockHandle);
|
||||
SICSLogWrite(pBueffel, eCommand);
|
||||
} else {
|
||||
snprintf(pBueffel,1023, "Executing -> %s <- from dummy socket\n", pText);
|
||||
SICSLogWrite(pBueffel, eCommand);
|
||||
}
|
||||
|
||||
if(strstr(pText,tclescape) == pText){
|
||||
return TclExecFunc(pCon,self,NULL,pText);
|
||||
@ -361,7 +350,7 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText)
|
||||
* log in history if succesfull
|
||||
*/
|
||||
if(iRet == 1){
|
||||
WriteCommandHistory(pText);
|
||||
Log(DEBUG,"history","%s",pText);
|
||||
}
|
||||
|
||||
|
||||
@ -1035,7 +1024,7 @@ static void printList(SConnection * pCon, int listID)
|
||||
static void freeList(int listID)
|
||||
{
|
||||
do {
|
||||
LLDstringDelete(listID);
|
||||
LLDdeleteString(listID);
|
||||
} while (0 != LLDnodePtr2First(listID));
|
||||
LLDdelete(listID);
|
||||
}
|
||||
|
@ -22,7 +22,8 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "nserver.h"
|
||||
#include "servlog.h"
|
||||
#include "logv2.h"
|
||||
|
||||
|
||||
extern void KeepStartupCommands(); /* ofac.c */
|
||||
|
||||
@ -62,7 +63,7 @@ int main(int argc, char *argv[])
|
||||
for (i = firstArg; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (strcasecmp(argv[i], "-nolog") == 0) {
|
||||
SICSLogEnable(0);
|
||||
DisableLog();
|
||||
}else if(strcmp(argv[i],"-keepstartup") == 0){
|
||||
KeepStartupCommands();
|
||||
#ifdef SITE_ANSTO
|
||||
|
3
ascon.c
3
ascon.c
@ -669,6 +669,7 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[])
|
||||
a->responseValid = 0;
|
||||
a->readState = 0;
|
||||
a->lineCount = 1;
|
||||
a->separator = NULL;
|
||||
a->killPrivate = NULL;
|
||||
a->private = NULL;
|
||||
|
||||
@ -752,7 +753,7 @@ AsconStatus AsconTask(Ascon * a)
|
||||
case AsconNotConnected:
|
||||
return AsconOffline;
|
||||
case AsconConnecting:
|
||||
return AsconUnconnected;
|
||||
return AsconConnectPending;
|
||||
case AsconConnectDone:
|
||||
a->state = AsconIdle;
|
||||
DynStringClear(a->errmsg); /* connection o.k. */
|
||||
|
1
ascon.h
1
ascon.h
@ -17,6 +17,7 @@ typedef struct Ascon Ascon;
|
||||
typedef enum {
|
||||
AsconOffline,
|
||||
AsconUnconnected,
|
||||
AsconConnectPending,
|
||||
AsconPending,
|
||||
AsconReady,
|
||||
AsconFailure /* codes after this indicate also failure */
|
||||
|
@ -81,8 +81,7 @@ int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char *cmd,
|
||||
/* outgoing command is correctly terminated */
|
||||
txn->out_buf = malloc(cmd_len + 1);
|
||||
if (txn->out_buf == NULL) {
|
||||
SICSLogWrite("Out of memory in AsyncProtocol::defaultPrepareTxn",
|
||||
eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::defaultPrepareTxn");
|
||||
return 0;
|
||||
}
|
||||
memcpy(txn->out_buf, cmd, cmd_len + 1);
|
||||
@ -91,7 +90,7 @@ int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char *cmd,
|
||||
int tlen = strlen(term);
|
||||
txn->out_buf = malloc(cmd_len + tlen + 1);
|
||||
if (txn->out_buf == NULL) {
|
||||
SICSLogWrite("Out of memory in AsyncProtocol::defaultPrepareTxn",
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::defaultPrepareTxn",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
@ -174,7 +173,7 @@ static char *decodeTerminator(char *code)
|
||||
count = strlen(code);
|
||||
pResult = (char *) malloc(count + 1);
|
||||
if (!pResult) {
|
||||
SICSLogWrite("Out of memory in AsyncProtocol::decodeTerminator",
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::decodeTerminator",
|
||||
eError);
|
||||
return NULL;
|
||||
}
|
||||
@ -329,7 +328,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp * pSics,
|
||||
|
||||
self = (pAsyncProtocol) malloc(sizeof(AsyncProtocol));
|
||||
if (self == NULL) {
|
||||
SICSLogWrite("Out of memory in AsyncProtocolCreate", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncProtocolCreate");
|
||||
return NULL;
|
||||
}
|
||||
memset(self, 0, sizeof(AsyncProtocol));
|
||||
@ -340,7 +339,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp * pSics,
|
||||
pKFunc = AsyncProtocolKill;
|
||||
iRet = AddCommand(pSics, (char *) protocolName, pFunc, pKFunc, self);
|
||||
if (!iRet) {
|
||||
SICSLogWrite("AddCommand failed in AsyncProtocolCreate", eError);
|
||||
Log(ERROR,"asquio","%s","AddCommand failed in AsyncProtocolCreate");
|
||||
AsyncProtocolKill(self);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ typedef enum {
|
||||
#define AQU_POP_CMD -5
|
||||
|
||||
struct __async_txn {
|
||||
int ref_counter; /**< reference counter (reference counted object) */
|
||||
pAsyncUnit unit; /**< unit that transaction is associated with */
|
||||
int txn_state; /**< protocol handler transaction parse state */
|
||||
ATX_STATUS txn_status; /**< status of the transaction OK, Error, ... */
|
||||
|
159
asyncqueue.c
159
asyncqueue.c
@ -22,7 +22,7 @@
|
||||
#include "asyncqueue.h"
|
||||
#include "nwatch.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <hexString.h>
|
||||
|
||||
typedef struct __async_command AQ_Cmd, *pAQ_Cmd;
|
||||
|
||||
@ -89,27 +89,36 @@ static const char *state_name(AsyncState the_state)
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the transaction and buffers
|
||||
*/
|
||||
static void free_transaction(pAsyncTxn myTxn)
|
||||
{
|
||||
if (myTxn) {
|
||||
if (--myTxn->ref_counter > 0)
|
||||
return;
|
||||
/*
|
||||
* Allow kill_private to clean it all if it wants
|
||||
*/
|
||||
if (myTxn->kill_private)
|
||||
myTxn->kill_private(myTxn);
|
||||
if (myTxn->out_buf)
|
||||
free(myTxn->out_buf);
|
||||
if (myTxn->inp_buf)
|
||||
free(myTxn->inp_buf);
|
||||
if (myTxn->proto_private)
|
||||
free(myTxn->proto_private);
|
||||
free(myTxn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the command and transaction structures and their contents
|
||||
*/
|
||||
static void free_command(pAQ_Cmd myCmd)
|
||||
{
|
||||
if (myCmd) {
|
||||
pAsyncTxn myTxn = myCmd->tran;
|
||||
if (myTxn) {
|
||||
/*
|
||||
* Allow kill_private to clean it all if it wants
|
||||
*/
|
||||
if (myTxn->kill_private)
|
||||
myTxn->kill_private(myTxn);
|
||||
if (myTxn->out_buf)
|
||||
free(myTxn->out_buf);
|
||||
if (myTxn->inp_buf)
|
||||
free(myTxn->inp_buf);
|
||||
if (myTxn->proto_private)
|
||||
free(myTxn->proto_private);
|
||||
free(myTxn);
|
||||
}
|
||||
free_transaction(myCmd->tran);
|
||||
free(myCmd);
|
||||
}
|
||||
}
|
||||
@ -198,7 +207,7 @@ static void AQ_Notify(pAsyncQueue self, int event)
|
||||
{
|
||||
pAsyncUnit unit;
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function:%s:%s", self->queue_name,
|
||||
__func__);
|
||||
for (unit = self->units; unit; unit = unit->next)
|
||||
if (unit->notify_func != NULL)
|
||||
@ -213,7 +222,7 @@ static int TimedReconnect(void *cntx, int mode)
|
||||
self->nw_tmr = 0;
|
||||
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name,
|
||||
__func__);
|
||||
|
||||
AQ_Purge(self);
|
||||
@ -231,7 +240,7 @@ static int TimedReconnect(void *cntx, int mode)
|
||||
if (iRet < 0) {
|
||||
snprintf(line, 132, "Failed reconnect on AsyncQueue '%s'",
|
||||
self->queue_name);
|
||||
SICSLogWrite(line, eStatus);
|
||||
Log(DEBUG,"asquio","%s",line);
|
||||
/* Timer for retry */
|
||||
NetWatchSetMode(self->nw_ctx, 0);
|
||||
/* implement an exponential backoff within limits */
|
||||
@ -242,12 +251,12 @@ static int TimedReconnect(void *cntx, int mode)
|
||||
self->retryTimer = 16000;
|
||||
AQ_SetTimer(self, self->retryTimer,
|
||||
TimedReconnect, self);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncWaiting\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncWaiting",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncWaiting;
|
||||
} else {
|
||||
NetWatchSetMode(self->nw_ctx, nwatch_write);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncConnecting\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncConnecting\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncConnecting;
|
||||
/* await reconnect result in MyCallback */
|
||||
@ -255,11 +264,11 @@ static int TimedReconnect(void *cntx, int mode)
|
||||
return 1;
|
||||
}
|
||||
NetWatchSetMode(self->nw_ctx, nwatch_read);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncConnected\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncConnected\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncConnected;
|
||||
snprintf(line, 132, "Reconnect on AsyncQueue '%s'", self->queue_name);
|
||||
SICSLogWrite(line, eStatus);
|
||||
Log(DEBUG,"asquio","%s",line);
|
||||
AQ_Purge(self);
|
||||
AQ_Notify(self, AQU_RECONNECT);
|
||||
return 1;
|
||||
@ -271,7 +280,7 @@ static int AQ_Reconnect(pAsyncQueue self)
|
||||
char line[132];
|
||||
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name,
|
||||
__func__);
|
||||
/*
|
||||
* Remove any old timer
|
||||
@ -281,7 +290,7 @@ static int AQ_Reconnect(pAsyncQueue self)
|
||||
|
||||
if (self->state == eAsyncConnected) {
|
||||
self->state = eAsyncIdle;
|
||||
SICSLogPrintf(eStatus, "Disconnect on AsyncQueue '%s'", self->queue_name);
|
||||
Log(DEBUG,"asquio", "Disconnect on AsyncQueue '%s'", self->queue_name);
|
||||
AQ_Notify(self, AQU_DISCONNECT);
|
||||
AQ_Purge(self);
|
||||
}
|
||||
@ -301,12 +310,12 @@ static int AQ_Reconnect(pAsyncQueue self)
|
||||
self->retryTimer = 125; /* initial delay */
|
||||
AQ_SetTimer(self, self->retryTimer,
|
||||
TimedReconnect, self);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncWaiting\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncWaiting\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncWaiting;
|
||||
} else {
|
||||
NetWatchSetMode(self->nw_ctx, nwatch_write);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncConnecting\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncConnecting\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncConnecting;
|
||||
/* await reconnect result in MyCallback */
|
||||
@ -314,11 +323,11 @@ static int AQ_Reconnect(pAsyncQueue self)
|
||||
return iRet;
|
||||
}
|
||||
NetWatchSetMode(self->nw_ctx, nwatch_read);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncConnected\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncConnected\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncConnected;
|
||||
snprintf(line, 132, "Reconnect on AsyncQueue '%s'", self->queue_name);
|
||||
SICSLogWrite(line, eStatus);
|
||||
Log(DEBUG,"asquio",line);
|
||||
AQ_Purge(self);
|
||||
AQ_Notify(self, AQU_RECONNECT);
|
||||
return 1;
|
||||
@ -335,7 +344,7 @@ static int StartCommand(pAsyncQueue self)
|
||||
int iRet = 0;
|
||||
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name,
|
||||
__func__);
|
||||
if (myCmd == NULL)
|
||||
return OKOK;
|
||||
@ -384,10 +393,8 @@ static int StartCommand(pAsyncQueue self)
|
||||
} else if (iRet > 0) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eError, &tv,
|
||||
"ERROR: %d unsolicited chars in AsyncQueue %s",
|
||||
iRet, self->queue_name);
|
||||
SICSLogWriteHexTime(reply, iRet, eError, &tv);
|
||||
Log(ERROR, "asquio","%d unsolicited chars in AsyncQueue %s",iRet, self->queue_name);
|
||||
LogHex(&tv,ERROR,SASQIO,reply,iRet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -495,9 +502,8 @@ static int CommandTimeout(void *cntx, int mode)
|
||||
if (self->trace) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eLog, &tv,
|
||||
"Timeout Trace on AsyncQueue %s", self->queue_name);
|
||||
SICSLogWriteHexTime(myCmd->tran->inp_buf, myCmd->tran->inp_idx, eLog, &tv);
|
||||
Log(DEBUG,"asquio", "Timeout Trace on AsyncQueue %s", self->queue_name);
|
||||
LogHex(&tv,DEBUG,SASQIO,myCmd->tran->inp_buf,myCmd->tran->inp_idx);
|
||||
}
|
||||
if (myCmd->retries > 0) {
|
||||
--myCmd->retries;
|
||||
@ -521,19 +527,30 @@ static int DelayedStart(void *cntx, int mode)
|
||||
{
|
||||
pAsyncQueue self = (pAsyncQueue) cntx;
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name,
|
||||
__func__);
|
||||
self->nw_tmr = 0;
|
||||
StartCommand(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void LogHexPrefix(struct timeval *tv, unsigned int severity, char *prefix, char *buffer, int bufferLength)
|
||||
{
|
||||
char *hexData = NULL;
|
||||
|
||||
hexData = bytesToHexString((uint8_t *)buffer,(size_t)bufferLength);
|
||||
if(hexData != NULL){
|
||||
LogTS(tv,severity,SASQIO,"%s:%s", prefix,hexData);
|
||||
free(hexData);
|
||||
}
|
||||
}
|
||||
|
||||
static int MyCallback(void *context, int mode)
|
||||
{
|
||||
pAsyncQueue self = (pAsyncQueue) context;
|
||||
|
||||
if (self->state != eAsyncConnected)
|
||||
SICSLogPrintf(eStatus, "Function: %s:%s\n", self->queue_name,
|
||||
Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name,
|
||||
__func__);
|
||||
if (mode & nwatch_read) {
|
||||
int iRet;
|
||||
@ -563,9 +580,8 @@ static int MyCallback(void *context, int mode)
|
||||
if (self->trace) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eLog, &tv,
|
||||
"Input Trace on AsyncQueue %s", self->queue_name);
|
||||
SICSLogWriteHexTime(myCmd->tran->inp_buf, myCmd->tran->inp_idx, eLog, &tv);
|
||||
Log(INFO, "asquio","Input Trace on AsyncQueue %s", self->queue_name);
|
||||
LogHex(&tv,INFO,SASQIO,myCmd->tran->inp_buf, myCmd->tran->inp_idx);
|
||||
}
|
||||
PopCommand(self);
|
||||
break;
|
||||
@ -573,18 +589,13 @@ static int MyCallback(void *context, int mode)
|
||||
int excess = nchars - 1 - i;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eError, &tv,
|
||||
"ERROR: Protocol error %d in AsyncQueue %s",
|
||||
Log(ERROR,"asquio",
|
||||
"Protocol error %d in AsyncQueue %s",
|
||||
iRet, self->queue_name);
|
||||
SICSLogWriteTime("Sent:", eError, &tv);
|
||||
SICSLogWriteHexTime(myCmd->tran->out_buf, myCmd->tran->out_len, eError, &tv);
|
||||
SICSLogWriteTime("Received:", eError, &tv);
|
||||
SICSLogWriteHexTime(myCmd->tran->inp_buf, myCmd->tran->inp_idx, eError, &tv);
|
||||
SICSLogWriteTime("Processed:", eError, &tv);
|
||||
SICSLogWriteHexTime(&reply[0], i, eError, &tv);
|
||||
SICSLogWriteTime("Unprocessed:", eError, &tv);
|
||||
SICSLogWriteHexTime(&reply[i], excess, eError, &tv);
|
||||
/* TODO: error */
|
||||
LogHexPrefix(&tv,ERROR,"Sent", myCmd->tran->out_buf,myCmd->tran->out_len);
|
||||
LogHexPrefix(&tv,ERROR,"Received", myCmd->tran->inp_buf,myCmd->tran->inp_len);
|
||||
LogHexPrefix(&tv,ERROR,"Processed", &reply[0],i);
|
||||
LogHexPrefix(&tv,ERROR,"Unprocessed", &reply[i],excess);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -592,30 +603,26 @@ static int MyCallback(void *context, int mode)
|
||||
int excess = nchars - 1 - i;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eError, &tv,
|
||||
"ERROR: %d excess chars in AsyncQueue %s",
|
||||
Log(ERROR, "asquio", "%d excess chars in AsyncQueue %s",
|
||||
excess, self->queue_name);
|
||||
SICSLogWriteHexTime(&reply[i], excess, eError, &tv);
|
||||
/* TODO: handle unsolicited */
|
||||
}
|
||||
} else {
|
||||
int excess = nchars - 1 - i;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eError, &tv,
|
||||
"ERROR: %d unsolicited chars in AsyncQueue %s",
|
||||
Log(ERROR, "asquio", "%d unsolicited chars in AsyncQueue %s",
|
||||
excess, self->queue_name);
|
||||
SICSLogWriteHexTime(&reply[i], excess, eError, &tv);
|
||||
/* TODO: handle unsolicited input */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mode & nwatch_write) {
|
||||
char line[132];
|
||||
SICSLogPrintf(eStatus, "Writeable socket callback on AsyncQueue %s",
|
||||
Log(DEBUG,"asquio", "Writeable socket callback on AsyncQueue %s",
|
||||
self->queue_name);
|
||||
NetWatchSetMode(self->nw_ctx, nwatch_read);
|
||||
SICSLogPrintf(eStatus, "In %s:%s: state %s => eAsyncConnected\n",
|
||||
Log(DEBUG,"asquio", "In %s:%s: state %s => eAsyncConnected\n",
|
||||
self->queue_name, __func__, state_name(self->state));
|
||||
self->state = eAsyncConnected;
|
||||
}
|
||||
@ -629,7 +636,7 @@ int AsyncUnitEnqueueHead(pAsyncUnit unit, pAsyncTxn context)
|
||||
assert(unit && unit->queue && unit->queue->protocol);
|
||||
myCmd = (pAQ_Cmd) malloc(sizeof(AQ_Cmd));
|
||||
if (myCmd == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitEnqueHead", eError);
|
||||
Log(ERROR,"asquio","Out of memory in AsyncUnitEnqueHead", eError);
|
||||
return 0;
|
||||
}
|
||||
memset(myCmd, 0, sizeof(AQ_Cmd));
|
||||
@ -648,7 +655,7 @@ int AsyncUnitEnqueueTxn(pAsyncUnit unit, pAsyncTxn pTxn)
|
||||
assert(unit && unit->queue && unit->queue->protocol);
|
||||
myCmd = (pAQ_Cmd) malloc(sizeof(AQ_Cmd));
|
||||
if (myCmd == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitEnqueueTxn", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncUnitEnqueueTxn");
|
||||
return 0;
|
||||
}
|
||||
memset(myCmd, 0, sizeof(AQ_Cmd));
|
||||
@ -670,7 +677,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
|
||||
assert(unit);
|
||||
myTxn = (pAsyncTxn) malloc(sizeof(AsyncTxn));
|
||||
if (myTxn == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitPrepareTxn", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn", eError);
|
||||
return NULL;
|
||||
}
|
||||
memset(myTxn, 0, sizeof(AsyncTxn));
|
||||
@ -705,7 +712,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
|
||||
} else {
|
||||
myTxn->out_buf = (char *) malloc(cmd_len + 5);
|
||||
if (myTxn->out_buf == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitPrepareTxn", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn");
|
||||
free(myTxn);
|
||||
return NULL;
|
||||
}
|
||||
@ -724,7 +731,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
|
||||
else {
|
||||
myTxn->inp_buf = malloc(rsp_len + 1);
|
||||
if (myTxn->inp_buf == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitPrepareTxn", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn", eError);
|
||||
free(myTxn->out_buf);
|
||||
free(myTxn);
|
||||
return NULL;
|
||||
@ -735,9 +742,23 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
|
||||
myTxn->unit = unit;
|
||||
myTxn->handleResponse = callback;
|
||||
myTxn->cntx = context;
|
||||
myTxn->ref_counter = 1;
|
||||
return myTxn;
|
||||
}
|
||||
|
||||
pAsyncTxn AsyncUnitHoldTxn(pAsyncTxn txn)
|
||||
{
|
||||
if (txn)
|
||||
txn->ref_counter++;
|
||||
return txn;
|
||||
}
|
||||
|
||||
void AsyncUnitFreeTxn(pAsyncTxn txn)
|
||||
{
|
||||
if (txn)
|
||||
free_transaction(txn);
|
||||
}
|
||||
|
||||
int AsyncUnitSendTxn(pAsyncUnit unit,
|
||||
const char *command, int cmd_len,
|
||||
AsyncTxnHandler callback, void *context, int rsp_len)
|
||||
@ -808,9 +829,7 @@ int AsyncUnitWrite(pAsyncUnit unit, void *buffer, int buflen)
|
||||
if (unit->queue->trace) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
SICSLogTimePrintf(eLog, &tv,
|
||||
"Output Trace on AsyncQueue %s", unit->queue->queue_name);
|
||||
SICSLogWriteHexTime(buffer, buflen, eLog, &tv);
|
||||
LogHexPrefix(&tv,DEBUG,"Output Trace on AsyncQueue", buffer, buflen);
|
||||
}
|
||||
sock = AsyncUnitGetSocket(unit);
|
||||
iRet = NETWrite(sock, buffer, buflen);
|
||||
@ -1376,7 +1395,7 @@ int AsyncUnitCreateHost(const char *host, const char *port,
|
||||
|
||||
unit = (pAsyncUnit) malloc(sizeof(AsyncUnit));
|
||||
if (unit == NULL) {
|
||||
SICSLogWrite("ERROR: Out of memory in AsyncUnitCreateHost", eError);
|
||||
Log(ERROR,"asquio","%s","Out of memory in AsyncUnitCreateHost", eError);
|
||||
*handle = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
10
asyncqueue.h
10
asyncqueue.h
@ -75,6 +75,16 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit,
|
||||
AsyncTxnHandler responseHandler,
|
||||
void *context, int rsp_len);
|
||||
|
||||
/** \brief clone a pointer to the transaction - must use AsyncUnitFreeTxn
|
||||
* \param txn the transaction to clone
|
||||
*/
|
||||
pAsyncTxn AsyncUnitHoldTxn(pAsyncTxn txn);
|
||||
|
||||
/** \brief free a cloned transaction
|
||||
* \param txn the transaction to free (returned by AsyncUnitHoldTxn)
|
||||
*/
|
||||
void AsyncUnitFreeTxn(pAsyncTxn txn);
|
||||
|
||||
/** \brief prepare and queue a transaction
|
||||
*
|
||||
* \param unit AsyncUnit
|
||||
|
@ -338,7 +338,12 @@ static int anetTestWrite(SocketDescriptor con)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------------
|
||||
There is something implicit in the return here: anetRead must return 0
|
||||
when the list of sockets changes. Otherwise ANETprocess cannot detect that it has
|
||||
an invalid socket list and jump out. In all other cases anetRead must return 1
|
||||
-------------------------------------------------------------------------------*/
|
||||
|
||||
static int anetRead(SocketDescriptor con)
|
||||
{
|
||||
int socke, handle, status;
|
||||
|
@ -45,6 +45,7 @@ static int BackgroundTask(void *data)
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int BackgroundCommand(SConnection * pCon, char *command)
|
||||
{
|
||||
long lID;
|
||||
pBckTask self = NULL;
|
||||
|
||||
self = calloc(1, sizeof(BckTask));
|
||||
@ -59,7 +60,8 @@ int BackgroundCommand(SConnection * pCon, char *command)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TaskRegisterN(pServ->pTasker, self->command, BackgroundTask, NULL, KillBckTask, self, 1);
|
||||
lID = TaskRegisterN(pServ->pTasker, self->command, BackgroundTask, NULL, KillBckTask, self, TASK_PRIO_LOW);
|
||||
SCPrintf(pCon, eValue, "bg = %ld", lID);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -77,7 +79,6 @@ int BackgroundAction(SConnection * pCon, SicsInterp * pSics,
|
||||
SCWrite(pCon, "ERROR: out of memory starting task", eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
50
binprot.c
50
binprot.c
@ -27,6 +27,7 @@
|
||||
*
|
||||
* and formatItem is one of the follwing
|
||||
*
|
||||
* a number (decimal format): returned byte must match (else error)
|
||||
* skip skip one byte
|
||||
* skip<n> skip <n> bytes
|
||||
* code returned function code, when bit7 is set, the response is
|
||||
@ -39,6 +40,7 @@
|
||||
* and append it to the response
|
||||
* float convert 4 bytes from ieee float
|
||||
* and append the number to the response
|
||||
* dump read all bytes in read buffer as hex (only for tests)
|
||||
* crc check crc (if wrong, "badCRC" is added to the response)
|
||||
*
|
||||
* multiple items in the response are space separated
|
||||
@ -49,16 +51,16 @@
|
||||
*
|
||||
* sct send 250 3 int2 10 2 crc / skip code skip float crc
|
||||
*
|
||||
* different crc's might be used (argv[2] opf BinInit):
|
||||
* different crc's might be used (argv[2] of BinInit):
|
||||
* modbus-crc: CRC-16-IBM, order: lo,hi
|
||||
* keller-crc: CRC-16-IBM, order: hi,lo
|
||||
* sycon-crc: sort of mod 256 checksum, byte stuffing included (no float allowed)
|
||||
* chksum-crc: simple 8bit checksum
|
||||
*/
|
||||
|
||||
typedef enum {intType, hexType, floatType,
|
||||
skipType, codeType, crcType, dumpType, errorType} BinDataType;
|
||||
// dumpType, errorType must be the last items
|
||||
typedef enum {intType, hexType, floatType, skipType, codeType, checkType,
|
||||
crcType, dumpType, endType, errorType} BinDataType;
|
||||
// dumpType, endType, errorType must be the last items
|
||||
|
||||
typedef enum {modbusCrc, kellerCrc, rsportCrc, syconCrc, chksumCrc} CrcAlgorithm;
|
||||
|
||||
@ -164,7 +166,7 @@ int BinReadItem(Ascon *a) {
|
||||
if (sscanf(p->nextFmt, "%30s%n", item, &valen) <= 0) {
|
||||
if (p->type < dumpType) {
|
||||
p->dumpFrom = GetDynStringLength(a->rdBuffer);
|
||||
p->type= dumpType;
|
||||
p->type = endType;
|
||||
}
|
||||
p->expectedChars = 999;
|
||||
return 0;
|
||||
@ -193,13 +195,22 @@ int BinReadItem(Ascon *a) {
|
||||
p->type = hexType;
|
||||
} else if (strcasecmp(item, "code") == 0) {
|
||||
p->type = codeType;
|
||||
} else if (strcasecmp(item, "dump") == 0) {
|
||||
p->dumpFrom = GetDynStringLength(a->rdBuffer);
|
||||
p->type = dumpType;
|
||||
} else if (strncasecmp(item, "skip", 4) == 0) {
|
||||
size = 1;
|
||||
sscanf(item + 4, "%d", &size);
|
||||
p->expectedChars = size;
|
||||
p->type = skipType;
|
||||
} else {
|
||||
return -1;
|
||||
} else {
|
||||
p->iValue = 0;
|
||||
if (1 == sscanf(item, "%ld", &p->iValue)) {
|
||||
p->expectedChars = 1;
|
||||
p->type = checkType;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
p->nextFmt += valen;
|
||||
return 1;
|
||||
@ -268,6 +279,7 @@ int BinHandler(Ascon *a) {
|
||||
int valen;
|
||||
BinDataType type;
|
||||
long iValue;
|
||||
unsigned long uValue;
|
||||
double fValue;
|
||||
BinPrivate *p = a->private;
|
||||
|
||||
@ -327,11 +339,12 @@ int BinHandler(Ascon *a) {
|
||||
BinError(a, "invalid integer");
|
||||
return 1;
|
||||
}
|
||||
uValue = iValue;
|
||||
for (i = size - 1; i >= 0; i--) {
|
||||
if (i < sizeof data) {
|
||||
data[i] = iValue % 256;
|
||||
data[i] = uValue % 256;
|
||||
}
|
||||
iValue /= 256;
|
||||
uValue >>= 8;
|
||||
}
|
||||
for (i = 0; i < size; i++) {
|
||||
if (i >= sizeof data) {
|
||||
@ -411,7 +424,11 @@ int BinHandler(Ascon *a) {
|
||||
snprintf(item, sizeof item, "%2.2x ", (str[i] & 255));
|
||||
DynStringConcat(p->result, item);
|
||||
}
|
||||
if (p->type == errorType) {
|
||||
if (p->type == endType && p->dumpFrom < l) {
|
||||
DynStringCopy(a->errmsg, "BINERR: superflous chars ");
|
||||
DynStringConcat(a->errmsg, GetCharArray(p->result));
|
||||
a->state = AsconFailed;
|
||||
} else if (p->type == errorType) {
|
||||
DynStringConcat(a->errmsg, GetCharArray(p->result));
|
||||
a->state = AsconFailed;
|
||||
} else {
|
||||
@ -492,6 +509,7 @@ int BinHandler(Ascon *a) {
|
||||
DynStringCopy(p->result, item);
|
||||
}
|
||||
break;
|
||||
case endType:
|
||||
case dumpType:
|
||||
break;
|
||||
case skipType:
|
||||
@ -500,7 +518,7 @@ int BinHandler(Ascon *a) {
|
||||
case intType:
|
||||
p->expectedChars--;
|
||||
p->iValue = p->iValue * 256 + (a->lastChar & 255);
|
||||
if (p->expectedChars <= 0) {
|
||||
if (p->expectedChars <= 0) {
|
||||
snprintf(item, sizeof item, "%ld ", p->iValue);
|
||||
DynStringConcat(p->result, item);
|
||||
}
|
||||
@ -555,6 +573,16 @@ int BinHandler(Ascon *a) {
|
||||
/* subtract CRC char (undo the addition) and subtract crc higher four bits */
|
||||
p->chksum -= a->lastChar + (a->lastChar & 0x0f) * 16;
|
||||
}
|
||||
break;
|
||||
case checkType:
|
||||
p->expectedChars--;
|
||||
if ((a->lastChar & 255) != p->iValue) {
|
||||
DynStringCopy(a->errmsg, "BINERR: mismatch ");
|
||||
p->type = errorType;
|
||||
p->dumpFrom = 0;
|
||||
/* skip to end */
|
||||
p->nextFmt = "";
|
||||
}
|
||||
}
|
||||
if (p->expectedChars <= 0) {
|
||||
BinReadItem(a);
|
||||
|
652
commandlog.c
652
commandlog.c
@ -1,652 +0,0 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
C O M M A N D L O G
|
||||
|
||||
A much requested facility for writing only user and manager level commands
|
||||
in a transcript file. This is it.
|
||||
|
||||
Mark Koennecke, June 1998
|
||||
|
||||
Extended to support Heinz Heers autolog-file
|
||||
Mark Koennecke, April-May 1999
|
||||
|
||||
Added a tail facility
|
||||
Mark Koennecke, October 1999
|
||||
|
||||
Added compact mode:
|
||||
- timestamps look different and are omitted if no other text is written
|
||||
- socket number information is written on the timestamp line
|
||||
|
||||
Added command history logging. Due to problems this is currently disabled by
|
||||
writeHistory = 0 and code in SetWriteHistory
|
||||
|
||||
Mark Koennecke, July 2010
|
||||
--------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <tcl.h>
|
||||
#include "splitter.h"
|
||||
#include "sics.h"
|
||||
#include "ifile.h"
|
||||
#include "sicsvar.h"
|
||||
#include "scaldate.h"
|
||||
#include "network.h"
|
||||
#include "circular.h"
|
||||
#include "stptok.h"
|
||||
|
||||
/* in conman.c */
|
||||
int TelnetWrite(mkChannel * pSock, char *pText);
|
||||
/*-------------------- the command log file pointer ---------------------*/
|
||||
static FILE *fd = NULL;
|
||||
static FILE *fauto = NULL;
|
||||
static char pFile[256];
|
||||
/*------------------------- command history logging --------------------*/
|
||||
static char pHistoryFilter[1024] = "";
|
||||
static int writeHistory = 0;
|
||||
/*-------------------- the tail buffer ---------------------------------*/
|
||||
static pCircular pTail = NULL;
|
||||
#define MAXTAIL 1000
|
||||
#define NOID -1964
|
||||
static time_t lastStamp = 0;
|
||||
static time_t iCompact = 0;
|
||||
static time_t tLastWrite = 0;
|
||||
char *cmdPrompt = ">";
|
||||
static int lastId = NOID;
|
||||
|
||||
static time_t tLogfile = 0;
|
||||
static time_t tStamp = 0;
|
||||
static int iEnd = 1;
|
||||
static int iAutoActive = 0;
|
||||
static int iIntervall = 60;
|
||||
/*----------------------------------------------------------------------*/
|
||||
void WriteToCommandLogId(char *prompt, int id, char *text)
|
||||
{
|
||||
int l, iPos;
|
||||
char *pPtr = NULL, *pCopy = NULL, *strippedText = text;
|
||||
struct tm *nowTm;
|
||||
time_t now;
|
||||
char stamp1[32], stamp2[32], buffer[80];
|
||||
int doStamp, doStampId;
|
||||
int old;
|
||||
|
||||
/* suppress status messages */
|
||||
if (strstr(text, "status =") != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* suppress TRANSACTIONFINISHED as well in order to make the WWW
|
||||
commandlog work and TRANSACTIONSTART in order to make the logfiles
|
||||
shorter
|
||||
*/
|
||||
if (strstr(text, "TRANSACTIONSTART") != NULL) {
|
||||
return;
|
||||
}
|
||||
if (strstr(text, "TRANSACTIONFINISHED") != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* we make a local copy, stripping off the newline at the
|
||||
end. We anyway need a copy later for the circular buffer */
|
||||
l = strlen(text);
|
||||
pPtr = strrchr(text, '\n');
|
||||
if (pPtr != NULL && (pPtr[1] == '\0' || pPtr[2] == '\0')) {
|
||||
l = pPtr - text;
|
||||
}
|
||||
pCopy = malloc(l + 1);
|
||||
if (pCopy == NULL)
|
||||
return;
|
||||
strncpy(pCopy, text, l); /* strlcpy is not correct here */
|
||||
pCopy[l] = '\0';
|
||||
if (prompt == cmdPrompt && iCompact) {
|
||||
pPtr = strstr(pCopy, "fulltransact ");
|
||||
if (pPtr && pPtr < pCopy + 3) {
|
||||
strippedText = pPtr + 13;
|
||||
}
|
||||
pPtr = strstr(pCopy, "transact ");
|
||||
if (pPtr && pPtr < pCopy + 3) {
|
||||
strippedText = pPtr + 9;
|
||||
}
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
/* create tail buffer as needed */
|
||||
if (!pTail) {
|
||||
pTail = createCircular(MAXTAIL, free);
|
||||
}
|
||||
|
||||
doStamp = 0;
|
||||
doStampId = 0;
|
||||
|
||||
if (iCompact == 1) {
|
||||
nowTm = localtime(&now);
|
||||
strftime(stamp1, sizeof stamp1, "%H:%M:%S", nowTm);
|
||||
if (prompt == NULL)
|
||||
prompt = "";
|
||||
if (id == NOID) {
|
||||
if (!prompt)
|
||||
prompt = " ";
|
||||
snprintf(buffer, sizeof buffer, "%s %s ", stamp1, prompt);
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "%s %2.0d| ", stamp1, id);
|
||||
}
|
||||
prompt = buffer;
|
||||
} else if (id == NOID) {
|
||||
if (!prompt) {
|
||||
prompt = "";
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "%s ", prompt);
|
||||
prompt = buffer;
|
||||
}
|
||||
} else if (iCompact == 0) {
|
||||
if (!prompt) {
|
||||
snprintf(buffer, sizeof buffer, "To sock %d : ", id);
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "sock %d>%s ", id, prompt);
|
||||
}
|
||||
prompt = buffer;
|
||||
} else if (iCompact > 1) {
|
||||
if (id != lastId) {
|
||||
lastId = id;
|
||||
doStampId = 1;
|
||||
}
|
||||
if (!prompt) {
|
||||
prompt = "";
|
||||
} else {
|
||||
snprintf(buffer, sizeof buffer, "%s ", prompt);
|
||||
prompt = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if (iCompact > 1) { /* write time stamp */
|
||||
if (now / iCompact != lastStamp / iCompact) {
|
||||
doStamp = 1;
|
||||
doStampId = 1;
|
||||
}
|
||||
if (doStampId) {
|
||||
lastStamp = now;
|
||||
nowTm = localtime(&now);
|
||||
strftime(stamp1, sizeof stamp1, "=== %H:%M:%S ===", nowTm);
|
||||
if (id != NOID) {
|
||||
snprintf(stamp2, sizeof stamp2, " socket %d ===", id);
|
||||
} else {
|
||||
stamp2[0] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* user file */
|
||||
if (fd != NULL) {
|
||||
if (doStampId) {
|
||||
fprintf(fd, "%s %s\n", stamp1, stamp2);
|
||||
}
|
||||
fprintf(fd, "%s%s\n", prompt, pCopy);
|
||||
}
|
||||
|
||||
/* automatic file */
|
||||
if (fauto != NULL) {
|
||||
tLastWrite = now;
|
||||
if (doStampId) {
|
||||
fprintf(fauto, "%s%s\n", stamp1, stamp2);
|
||||
}
|
||||
fprintf(fauto, "%s%s\n", prompt, strippedText);
|
||||
}
|
||||
|
||||
/* to all listening sockets. The check is necessary to resolve a shutdown problem */
|
||||
if (pServ->pTasker != NULL) {
|
||||
if (doStamp) {
|
||||
TaskSignal(pServ->pTasker, COMLOG, stamp1);
|
||||
SCOnlySockWrite(GetSendingConnection(), stamp1, eLog);
|
||||
}
|
||||
TaskSignal(pServ->pTasker, COMLOG, pCopy);
|
||||
}
|
||||
|
||||
/* tail buffer */
|
||||
if (pTail != NULL) {
|
||||
if (doStamp) {
|
||||
setCircular(pTail, strdup(stamp1));
|
||||
nextCircular(pTail);
|
||||
}
|
||||
setCircular(pTail, strdup(pCopy));
|
||||
nextCircular(pTail);
|
||||
}
|
||||
lastId = id;
|
||||
if(pCopy != NULL){
|
||||
free(pCopy);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
void WriteToCommandLog(char *prompt, char *text)
|
||||
{
|
||||
WriteToCommandLogId(prompt, NOID, text);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
void WriteToCommandLogCmd(int id, char *text)
|
||||
{
|
||||
WriteToCommandLogId(cmdPrompt, id, text);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
int CompactCommandLog(void)
|
||||
{
|
||||
return iCompact > 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void PrintTail(int iNum, SConnection * pCon)
|
||||
{
|
||||
char *pPtr = NULL;
|
||||
int i;
|
||||
|
||||
if (pTail == NULL) {
|
||||
SCWrite(pCon, "Nothing to print", eError);
|
||||
return;
|
||||
}
|
||||
|
||||
/* step back */
|
||||
for (i = 0; i < iNum; i++) {
|
||||
previousCircular(pTail);
|
||||
}
|
||||
|
||||
/* now step ahead and print. I have to use a trick here: I do not
|
||||
want the tail stuff to show up in log files. Thus I write it
|
||||
directly to the connection socket.
|
||||
*/
|
||||
for (i = 0; i < iNum; i++) {
|
||||
pPtr = (char *) getCircular(pTail);
|
||||
if (pPtr != NULL) {
|
||||
SCPureSockWrite(pCon, pPtr, eWarning);
|
||||
}
|
||||
nextCircular(pTail);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
void CLFormatTime(char *pBuffer, int iBufLen)
|
||||
{
|
||||
time_t iDate;
|
||||
struct tm *psTime;
|
||||
|
||||
/* make time string */
|
||||
iDate = time(NULL);
|
||||
psTime = localtime(&iDate);
|
||||
memset(pBuffer, 0, iBufLen);
|
||||
strftime(pBuffer, iBufLen, "%Y-%m-%d@%H-%M-%S", psTime);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Build an automatically generated log file name and open it.
|
||||
*/
|
||||
static void AutoLog(void)
|
||||
{
|
||||
char pBueffel[1024];
|
||||
char pTime[80];
|
||||
pSicsVariable pInst = NULL;
|
||||
char *pPtr = NULL;
|
||||
SConnection *pIntern = NULL;
|
||||
|
||||
if (fauto) {
|
||||
fclose(fauto);
|
||||
fauto = NULL;
|
||||
}
|
||||
|
||||
/* find path */
|
||||
pPtr = IFindOption(pSICSOptions, "LogFileDir");
|
||||
if (!pPtr) {
|
||||
pPtr = strdup("~/log");
|
||||
printf("WARNING: Required SICS option LogFileDir not found");
|
||||
}
|
||||
|
||||
/* get time */
|
||||
CLFormatTime(pTime, 79);
|
||||
|
||||
/* build file name */
|
||||
snprintf(pBueffel,1024, "%s/auto%s.log", pPtr, pTime);
|
||||
|
||||
/* open file */
|
||||
fauto = fopen(pBueffel, "w");
|
||||
if (!fauto) {
|
||||
ServerWriteGlobal("ERROR: failed to open autolog file", eError);
|
||||
}
|
||||
|
||||
/* write the instrument name to it for identification */
|
||||
pInst = FindVariable(pServ->pSics, "instrument");
|
||||
if (pInst) {
|
||||
snprintf(pBueffel,1024, "Logfile started at instrument %s at %s",
|
||||
pInst->text, pTime);
|
||||
WriteToCommandLog("SYS>>", pBueffel);
|
||||
}
|
||||
|
||||
/* if a file to execute is configured, execute it */
|
||||
pPtr = NULL;
|
||||
pPtr = IFindOption(pSICSOptions, "logstartfile");
|
||||
if (pPtr != NULL) {
|
||||
pIntern = SCCreateDummyConnection(pServ->pSics);
|
||||
if (!pIntern) {
|
||||
return;
|
||||
}
|
||||
SCnoSock(pIntern);
|
||||
SCSetRights(pIntern, usUser);
|
||||
snprintf(pBueffel,1024, "fileeval %s", pPtr);
|
||||
InterpExecute(pServ->pSics, pIntern, pBueffel);
|
||||
SCDeleteConnection(pIntern);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
AutoTask puts a time stamp into the auto log file any hour and
|
||||
creates a new log file any 24 hours
|
||||
*/
|
||||
static int AutoTask(void *pData)
|
||||
{
|
||||
time_t tNow;
|
||||
char pTime[80];
|
||||
struct tm *sTime;
|
||||
long julian;
|
||||
unsigned yr, mo, dd;
|
||||
|
||||
tNow = time(NULL);
|
||||
if (tNow > tLogfile) {
|
||||
AutoLog();
|
||||
sTime = localtime(&tNow);
|
||||
/* find next day, do so by converting to julian Date, add one
|
||||
and calculate back. The (stolen) julian calculations will
|
||||
take care of all the leaps and month and year etc.
|
||||
*/
|
||||
julian = ymd_to_scalar(sTime->tm_year + 1900, sTime->tm_mon + 1,
|
||||
sTime->tm_mday);
|
||||
julian++;
|
||||
scalar_to_ymd(julian, &yr, &mo, &dd);
|
||||
sTime->tm_sec = 0;
|
||||
sTime->tm_min = 1;
|
||||
sTime->tm_hour = 0;
|
||||
sTime->tm_mday = dd;
|
||||
sTime->tm_mon = mo - 1;
|
||||
sTime->tm_year = yr - 1900;
|
||||
tLogfile = mktime(sTime);
|
||||
if (tLogfile < 0)
|
||||
tLogfile = tNow + 60 * 60 * 24;
|
||||
}
|
||||
if (tNow > tStamp && iIntervall > 0) {
|
||||
CLFormatTime(pTime, 79);
|
||||
WriteToCommandLog("TIMESTAMP>> ", pTime);
|
||||
sTime = localtime(&tNow);
|
||||
sTime->tm_sec = 0;
|
||||
sTime->tm_min += iIntervall;
|
||||
if (sTime->tm_min >= 60) {
|
||||
sTime->tm_min = 0;
|
||||
sTime->tm_hour++;
|
||||
}
|
||||
if (sTime->tm_hour >= 24)
|
||||
sTime->tm_hour = 0;
|
||||
tStamp = mktime(sTime);
|
||||
if ((tStamp < 0) || ((tStamp - tNow) < 100)) {
|
||||
tStamp = tNow + iIntervall * 60;
|
||||
}
|
||||
if (fauto)
|
||||
fflush(fauto);
|
||||
}
|
||||
|
||||
if (fauto && tLastWrite > 0 && tNow > tLastWrite) {
|
||||
fflush(fauto);
|
||||
tLastWrite = 0;
|
||||
}
|
||||
return iEnd;
|
||||
}
|
||||
|
||||
/*----------- a command to configure the log --------------------------*/
|
||||
int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char *pPtr = NULL;
|
||||
char pBueffel[1024];
|
||||
int iVal, iRet;
|
||||
|
||||
if (argc == 1) {
|
||||
if (fd) {
|
||||
sprintf(pBueffel, "Command log ACTIVE at %s", pFile);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon, "Command logging DISABLED", eValue);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle tail */
|
||||
strtolower(argv[1]);
|
||||
if (strcmp(argv[1], "tail") == 0) {
|
||||
/* check for optional number of lines argument */
|
||||
iVal = 20;
|
||||
if (argc >= 3) {
|
||||
iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal);
|
||||
if (iRet != TCL_OK)
|
||||
iVal = 20;
|
||||
}
|
||||
PrintTail(iVal, pCon);
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* handle write
|
||||
*/
|
||||
|
||||
if (strcmp(argv[1], "write") == 0) {
|
||||
Arg2Text(argc-2, &argv[2],pBueffel,sizeof(pBueffel));
|
||||
WriteToCommandLogId(NULL, pCon->sockHandle,pBueffel);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check rights */
|
||||
if (!SCMatchRights(pCon, usMugger)) {
|
||||
SCWrite(pCon, "ERROR: only managers may configure the logfile",
|
||||
eError);
|
||||
SCWrite(pCon, "ERROR: Request refused", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check no of args */
|
||||
if (argc < 2) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient number or arguments to commandlog",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "new") == 0) { /* new command */
|
||||
if (argc < 3) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient number or arguments to commandlog new",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
fd = NULL;
|
||||
}
|
||||
/* make the filename */
|
||||
pPtr = IFindOption(pSICSOptions, "LogFileDir");
|
||||
if (!pPtr) {
|
||||
SCWrite(pCon, "WARNING: no log file directory specified", eWarning);
|
||||
snprintf(pBueffel,1023, "%s", argv[2]);
|
||||
|
||||
} else {
|
||||
snprintf(pBueffel,1023, "%s/%s", pPtr, argv[2]);
|
||||
}
|
||||
fd = fopen(pBueffel, "w");
|
||||
if (!fd) {
|
||||
snprintf(pBueffel,1023, "ERROR: cannot open %s/%s for writing", pPtr,
|
||||
argv[2]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
strlcpy(pFile, argv[2],255);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "auto") == 0) {
|
||||
if (iAutoActive) {
|
||||
SCWrite(pCon, "ERROR: autologging is already active", eError);
|
||||
return 0;
|
||||
}
|
||||
TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, 1);
|
||||
SCSendOK(pCon);
|
||||
iAutoActive = 1;
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "intervall") == 0) {
|
||||
if (argc > 2) {
|
||||
iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal);
|
||||
if (iRet != TCL_OK) {
|
||||
SCWrite(pCon, "ERROR: failed to convert new intervall to number",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
iIntervall = iVal;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "%s.intervall [min] = %d", argv[0], iIntervall);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "history") == 0) {
|
||||
if (argc > 2) {
|
||||
iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iVal);
|
||||
if (iRet != TCL_OK) {
|
||||
SCWrite(pCon, "ERROR: failed to convert new history to number",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
writeHistory = iVal;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "%s.writeHistory = %d", argv[0], writeHistory);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "historyfilter") == 0) {
|
||||
if (argc > 2) {
|
||||
if(strlen(argv[2]) < 1024){
|
||||
strcpy(pHistoryFilter,argv[2]);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: history filter to long", eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "%s.historyFilter = %s", argv[0], pHistoryFilter);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "compact") == 0) {
|
||||
if (argc > 2) {
|
||||
iCompact = atoi(argv[2]);
|
||||
if (iCompact > 0)
|
||||
iIntervall = 0;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "%s.compact [sec] = %d", argv[0], (int)iCompact);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "close") == 0) { /* close command */
|
||||
fclose(fd);
|
||||
fd = NULL;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
snprintf(pBueffel, 1024,"ERROR: subcommand %s to commandlog unknown", argv[1]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void CommandLogClose(void *pData)
|
||||
{
|
||||
if (fd) {
|
||||
fclose(fd);
|
||||
}
|
||||
if (fauto)
|
||||
fclose(fauto);
|
||||
if (pData)
|
||||
KillDummy(pData);
|
||||
if (pTail)
|
||||
deleteCircular(pTail);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void CommandLogInit(void)
|
||||
{
|
||||
AddCommand(pServ->pSics, "commandlog", CommandLog, CommandLogClose, NULL);
|
||||
}
|
||||
/*---------------------- History -----------------------------------------*/
|
||||
static FILE *comHistory = NULL;
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int openHistoryLog()
|
||||
{
|
||||
char *fileName = NULL;
|
||||
char fileBuffer[1024];
|
||||
time_t iDate;
|
||||
struct tm *psTime;
|
||||
|
||||
|
||||
if (comHistory == NULL) {
|
||||
fileName = IFindOption(pSICSOptions, "historylog");
|
||||
if (fileName != NULL) {
|
||||
strlcpy(fileBuffer, fileName,1024);
|
||||
} else {
|
||||
iDate = time(NULL);
|
||||
psTime = localtime(&iDate);
|
||||
fileBuffer[0] = '\0';
|
||||
fileName = getenv("HOME");
|
||||
if (fileName != NULL) {
|
||||
snprintf(fileBuffer, 1023, "%s/log/comhistory%4.4d.log",
|
||||
fileName, psTime->tm_year + 1900);
|
||||
}
|
||||
}
|
||||
comHistory = fopen(fileBuffer, "a+");
|
||||
}
|
||||
if (comHistory == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------
|
||||
* This is to suppress certain stuff from the history log in order to stop it
|
||||
* from filling with garbage
|
||||
-----------------------------------------------------------------------------*/
|
||||
static int historyFilter(char *command)
|
||||
{
|
||||
static char *toRemove[] = {"sct", "hupdate","contextdo","transact", NULL};
|
||||
char token[50];
|
||||
char *pPtr = NULL;
|
||||
int i = 0;
|
||||
|
||||
while(toRemove[i] != NULL){
|
||||
if(strstr(command,toRemove[i]) != NULL){
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
pPtr = pHistoryFilter;
|
||||
while((pPtr = stptok(pPtr,token,50,":")) != NULL){
|
||||
if(strstr(command,token) != NULL){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void WriteCommandHistory(char *txt)
|
||||
{
|
||||
if(writeHistory == 0){
|
||||
return;
|
||||
}
|
||||
if(comHistory == NULL){
|
||||
openHistoryLog();
|
||||
}
|
||||
if(comHistory != NULL){
|
||||
if(historyFilter(txt)){
|
||||
fprintf(comHistory,"%s\n", txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void SetWriteHistory(int i)
|
||||
{
|
||||
/* writeHistory = i;*/
|
||||
writeHistory = 0;
|
||||
}
|
22
commandlog.h
22
commandlog.h
@ -1,22 +0,0 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
C O M M A N D L O G
|
||||
|
||||
A much requested facility for writing only user an manager level commands
|
||||
in a transcript file. This is it.
|
||||
|
||||
Mark Koennecke, June 1998
|
||||
|
||||
--------------------------------------------------------------------------*/
|
||||
#ifndef COMMANDLOG
|
||||
#define COMMANDLOG
|
||||
void WriteToCommandLog(const char *prompt, const char *pText);
|
||||
void WriteToCommandLogId(char *prompt, int id, char *text);
|
||||
void WriteToCommandLogCmd(int id, char *text);
|
||||
int CompactCommandLog(void);
|
||||
int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
void CommandLogClose(void *pData);
|
||||
void WriteCommandHistory(char *txt);
|
||||
void SetWriteHistory(int i);
|
||||
#endif
|
522
conman.c
522
conman.c
@ -62,13 +62,11 @@
|
||||
#include "passwd.h"
|
||||
#include "splitter.h"
|
||||
#include "macro.h"
|
||||
#include "servlog.h"
|
||||
#include "status.h"
|
||||
#include "interrupt.h"
|
||||
#include "ifile.h"
|
||||
#include "token.h"
|
||||
#include "uubuffer.h"
|
||||
#include "commandlog.h"
|
||||
#include "stptok.h"
|
||||
#include "statusfile.h"
|
||||
#include "sicshipadaba.h"
|
||||
@ -89,7 +87,7 @@ extern struct json_object *mkJSON_Object(SConnection * pCon, char *pBuffer,
|
||||
|
||||
extern pServer pServ;
|
||||
|
||||
#include "outcode.c" /* text for OutCode */
|
||||
#include "outcode.h" /* text for OutCode */
|
||||
|
||||
int KillCapture(SConnection * pCon);
|
||||
|
||||
@ -158,9 +156,9 @@ char *ConID(SConnection *pCon)
|
||||
|
||||
if(ANETvalidHandle(pCon->sockHandle)){
|
||||
ANETinfo(pCon->sockHandle, host, sizeof(host));
|
||||
snprintf(id,sizeof(id),"%s:%2.2d", host, pCon->sockHandle);
|
||||
snprintf(id,sizeof(id),"%s:sock%3.3d", host, pCon->sockHandle);
|
||||
} else {
|
||||
snprintf(id,sizeof(id),"disconnected:%2.2ld", pCon->ident);
|
||||
snprintf(id,sizeof(id),"disconnected:con%ld", pCon->ident);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@ -200,7 +198,7 @@ static SConnection *SCMakeConnection()
|
||||
pRes = (SConnection *) malloc(sizeof(SConnection));
|
||||
if (!pRes) {
|
||||
/* This is a serious, very serious error! */
|
||||
SICSLogWrite("ERROR: No memory to allocate connection!!", eInternal);
|
||||
Log(ERROR,"sys","%s","No memory to allocate connection!!");
|
||||
return NULL;
|
||||
}
|
||||
memset(pRes, 0, sizeof(SConnection));
|
||||
@ -223,8 +221,7 @@ static SConnection *CreateConnection(SicsInterp * pSics)
|
||||
used name */
|
||||
if (lastIdent == LONG_MAX) {
|
||||
/* This is a serious, very serious error! */
|
||||
SICSLogWrite("ERROR: Run out of connection identifiers!!",
|
||||
eInternal);
|
||||
Log(FATAL,"sys""%s","Run out of connection identifiers!!");
|
||||
return NULL;
|
||||
}
|
||||
lastIdent++;
|
||||
@ -235,7 +232,7 @@ static SConnection *CreateConnection(SicsInterp * pSics)
|
||||
pRes->pDes = CreateDescriptor("Connection");
|
||||
if (!pRes->pDes) {
|
||||
/* This is a serious, very serious error! */
|
||||
SICSLogWrite("ERROR: No memory to allocate connection!!", eInternal);
|
||||
Log(ERROR,"sys","%s","No memory to allocate connection!!");
|
||||
FreeConnection(pRes);
|
||||
return NULL;
|
||||
}
|
||||
@ -247,7 +244,7 @@ static SConnection *CreateConnection(SicsInterp * pSics)
|
||||
pRes->pStack = CreateCommandStack();
|
||||
if ((pRes->iList < 0) || (!pRes->pStack)) {
|
||||
/* This is a serious, very serious error! */
|
||||
SICSLogWrite("ERROR: No memory to allocate connection!!", eInternal);
|
||||
Log(ERROR,"sys","%s","No memory to allocate connection!!");
|
||||
DeleteDescriptor(pRes->pDes);
|
||||
FreeConnection(pRes);
|
||||
return NULL;
|
||||
@ -310,7 +307,7 @@ SConnection *SCCreateDummyConnection(SicsInterp * pSics)
|
||||
pRes->iUserRights = usInternal;
|
||||
pRes->iGrab = 0;
|
||||
|
||||
SICSLogWrite("Accepted dummy connection ", eInternal);
|
||||
/* Log(INFO,"SYS","%s","Accepted dummy connection "); */
|
||||
|
||||
return pRes;
|
||||
}
|
||||
@ -319,11 +316,11 @@ SConnection *SCCreateDummyConnection(SicsInterp * pSics)
|
||||
int VerifyConnection(SConnection * self)
|
||||
{
|
||||
if (!self) {
|
||||
SICSLogWrite("MAGICERROR: Invalid call to NULL connection", eError);
|
||||
Log(ERROR,"sys","%s","MAGICERROR: Invalid call to NULL connection");
|
||||
return 0;
|
||||
}
|
||||
if (self->lMagic != CONMAGIC) {
|
||||
SICSLogWrite("MAGICERROR: corrupted connection object", eError);
|
||||
Log(ERROR,"sys","%s","MAGICERROR: corrupted connection object");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -379,8 +376,7 @@ void SCDeleteMasterFields(SConnection * pVictim)
|
||||
if (SCActive(pVictim)) {
|
||||
SCnoSock(pVictim);
|
||||
ANETclose(pVictim->sockHandle);
|
||||
WriteToCommandLog("SYS>",
|
||||
"ERROR: Erraneous deletion of used Connection stopped");
|
||||
Log(ERROR,"sys","%s","Erraneous deletion of used Connection stopped");
|
||||
pVictim->sockHandle = -1;
|
||||
return;
|
||||
}
|
||||
@ -410,10 +406,9 @@ void SCDeleteMasterFields(SConnection * pVictim)
|
||||
|
||||
/* log the kill */
|
||||
if (pVictim->sockHandle >= 0 && pVictim->iLogin == 1 &&
|
||||
(pVictim->iUserRights < 3 || !CompactCommandLog())) {
|
||||
pVictim->iUserRights < 3) {
|
||||
sprintf(pBueffel, "Deleting connection %d", pVictim->sockHandle);
|
||||
WriteToCommandLog("SYS>", pBueffel);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
Log(DEBUG,"sys","%s", pBueffel);
|
||||
}
|
||||
|
||||
/* close all open files and sockets */
|
||||
@ -481,7 +476,10 @@ SConnection *SCCopyConnection(SConnection * pCon)
|
||||
result->iMacro = pCon->iMacro;
|
||||
result->iTelnet = pCon->iTelnet;
|
||||
result->iOutput = pCon->iOutput;
|
||||
result->write = pCon->write;
|
||||
if (pCon->oldWriteFunc != NULL)
|
||||
result->write = pCon->oldWriteFunc;
|
||||
else
|
||||
result->write = pCon->write;
|
||||
result->listening = pCon->listening;
|
||||
result->eInterrupt = pCon->eInterrupt;
|
||||
result->inUse = pCon->inUse;
|
||||
@ -657,9 +655,6 @@ int SCWrite(SConnection * self, char *pBuffer, int iOut)
|
||||
if (pBuffer == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if(!SCinMacro(self) || mustWrite(iOut) ){
|
||||
traceCommand(ConID(self),"out:%s", pBuffer);
|
||||
}
|
||||
return self->write(self, pBuffer, iOut);
|
||||
}
|
||||
|
||||
@ -745,8 +740,8 @@ static int doSockWrite(SConnection * self, char *buffer)
|
||||
if (!iRet) {
|
||||
SCnoSock(self);
|
||||
if (!self->listening && self->iLogin == 1 &&
|
||||
(self->iUserRights < 3 || !CompactCommandLog())) {
|
||||
WriteToCommandLog("SYS>", "Connection broken on send");
|
||||
self->iUserRights < 3) {
|
||||
Log(ERROR,"sys","%s", "Connection broken on send");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -759,25 +754,6 @@ static int doSockWrite(SConnection * self, char *buffer)
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void testAndWriteCommandLog(SConnection * pCon, char *buffer,
|
||||
int iOut)
|
||||
{
|
||||
if (SCGetRights(pCon) <= usUser) {
|
||||
if (SCinMacro(pCon) != 1) {
|
||||
SetSendingConnection(pCon);
|
||||
WriteToCommandLogId(NULL, pCon->sockHandle, buffer);
|
||||
SetSendingConnection(NULL);
|
||||
} else {
|
||||
if (iOut == eLog || iOut == eLogError) {
|
||||
SetSendingConnection(pCon);
|
||||
WriteToCommandLogId(NULL, pCon->sockHandle, buffer);
|
||||
SetSendingConnection(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void testAndStoreInTcl(SConnection * pCon, char *buffer, int iOut)
|
||||
{
|
||||
@ -824,56 +800,86 @@ static int isOK(const char *buffer)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static void testAndWriteSICSLog(SConnection * self, char *buffer, int iOut)
|
||||
static void testAndWriteLog(SConnection * self, char *buffer, int iOut)
|
||||
{
|
||||
char tp;
|
||||
/* We don't want to log the "OK" messages */
|
||||
if (isOK(buffer))
|
||||
return;
|
||||
unsigned int severity;
|
||||
|
||||
if (SCinMacro(self)) {
|
||||
tp = 'M';
|
||||
if (sicsdebug())
|
||||
tp = 'D';
|
||||
} else
|
||||
tp = 'N';
|
||||
switch (iOut) {
|
||||
case eStatus:
|
||||
case eStart:
|
||||
case eFinish:
|
||||
case eEvent:
|
||||
case eHdbValue:
|
||||
case eHdbEvent:
|
||||
case eLog:
|
||||
case eLogError:
|
||||
case eError:
|
||||
case eWarning:
|
||||
/* Log it */
|
||||
SICSLogWriteCode(buffer, iOut, tp);
|
||||
return;
|
||||
case eValue:
|
||||
if (sicsdebug() || !SCinMacro(self)) {
|
||||
/* Log it */
|
||||
SICSLogWriteCode(buffer, iOut, tp);
|
||||
return;
|
||||
} else {
|
||||
/* Suppressed */
|
||||
#if 0
|
||||
tp = tolower(tp);
|
||||
SICSLogWriteCode(buffer, iOut, tp);
|
||||
#endif
|
||||
return;
|
||||
/*
|
||||
first those which allways go into the log
|
||||
*/
|
||||
|
||||
if(SCGetRights(self) > usUser) {
|
||||
severity = DEBUG;
|
||||
} else {
|
||||
severity = INFO;
|
||||
}
|
||||
|
||||
switch(iOut){
|
||||
case eInternal:
|
||||
Log(ERROR,"sys","%s",buffer);
|
||||
break;
|
||||
case eCommand:
|
||||
if(!SCinMacro(self)){
|
||||
Log(DEBUG,"sys","%s",buffer);
|
||||
}
|
||||
break;
|
||||
case eHWError:
|
||||
case eInError:
|
||||
Log(ERROR,"dev","%s",buffer);
|
||||
break;
|
||||
case eStatus:
|
||||
Log(DEBUG,"io","%s",buffer);
|
||||
break;
|
||||
case eEvent:
|
||||
if(strstr(buffer,"ERROR") != NULL){
|
||||
Log(ERROR,"notify",buffer);
|
||||
}else if(strstr(buffer,"WARNING") != NULL) {
|
||||
Log(WARN,"notify",buffer);
|
||||
} else {
|
||||
Log(DEBUG,"notify",buffer);
|
||||
}
|
||||
break;
|
||||
case eHdbEvent:
|
||||
case eHdbValue:
|
||||
Log(INFO,"notify","%s",buffer);
|
||||
break;
|
||||
case eLog:
|
||||
Log(severity,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
break;
|
||||
case eLogError:
|
||||
Log(ERROR,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
break;
|
||||
case eError:
|
||||
if(!SCinMacro(self)){
|
||||
if(severity == DEBUG){
|
||||
Log(DEBUG,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
} else {
|
||||
Log(ERROR,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eWarning:
|
||||
if(!SCinMacro(self)){
|
||||
if(severity == DEBUG){
|
||||
Log(DEBUG,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
} else {
|
||||
Log(WARN,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case eValue:
|
||||
if(!SCinMacro(self)){
|
||||
Log(severity,"com","sock%03.3d:%s",self->sockHandle,buffer);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("Unrecognized ouput code %d in testAndWriteSICSLog: FIXME!!!\n", iOut);
|
||||
SICSLogWriteCode(buffer, iOut, tp);
|
||||
return;
|
||||
Log(DEBUG,"sys","Unknown outcode %d detected, FIXME ASAP!!!", iOut);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int SCNormalWrite(SConnection * self, char *buffer, int iOut)
|
||||
{
|
||||
@ -888,13 +894,7 @@ int SCNormalWrite(SConnection * self, char *buffer, int iOut)
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
#if 0
|
||||
SICSLogWrite(buffer, iOut);
|
||||
#else
|
||||
testAndWriteSICSLog(self, buffer, iOut);
|
||||
#endif
|
||||
|
||||
testAndWriteCommandLog(self, buffer, iOut);
|
||||
testAndWriteLog(self, buffer, iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
|
||||
@ -915,10 +915,7 @@ int SCAllWrite(SConnection * self, char *buffer, int iOut)
|
||||
return 1; /* do not write empty line */
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
SICSLogWrite(buffer, iOut);
|
||||
|
||||
testAndWriteCommandLog(self, buffer, iOut);
|
||||
testAndWriteLog(self, buffer, iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
|
||||
@ -943,10 +940,7 @@ int SCACTWrite(SConnection * self, char *buffer, int iOut)
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
sprintf(pBueffel, "Next line intended for socket: %d", self->sockHandle);
|
||||
SICSLogWrite(buffer, iOut);
|
||||
|
||||
testAndWriteCommandLog(self, buffer, iOut);
|
||||
testAndWriteLog(self, buffer, iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
|
||||
@ -983,11 +977,7 @@ int SCWriteWithOutcode(SConnection * self, char *buffer, int iOut)
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
sprintf(pBueffel, "Next line intended for socket: %d", self->sockHandle);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
SICSLogWrite(buffer, iOut);
|
||||
|
||||
testAndWriteCommandLog(self, buffer, iOut);
|
||||
testAndWriteLog(self, buffer, iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
/*
|
||||
@ -996,8 +986,7 @@ int SCWriteWithOutcode(SConnection * self, char *buffer, int iOut)
|
||||
length = strlen(buffer) + strlen(pCode[iOut]) + 10;
|
||||
bufPtr = (char *) malloc(length * sizeof(char));
|
||||
if (!bufPtr) {
|
||||
SICSLogWrite("SYS>>ERROR: out of memory in SCWriteWithOutcode",
|
||||
eError);
|
||||
Log(ERROR,"sys","%s","out of memory in SCWriteWithOutcode");
|
||||
return 0;
|
||||
}
|
||||
memset(bufPtr, 0, length * sizeof(char));
|
||||
@ -1075,9 +1064,7 @@ int SCOnlySockWrite(SConnection * self, char *buffer, int iOut)
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
sprintf(pBueffel, "Next line intended for socket: %d", self->sockHandle);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
SICSLogWrite(buffer, iOut);
|
||||
testAndWriteLog(self,buffer,iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
|
||||
@ -1135,7 +1122,7 @@ int SCLogWrite(SConnection * self, char *buffer, int iOut)
|
||||
return 0;
|
||||
}
|
||||
SetSendingConnection(self);
|
||||
WriteToCommandLogId(NULL, self->sockHandle, buffer);
|
||||
Log(INFO,"com","sock%03.3d%s", self->sockHandle, buffer);
|
||||
SetSendingConnection(NULL);
|
||||
|
||||
if(self->iProtocolID == PROTACT) { /* act */
|
||||
@ -1209,12 +1196,8 @@ int SCFileWrite(SConnection * self, char *buffer, int iOut)
|
||||
}
|
||||
|
||||
/* log it for any case */
|
||||
sprintf(pBueffel, "Next line intended for socket: %d", self->sockHandle);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
|
||||
SICSLogWrite(buffer, iOut);
|
||||
|
||||
testAndWriteCommandLog(self, buffer, iOut);
|
||||
testAndWriteLog(self, buffer, iOut);
|
||||
|
||||
testAndStoreInTcl(self, buffer, iOut);
|
||||
|
||||
@ -1257,7 +1240,7 @@ int SCWriteUUencoded(SConnection * pCon, char *pName, void *pData,
|
||||
ANETwrite(pCon->sockHandle, pPtr, iLength);
|
||||
}
|
||||
|
||||
traceCommand(ConID(pCon),"out:UUData %s %d", pName, iLength);
|
||||
Log(DEBUG,"com","%s:out:UUData %s %d",ConID(pCon) ,pName, iLength);
|
||||
|
||||
|
||||
#ifdef UUDEB
|
||||
@ -1360,7 +1343,7 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
|
||||
SCWrite(self, "ERROR: out of memory in SCWriteZipped", eError);
|
||||
return 0;
|
||||
}
|
||||
traceCommand(ConID(self),"out:SICSBIN ZIP %s %d", pName, compressedLength);
|
||||
Log(DEBUG,"com", "%s:out:SICSBIN ZIP %s %d", ConID(self), pName, compressedLength);
|
||||
|
||||
|
||||
iRet = ANETwrite(self->sockHandle, pHeader, strlen(pHeader));
|
||||
@ -1435,7 +1418,7 @@ int SCWriteBinary(SConnection * self, char *pName, void *pData,
|
||||
SCWrite(self, "ERROR: out of memory in SCWriteBinary", eError);
|
||||
return 0;
|
||||
}
|
||||
traceCommand(ConID(self),"out:SICSBIN BIN %s %d", pName, iDataLen);
|
||||
Log(DEBUG,"com","%s:out:SICSBIN BIN %s %d", ConID(self), pName, iDataLen);
|
||||
|
||||
iRet = ANETwrite(self->sockHandle, pHeader, strlen(pHeader));
|
||||
iRet = ANETwrite(self->sockHandle, pData, iDataLen);
|
||||
@ -1450,147 +1433,6 @@ int SCWriteBinary(SConnection * self, char *pName, void *pData,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------
|
||||
* left in for documentation............
|
||||
*/
|
||||
int SCWriteZippedOld(SConnection * self, char *pName, void *pData,
|
||||
int iDataLen)
|
||||
{
|
||||
char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL;
|
||||
int compressedLength, iRet, iRet2, iCount, protocolID;
|
||||
z_stream compStream;
|
||||
commandContext cc;
|
||||
|
||||
/* check for a valid connection */
|
||||
if (!VerifyConnection(self)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a telnet connection will corrupt the compressed stream, so
|
||||
stop it!
|
||||
*/
|
||||
if (self->iTelnet) {
|
||||
SCWrite(self,
|
||||
"ERROR: the telnet protocoll will corrupt compressed data!",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
do nothing if no data
|
||||
*/
|
||||
if (pName == NULL || pData == NULL) {
|
||||
SCWrite(self, "ERROR: no data to write in SCWriteZiped", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize the compression stuff */
|
||||
compStream.zalloc = (alloc_func) NULL;
|
||||
compStream.zfree = (free_func) NULL;
|
||||
compStream.opaque = (voidpf) NULL;
|
||||
|
||||
iRet = deflateInit(&compStream, Z_DEFAULT_COMPRESSION);
|
||||
if (iRet != Z_OK) {
|
||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* first pass: find out how the long the compressed buffer will be */
|
||||
compressedLength = 0;
|
||||
compStream.next_in = (Bytef *) pData;
|
||||
compStream.next_out = (Bytef *) outBuf;
|
||||
compStream.avail_in = iDataLen;
|
||||
compStream.avail_out = 65536;
|
||||
while (compStream.total_in < iDataLen) {
|
||||
iRet = deflate(&compStream, Z_NO_FLUSH);
|
||||
if (iRet != Z_OK) {
|
||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
compStream.next_out = (Bytef *) outBuf;
|
||||
compStream.avail_out = 65536;
|
||||
}
|
||||
for (;;) {
|
||||
iRet = deflate(&compStream, Z_FINISH);
|
||||
if (iRet == Z_STREAM_END)
|
||||
break;
|
||||
if (iRet != Z_OK) {
|
||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
compressedLength = compStream.total_out;
|
||||
deflateEnd(&compStream);
|
||||
|
||||
/* write header line */
|
||||
memset(outBuf, 0, 65536);
|
||||
|
||||
protocolID = GetProtocolID(self);
|
||||
if (protocolID == PROTACT) {
|
||||
cc = SCGetContext(self);
|
||||
sprintf(outBuf, "SICSBIN ZIP %s %d %d\r\n", pName,
|
||||
compressedLength, cc.transID);
|
||||
} else {
|
||||
sprintf(outBuf, "SICSBIN ZIP %s %d \r\n", pName, compressedLength);
|
||||
}
|
||||
pHeader = strdup(outBuf);
|
||||
if (pHeader == NULL) {
|
||||
SCWrite(self, "ERROR: out of memory in SCWriteZipped", eError);
|
||||
return 0;
|
||||
}
|
||||
traceCommand(ConID(self),"out:SICSBIN ZIP %s %d", pName, compressedLength);
|
||||
|
||||
|
||||
/* now reset the deflater and do the same with writing data */
|
||||
compStream.zalloc = (alloc_func) NULL;
|
||||
compStream.zfree = (free_func) NULL;
|
||||
compStream.opaque = (voidpf) NULL;
|
||||
|
||||
|
||||
/*
|
||||
This is writing everything in one go as I found that writing in
|
||||
several chunks did not ensure that all the data arrived at the
|
||||
Java side.
|
||||
*/
|
||||
|
||||
iRet = deflateInit(&compStream, Z_DEFAULT_COMPRESSION);
|
||||
if (iRet != Z_OK) {
|
||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pBuf = (char *) malloc((iDataLen + iDataLen / 10 + 50) * sizeof(char));
|
||||
memset(pBuf, 0, (iDataLen + iDataLen / 10 + 50) * sizeof(char));
|
||||
compStream.next_in = (Bytef *) pData;
|
||||
compStream.next_out = (Bytef *) pBuf;
|
||||
compStream.avail_in = iDataLen;
|
||||
compStream.avail_out = iDataLen + iDataLen / 10 + 50;
|
||||
iRet = deflate(&compStream, Z_FINISH);
|
||||
if (iRet != Z_STREAM_END) {
|
||||
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = ANETwrite(self->sockHandle, pHeader, strlen(pHeader));
|
||||
iRet = ANETwrite(self->sockHandle, pBuf, compStream.total_out);
|
||||
if (iRet != 1) {
|
||||
sprintf(outBuf, "ERROR: network error %d on zipped send", iRet);
|
||||
SCWrite(self, outBuf, eError);
|
||||
return 0;
|
||||
}
|
||||
/* printf("Sent zipped data: %s with %d\n", pHeader, iRet); */
|
||||
|
||||
deflateEnd(&compStream);
|
||||
free(pHeader);
|
||||
free(pBuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int SCSendOK(SConnection * self)
|
||||
{
|
||||
@ -1691,7 +1533,7 @@ int SCPrompt(SConnection * pCon, char *pPrompt, char *pResult, int iLen)
|
||||
if (iRet == 1) {
|
||||
CostaLock(master->pStack);
|
||||
strlcpy(pResult, pPtr, iLen);
|
||||
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
|
||||
Log(INFO,"sys","prompted%03.3d:", pCon->sockHandle, pPtr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -1736,7 +1578,7 @@ int SCPromptTMO(SConnection * pCon, char *pPrompt, char *pResult, int iLen, int
|
||||
if (iRet == 1) {
|
||||
CostaLock(master->pStack);
|
||||
strlcpy(pResult, pPtr, iLen);
|
||||
WriteToCommandLogId(" prompted>", pCon->sockHandle, pPtr);
|
||||
Log(INFO,"com"," prompted%03.3d:", pCon->sockHandle, pPtr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -1837,10 +1679,10 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
|
||||
SetSendingConnection(self);
|
||||
if (self->sockHandle >= 0) {
|
||||
if(strstr(pCommand,"Poch") == NULL){
|
||||
WriteToCommandLogCmd(self->sockHandle, pCommand);
|
||||
Log(INFO,"com","sock%03.3d:",self->sockHandle, pCommand);
|
||||
}
|
||||
} else {
|
||||
WriteToCommandLog("CRON>>", pCommand);
|
||||
Log(INFO,"sys","CRON:%s", pCommand);
|
||||
}
|
||||
SetSendingConnection(NULL);
|
||||
}
|
||||
@ -1865,7 +1707,16 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand)
|
||||
return 0;
|
||||
}
|
||||
strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN);
|
||||
traceCommand(ConID(self),"in:%s", pCommand);
|
||||
/*
|
||||
do not log the log command; defeats log control
|
||||
*/
|
||||
if(strstr(pCommand,"log ") == NULL) {
|
||||
if(SCGetRights(self) > usUser){
|
||||
Log(DEBUG,"com","%s:in:%s", ConID(self),pCommand);
|
||||
} else {
|
||||
Log(INFO,"com", "%s:in:%s", ConID(self),pCommand);
|
||||
}
|
||||
}
|
||||
iRet = InterpExecute(pInter, pCopy, pCommand);
|
||||
SCDeleteConnection(pCopy);
|
||||
StatusFileTask(NULL); /* save changed parameters */
|
||||
@ -2001,19 +1852,9 @@ int ConfigCon(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
if (CompactCommandLog()) {
|
||||
if (pCon->iUserRights < 3 || i < 3) {
|
||||
ANETinfo(pCon->sockHandle, pHost, sizeof pHost);
|
||||
snprintf(pBueffel, sizeof pBueffel,
|
||||
"User %s from %s switched to %d privilege",
|
||||
argv[2], pHost, i);
|
||||
WriteToCommandLogId("SYS>", pCon->sockHandle, pBueffel);
|
||||
}
|
||||
} else {
|
||||
snprintf(pBueffel, 511, "User %s handle %d switched to %d privilege",
|
||||
snprintf(pBueffel, 511, "User %s handle %d switched to %d privilege",
|
||||
argv[2], pCon->sockHandle, i);
|
||||
WriteToCommandLog("SYS>", pBueffel);
|
||||
}
|
||||
Log(INFO,"sys","%s", pBueffel);
|
||||
pCon->iUserRights = i;
|
||||
pMaster->iUserRights = i;
|
||||
SCWrite(pCon, "Change of Authorisation Acknowledged", eWarning);
|
||||
@ -2276,114 +2117,9 @@ static void hookFunc(const char *pText, OutCode eOut, void*pData)
|
||||
|
||||
int KillCapture(SConnection * pCon)
|
||||
{
|
||||
RemSICSLogHook(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
the command function:
|
||||
Syntax:
|
||||
Kill kills all logging
|
||||
Log OutCode starts loggin OutCode events
|
||||
All starts logging all events
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
int LogCapture(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
SConnection * pConMaster;
|
||||
char pBueffel[512];
|
||||
int i;
|
||||
|
||||
pConMaster = SCfindMaster(pCon);
|
||||
if (pConMaster == NULL)
|
||||
return 0;
|
||||
/* check no af args */
|
||||
if (argc < 2) {
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "Insufficient number of arguments to %s", argv[0]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
argtolower(argc, argv);
|
||||
|
||||
/* Branch according to argv[1] */
|
||||
if (strcmp(argv[1], "kill") == 0 || strcmp(argv[1], "none") == 0) {
|
||||
SCPrintf(pCon, eLog, "getlog %s", argv[1]);
|
||||
KillCapture(pConMaster);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "what") == 0) {
|
||||
unsigned int code_bits = 0;
|
||||
pDynString buffer;
|
||||
code_bits = (1 << iNoCodes) - 1;
|
||||
buffer = CreateDynString(100, 100);
|
||||
for (i = 0; i < iNoCodes; ++i) {
|
||||
if (code_bits & (1 << i)) {
|
||||
if (GetDynStringLength(buffer) > 0)
|
||||
DynStringConcatChar(buffer, ',');
|
||||
DynStringConcat(buffer, (char *)OutCodeToTxt(i));
|
||||
}
|
||||
}
|
||||
SCPrintf(pCon, eLog, "getlog %s", GetCharArray(buffer));
|
||||
DeleteDynString(buffer);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "list") == 0) {
|
||||
unsigned int code_bits = 0;
|
||||
pDynString buffer;
|
||||
code_bits = GetSICSLogHook(pConMaster);
|
||||
if (code_bits == 0) {
|
||||
SCPrintf(pCon, eLog, "getlog none");
|
||||
return 1;
|
||||
}
|
||||
buffer = CreateDynString(100, 100);
|
||||
for (i = 0; i < iNoCodes; ++i) {
|
||||
if (code_bits & (1 << i)) {
|
||||
if (GetDynStringLength(buffer) > 0)
|
||||
DynStringConcatChar(buffer, ',');
|
||||
DynStringConcat(buffer, (char *)OutCodeToTxt(i));
|
||||
}
|
||||
}
|
||||
SCPrintf(pCon, eLog, "getlog %s", GetCharArray(buffer));
|
||||
DeleteDynString(buffer);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "all") == 0) {
|
||||
SCPrintf(pCon, eLog, "getlog all");
|
||||
AddSICSLogHook(hookFunc, "all", pConMaster);
|
||||
return 1;
|
||||
} else if (argc == 2) {
|
||||
/* must be outcode, try find it */
|
||||
SCPrintf(pCon, eLog, "getlog %s", argv[1]);
|
||||
AddSICSLogHook(hookFunc, argv[1], pConMaster);
|
||||
return 1;
|
||||
} else {
|
||||
/* make it a list */
|
||||
int i;
|
||||
size_t len;
|
||||
char *pBuff;
|
||||
for (i = 1, len = 0; i < argc; ++i)
|
||||
len += strlen(argv[i]) + 1;
|
||||
if (len > sizeof(pBueffel))
|
||||
pBuff = malloc(len);
|
||||
else
|
||||
pBuff = pBueffel;
|
||||
if (pBuff == NULL) {
|
||||
SCWrite(pCon, "Out of memory in LogCapture\n", eError);
|
||||
return 1;
|
||||
}
|
||||
for (i = 1, len = 0; i < argc; ++i) {
|
||||
if (i > 1)
|
||||
pBuff[len++] = ',';
|
||||
strcpy(&pBuff[len], argv[i]);
|
||||
len += strlen(argv[i]);
|
||||
}
|
||||
SCPrintf(pCon, eLog, "getlog %s", pBuff);
|
||||
AddSICSLogHook(hookFunc, pBuff, pConMaster);
|
||||
if (pBuff != pBueffel)
|
||||
free(pBuff);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* ------------------------------------------------------------------------
|
||||
the command function:
|
||||
Syntax:
|
||||
@ -2434,7 +2170,7 @@ int LogOutput(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
strcpy(&pBuff[len], argv[i]);
|
||||
len += strlen(argv[i]);
|
||||
}
|
||||
SICSLogWrite(pBuff, outcode);
|
||||
Log(INFO,"com","%s",pBuff);
|
||||
if (pBuff != pBueffel)
|
||||
free(pBuff);
|
||||
return 1;
|
||||
@ -2457,6 +2193,7 @@ int SCTaskFunction(void *pData)
|
||||
if (SCActive(self)) {
|
||||
return 1;
|
||||
} else {
|
||||
Log(INFO,"sys","Handle %d disconnected", self->sockHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -2487,6 +2224,7 @@ int SCTaskFunction(void *pData)
|
||||
if (strstr(pPtr, "logoff") != NULL) {
|
||||
ANETclose(self->sockHandle);
|
||||
self->iEnd = 1;
|
||||
Log(INFO,"sys","Handle %d loging off", self->sockHandle);
|
||||
free(pPtr);
|
||||
return 1;
|
||||
}
|
||||
@ -2513,27 +2251,15 @@ int SCTaskFunction(void *pData)
|
||||
self->iLogin = 1;
|
||||
SCSetRights(self, iRet);
|
||||
pHost[0] = '\0';
|
||||
if (CompactCommandLog()) {
|
||||
if (iRet < 3) {
|
||||
ANETinfo(self->sockHandle, pHost, 131);
|
||||
sprintf(pBueffel, "Accepted connection %s from %s as %s",
|
||||
ConName(self->ident), pHost, pUser);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
WriteToCommandLogId("SYS>", self->sockHandle, pBueffel);
|
||||
}
|
||||
} else {
|
||||
ANETinfo(self->sockHandle, pHost, 131);
|
||||
snprintf(pBueffel, 511,
|
||||
ANETinfo(self->sockHandle, pHost, 131);
|
||||
snprintf(pBueffel, 511,
|
||||
"Accepted connection %s on socket %d from %s",
|
||||
ConName(self->ident), self->sockHandle, pHost);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
WriteToCommandLog("SYS >", pBueffel);
|
||||
}
|
||||
Log(INFO,"sys","%s",pBueffel);
|
||||
free(pPtr);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(self, "ERROR: Bad login", eError);
|
||||
printf("Bad login string %s\n", pPtr);
|
||||
SCPrintf(self, eError, "ERROR: Bad login: %s", pPtr);
|
||||
}
|
||||
}
|
||||
free(pPtr);
|
||||
|
1
conman.h
1
conman.h
@ -40,7 +40,6 @@ typedef struct __SConnection {
|
||||
pObjectDescriptor pDes; /* must be here */
|
||||
long lMagic; /* connection object ID */
|
||||
long ident; /* connection idetification */
|
||||
struct __SConnection *next; /* pointer for freeConnection managenment */
|
||||
int sockHandle; /* socket handle */
|
||||
int iTelnet; /* telnet flag */
|
||||
int iMacro; /* suppress I/O in macro */
|
||||
|
@ -747,7 +747,7 @@ int CounterInterest(int iEvent, void *pEvent, void *pUser)
|
||||
* prevent this to be written to log files
|
||||
*/
|
||||
SCSetRights(pCon, usSpy);
|
||||
SCWrite(pCon, pBueffel, eLog);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -1022,7 +1022,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
if (!SCMatchRights(pCon, usMugger)) {
|
||||
if (!SCMatchRights(pCon, usUser)) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: Insufficient privilege to set threshold", eError);
|
||||
return 0;
|
||||
|
56
countersec.c
56
countersec.c
@ -39,27 +39,40 @@ static void SecCounterSetError(pCounter self, char *text)
|
||||
if(node != NULL){
|
||||
v = MakeHdbText(strdup(text));
|
||||
UpdateHipadabaPar(node,v,NULL);
|
||||
Log(VERBOSE,"par","%s:error:%s", self->name,text);
|
||||
ReleaseHdbValue(&v);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code)
|
||||
{
|
||||
pHdb node = NULL;
|
||||
pHdb node = NULL, status = NULL;
|
||||
hdbValue v;
|
||||
|
||||
node = GetHipadabaNode(self->pDes->parNode, "control");
|
||||
status = GetHipadabaNode(self->pDes->parNode, "status");
|
||||
assert(node != NULL);
|
||||
assert(status != NULL);
|
||||
v = MakeHdbFloat(code);
|
||||
if(code != START && strcmp(status->value.v.text,"starting") == 0){
|
||||
UpdateHipadabaPar(node,MakeHdbText("run"),NULL);
|
||||
}
|
||||
return SetHipadabaPar(node,v,pCon);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int SecCtrHalt(void *pData)
|
||||
{
|
||||
pCounter self = (pCounter)pData;
|
||||
pHdb node = NULL;
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
SecCtrInvokeFunction(self,pServ->dummyCon, STOP);
|
||||
node = GetHipadabaNode(self->pDes->parNode, "status");
|
||||
assert(node != NULL);
|
||||
if(strcmp(node->value.v.text,"starting") == 0){
|
||||
UpdateHipadabaPar(node,MakeHdbText("run"),NULL);
|
||||
}
|
||||
ReleaseCountLock(self->pCountInt);
|
||||
return 1;
|
||||
}
|
||||
@ -77,7 +90,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
}
|
||||
|
||||
statusNode = GetHipadabaNode(self->pDes->parNode, "status");
|
||||
UpdateHipadabaPar(statusNode,MakeHdbText("run"), pCon);
|
||||
UpdateHipadabaPar(statusNode,MakeHdbText("starting"), pCon);
|
||||
status = SecCtrInvokeFunction(self,pCon, START);
|
||||
self->haltFixFlag = 0;
|
||||
if(status == 1){
|
||||
@ -86,6 +99,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
self->tStart = time(NULL);
|
||||
node = GetHipadabaNode(self->pDes->parNode, "control");
|
||||
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
|
||||
Log(VERBOSE,"par","%s:control:%s", self->name,"0");
|
||||
SetHdbProperty(node,"geterror", NULL);
|
||||
/*
|
||||
* set time to 0. Otherwise, if there is a delay,
|
||||
@ -94,6 +108,7 @@ static int SecStartCount(void *pData, SConnection *pCon)
|
||||
*/
|
||||
node = GetHipadabaNode(self->pDes->parNode, "time");
|
||||
UpdateHipadabaPar(node,MakeHdbFloat(.0), pCon);
|
||||
Log(VERBOSE,"par","%s:time:%s", self->name,"0");
|
||||
InvokeCallBack(self->pCall,COUNTSTART, pCon);
|
||||
SecCounterSetError(self,"None");
|
||||
return 1;
|
||||
@ -150,6 +165,8 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
|
||||
status = HWIdle;
|
||||
} else if (strstr(v.v.text, "run") != NULL) {
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "starting") != NULL) {
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "nobeam") != NULL) {
|
||||
status = HWNoBeam;
|
||||
} else if (strstr(v.v.text, "pause") != NULL) {
|
||||
@ -192,6 +209,9 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon)
|
||||
The 1 below is only correct for PSI where only the first
|
||||
monitor can be the control monitor. Elsewhere this must be the
|
||||
control monitor channel
|
||||
|
||||
This may need to change with the second generation DAQ where the
|
||||
count control channel can be changed.
|
||||
*/
|
||||
fControl = v.v.intArray[1];
|
||||
}
|
||||
@ -291,7 +311,9 @@ static int SecCtrSetMode(pCounter self, CounterMode eNew)
|
||||
v = MakeHdbText("monitor");
|
||||
break;
|
||||
}
|
||||
Log(VERBOSE,"par","%s:mode:%s", self->name,v.v.text);
|
||||
return SetHipadabaPar(node,v,NULL);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static CounterMode SecCtrGetMode(pCounter self)
|
||||
@ -321,6 +343,7 @@ static int SecCtrSetPreset(pCounter self, float val)
|
||||
node = GetHipadabaNode(self->pDes->parNode,"preset");
|
||||
assert(node != NULL);
|
||||
v = MakeHdbFloat(val);
|
||||
Log(VERBOSE,"par","%s:preset:%f", self->name,v.v.doubleValue);
|
||||
return SetHipadabaPar(node,v,NULL);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -559,6 +582,32 @@ static int CountStatusCmd(pSICSOBJ ccmd, SConnection * con,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
Disallows status changes from starting to anything else but run or
|
||||
error
|
||||
----------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn SecStatusCallback(pHdb node, void *userData,
|
||||
pHdbMessage message)
|
||||
{
|
||||
pHdbDataMessage mm = NULL;
|
||||
hdbValue v;
|
||||
pCounter self = (pCounter)userData;
|
||||
|
||||
mm = GetHdbUpdateMessage(message);
|
||||
if (mm != NULL) {
|
||||
v = *mm->v;
|
||||
if(strcmp(node->value.v.text,"starting") == 0) {
|
||||
if(strstr(v.v.text,"run") == 0 && strstr(v.v.text,"error") == 0) {
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
if(strcmp(v.v.text,node->value.v.text) != 0){
|
||||
Log(VERBOSE,"par","%s:status:%s", self->name,v.v.text);
|
||||
}
|
||||
}
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
{
|
||||
@ -644,6 +693,9 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length)
|
||||
if (child == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
AppendHipadabaCallback(child,
|
||||
MakeHipadabaCallback(SecStatusCallback, pRes,
|
||||
NULL));
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeSICSHdbPar("error", usInternal, MakeHdbText("None"));
|
||||
|
2
danu.c
2
danu.c
@ -122,7 +122,7 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
||||
iNum = readDataNumber(self);
|
||||
if (iNum > 0) {
|
||||
snprintf(pBueffel, 131, "sicsdatanumber = %d", iNum);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -67,7 +67,6 @@
|
||||
#include "devexec.h"
|
||||
#include "status.h"
|
||||
#include "lld.h"
|
||||
#include "commandlog.h"
|
||||
#include "ifile.h"
|
||||
|
||||
/*
|
||||
@ -250,7 +249,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||
char *overwriteOption;
|
||||
float oldVal;
|
||||
long taskID;
|
||||
pTaskGroupData taskGroup = NULL;
|
||||
|
||||
assert(self);
|
||||
assert(pDes);
|
||||
@ -329,7 +327,7 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
|
||||
self->lTask = TaskRegisterN(self->pTask,"devexec",
|
||||
DevExecTask,
|
||||
DevExecSignal,
|
||||
NULL, self,1);
|
||||
NULL, self,TASK_PRIO_HIGH);
|
||||
}
|
||||
pCon->conStatus = HWBusy;
|
||||
return 1;
|
||||
|
@ -118,6 +118,8 @@ $\langle$devcheck {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int DevExecTask(void *pEL);@\\
|
||||
\mbox{}\verb@ void DevExecSignal(void *pEL, int iSignal, void *pSigData);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int GetDevExecInstStatus(pExeList self);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\Diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
|
3
devser.c
3
devser.c
@ -308,7 +308,7 @@ DevSer *DevMake(SConnection * con, int argc, char *argv[])
|
||||
devser->status = AsconUnconnected;
|
||||
devser->startTime = -1;
|
||||
TaskRegisterN(pServ->pTasker, AsconHostport(ascon),
|
||||
DevQueueTask, NULL, NULL, devser, 0);
|
||||
DevQueueTask, NULL, NULL, devser, TASK_PRIO_HIGH);
|
||||
return devser;
|
||||
}
|
||||
|
||||
@ -580,6 +580,7 @@ char *DevStatus(DevSer *devser) {
|
||||
switch (devser->status) {
|
||||
case AsconOffline: return "disconnected";
|
||||
case AsconUnconnected: return "unconnected";
|
||||
case AsconConnectPending: return "connecting";
|
||||
/*
|
||||
case AsconPending: return "busy";
|
||||
case AsconReady: return "ready";
|
||||
|
@ -278,6 +278,7 @@ static int StartDiffScan(pDiffScan self, pScanData pScan,
|
||||
if (status != OKOK) {
|
||||
return 0;
|
||||
}
|
||||
pCount->pCountInt->lastStatus = HWBusy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -475,13 +476,14 @@ int RunDiffScan(pDiffScan self, pScanData pScan,
|
||||
InvokeCallBack(self->scanObject->pCall, SCANSTART, self->scanObject);
|
||||
|
||||
|
||||
lID = TaskRegisterN(pServ->pTasker,"diffscan", DiffScanTask, NULL, NULL, self, 10);
|
||||
lID = TaskRegisterN(pServ->pTasker,"diffscan", DiffScanTask, NULL, NULL, self, TASK_PRIO_HIGH);
|
||||
TaskWait(pServ->pTasker, lID);
|
||||
|
||||
|
||||
pCount = (pCounter) self->scanObject->pCounterData;
|
||||
pCount->pCountInt->Halt(pCount);
|
||||
InvokeCallBack(self->scanObject->pCall, SCANEND, self->scanObject);
|
||||
pCount->pCountInt->lastStatus = HWIdle;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
3
drive.c
3
drive.c
@ -302,7 +302,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* interpret arguments as pairs (name, value) and check */
|
||||
/* interpret arguments as pairs (name, value) and try to start */
|
||||
for (i = 1; i < argc; i += 2) {
|
||||
if (argv[i + 1] == NULL) {
|
||||
snprintf(pBueffel, 511, "ERROR: no value found for driving %s", argv[i]);
|
||||
@ -318,6 +318,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
"ERROR: target %s value for %s is not a finite number",
|
||||
argv[i + 1], argv[i]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
StopExe(GetExecutor(), "ALL");
|
||||
return 0;
|
||||
}
|
||||
iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget);
|
||||
|
@ -66,7 +66,6 @@
|
||||
#include "chadapter.h"
|
||||
#include "status.h"
|
||||
#include "site.h"
|
||||
#include "commandlog.h"
|
||||
/*--------------------- Functions needed to implement interfaces -----------*/
|
||||
static long EVIDrive(void *pData, SConnection * pCon, float fVal)
|
||||
{
|
||||
@ -607,7 +606,7 @@ static int EVIIsInTolerance(void *pData)
|
||||
*/
|
||||
memset(pError, 0, 132 * sizeof(char));
|
||||
self->pDriv->GetError(self->pDriv, &iCode, pError, 131);
|
||||
WriteToCommandLog("emon>> ", pError);
|
||||
Log(ERROR,"dev", "emon:%s", pError);
|
||||
iStat = self->pDriv->TryFixIt(self->pDriv, iCode);
|
||||
if ((iStat == DEVOK) || (iStat == DEVREDO)) {
|
||||
return 1; /* effectively a redo in some time */
|
||||
|
3
exebuf.c
3
exebuf.c
@ -18,7 +18,6 @@
|
||||
#include "dynstring.h"
|
||||
#include "exebuf.i"
|
||||
#include "status.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
char *ConID(SConnection *pCon); /* in conman.c */
|
||||
|
||||
@ -302,7 +301,7 @@ int exeBufProcess(pExeBuf self, SicsInterp * pSics,
|
||||
}
|
||||
}
|
||||
|
||||
traceCommand(ConID(pCon),"batch:%s", cmd);
|
||||
Log(INFO,"com","%s:batch:%s", ConID(pCon), cmd);
|
||||
status = Tcl_Eval(pTcl, cmd);
|
||||
if (status != TCL_OK) {
|
||||
if (pCon->sicsError == 0) {
|
||||
|
4
exeman.c
4
exeman.c
@ -24,7 +24,6 @@
|
||||
#include "exeman.i"
|
||||
#include "exeman.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "commandlog.h"
|
||||
#include "protocol.h"
|
||||
/*-------------------------------------------------------------------*/
|
||||
static void KillExeMan(void *data)
|
||||
@ -320,8 +319,7 @@ static int SCHdbWrite(SConnection * self, char *message, int outCode)
|
||||
v.dataType = HIPTEXT;
|
||||
val = CreateDynString(128, 128);
|
||||
if (val == NULL) {
|
||||
WriteToCommandLog("INTERNAL ERROR>>",
|
||||
"No memory to append to log in SCHdbWrite");
|
||||
Log(ERROR,"sys","%s", "No memory to append to log in SCHdbWrite");
|
||||
return 0;
|
||||
}
|
||||
if (v.v.text != NULL) {
|
||||
|
19
fourmess.c
19
fourmess.c
@ -393,7 +393,7 @@ static int FourMessStoreIntern(pSICSOBJ self, SConnection * pCon,
|
||||
double fHkl[3], double fPosition[4], char *extra)
|
||||
{
|
||||
pFourMess priv = self->pPrivate;
|
||||
float fSum, fSigma, fTemp, fMF, fStep = .0, fPreset =.0;
|
||||
float fSum, fSigma, fTemp, fStep = .0, fPreset =.0, fMF;
|
||||
int i, iLF, iRet, iNP, ii;
|
||||
long *lCounts = NULL;
|
||||
pEVControl pEva = NULL;
|
||||
@ -487,7 +487,7 @@ static int FourMessStoreIntern(pSICSOBJ self, SConnection * pCon,
|
||||
}
|
||||
|
||||
/* get mf */
|
||||
fMF = -777.77;
|
||||
fMF = -0.00;
|
||||
pEva = (pEVControl) FindCommandData(pServ->pSics, "mf",
|
||||
"Environment Controller");
|
||||
if (pEva == NULL) {
|
||||
@ -811,6 +811,21 @@ static int GenInconsumerate(pSICSOBJ self, SConnection * pCon,
|
||||
SCPrintf(pCon,eLog, "%d of %d input reflections processed", i, startCount);
|
||||
}
|
||||
}
|
||||
/*
|
||||
add satellites of 0,0,0,
|
||||
*/
|
||||
for(i = 0; i < 3; i++){
|
||||
hkl[i] = 0. + qvec[i];
|
||||
}
|
||||
AddRefIdx(priv->messList, hkl);
|
||||
iGen++;
|
||||
for(i = 0; i < 3; i++){
|
||||
hkl[i] = 0. - qvec[i];
|
||||
}
|
||||
if(FindHKL(priv->messList, hkl[0], hkl[1], hkl[2]) == NULL){
|
||||
AddRefIdx(priv->messList, hkl);
|
||||
iGen++;
|
||||
}
|
||||
SCPrintf(pCon, eValue,
|
||||
"%d additional inconsumerate reflections generated", iGen);
|
||||
return 1;
|
||||
|
65
hexString.c
Normal file
65
hexString.c
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* hexString.c
|
||||
* byteutils
|
||||
*
|
||||
* Created by Richard Murphy on 3/7/10.
|
||||
* Copyright 2010 McKenzie-Murphy. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hexString.h"
|
||||
|
||||
/* utility function to convert hex character representation to their nibble (4 bit) values */
|
||||
static uint8_t
|
||||
nibbleFromChar(char c)
|
||||
{
|
||||
if(c >= '0' && c <= '9') return c - '0';
|
||||
if(c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
if(c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
return 255;
|
||||
}
|
||||
|
||||
/* Convert a string of characters representing a hex buffer into a series of bytes of that real value */
|
||||
uint8_t
|
||||
*hexStringToBytes(char *inhex)
|
||||
{
|
||||
uint8_t *retval;
|
||||
uint8_t *p;
|
||||
int len, i;
|
||||
|
||||
len = strlen(inhex) / 2;
|
||||
retval = malloc(len+1);
|
||||
for(i=0, p = (uint8_t *) inhex; i<len; i++) {
|
||||
retval[i] = (nibbleFromChar(*p) << 4) | nibbleFromChar(*(p+1));
|
||||
p += 2;
|
||||
}
|
||||
retval[len] = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static char byteMap[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
static int byteMapLen = sizeof(byteMap);
|
||||
|
||||
/* Utility function to convert nibbles (4 bit values) into a hex character representation */
|
||||
static char
|
||||
nibbleToChar(uint8_t nibble)
|
||||
{
|
||||
if(nibble < byteMapLen) return byteMap[nibble];
|
||||
return '*';
|
||||
}
|
||||
|
||||
/* Convert a buffer of binary values into a hex string representation */
|
||||
char
|
||||
*bytesToHexString(uint8_t *bytes, size_t buflen)
|
||||
{
|
||||
char *retval;
|
||||
int i;
|
||||
|
||||
retval = malloc(buflen*2 + 1);
|
||||
for(i=0; i<buflen; i++) {
|
||||
retval[i*2] = nibbleToChar(bytes[i] >> 4);
|
||||
retval[i*2+1] = nibbleToChar(bytes[i] & 0x0f);
|
||||
}
|
||||
retval[i] = '\0';
|
||||
return retval;
|
||||
}
|
18
hexString.h
Normal file
18
hexString.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* hexString.h
|
||||
* byteutils
|
||||
*
|
||||
* Created by Richard Murphy on 3/7/10.
|
||||
* Copyright 2010 McKenzie-Murphy. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
uint8_t
|
||||
*hexStringToBytes(char *inhex);
|
||||
|
||||
char
|
||||
*bytesToHexString(uint8_t *bytes, size_t buflen);
|
@ -996,11 +996,11 @@ static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
|
||||
if (iEvent == COUNTSTART && pUser != NULL) {
|
||||
pCon = (SConnection *) pUser;
|
||||
assert(pCon);
|
||||
SCWrite(pCon, "HMCOUNTSTART", eWarning);
|
||||
SCWrite(pCon, "HMCOUNTSTART", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == COUNTEND) {
|
||||
assert(pCon);
|
||||
SCWrite(pCon, "HMCOUNTEND", eWarning);
|
||||
SCWrite(pCon, "HMCOUNTEND", eEvent);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
26
interface.c
26
interface.c
@ -101,7 +101,16 @@ pIDrivable CreateDrivableInterface(void)
|
||||
pRes->drivableStatus = HWIdle;
|
||||
return pRes;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int DefaultReadStatus(void *self, SConnection *pCon)
|
||||
{
|
||||
pICountable pCount = GetCountableInterface(self);
|
||||
if(pCount != NULL){
|
||||
return pCount->lastStatus;
|
||||
} else {
|
||||
return HWFault;
|
||||
}
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pICountable CreateCountableInterface(void)
|
||||
{
|
||||
@ -113,6 +122,8 @@ pICountable CreateCountableInterface(void)
|
||||
}
|
||||
memset(pRes, 0, sizeof(ICountable));
|
||||
pRes->ID = COUNTID;
|
||||
pRes->lastStatus = HWIdle;
|
||||
pRes->ReadStatus = DefaultReadStatus;
|
||||
return pRes;
|
||||
}
|
||||
|
||||
@ -230,6 +241,8 @@ static int DriveTaskFunc(void *data)
|
||||
}
|
||||
if(status == HWFault){
|
||||
taskData->pDriv->iErrorCount++;
|
||||
} else {
|
||||
taskData->pDriv->iErrorCount = 0;
|
||||
}
|
||||
if(status == HWFault || status == HWPosFault){
|
||||
SetDevexecStatus(pServ->pExecutor,DEVERROR);
|
||||
@ -260,7 +273,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
|
||||
return -1;
|
||||
}
|
||||
if(pDriv->CheckLimits(obj,fTarget,error,sizeof(error)) != OKOK){
|
||||
SCPrintf(pCon,eError,"ERROR: %s cannot reach %f, reason %s", name,
|
||||
SCPrintf(pCon,eLogError,"ERROR: %s cannot reach %f, reason %s", name,
|
||||
fTarget, error);
|
||||
return -1;
|
||||
}
|
||||
@ -284,13 +297,15 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget)
|
||||
taskData->pDriv = pDriv;
|
||||
taskData->pCon = SCCopyConnection(pCon);
|
||||
taskData->name = strdup(name);
|
||||
|
||||
LogIS(INFO,SSYS,"drive:DriveTask started: %s to %f", name, fTarget);
|
||||
|
||||
return TaskRegisterN(pServ->pTasker,
|
||||
name,
|
||||
DriveTaskFunc,
|
||||
DriveTaskSignal,
|
||||
KillDriveTaskData,
|
||||
taskData,0);
|
||||
taskData, TASK_PRIO_HIGH);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pICountable GetCountableInterface(void *pObject)
|
||||
@ -378,6 +393,7 @@ static int CountTaskFunc(void *data)
|
||||
assert(taskData != NULL);
|
||||
|
||||
status = taskData->pCount->CheckCountStatus(taskData->obj,taskData->pCon);
|
||||
taskData->pCount->lastStatus = status;
|
||||
if(status == HWBusy) {
|
||||
return 1;
|
||||
} else if(status == HWNoBeam){
|
||||
@ -437,12 +453,14 @@ long StartCountTask(void *obj, SConnection *pCon, char *name)
|
||||
taskData->pCon = SCCopyConnection(pCon);
|
||||
taskData->name = strdup(name);
|
||||
|
||||
LogIS(INFO,SSYS,"count:CountTask started: %s", name);
|
||||
|
||||
return TaskRegisterN(pServ->pTasker,
|
||||
name,
|
||||
CountTaskFunc,
|
||||
CountTaskSignal,
|
||||
KillCountTaskData,
|
||||
taskData,0);
|
||||
taskData, TASK_PRIO_HIGH);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
@ -62,11 +62,13 @@
|
||||
typedef struct {
|
||||
int ID;
|
||||
int running;
|
||||
int lastStatus;
|
||||
int (*Halt)(void *self);
|
||||
void (*SetCountParameters)(void *self, float fPreset,
|
||||
CounterMode eMode);\
|
||||
CounterMode eMode);
|
||||
int (*StartCount)(void *self, SConnection *pCon);
|
||||
int (*CheckCountStatus)(void *self, SConnection *pCon);
|
||||
int (*ReadStatus)(void *self, SConnection *pCon);
|
||||
int (*Pause)(void *self, SConnection *pCon);
|
||||
int (*Continue)(void *self, SConnection *pCon);
|
||||
int (*TransferData)(void *self, SConnection *pCon);
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "splitter.h"
|
||||
#include "configfu.h"
|
||||
#include "devexec.h"
|
||||
#include "servlog.h"
|
||||
#include "nread.h"
|
||||
#include "task.h"
|
||||
#include "event.h"
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#define LLDstringCreate() LLDblobCreate()
|
||||
|
||||
#define LLDdeleteString(l) LLDdeleteBlob(l)
|
||||
|
||||
#define LLDstringInsert(l,s) LLDblobInsert( l, s, strlen( s ) +1 )
|
||||
|
||||
#define LLDstringAdd(l,s) LLDblobAdd( l, s, strlen( s ) +1 )
|
||||
|
21
logger.c
21
logger.c
@ -15,18 +15,6 @@ Markus Zolliker, Sept 2004
|
||||
#include <ctype.h>
|
||||
#include "logger.h"
|
||||
|
||||
struct Logger {
|
||||
char *name;
|
||||
char *old;
|
||||
int oldsize;
|
||||
int period;
|
||||
time_t last, lastWrite, omitTime;
|
||||
int numeric;
|
||||
float omitValue;
|
||||
int exact;
|
||||
Logger *next;
|
||||
};
|
||||
|
||||
static char *dir = NULL;
|
||||
static Logger *list;
|
||||
static time_t lastLife = 0;
|
||||
@ -152,6 +140,7 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value)
|
||||
int l, ext, writeInfo;
|
||||
FILE *fil;
|
||||
time_t beforenow;
|
||||
char *nl;
|
||||
|
||||
if (log->name[0] == '\0')
|
||||
return 0;
|
||||
@ -211,7 +200,13 @@ int LoggerWrite0(Logger * log, time_t now, int period, char *value)
|
||||
}
|
||||
}
|
||||
strftime(stim, sizeof stim, "%H:%M:%S", &tm);
|
||||
fprintf(fil, "%s\t%s\n", stim, value);
|
||||
nl = strchr(value, '\n');
|
||||
if (nl == NULL) {
|
||||
fprintf(fil, "%s\t%s\n", stim, value);
|
||||
} else {
|
||||
/* newline within string! do write only characters before nl */
|
||||
fprintf(fil, "%s\t%.*s\n", stim, (nl - value), value);
|
||||
}
|
||||
log->lastWrite = now;
|
||||
fclose(fil);
|
||||
|
||||
|
15
logger.h
15
logger.h
@ -10,7 +10,20 @@ Markus Zolliker, Sept 2004
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct Logger Logger;
|
||||
typedef struct Logger {
|
||||
/* public */
|
||||
char *name;
|
||||
int numeric;
|
||||
int period;
|
||||
int exact;
|
||||
/* private: */
|
||||
char *old;
|
||||
int oldsize;
|
||||
time_t last, lastWrite, omitTime;
|
||||
float omitValue;
|
||||
struct Logger *next;
|
||||
} Logger;
|
||||
|
||||
|
||||
Logger *LoggerMake(char *name, int period, int exact);
|
||||
void LoggerKill(Logger * log);
|
||||
|
100
loglisten.c
Normal file
100
loglisten.c
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* This is a means to listen into the stream of log messages from the logv2
|
||||
* logging system.
|
||||
*
|
||||
* Mark Koennecke, May 2016
|
||||
*/
|
||||
#include <sics.h>
|
||||
#include <logv2.h>
|
||||
#include <lld.h>
|
||||
|
||||
/*
|
||||
From logv2.c
|
||||
*/
|
||||
extern int subsystemFromText(const char *text);
|
||||
/*=============================================================================*/
|
||||
static int listenerList;
|
||||
static int callbackRegistered = 0;
|
||||
|
||||
typedef struct {
|
||||
SConnection *pCon;
|
||||
char subsystem[64];
|
||||
} ListenEntry;
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static void LogListenCallback(unsigned int severity, const char *timeStamp,
|
||||
const char *subsystem,
|
||||
const char *message, void *userData)
|
||||
{
|
||||
ListenEntry current;
|
||||
int status, cleanupNeeded = 0;
|
||||
|
||||
if(logFilter(severity,subsystem,message) == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
status = LLDnodePtr2First(listenerList);
|
||||
while(status != 0){
|
||||
LLDnodeDataTo(listenerList,¤t);
|
||||
if(strcmp(current.subsystem,subsystem) == 0) {
|
||||
if(SCisConnected(current.pCon)){
|
||||
SCPureSockWrite(current.pCon,(char *)message,eValue);
|
||||
} else {
|
||||
cleanupNeeded = 1;
|
||||
}
|
||||
}
|
||||
status = LLDnodePtr2Next(listenerList);
|
||||
}
|
||||
|
||||
/*
|
||||
lld lists sometimes get confused when deleting nodes on the fly.
|
||||
This is why this has been put into a separate loop
|
||||
*/
|
||||
if(cleanupNeeded){
|
||||
status = LLDnodePtr2First(listenerList);
|
||||
while(status != 0){
|
||||
LLDnodeDataTo(listenerList,¤t);
|
||||
if(!SCisConnected(current.pCon)){
|
||||
SCDeleteConnection(current.pCon);
|
||||
LLDnodeDelete(listenerList);
|
||||
}
|
||||
status = LLDnodePtr2Next(listenerList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static int LogListenAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
ListenEntry listLog;
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: need subsystem argument for loglisten", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(subsystemFromText(argv[1]) < 0){
|
||||
SCPrintf(pCon,eError, "ERROR: invalid subsystem %s specified", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
listLog.pCon = SCCopyConnection(pCon);
|
||||
strncpy(listLog.subsystem,argv[1],sizeof(listLog.subsystem));
|
||||
LLDnodeAppendFrom(listenerList,&listLog);
|
||||
|
||||
if(!callbackRegistered){
|
||||
RegisterLogCallback(LogListenCallback,NULL);
|
||||
callbackRegistered = 1;
|
||||
}
|
||||
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void LogListenInit(void)
|
||||
{
|
||||
listenerList = LLDcreate(sizeof(ListenEntry));
|
||||
AddCmd("loglisten", LogListenAction);
|
||||
}
|
692
logv2.c
Normal file
692
logv2.c
Normal file
@ -0,0 +1,692 @@
|
||||
/*
|
||||
This is a reimplementation of SICS logging. The aim is to
|
||||
merge all the different logs within SICS to the new logging
|
||||
system
|
||||
|
||||
COPYRIGHT: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2016
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <logv2.h>
|
||||
#include <sics.h>
|
||||
#include <splitter.h>
|
||||
#include <lld_str.h>
|
||||
#include <lld.h>
|
||||
#include <dynstring.h>
|
||||
#include <hexString.h>
|
||||
/*==============================================================================
|
||||
some static fields which control log file rotation
|
||||
===============================================================================*/
|
||||
static FILE *logFile = NULL;
|
||||
static unsigned int MAXFILELINES = 100000;
|
||||
static unsigned int lineCount = 0;
|
||||
static char logTemplate[1024];
|
||||
static char logFilename[1024];
|
||||
static unsigned int logDisabled = 0;
|
||||
static int unsigned logConfigured = 0;
|
||||
|
||||
/*================ The default log level =======================================*/
|
||||
static unsigned int globalLogLevel = INFO;
|
||||
|
||||
/*========= The list of sub systems for which full logging is enabled ==========*/
|
||||
unsigned int logEnabledArray[MAXSUB ];
|
||||
|
||||
/*================== Callback management =======================================*/
|
||||
typedef struct {
|
||||
LogCallback func;
|
||||
void *userData;
|
||||
} LogCBData;
|
||||
|
||||
static int callbackList;
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void formatTimeStamp(struct timeval *tp,
|
||||
char *buffer, unsigned int bufferLength, unsigned int small)
|
||||
{
|
||||
struct tm *time;
|
||||
int year, month, day, hour, min, sec, usec;
|
||||
char delim = '-';
|
||||
struct timeval tv;
|
||||
|
||||
if(tp == NULL){
|
||||
gettimeofday(&tv, NULL);
|
||||
} else {
|
||||
tv = *tp;
|
||||
}
|
||||
|
||||
time = localtime(&tv.tv_sec);
|
||||
year = 1900 + time->tm_year;
|
||||
month = time->tm_mon + 1;
|
||||
day = time->tm_mday;
|
||||
hour = time->tm_hour;
|
||||
min = time->tm_min;
|
||||
sec = time->tm_sec;
|
||||
usec = (int) tv.tv_usec;
|
||||
if(small == 1){
|
||||
snprintf(buffer,bufferLength, "%04d-%02d-%02dT%02d%c%02d%c%02d",
|
||||
year, month, day, hour, delim, min, delim, sec);
|
||||
} else {
|
||||
snprintf(buffer,bufferLength, "%04d-%02d-%02dT%02d%c%02d%c%02d.%06d",
|
||||
year, month, day, hour, delim, min, delim, sec, usec);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static char *makeLogFileName(void)
|
||||
{
|
||||
char timeStamp[256];
|
||||
char *filename = NULL;
|
||||
unsigned int length;
|
||||
|
||||
formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),1);
|
||||
length = strlen(logTemplate) + strlen(timeStamp) + 30;
|
||||
filename = malloc(length*sizeof(char));
|
||||
if(filename != NULL){
|
||||
sprintf(filename,"%s-%s.log",logTemplate,timeStamp);
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void LogClose(void *data)
|
||||
{
|
||||
if(logFile != NULL){
|
||||
fclose(logFile);
|
||||
}
|
||||
logFile = NULL;
|
||||
lineCount = 0;
|
||||
strcpy(logFilename,"undefined");
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void checkLogFile(void)
|
||||
{
|
||||
char *filename = NULL;
|
||||
char *oldLogFile = NULL;
|
||||
char timeStamp[132];
|
||||
|
||||
if(logDisabled || logConfigured == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
close when full
|
||||
*/
|
||||
if(logFile != NULL && lineCount >= MAXFILELINES){
|
||||
oldLogFile = strdup(logFilename);
|
||||
filename = makeLogFileName();
|
||||
formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),0);
|
||||
fprintf(logFile,"%s:sys:INFO:Next logfile %s\n",timeStamp,filename);
|
||||
LogClose(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
start a new log file
|
||||
*/
|
||||
if(logFile == NULL){
|
||||
if(filename == NULL){
|
||||
filename = makeLogFileName();
|
||||
}
|
||||
if(filename != NULL){
|
||||
logFile = fopen(filename,"w");
|
||||
strncpy(logFilename,filename,sizeof(logFilename));
|
||||
if(oldLogFile != NULL){
|
||||
fprintf(logFile,"%s:sys:INFO:Previous logfile %s\n",timeStamp,oldLogFile);
|
||||
free(oldLogFile);
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void writeLog(char *logMessage)
|
||||
{
|
||||
int nChar;
|
||||
unsigned int end;
|
||||
char *pPtr;
|
||||
const char delim = '\n';
|
||||
|
||||
if(logMessage == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
remove a trailing newline
|
||||
*/
|
||||
end = strlen(logMessage);
|
||||
if(logMessage[end-1] == delim){
|
||||
logMessage[end-1] = '\0';
|
||||
}
|
||||
|
||||
if(logFile != NULL){
|
||||
nChar = fprintf(logFile,"%s\n",logMessage);
|
||||
lineCount++;
|
||||
}
|
||||
|
||||
}
|
||||
/*=============================================================================*/
|
||||
void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength)
|
||||
{
|
||||
static const char *severityText[] = {"FATAL",
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"INFO",
|
||||
"VERBOSE",
|
||||
"DEBUG",
|
||||
"INVALID"
|
||||
};
|
||||
|
||||
if(severity > DEBUG){
|
||||
severity = INVALID;
|
||||
}
|
||||
strncpy(buffer,severityText[severity-1],bufferLength);
|
||||
}
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
static unsigned int sevFromText(const char *txt)
|
||||
{
|
||||
static const char *severityText[] = {"fatal",
|
||||
"error",
|
||||
"warn",
|
||||
"info",
|
||||
"verbose",
|
||||
"debug",
|
||||
NULL
|
||||
};
|
||||
int sev = 0;
|
||||
while(severityText[sev] != NULL){
|
||||
if(strcmp(txt,severityText[sev]) == 0){
|
||||
break;
|
||||
}
|
||||
sev++;
|
||||
}
|
||||
sev++; /* starting at 1 rather then 0 */
|
||||
return sev;
|
||||
}
|
||||
/*=============================================================================*/
|
||||
int subsystemFromText(const char *text)
|
||||
{
|
||||
int i;
|
||||
static const char *subText[] = {"sys",
|
||||
"com",
|
||||
"asquio",
|
||||
"io",
|
||||
"dev",
|
||||
"par",
|
||||
"notify",
|
||||
"history",
|
||||
"INVALID",
|
||||
};
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
if(strcmp(subText[i],text) == 0){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void formatSubsystem(unsigned int sub, char *buffer, unsigned int bufferLength)
|
||||
{
|
||||
static const char *subText[] = {"sys",
|
||||
"com",
|
||||
"asquio",
|
||||
"io",
|
||||
"dev",
|
||||
"par",
|
||||
"notify",
|
||||
"history",
|
||||
"INVALID",
|
||||
};
|
||||
|
||||
if(sub > SPAR){
|
||||
sub = SINVALID;
|
||||
}
|
||||
strncpy(buffer,subText[sub],bufferLength);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
unsigned int logFilter(unsigned int severity, const char *subsystem, const char *logMessage)
|
||||
{
|
||||
int status;
|
||||
char buffer[1024];
|
||||
unsigned int sub;
|
||||
|
||||
if(logDisabled || logConfigured == 0){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
suppress empty messages
|
||||
*/
|
||||
if(strlen(logMessage) < 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
If it is in the list of enabled subsystems, everything is logged
|
||||
*/
|
||||
sub = subsystemFromText(subsystem);
|
||||
if(sub >= 0 && severity <= logEnabledArray[sub]){
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
test against the global log level
|
||||
*/
|
||||
if(severity > globalLogLevel){
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
I wish to avoid excessive dynamic memory allocation in logging. Thus I pass
|
||||
in generous preallocated buffers and allocate only when the passed in buffer
|
||||
is not big enough. This trick is used througout this code.
|
||||
------------------------------------------------------------------------------*/
|
||||
static char *formatLogLine(char *timeStamp,char *severityTXT,
|
||||
const char* subsystem,
|
||||
char *logData, char *logLine,
|
||||
unsigned int logLineLength)
|
||||
{
|
||||
unsigned int totalLength;
|
||||
char *lineTxt = NULL;
|
||||
|
||||
totalLength = strlen(timeStamp) + strlen(severityTXT) + strlen(subsystem)
|
||||
+ strlen(logData) + 10;
|
||||
|
||||
if(totalLength > logLineLength){
|
||||
lineTxt = malloc((totalLength+1)*sizeof(char));
|
||||
} else {
|
||||
lineTxt = logLine;
|
||||
}
|
||||
if(lineTxt != NULL){
|
||||
sprintf(lineTxt,"%s:%s:%s:%s",
|
||||
timeStamp,
|
||||
subsystem,
|
||||
severityTXT,
|
||||
logData);
|
||||
}
|
||||
return lineTxt;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void RegisterLogCallback(LogCallback func, void *userData)
|
||||
{
|
||||
LogCBData lcb;
|
||||
|
||||
lcb.func = func;
|
||||
lcb.userData = userData;
|
||||
LLDnodeAppendFrom(callbackList,&lcb);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void RemoveLogCallback(LogCallback func)
|
||||
{
|
||||
int status;
|
||||
LogCBData lcb;
|
||||
|
||||
status = LLDnodePtr2First(callbackList);
|
||||
while(status == 1){
|
||||
LLDnodeDataTo(callbackList,&lcb);
|
||||
if(lcb.func == func){
|
||||
LLDnodeDelete(callbackList);
|
||||
return;
|
||||
}
|
||||
status = LLDnodePtr2Next(callbackList);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void notifyListeners(unsigned int severity, const char *subsystem,
|
||||
const char *timeStamp, char *logData)
|
||||
{
|
||||
int status;
|
||||
LogCBData lcb;
|
||||
|
||||
status = LLDnodePtr2First(callbackList);
|
||||
while(status == 1){
|
||||
LLDnodeDataTo(callbackList,&lcb);
|
||||
lcb.func(severity, timeStamp, subsystem,logData,lcb.userData);
|
||||
status = LLDnodePtr2Next(callbackList);
|
||||
}
|
||||
|
||||
}
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
static void LogInternal(char *timeText, unsigned int severity, const char *subsystem,
|
||||
char *logMessage)
|
||||
{
|
||||
char severityTXT[60], logLine[3072], *fullMessage = NULL;
|
||||
|
||||
checkLogFile();
|
||||
|
||||
formatSeverity(severity,severityTXT,sizeof(severityTXT));
|
||||
|
||||
notifyListeners(severity,subsystem,timeText, logMessage);
|
||||
|
||||
|
||||
if(logFilter(severity,subsystem,(const char *)logMessage) == 1){
|
||||
return;
|
||||
}
|
||||
|
||||
fullMessage = formatLogLine(timeText,severityTXT,subsystem,
|
||||
logMessage, logLine, sizeof(logLine));
|
||||
|
||||
writeLog(fullMessage);
|
||||
|
||||
|
||||
/*
|
||||
clean up
|
||||
*/
|
||||
if(fullMessage != logLine){
|
||||
free(fullMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...)
|
||||
{
|
||||
char timeStamp[132];
|
||||
char subText[30];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatSubsystem(subsystem,subText,sizeof(subText));
|
||||
formatTimeStamp(NULL, timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
restart the vararg stuff.
|
||||
*/
|
||||
va_start(ap,format);
|
||||
dataLength = vsnprintf(logData,sizeof(logData),format,ap);
|
||||
logMessage = logData;
|
||||
va_end(ap);
|
||||
if(dataLength > sizeof(logData)){
|
||||
dynMessage = malloc((dataLength+1)*sizeof(char));
|
||||
if(dynMessage != NULL){
|
||||
va_start(ap,format);
|
||||
vsnprintf(dynMessage,(dataLength+1)*sizeof(char),format,ap);
|
||||
va_end(ap);
|
||||
logMessage = dynMessage;
|
||||
}
|
||||
}
|
||||
|
||||
LogInternal(timeStamp, severity, subText,logMessage);
|
||||
|
||||
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*-------------------------------------------------------------------------------*/
|
||||
void LogTS(struct timeval *tv, unsigned int severity, unsigned int subsystem,const char *format,...)
|
||||
{
|
||||
char subText[30], timeStamp[256];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatSubsystem(subsystem,subText,sizeof(subText));
|
||||
formatTimeStamp(tv, timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
restart the vararg stuff.
|
||||
*/
|
||||
va_start(ap,format);
|
||||
dataLength = vsnprintf(logData,sizeof(logData),format,ap);
|
||||
logMessage = logData;
|
||||
va_end(ap);
|
||||
if(dataLength > sizeof(logData)){
|
||||
dynMessage = malloc((dataLength+1)*sizeof(char));
|
||||
if(dynMessage != NULL){
|
||||
va_start(ap,format);
|
||||
vsnprintf(dynMessage,(dataLength+1)*sizeof(char),format,ap);
|
||||
va_end(ap);
|
||||
logMessage = dynMessage;
|
||||
}
|
||||
}
|
||||
|
||||
LogInternal((char *)timeStamp, severity, subText,logMessage);
|
||||
|
||||
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void LogHex(struct timeval*tv, unsigned int severity, unsigned int subsystem,
|
||||
char *buffer, int bufferLength)
|
||||
{
|
||||
char subText[30], timeStamp[256], *hexData;
|
||||
|
||||
formatSubsystem(subsystem,subText,sizeof(subText));
|
||||
formatTimeStamp(tv, timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
hexData = bytesToHexString((uint8_t *)buffer,(size_t)bufferLength);
|
||||
|
||||
if(hexData != NULL){
|
||||
LogInternal((char *)timeStamp, severity, subText,hexData);
|
||||
free(hexData);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void Log(unsigned int severity, const char *subsystem,const char *format,...)
|
||||
{
|
||||
char timeStamp[132];
|
||||
char logData[2024], *logMessage = NULL;
|
||||
char *dynMessage = NULL;
|
||||
va_list ap;
|
||||
int dataLength;
|
||||
|
||||
|
||||
formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),0);
|
||||
|
||||
/*
|
||||
If we have enough space put the logData into our generous buffer. Else
|
||||
allocate a dynamic buffer. I cannot do this in a subroutine as I need to
|
||||
restart the vararg stuff.
|
||||
*/
|
||||
va_start(ap,format);
|
||||
dataLength = vsnprintf(logData,sizeof(logData),format,ap);
|
||||
logMessage = logData;
|
||||
va_end(ap);
|
||||
if(dataLength > sizeof(logData)){
|
||||
dynMessage = malloc((dataLength+1)*sizeof(char));
|
||||
if(dynMessage != NULL){
|
||||
va_start(ap,format);
|
||||
vsnprintf(dynMessage,(dataLength+1)*sizeof(char),format,ap);
|
||||
va_end(ap);
|
||||
logMessage = dynMessage;
|
||||
}
|
||||
}
|
||||
|
||||
LogInternal(timeStamp, severity, subsystem,logMessage);
|
||||
|
||||
|
||||
if(dynMessage != NULL){
|
||||
free(dynMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*------------------------------------------------------------------------------*/
|
||||
static pDynString ListEnabled(void)
|
||||
{
|
||||
int status, i;
|
||||
char buffer[1024], sub[30], sev[30];
|
||||
pDynString result = CreateDynString(64,64);
|
||||
|
||||
if(result == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
formatSeverity(logEnabledArray[i],sev,sizeof(sev));
|
||||
formatSubsystem(i,sub,sizeof(sub));
|
||||
DynStringConcat(result,sub);
|
||||
DynStringConcatChar(result,':');
|
||||
DynStringConcat(result,sev);
|
||||
DynStringConcatChar(result,'\n');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*============================================================================
|
||||
The Interpreter Interface
|
||||
==============================================================================*/
|
||||
static int LogAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
char message[1024];
|
||||
unsigned int sev;
|
||||
|
||||
if(argc < 4) {
|
||||
SCWrite(pCon,"ERROR: need severity subsystem message parameters", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
interpret severity
|
||||
*/
|
||||
strtolower(argv[1]);
|
||||
sev = sevFromText(argv[1]);
|
||||
if(sev >= INVALID){
|
||||
SCPrintf(pCon,eError,"ERROR: %s is no valid severity code", argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Arg2Text(argc-3,&argv[3],message,sizeof(message));
|
||||
|
||||
Log(sev,argv[2],"%s",message);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int LogConfigAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
unsigned int sev, sub;
|
||||
char buffer[64];
|
||||
pDynString result = NULL;
|
||||
|
||||
if(argc < 2) {
|
||||
SCWrite(pCon,"ERROR: need keyword", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strtolower(argv[1]);
|
||||
|
||||
if(strcmp(argv[1],"maxlines") == 0){
|
||||
if(argc > 2){
|
||||
MAXFILELINES = atoi(argv[2]);
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCPrintf(pCon,eValue,"logconfig.maxlines = %d", MAXFILELINES);
|
||||
}
|
||||
} else if(strcmp(argv[1],"logtemplate") == 0){
|
||||
if(argc > 2){
|
||||
strncpy(logTemplate,argv[2],sizeof(logTemplate));
|
||||
logConfigured = 1;
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCPrintf(pCon,eValue,"logconfig.logtemplate = %s", logTemplate);
|
||||
}
|
||||
}else if(strcmp(argv[1],"flush") == 0){
|
||||
fflush(logFile);
|
||||
SCSendOK(pCon);
|
||||
} else if(strcmp(argv[1],"filename") == 0) {
|
||||
SCPrintf(pCon,eValue,"logconfig.filename = %s", logFilename);
|
||||
} else if(strcmp(argv[1],"close") == 0) {
|
||||
LogClose(NULL);
|
||||
SCSendOK(pCon);
|
||||
}else if(strcmp(argv[1],"level") == 0 ) {
|
||||
if(argc > 2) {
|
||||
sev = sevFromText(argv[2]);
|
||||
if(sev >= INVALID) {
|
||||
SCPrintf(pCon,eError,"ERROR: %s is no valid log level", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
globalLogLevel = sev;
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
formatSeverity(globalLogLevel,buffer,sizeof(buffer));
|
||||
SCPrintf(pCon,eValue,"logconfig.level = %s", buffer);
|
||||
}
|
||||
}else if (strcmp(argv[1],"enable") == 0) {
|
||||
if(argc > 2){
|
||||
if(strlen(argv[2]) >= 1024) {
|
||||
SCWrite(pCon,"ERROR: subsystem name to long",eError);
|
||||
return 0;
|
||||
}
|
||||
sub = subsystemFromText(argv[2]);
|
||||
if(sub >= 0){
|
||||
logEnabledArray[sub] = DEBUG;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: invalid subsystem %s requested", argv[2]);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: need subsystem argument for enable",eError);
|
||||
return 0;
|
||||
}
|
||||
}else if (strcmp(argv[1],"disable") == 0) {
|
||||
if(argc > 2){
|
||||
sub = subsystemFromText(argv[2]);
|
||||
if(sub >= 0){
|
||||
logEnabledArray[sub] = ERROR;
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: invalid subsystem %s requested", argv[2]);
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: need subsystem argument for disable",eError);
|
||||
return 0;
|
||||
}
|
||||
} else if(strcmp(argv[1],"listenabled") == 0) {
|
||||
result = ListEnabled();
|
||||
if(result != NULL){
|
||||
SCWrite(pCon,GetCharArray(result),eValue);
|
||||
DeleteDynString(result);
|
||||
}
|
||||
} else {
|
||||
SCPrintf(pCon,eError,"ERROR: unknown keyword %s",argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void DisableLog(void)
|
||||
{
|
||||
logDisabled = 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
void Logv2Init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
callbackList = LLDcreate(sizeof(LogCBData));
|
||||
strcpy(logTemplate,"unconfiguredLogTemplate");
|
||||
|
||||
AddCmd("log", LogAction);
|
||||
AddCommand(pServ->pSics,"logconfig", LogConfigAction,
|
||||
LogClose, NULL);
|
||||
|
||||
for(i = 0; i < MAXSUB; i++){
|
||||
logEnabledArray[i] = ERROR;
|
||||
}
|
||||
}
|
135
logv2.h
Normal file
135
logv2.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
This is a reimplementation of SICS logging. The aim is to
|
||||
merge all the different logs within SICS to the new logging
|
||||
system
|
||||
|
||||
COPYRIGHT: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2016
|
||||
*/
|
||||
|
||||
#ifndef __LOGV2
|
||||
#define __LOGV2
|
||||
#include <stdarg.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/*
|
||||
severity codes
|
||||
*/
|
||||
#define FATAL 1
|
||||
#define ERROR 2
|
||||
#define WARN 3
|
||||
#define INFO 4
|
||||
#define VERBOSE 5
|
||||
#define DEBUG 6
|
||||
#define INVALID 7 /* internal olny, do not use, means invalid severity passed */
|
||||
|
||||
|
||||
/*
|
||||
subsystem codes
|
||||
*/
|
||||
#define SSYS 0
|
||||
#define SCOM 1
|
||||
#define SASQIO 2
|
||||
#define SIO 3
|
||||
#define SDEV 4
|
||||
#define SPAR 5
|
||||
#define SNOTIFY 6
|
||||
#define SHISTORY 7
|
||||
#define SINVALID 8
|
||||
|
||||
#define MAXSUB 7
|
||||
|
||||
|
||||
/* write a log message
|
||||
* \param severity The message severity. Must be one of the defines given above
|
||||
* \param subsystem The subsystem reporting the log messages
|
||||
* \param format The format string for the message
|
||||
* \param ... The data to format
|
||||
*/
|
||||
void Log(unsigned int severity, const char *subsystem,const char *format,...);
|
||||
|
||||
/* write a log message, but with the subsystem specified by an integer
|
||||
* \param severity The message severity. Must be one of the defines given above
|
||||
* \param subsystem The subsystem reporting the log messages
|
||||
* \param format The format string for the message
|
||||
* \param ... The data to format
|
||||
*/
|
||||
void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...);
|
||||
/* write a log message, but with the subsystem specified by an integer and user supplied timestamp
|
||||
* \param timeStamp A user supplied timestamp
|
||||
* \param severity The message severity. Must be one of the defines given above
|
||||
* \param subsystem The subsystem reporting the log messages
|
||||
* \param format The format string for the message
|
||||
* \param ... The data to format
|
||||
*/
|
||||
void LogTS(struct timeval *tv, unsigned int severity, unsigned int subsystem,const char *format,...);
|
||||
/*
|
||||
* write a log entry in hex
|
||||
* \param timeStamp A user supplied timestamp. Can be NULL, then the current time is used
|
||||
* \param severity The message severity. Must be one of the defines given above
|
||||
* \param subsystem The subsystem reporting the log messages
|
||||
* \param buffer the bytes to log as hex
|
||||
* \param bufferLength The length of buffer
|
||||
*/
|
||||
void LogHex(struct timeval*tv, unsigned int severity, unsigned int subsystem,char *buffer, int bufferLength);
|
||||
|
||||
|
||||
/* The callback functio which is called by the logging system on log events
|
||||
* \param severity The message severity
|
||||
* \param timeStamp The time stamp of the log message
|
||||
* \param subsystem The subsystem of the log message
|
||||
* \param message The log message
|
||||
* \param userData A pointer to a user define ddata structure passed through
|
||||
* transparantly from RegisterLogCallback
|
||||
*/
|
||||
|
||||
/*
|
||||
At this time LogCallback do not do any filtering. Thus, they see every message.
|
||||
The idea is that suitable filtering functions ought to be implemented as helper
|
||||
functions once the exact usage of the log \callbacks becomes clearer.
|
||||
*/
|
||||
|
||||
typedef void (*LogCallback)(unsigned int severity, const char *timeStamp,
|
||||
const char *subsystem,
|
||||
const char *message, void *userData);
|
||||
|
||||
/* register a LogCallback
|
||||
* \param func The function to call whena suitable log message has been found
|
||||
* \param userData A pointer to user defined data which is passed through to the
|
||||
* callback function. The log system does not free that pointer; this is up to the caller
|
||||
* \return An callback ID which can be used for RemoveLogCallback
|
||||
*/
|
||||
|
||||
void RegisterLogCallback(LogCallback func, void *userData);
|
||||
void RemoveLogCallback(LogCallback func);
|
||||
|
||||
/* test if this log entry is filtered. Made a part of the API in support of
|
||||
* log listeners
|
||||
* \param severity the severity of the message
|
||||
* \param subsystem the subsystem of the message
|
||||
* \return 1 when filtered, 0 else
|
||||
*/
|
||||
unsigned int logFilter(unsigned int severity, const char *subsystem, const char *logMessage);
|
||||
/*
|
||||
*Disable logging in support of the nolog option in SICSmain.c
|
||||
*/
|
||||
void DisableLog(void);
|
||||
/*
|
||||
* close the log as cleanup on exit
|
||||
*/
|
||||
void LogClose(void *data);
|
||||
|
||||
/*
|
||||
* internal use in other logging functions
|
||||
* \param severity The severity to encode
|
||||
* \param buffer The buffer to write the severity as text too
|
||||
* \param bufferLengh The length of buffer in order to prevent buffer overwrites
|
||||
*/
|
||||
void formatSeverity(unsigned int severity,
|
||||
char *buffer, unsigned int bufferLength);
|
||||
|
||||
extern unsigned int logEnabledArray[];
|
||||
#define logEnabled(subsystem,severity) (severity <= logEnabledArray[subsystem])
|
||||
|
||||
#endif
|
101
lscprot.c
Normal file
101
lscprot.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include "ascon.h"
|
||||
#include "ascon.i"
|
||||
|
||||
/*
|
||||
* script context protocol for LakeShore 370 / 340 etc. models
|
||||
* a 50 msec waiting time is needed after each reply / command
|
||||
*
|
||||
* Markus Zolliker May 2016
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
double last;
|
||||
double delay;
|
||||
} LscPrivate;
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int LscProtHandler(Ascon *a)
|
||||
{
|
||||
LscPrivate *p;
|
||||
int res;
|
||||
|
||||
if (a->state == AsconWriteStart) {
|
||||
p = a->private;
|
||||
if (DoubleTime() < p->last + p->delay) { // 50 msec
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
res = AsconStdHandler(a);
|
||||
if (a->state == AsconReadDone) {
|
||||
p = a->private;
|
||||
p->last = DoubleTime();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void LscPrivateKill(void *p) {
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int LscProtInit(Ascon *a, SConnection *con, int argc, char *argv[])
|
||||
{
|
||||
enum nPars {NA=4};
|
||||
char *pars[NA];
|
||||
static char *parn[NA]={
|
||||
"sendterminator",
|
||||
"timeout",
|
||||
"replyterminator",
|
||||
"writedelay"
|
||||
};
|
||||
char *msg;
|
||||
LscPrivate *p;
|
||||
|
||||
assert(argc>1);
|
||||
a->hostport = strdup(argv[1]);
|
||||
|
||||
if (!AsconInterpreteArgs(argc-2, argv+2, NA, parn, pars)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = calloc(sizeof(*p), 1);
|
||||
if (p == NULL) return 0;
|
||||
|
||||
p->last = DoubleTime();
|
||||
a->private = p;
|
||||
a->killPrivate = LscPrivateKill;
|
||||
|
||||
if (pars[0]) {
|
||||
a->sendTerminator = strdup(pars[0]);
|
||||
} else {
|
||||
a->sendTerminator = strdup("\n");
|
||||
}
|
||||
if (pars[1] && pars[1][0] != '\0') {
|
||||
a->timeout = atof(pars[1]);
|
||||
} else {
|
||||
a->timeout = 2.0; /* sec */
|
||||
}
|
||||
if (pars[2] && pars[2][0] != '\0') {
|
||||
a->replyTerminator = strdup(pars[2]);
|
||||
} else {
|
||||
a->replyTerminator = NULL;
|
||||
}
|
||||
if (pars[3] && pars[3][0] != '\0') {
|
||||
p->delay = atof(pars[3]);
|
||||
} else {
|
||||
p->delay = 0.05;
|
||||
}
|
||||
AsconCheckTerminators(a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void AddLscProtocol()
|
||||
{
|
||||
static AsconProtocol lscprot;
|
||||
lscprot.name = "lsc";
|
||||
lscprot.handler = LscProtHandler;
|
||||
lscprot.init = LscProtInit;
|
||||
AsconInsertProtocol(&lscprot);
|
||||
}
|
44
macro.c
44
macro.c
@ -67,12 +67,10 @@
|
||||
#include "splitter.h"
|
||||
#include "ifile.h"
|
||||
#include "Dbg.h"
|
||||
#include "servlog.h"
|
||||
#include "sicsglobal.h"
|
||||
#include "stringdict.h"
|
||||
#include "exeman.h"
|
||||
#include "nxcopy.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
#define SICSERROR "005567SICS"
|
||||
/*----------------------------------------------------------------------------
|
||||
@ -193,7 +191,14 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter,
|
||||
|
||||
/* finish */
|
||||
if (iRet == 1) {
|
||||
WriteCommandHistory(comBuffer);
|
||||
Arg2Text(argc-1,&argv[1],comBuffer,sizeof(comBuffer));
|
||||
/*
|
||||
suppress the sct commands: there is no point in having them in
|
||||
the history
|
||||
if(strstr(argv[1],"sct") == NULL){
|
||||
Log(DEBUG,"history","%s",comBuffer);
|
||||
}
|
||||
*/
|
||||
return TCL_OK;
|
||||
} else {
|
||||
Tcl_SetVar(pInter, SICSERROR, "yes", TCL_GLOBAL_ONLY);
|
||||
@ -476,8 +481,7 @@ int MacroFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
|
||||
|
||||
/* handle status first */
|
||||
|
||||
SICSLogWrite("Evaluating in MacroFileEval", eValue);
|
||||
SICSLogWrite(argv[1], eValue);
|
||||
Log(INFO,"com","Evaluating %s in MacroFileEval", argv[1]);
|
||||
if (pFile) {
|
||||
free(pFile);
|
||||
}
|
||||
@ -601,10 +605,10 @@ int InternalFileEval(SConnection * pCon, SicsInterp * pInter, void *pData,
|
||||
ClientPut is installed as a command to write data to the client from
|
||||
a server script. Syntax:
|
||||
ClientPut text outputcode
|
||||
The output code is optional and and defaults to eStatus.
|
||||
The output code is optional and and defaults to eLog.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#include "outcode.c"
|
||||
#include "outcode.h"
|
||||
|
||||
int ClientPut(SConnection * pCon, SicsInterp * pInter, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -702,6 +706,17 @@ int ClientPut(SConnection * pCon, SicsInterp * pInter, void *pData,
|
||||
memset(pMessage, 0, (iLen + 100) * sizeof(char));
|
||||
Arg2Text(iCode - 1, &argv[1], pMessage, (iLen + 100) * sizeof(char));
|
||||
|
||||
/*
|
||||
as the outcode is optional we have to test the message in order to get
|
||||
proper outcodes for the log
|
||||
*/
|
||||
if(strstr(pMessage,"ERROR") != NULL){
|
||||
eOut = eLogError;
|
||||
}
|
||||
if(strstr(pMessage,"WARNING") != NULL){
|
||||
eOut = eWarning;
|
||||
}
|
||||
|
||||
SCWrite(pCon, pMessage, eOut);
|
||||
if (pMessage) {
|
||||
free(pMessage);
|
||||
@ -975,9 +990,7 @@ static int TclAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
Tcl_ResetResult(pTcl);
|
||||
SetWriteHistory(0);
|
||||
iRet = Tcl_Eval(pTcl, pCommand);
|
||||
SetWriteHistory(1);
|
||||
if (iRet == TCL_OK) {
|
||||
if (strlen(pTcl->result) > 0) {
|
||||
SCPrintf(pCon, eValue, "%s", pTcl->result);
|
||||
@ -1070,6 +1083,13 @@ int TclPublish(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
Transact executes a command and sends a TRANSACTIONFINISHED string
|
||||
at the end. This is to permit clients to search for this string in
|
||||
order to find out when a command has finished.
|
||||
|
||||
MK, May 2016
|
||||
|
||||
I changed this to write the TRANSACT strings only to the socket and not to the
|
||||
log. Because this is clogging the log with useless stuff. If you want to
|
||||
debug the protocol you still can sit on the line with sockspy. But I am unsure
|
||||
of this change...
|
||||
*/
|
||||
|
||||
|
||||
@ -1078,6 +1098,7 @@ int TransactAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char pBuffer[1024];
|
||||
char pStartBuffer[1088];
|
||||
char *pCommand;
|
||||
int iRet;
|
||||
|
||||
@ -1088,11 +1109,12 @@ int TransactAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
}
|
||||
strtolower(argv[0]);
|
||||
if (strcmp(argv[0], "fulltransact") == 0) {
|
||||
SCPrintf(pCon, eLog, "TRANSACTIONSTART %s", pCommand);
|
||||
snprintf(pStartBuffer, sizeof(pStartBuffer), "TRANSACTIONSTART %s", pCommand);
|
||||
SCPureSockWrite(pCon, pStartBuffer,eLog);
|
||||
}
|
||||
iRet = InterpExecute(pSics, pCon, pCommand);
|
||||
if (pCommand != pBuffer)
|
||||
free(pCommand);
|
||||
SCWrite(pCon, "TRANSACTIONFINISHED", eLog);
|
||||
SCPureSockWrite(pCon, "TRANSACTIONFINISHED", eLog);
|
||||
return iRet;
|
||||
}
|
||||
|
14
make_gen
14
make_gen
@ -10,18 +10,18 @@ EPICSOBJ=
|
||||
|
||||
COBJ = Sclient.o network.o ifile.o intcli.o $(FORTIFYOBJ)
|
||||
SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
servlog.o sicvar.o nserver.o SICSmain.o motorlist.o\
|
||||
sicvar.o nserver.o SICSmain.o motorlist.o\
|
||||
sicsexit.o costa.o task.o $(FORTIFYOBJ) testprot.o\
|
||||
macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \
|
||||
devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \
|
||||
lld_blob.o strrepl.o lin2ang.o fomerge.o \
|
||||
lld_blob.o strrepl.o lin2ang.o fomerge.o loglisten.o \
|
||||
script.o o2t.o alias.o stringdict.o sdynar.o \
|
||||
histmem.o histdriv.o histsim.o interface.o callback.o \
|
||||
event.o emon.o evcontroller.o evdriver.o simev.o perfmon.o \
|
||||
danu.o nxdict.o varlog.o stptok.o nread.o trigd.o cell.o\
|
||||
scan.o fitcenter.o telnet.o token.o wwildcard.o hklmot.o\
|
||||
tclev.o hkl.o integrate.o optimise.o dynstring.o nxutil.o \
|
||||
uubuffer.o commandlog.o udpquieck.o fourtable.o\
|
||||
uubuffer.o udpquieck.o fourtable.o hexString.o\
|
||||
rmtrail.o help.o nxupdate.o confvirtualmot.o vector.o\
|
||||
simchop.o choco.o chadapter.o trim.o scaldate.o tasub.o\
|
||||
xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\
|
||||
@ -33,7 +33,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
|
||||
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
|
||||
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
|
||||
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
|
||||
sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
|
||||
ascon.o scriptcontext.o logger.o logreader.o logsetup.o \
|
||||
savehdb.o statusfile.o sicshdbfactory.o proxy.o devser.o \
|
||||
moregress.o multicounter.o regresscter.o histregress.o \
|
||||
@ -45,15 +45,15 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \
|
||||
rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \
|
||||
histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\
|
||||
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \
|
||||
singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o lscprot.o \
|
||||
messagepipe.o sicsget.o remoteobject.o pmacprot.o charbychar.o binprot.o \
|
||||
cnvrt.o tclClock.o tclDate.o tclUnixTime.o
|
||||
cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o logv2.o outcode.o
|
||||
|
||||
MOTOROBJ = motor.o simdriv.o
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
VELOOBJ = velo.o velosim.o
|
||||
|
||||
OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA) $(EPICSOBJ)
|
||||
OBJ = $(SOBJ) $(MOTOROBJ) $(COUNTEROBJ) $(VELOOBJ) $(DIFIL) $(EXTRA) $(EPICSOBJ)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .tcl .htm .c .o .tc
|
||||
|
@ -13,15 +13,15 @@ NIOBJ= nigpib.o
|
||||
NILIB=$(SINQDIR)/sl6/lib/cib.o
|
||||
|
||||
EPICSDIR=$(SINQDIR)/sl6/lib/linux-x86
|
||||
EPICSLIBS=$(EPICSDIR)/libezca.a $(EPICSDIR)/libca.a $(EPICSDIR)/libCom.a -lreadline -lhistory
|
||||
#EPICSLIBS=-L$(EPICSDIR) -lezca -lca -lCom
|
||||
#EPICSLIBS=$(EPICSDIR)/libezca.a $(EPICSDIR)/libca.a $(EPICSDIR)/libCom.a -lreadline -lhistory
|
||||
EPICSLIBS=-L$(EPICSDIR) -lezca -lca -lCom
|
||||
|
||||
include sllinux_def
|
||||
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -I$(HDFROOT)/include -DNXXML -DHDF5 $(NI) \
|
||||
-I$(SICSROOT)/sicspsi/hardsup -I$(SICSROOT) -I. -MMD \
|
||||
-I$(SICSROOT)/sicspsi -I$(SICSROOT) -I. -MMD \
|
||||
-Werror -DCYGNUS -DNONINTF $(DBG) $(DFORTIFY) \
|
||||
-Wall -Wno-unused -Wunused-value -Wno-comment -Wno-switch
|
||||
|
||||
@ -33,7 +33,7 @@ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB) $(EPICSLIBS) \
|
||||
-ltcl -lNeXus $(HDFROOT)/lib/libhdf5.a \
|
||||
$(HDFROOT)/lib/libsz.a \
|
||||
$(HDFROOT)/lib/libjson.a \
|
||||
-ldl -lz $(HDFROOT)/lib/libmxml.a $(HDFROOT)/lib/libghttp.a -lm -lc -lpthread
|
||||
-ldl -lz $(HDFROOT)/lib/libmxml.a $(HDFROOT)/lib/libghttp.a -lm -lc -lpthread -lsqlite3 -lbson-1.0 -lmongoc-1.0
|
||||
|
||||
include make_gen
|
||||
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include "motor.h"
|
||||
|
||||
#define MAXPTS 100
|
||||
#define DEBUG 0
|
||||
|
||||
typedef struct __MAXIMIZE {
|
||||
pObjectDescriptor pDes;
|
||||
|
1
motor.c
1
motor.c
@ -56,7 +56,6 @@
|
||||
#include "motor.h"
|
||||
#include "splitter.h"
|
||||
#include "status.h"
|
||||
#include "servlog.h"
|
||||
#include "tclmotdriv.h"
|
||||
#include "site.h"
|
||||
/*-------------------------------------------------------------------------
|
||||
|
47
motorsec.c
47
motorsec.c
@ -58,6 +58,7 @@ static void SecMotorSetError(pMotor self, char *text)
|
||||
if(node != NULL){
|
||||
v = MakeHdbText(strdup(text));
|
||||
UpdateHipadabaPar(node,v,NULL);
|
||||
Log(VERBOSE,"par","%s:error:%s", self->name,text);
|
||||
ReleaseHdbValue(&v);
|
||||
}
|
||||
}
|
||||
@ -84,6 +85,7 @@ static int SecMotorSetPar(pMotor self, SConnection * pCon, char *name,
|
||||
status = SICSHdbSetPar(self, pCon, name, value);
|
||||
if (status == 1) {
|
||||
SCparChange(pCon);
|
||||
Log(VERBOSE,"par","%s:%s:%f", self->name,name,fVal);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
@ -287,6 +289,7 @@ static void handleMoveCallback(pMotor self, SConnection * pCon)
|
||||
node = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||
GetHipadabaPar(node, &v, pCon);
|
||||
UpdateHipadabaPar(node, v, pCon);
|
||||
Log(VERBOSE,"par","%s:hardposition:%f",self->name,v.v.doubleValue);
|
||||
self->posCount = 0;
|
||||
}
|
||||
}
|
||||
@ -321,7 +324,7 @@ static int SecMotorStatus(void *sulf, SConnection * pCon)
|
||||
handleMoveCallback(self, pCon);
|
||||
status = HWBusy;
|
||||
} else if (strstr(v.v.text, "poserror") != NULL) {
|
||||
SCWrite(pCon,"WARNING: Position not reached",eLog);
|
||||
SCPrintf(pCon,eWarning,"WARNING: %s repositioned", self->name);
|
||||
status = checkPosition(self, pCon);
|
||||
} else if (strstr(v.v.text, "restart") != NULL) {
|
||||
SCPrintf(pCon,eLog,"WARNING: restarting motor %s", self->name);
|
||||
@ -539,6 +542,7 @@ static hdbCallbackReturn SecMotorCallback(pHdb node, void *userData,
|
||||
UpdateHipadabaPar(child, MakeHdbText("run"), pCon);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "targetposition");
|
||||
UpdateHipadabaPar(child, MakeHdbFloat(fHard), pCon);
|
||||
Log(VERBOSE,"par","%s:targetposition:%f", self->name,fHard);
|
||||
child = GetHipadabaNode(self->pDescriptor->parNode, "hardposition");
|
||||
SetHipadabaPar(child, MakeHdbFloat(fHard), pCon);
|
||||
|
||||
@ -579,6 +583,9 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
|
||||
mm = GetHdbUpdateMessage(message);
|
||||
if (mm != NULL) {
|
||||
v = *mm->v;
|
||||
if(ABS(v.v.doubleValue - node->value.v.doubleValue) > .01){
|
||||
Log(VERBOSE,"par","%s:hardposition:%f", self->name,v.v.doubleValue);
|
||||
}
|
||||
fVal = hardToSoftPosition(self, (float) v.v.doubleValue);
|
||||
v.v.doubleValue = fVal;
|
||||
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
|
||||
@ -596,6 +603,41 @@ static hdbCallbackReturn HardUpdateCallback(pHdb node, void *userData,
|
||||
}
|
||||
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn StatusUpdateCallback(pHdb node, void *userData,
|
||||
pHdbMessage message)
|
||||
{
|
||||
pHdbDataMessage mm = NULL;
|
||||
pHdbPropertyChange pm = NULL;
|
||||
pMotor self = (pMotor) userData;
|
||||
float fVal;
|
||||
hdbValue v;
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
mm = GetHdbUpdateMessage(message);
|
||||
if (mm != NULL) {
|
||||
v = *mm->v;
|
||||
if(strcmp(v.v.text,node->value.v.text) != 0){
|
||||
UpdateHipadabaPar(self->pDescriptor->parNode, v, mm->callData);
|
||||
Log(VERBOSE,"par","%s:status:%s", self->name,v.v.text);
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
/*
|
||||
forward geterror
|
||||
*/
|
||||
pm = GetPropertyChangeMessage(message);
|
||||
if(pm != NULL){
|
||||
if(strstr(pm->key,"geterror") != NULL){
|
||||
SetHdbProperty(self->pDescriptor->parNode,pm->key, pm->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
@ -882,6 +924,9 @@ pMotor SecMotorInit(char *name)
|
||||
|
||||
child = MakeHipadabaNode("status", HIPTEXT, 1);
|
||||
SetHdbProperty(child, "motname", name);
|
||||
AppendHipadabaCallback(child,
|
||||
MakeHipadabaCallback(StatusUpdateCallback, pM,
|
||||
NULL));
|
||||
AddHipadabaChild(node, child, NULL);
|
||||
|
||||
child = MakeHipadabaNode("error", HIPTEXT, 1);
|
||||
|
@ -100,9 +100,12 @@ static int MMCCStart(void *pData, SConnection * pCon)
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
for (i = 0; i < self->nSlaves; i++) {
|
||||
ReleaseCountLock(self->slaves[i]);
|
||||
self->slaves[i]->SetCountParameters(self->slaveData[i],
|
||||
/*
|
||||
start slaves
|
||||
*/
|
||||
for (i = 1; i < self->nSlaves; i++) {
|
||||
ReleaseCountLock(self->slaves[i]);
|
||||
self->slaves[i]->SetCountParameters(self->slaveData[i],
|
||||
pCount->pDriv->fPreset,
|
||||
pCount->pDriv->eMode);
|
||||
status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
|
||||
@ -112,6 +115,22 @@ static int MMCCStart(void *pData, SConnection * pCon)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
start master
|
||||
*/
|
||||
|
||||
self->slaves[0]->SetCountParameters(self->slaveData[0],
|
||||
pCount->pDriv->fPreset,
|
||||
pCount->pDriv->eMode);
|
||||
status = self->slaves[0]->StartCount(self->slaveData[0], pCon);
|
||||
if (status != OKOK) {
|
||||
MMCCHalt(pData);
|
||||
ReleaseCountLock(pCount->pCountInt);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
pCount->isUpToDate = 0;
|
||||
pCount->tStart = time(NULL);
|
||||
InvokeCallBack(pCount->pCall, COUNTSTART, pCon);
|
||||
|
@ -17,6 +17,10 @@
|
||||
#include <macro.h>
|
||||
#include <status.h>
|
||||
#include "sicshipadaba.h"
|
||||
|
||||
#define slaveSTARTING -100
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
float fPreset;
|
||||
@ -39,15 +43,18 @@ static void SecCounterSetError(pCounter self, char *text)
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void doCountCommand(pHdb self, SConnection *pCon, int command)
|
||||
{
|
||||
pHdb master = NULL, slaves = NULL;
|
||||
pHdb master = NULL, slaves = NULL, status = NULL;
|
||||
char *pPtr, name[80];
|
||||
pICountable pCount = NULL;
|
||||
void *data;
|
||||
|
||||
master = GetHipadabaNode(self,"master");
|
||||
slaves = GetHipadabaNode(self,"slaves");
|
||||
status = GetHipadabaNode(self,"status");
|
||||
assert(master != NULL);
|
||||
assert(slaves != NULL);
|
||||
assert(status != NULL);
|
||||
|
||||
|
||||
/*
|
||||
treat master
|
||||
@ -61,7 +68,12 @@ static void doCountCommand(pHdb self, SConnection *pCon, int command)
|
||||
pCount->Halt(data);
|
||||
break;
|
||||
case 1002: /*pause */
|
||||
pCount->Pause(data,pCon);
|
||||
if(strcmp(status->value.v.text,"starting") == 0){
|
||||
SCWrite(pCon,"WARNINg: cannot pause when not yet started", eWarning);
|
||||
return;
|
||||
} else {
|
||||
pCount->Pause(data,pCon);
|
||||
}
|
||||
break;
|
||||
case 1003: /* continue */
|
||||
pCount->Continue(data,pCon);
|
||||
@ -119,7 +131,7 @@ static void copyExponent(pHdb self, void *data)
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
{
|
||||
pHdb mode = NULL, preset = NULL, master = NULL, slaves = NULL;
|
||||
pHdb mode = NULL, preset = NULL, slaves = NULL;
|
||||
pHdb sID, mID;
|
||||
char *pPtr, name[80];
|
||||
pICountable pCount = NULL;
|
||||
@ -130,13 +142,11 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
|
||||
mode = GetHipadabaNode(self,"mode");
|
||||
preset = GetHipadabaNode(self,"preset");
|
||||
master = GetHipadabaNode(self,"master");
|
||||
slaves = GetHipadabaNode(self,"slaves");
|
||||
sID = GetHipadabaNode(self,"slaveID");
|
||||
mID = GetHipadabaNode(self,"masterID");
|
||||
assert(mode != NULL);
|
||||
assert(preset != NULL);
|
||||
assert(master != NULL);
|
||||
assert(slaves != NULL);
|
||||
assert(sID != NULL);
|
||||
assert(mID != NULL);
|
||||
@ -176,15 +186,76 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
}
|
||||
}
|
||||
|
||||
v = MakeHdbInt(slaveID);
|
||||
UpdateHipadabaPar(sID,v,pCon);
|
||||
|
||||
v = MakeHdbInt(slaveSTARTING);
|
||||
UpdateHipadabaPar(mID,v,pCon);
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static int checkSlavesStarted(pCounter self, SConnection *pCon)
|
||||
{
|
||||
char *pPtr, name[80];
|
||||
pHdb slaves = NULL, status = NULL, preset = NULL, master = NULL, mode = NULL, mID = NULL;
|
||||
pDummy data = NULL;
|
||||
pICountable pCount = NULL;
|
||||
CounterMode eMode;
|
||||
long masterID;
|
||||
hdbValue v;
|
||||
|
||||
mID = GetHipadabaNode(self->objectNode,"masterID");
|
||||
assert(mID != NULL);
|
||||
|
||||
if(mID->value.v.intValue != slaveSTARTING){
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(SCGetInterrupt(pCon) != eContinue) {
|
||||
doCountCommand(self->objectNode,pCon,1001);
|
||||
mID->value.v.intValue = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
slaves = GetHipadabaNode(self->objectNode,"slaves");
|
||||
assert(slaves != NULL);
|
||||
|
||||
pPtr = slaves->value.v.text;
|
||||
while((pPtr = stptok(pPtr,name,sizeof(name),",")) != NULL){
|
||||
data = FindCommandData(pServ->pSics,name,NULL);
|
||||
if(data != NULL){
|
||||
status = GetHipadabaNode(data->pDescriptor->parNode,"status");
|
||||
if(status != NULL){
|
||||
if(strstr(status->value.v.text,"starting") != NULL){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
start master
|
||||
when we are here all HM were started and we can start master
|
||||
*/
|
||||
mode = GetHipadabaNode(self->objectNode,"mode");
|
||||
preset = GetHipadabaNode(self->objectNode,"preset");
|
||||
master = GetHipadabaNode(self->objectNode,"master");
|
||||
assert(master != NULL);
|
||||
assert(mode != NULL);
|
||||
assert(preset != NULL);
|
||||
|
||||
strtolower(mode->value.v.text);
|
||||
if(strcmp(mode->value.v.text,"timer") == 0) {
|
||||
eMode = eTimer;
|
||||
} else {
|
||||
eMode = ePreset;
|
||||
}
|
||||
|
||||
data = FindCommandData(pServ->pSics,master->value.v.text,NULL);
|
||||
if(data != NULL){
|
||||
pCount = GetCountableInterface(data);
|
||||
if(pCount != NULL){
|
||||
copyExponent(self,data);
|
||||
copyExponent(self->objectNode,data);
|
||||
pCount->SetCountParameters(data,preset->value.v.doubleValue,
|
||||
eMode);
|
||||
masterID = StartCountTask(data,pCon,master->value.v.text);
|
||||
@ -193,9 +264,8 @@ static void startMultiCounting(pHdb self, SConnection *pCon)
|
||||
|
||||
v = MakeHdbInt(masterID);
|
||||
UpdateHipadabaPar(mID,v,pCon);
|
||||
v = MakeHdbInt(slaveID);
|
||||
UpdateHipadabaPar(sID,v,pCon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn MultiSecControllCallback(pHdb node,
|
||||
@ -422,6 +492,10 @@ static int MultiSecStatus(void *pData, SConnection * pCon)
|
||||
pCounter self = (pCounter)pData;
|
||||
|
||||
|
||||
if(!checkSlavesStarted(self,pCon)) {
|
||||
return HWBusy;
|
||||
}
|
||||
|
||||
if(isMultiMasterRunning(self,pCon, &status)){
|
||||
return status;
|
||||
}
|
||||
|
13
network.c
13
network.c
@ -52,7 +52,6 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "sics.h"
|
||||
#include "commandlog.h"
|
||||
#include "uselect.h"
|
||||
|
||||
#define PORT 1
|
||||
@ -69,10 +68,14 @@ struct timeval lastclose = { -1, 0 };
|
||||
*/
|
||||
static void NetError(const char pText[])
|
||||
{
|
||||
/*
|
||||
SICSLogWrite(pText,eError);
|
||||
*/
|
||||
WriteToCommandLog("NET>", pText);
|
||||
unsigned int severity = DEBUG;
|
||||
if(strstr(pText,"ERROR") != NULL){
|
||||
severity = ERROR;
|
||||
} else if(strstr(pText,"WARNING") != NULL){
|
||||
severity = WARN;
|
||||
}
|
||||
|
||||
Log(severity,"io","%s", pText);
|
||||
}
|
||||
|
||||
/* ---------------------------- Local ------------------------------------
|
||||
|
70
nread.c
70
nread.c
@ -29,7 +29,6 @@
|
||||
#include "passwd.h"
|
||||
#include "conman.h"
|
||||
#include "SCinter.h"
|
||||
#include "servlog.h"
|
||||
#include "costa.h"
|
||||
#include "task.h"
|
||||
#include "emon.h"
|
||||
@ -39,7 +38,6 @@
|
||||
#include "interrupt.h"
|
||||
#include "telnet.h"
|
||||
#include "nread.h"
|
||||
#include "commandlog.h"
|
||||
#include "uselect.h"
|
||||
#include "trace.h"
|
||||
#include "protocol.h"
|
||||
@ -163,7 +161,7 @@ int NetReadRegister(pNetRead self, mkChannel * pSock, eNRType eType,
|
||||
if (sEntry.pSock->sockid == pSock->sockid) {
|
||||
snprintf(buffer, sizeof buffer, "NetReadRegister twice %d type %d",
|
||||
pSock->sockid, eType);
|
||||
WriteToCommandLog("SYS>", buffer);
|
||||
Log(ERROR,"sys", buffer);
|
||||
return 1;
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
@ -219,16 +217,16 @@ static int NetReadAccept(pNetRead self, mkChannel * pSock)
|
||||
pRes = SCreateConnection(self->pMain->pSics,pNew,3);
|
||||
*/
|
||||
if (!pRes) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
NETClosePort(pNew);
|
||||
free(pNew);
|
||||
return 0;
|
||||
} else {
|
||||
/* register the connection and create a task for it here */
|
||||
NetReadRegister(self, pNew, command, pRes);
|
||||
TaskRegister(self->pMain->pTasker,
|
||||
TaskRegisterN(self->pMain->pTasker, "NetReadAccept",
|
||||
SCTaskFunction,
|
||||
SCSignalFunction, SCDeleteConnection, pRes, 1);
|
||||
SCSignalFunction, SCDeleteConnection, pRes, TASK_PRIO_LOW);
|
||||
SCSendOK(pRes);
|
||||
return 1;
|
||||
}
|
||||
@ -264,11 +262,8 @@ static int NetReadRead(pNetRead self, pNetItem pItem)
|
||||
if (pPtr) {
|
||||
sscanf(pPtr, "%s %d", pMuell, &iInt);
|
||||
if (SCMatchRights(pItem->pCon, usUser)) {
|
||||
traceCommand(ConID(pItem->pCon),"interrupt: %d",iInt);
|
||||
TaskSignal(self->pMain->pTasker, SICSINT, &iInt);
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "INTERRUPT %d issued on sock %d",
|
||||
iInt, pItem->pCon->pSock->sockid);
|
||||
WriteToCommandLog("SYS>", pBueffel);
|
||||
Log(ERROR,"com","sock%03.3d:INTERRUPT", pItem->pCon->pSock->sockid);
|
||||
if (iInt == eEndServer) {
|
||||
TaskStop(self->pMain->pTasker);
|
||||
}
|
||||
@ -363,7 +358,7 @@ static int TelnetAccept(pNetRead self, mkChannel * pSock)
|
||||
pRes = SCreateConnection(self->pMain->pSics,pNew,usSpy);
|
||||
*/
|
||||
if (!pRes) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
NETClosePort(pNew);
|
||||
free(pNew);
|
||||
return 0;
|
||||
@ -371,16 +366,15 @@ static int TelnetAccept(pNetRead self, mkChannel * pSock)
|
||||
/* Create a task object for the telnet connection */
|
||||
pTel = CreateTelnet(pRes);
|
||||
if (!pTel) {
|
||||
SICSLogWrite("Failure to allocate new Telnet Task Object",
|
||||
eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Telnet Task Object");
|
||||
SCDeleteConnection(pRes);
|
||||
return 0;
|
||||
}
|
||||
/* register connection and task */
|
||||
pRes->iTelnet = 1;
|
||||
NetReadRegister(self, pNew, tcommand, pRes);
|
||||
TaskRegister(self->pMain->pTasker,
|
||||
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
|
||||
TaskRegisterN(self->pMain->pTasker," TelnetAccept",
|
||||
TelnetTask, TelnetSignal, DeleteTelnet, pTel, TASK_PRIO_LOW);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
@ -466,10 +460,7 @@ static int TelnetRead(pNetRead self, pNetItem pItem)
|
||||
}
|
||||
}
|
||||
TaskSignal(self->pMain->pTasker, SICSINT, &iInt);
|
||||
traceCommand(ConID(pItem->pCon),"interrupt: %d",iInt);
|
||||
snprintf(pError,sizeof(pError)-1, "INTERRUPT %d issued on sock %d", iInt,
|
||||
pItem->pCon->pSock->sockid);
|
||||
WriteToCommandLog("SYS>", pError);
|
||||
Log(ERROR,"com","%s:interrupt: %d", ConID(pItem->pCon),iInt);
|
||||
if (iInt == eEndServer) {
|
||||
TaskStop(self->pMain->pTasker);
|
||||
}
|
||||
@ -627,7 +618,7 @@ static int TelnetRead(pNetRead self, pNetItem pItem)
|
||||
default:
|
||||
/* There is something wrong here! */
|
||||
snprintf(pError,sizeof(pError)-1, "ERROR: bad telnet code %d", cChar);
|
||||
SICSLogWrite(pError, eInternal);
|
||||
Log(ERROR,"sys","%s",pError);
|
||||
pItem->tStatus = tData;
|
||||
break;
|
||||
|
||||
@ -706,15 +697,15 @@ int NetReaderTask(void *pData)
|
||||
}
|
||||
conCount++;
|
||||
if (conCount > 100) {
|
||||
WriteToCommandLog("WAYTOMANYCONNECTIONS> ",
|
||||
Log(ERROR,"sys","%s","WAYTOMANYCONNECTIONS:%s ",
|
||||
GetCharArray(self->conList));
|
||||
}
|
||||
iRet = LLDnodePtr2Next(self->iList);
|
||||
}
|
||||
|
||||
if (conCount > 100) {
|
||||
WriteToCommandLog("WAYTOMANYCONNECTIONS> ",
|
||||
GetCharArray(self->conList));
|
||||
Log(ERROR,"sys","%s","WAYTOMANYCONNECTIONS:%s ",
|
||||
GetCharArray(self->conList));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -898,8 +889,8 @@ int NetReadWait4Data(pNetRead self, int iSocket)
|
||||
pNew->pChan = pChan;
|
||||
pNew->iEnd = 0;
|
||||
pNew->pRead = self;
|
||||
lID = TaskRegister(self->pMain->pTasker,
|
||||
Wait4ReadTask, ReadWaitSignal, ReadWaitFree, pNew, 0);
|
||||
lID = TaskRegisterN(self->pMain->pTasker, "NetReadWait4Data",
|
||||
Wait4ReadTask, ReadWaitSignal, ReadWaitFree, pNew, TASK_PRIO_HIGH);
|
||||
|
||||
/* wait for finish */
|
||||
TaskWait(self->pMain->pTasker, lID);
|
||||
@ -1039,12 +1030,10 @@ static int testAndInvokeInterrupt(pCommandCBData self, int handle)
|
||||
if ((pInt = strstr(pPtr, "INT1712")) != NULL) {
|
||||
sscanf(pInt, "%s %d", buffer, &iInt);
|
||||
if (SCMatchRights(self->pCon, usUser)) {
|
||||
traceCommand(ConID(self->pCon),"interrupt:%d",iInt);
|
||||
Log(INFO, "com","%s:interrupt:%d", ConID(self->pCon), iInt);
|
||||
TaskSignal(pServ->pTasker, SICSINT, &iInt);
|
||||
snprintf(buffer, 512, "INTERRUPT %d issued on sock %d",
|
||||
iInt, handle);
|
||||
WriteToCommandLog("SYS>", buffer);
|
||||
SICSLogWrite(buffer, eInternal);
|
||||
if (iInt == eEndServer) {
|
||||
TaskStop(pServ->pTasker);
|
||||
}
|
||||
@ -1115,12 +1104,12 @@ static int CommandAcceptCB(int handle, void *userData)
|
||||
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
||||
usData = malloc(sizeof(CommandCBData));
|
||||
if (pCon == NULL || usData == NULL) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
return 0;
|
||||
}
|
||||
usData->command = CreateDynString(256, 256);
|
||||
if (usData->command == NULL) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
return 0;
|
||||
}
|
||||
usData->pCon = pCon;
|
||||
@ -1129,7 +1118,7 @@ static int CommandAcceptCB(int handle, void *userData)
|
||||
TaskRegisterN(pServ->pTasker,
|
||||
buffer,
|
||||
SCTaskFunction,
|
||||
SCSignalFunction, SCDeleteConnection, pCon, 1);
|
||||
SCSignalFunction, SCDeleteConnection, pCon, TASK_PRIO_LOW);
|
||||
ANETsetReadCallback(handle, CommandDataCB, usData, killCommandCBData);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
@ -1301,8 +1290,7 @@ static int ANETTelnetProcess(int handle, void *usData)
|
||||
|
||||
default:
|
||||
/* There is something wrong here! */
|
||||
snprintf(pError,sizeof(pError)-1, "ERROR: bad telnet code %d", cChar);
|
||||
SICSLogWrite(pError, eInternal);
|
||||
Log(ERROR,"sys","Bad telnet code %d", cChar);
|
||||
self->state = tData;
|
||||
break;
|
||||
|
||||
@ -1323,12 +1311,12 @@ static int TelnetAcceptCB(int handle, void *userData)
|
||||
pCon = SCreateConnection(pServ->pSics, handle, 3);
|
||||
usData = malloc(sizeof(CommandCBData));
|
||||
if (pCon == NULL || usData == NULL) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
return 0;
|
||||
}
|
||||
usData->command = CreateDynString(256, 256);
|
||||
if (usData->command == NULL) {
|
||||
SICSLogWrite("Failure to allocate new Connection", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Connection");
|
||||
return 0;
|
||||
}
|
||||
usData->pCon = pCon;
|
||||
@ -1336,7 +1324,7 @@ static int TelnetAcceptCB(int handle, void *userData)
|
||||
/* Create a task object for the telnet connection */
|
||||
pTel = CreateTelnet(pCon);
|
||||
if (!pTel) {
|
||||
SICSLogWrite("Failure to allocate new Telnet Task Object", eInternal);
|
||||
Log(ERROR,"sys","%s","Failure to allocate new Telnet Task Object");
|
||||
SCDeleteConnection(pCon);
|
||||
return 0;
|
||||
}
|
||||
@ -1345,7 +1333,7 @@ static int TelnetAcceptCB(int handle, void *userData)
|
||||
snprintf(buffer,sizeof(buffer),"con%ld", pCon->ident);
|
||||
TaskRegisterN(pServ->pTasker,
|
||||
buffer,
|
||||
TelnetTask, TelnetSignal, DeleteTelnet, pTel, 1);
|
||||
TelnetTask, TelnetSignal, DeleteTelnet, pTel, TASK_PRIO_LOW);
|
||||
ANETsetReadCallback(handle, ANETTelnetProcess,
|
||||
usData, killCommandCBData);
|
||||
SCSendOK(pCon);
|
||||
@ -1355,8 +1343,12 @@ static int TelnetAcceptCB(int handle, void *userData)
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
static void NREADlog(int level, char *txt, void *userData)
|
||||
{
|
||||
traceSys("anet","%s",txt);
|
||||
SICSLogWrite(txt, (level == ANETERROR) ? eLogError : eLog);
|
||||
/*
|
||||
suppress the connection messages
|
||||
*/
|
||||
if(level != ANETCON){
|
||||
traceSys("anet","%s",txt);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------------*/
|
||||
|
20
nserver.c
20
nserver.c
@ -37,7 +37,6 @@
|
||||
#include "tcldrivable.h"
|
||||
#include "nserver.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
|
||||
extern int openDevexecLog(); /* in devexec.c */
|
||||
@ -49,6 +48,7 @@ static void StopExit(void)
|
||||
if (pServ) {
|
||||
StopServer(pServ);
|
||||
}
|
||||
LogClose(NULL);
|
||||
}
|
||||
|
||||
#define DEFAULTINIFILE "servo.tcl"
|
||||
@ -114,16 +114,16 @@ int InitServer(char *file, pServer * pServ)
|
||||
assert(self->pSics);
|
||||
|
||||
/* initialise tasker */
|
||||
assert(TaskerInit(&self->pTasker));
|
||||
TaskerInit(&self->pTasker);
|
||||
assert(self->pTasker != NULL);
|
||||
|
||||
pSICSOptions = IFAddOption(pSICSOptions, "ConnectionCount", "0");
|
||||
pSICSOptions = IFAddOption(pSICSOptions, "ConMask", "0");
|
||||
|
||||
/* initialize the network watcher */
|
||||
TaskRegister(self->pTasker, NetWatchTask, NULL, NULL, NULL, 1);
|
||||
TaskRegisterN(self->pTasker, "nwatch", NetWatchTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
|
||||
/* initialise the server from script */
|
||||
SetWriteHistory(0);
|
||||
if (file == NULL) {
|
||||
iRet = InitObjectCommands(self, DEFAULTINIFILE);
|
||||
} else {
|
||||
@ -181,7 +181,7 @@ int InitServer(char *file, pServer * pServ)
|
||||
iCommandTimeOut)) != NULL);
|
||||
TaskRegisterN(self->pTasker, "Network Reader",
|
||||
NetReaderTask, NetReaderSignal, NULL, /* call DeleteNetReader later than TaskerDelete */
|
||||
pReader, 1);
|
||||
pReader, TASK_PRIO_HIGH);
|
||||
self->pReader = pReader;
|
||||
|
||||
/* the socket */
|
||||
@ -243,17 +243,17 @@ int InitServer(char *file, pServer * pServ)
|
||||
/* install environment monitor */
|
||||
self->pMonitor = GetEnvMon(self->pSics);
|
||||
TaskRegisterN(self->pTasker,"EV Monitor",
|
||||
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, 1);
|
||||
EnvMonTask, EnvMonSignal, NULL, self->pMonitor, TASK_PRIO_HIGH);
|
||||
|
||||
/* install performance monitor */
|
||||
pMon = CreatePerfMon(20);
|
||||
AddCommand(self->pSics, "Performance", PerfMonWrapper, DeletePerfMon,
|
||||
pMon);
|
||||
TaskRegisterN(self->pTasker,"perfmon", PerfMonTask, PerfMonSignal, NULL, pMon, 1);
|
||||
TaskRegisterN(self->pTasker,"perfmon", PerfMonTask, PerfMonSignal, NULL, pMon, TASK_PRIO_HIGH);
|
||||
/* Install a second one for higher granularity measurement */
|
||||
pMon = CreatePerfMon(2);
|
||||
TaskRegisterN(self->pTasker,"perfmon2",
|
||||
PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, 1);
|
||||
PerfMonTask, PerfMonSignal, DeletePerfMon, pMon, TASK_PRIO_HIGH);
|
||||
|
||||
|
||||
/* install telnet port */
|
||||
@ -264,7 +264,6 @@ int InitServer(char *file, pServer * pServ)
|
||||
strcpy(pBueffel, "restore");
|
||||
SCInvoke(self->dummyCon, self->pSics, pBueffel);
|
||||
}
|
||||
SetWriteHistory(1);
|
||||
|
||||
INIT(StatusFileInit);
|
||||
|
||||
@ -375,6 +374,7 @@ void StopServer(pServer self)
|
||||
|
||||
free(self);
|
||||
|
||||
LogClose(NULL);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -465,7 +465,7 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
|
||||
sWait.dFinish = DoubleTime() + (double)fVal;
|
||||
sWait.iEnd = 0;
|
||||
lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, 1);
|
||||
lID = TaskRegisterN(pTask,"wait", WaitTask, WaitSignal, NULL, &sWait, TASK_PRIO_HIGH);
|
||||
TaskWait(pTask, lID); if (SCGetInterrupt(pCon) != eContinue) {
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -188,6 +188,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
|
||||
self->fileHandle = NULL;
|
||||
self->dictHandle = NULL;
|
||||
SendQuieck(QUIECK, buffer);
|
||||
traceIO("datafile", "Closing datafile");
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else if (strcmp(argv[1], "reopen") == 0) {
|
||||
@ -215,6 +216,7 @@ static int handleFileOperations(SConnection * pCon, pNXScript self,
|
||||
if (self->fileHandle != NULL) {
|
||||
NXclose(&self->fileHandle);
|
||||
self->fileHandle = NULL;
|
||||
traceIO("datafile", "Closing datafile");
|
||||
}
|
||||
if (self->dictHandle != NULL) {
|
||||
NXDclose(self->dictHandle, NULL);
|
||||
|
@ -81,7 +81,7 @@ static int CountCallback(int iEvent, void *pEventData, void *pUser)
|
||||
self->nextUpdate = time(NULL) + self->updateIntervall;
|
||||
self->iEnd = 0;
|
||||
self->pCon = pCon;
|
||||
TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, 1);
|
||||
TaskRegisterN(pServ->pTasker, "NXupdater", UpdateTask, NULL, NULL, self, TASK_PRIO_HIGH);
|
||||
return 1;
|
||||
} else if (iEvent == COUNTEND) {
|
||||
self->iEnd = 1;
|
||||
|
7
obdes.c
7
obdes.c
@ -43,9 +43,8 @@
|
||||
#include "fortify.h"
|
||||
#include "obdes.h"
|
||||
#include "conman.h"
|
||||
#include "servlog.h"
|
||||
#include "hipadaba.h"
|
||||
|
||||
#include "logv2.h"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void *DefaultGetInterface(void *pData, int iID)
|
||||
{
|
||||
@ -102,14 +101,14 @@ pDummy CreateDummy(char *name)
|
||||
|
||||
pRes = (pDummy) malloc(sizeof(Dummy));
|
||||
if (!pRes) {
|
||||
SICSLogWrite("Out of Memory in CreateDummy", eInternal);
|
||||
Log(ERROR,"sys","Out of Memory in CreateDummy");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRes->pDescriptor = CreateDescriptor(name);
|
||||
if (!pRes->pDescriptor) {
|
||||
free(pRes);
|
||||
SICSLogWrite("Out of Memory in CreateDummy", eInternal);
|
||||
Log(ERROR,"sys","%s","Out of Memory in CreateDummy");
|
||||
return NULL;
|
||||
}
|
||||
return pRes;
|
||||
|
6
ofac.c
6
ofac.c
@ -43,7 +43,6 @@ static void InitGeneral(void)
|
||||
INIT(LogSetupInit);
|
||||
INIT(InstallBackground);
|
||||
INIT(MakeProtocol);
|
||||
INIT(CommandLogInit);
|
||||
INIT(UdpInit);
|
||||
INIT(HelpInit);
|
||||
INIT(AddTestProt);
|
||||
@ -52,9 +51,12 @@ static void InitGeneral(void)
|
||||
INIT(AddBinProtocol);
|
||||
INIT(AddPMACProtocoll);
|
||||
INIT(AddCharByCharProtocoll);
|
||||
INIT(AddLscProtocol);
|
||||
INIT(MakeTrace);
|
||||
INIT(InitTaskOBJ);
|
||||
INIT(RemoteObjectInit);
|
||||
INIT(Logv2Init);
|
||||
INIT(LogListenInit);
|
||||
INIT(SiteInit); /* site specific initializations */
|
||||
}
|
||||
|
||||
@ -91,7 +93,6 @@ static void InitIniCommands(SicsInterp * pInter)
|
||||
PCMD("findalias", LocateAliasAction);
|
||||
PCMD("fulltransact", TransactAction);
|
||||
PCMD("GetInt", GetSICSInterrupt);
|
||||
PCMD("GetLog", LogCapture);
|
||||
PCMD("GumPut", GumPut);
|
||||
PCMD("InternEval", InternalFileEval);
|
||||
PCMD("kill_command", SICSKill);
|
||||
@ -131,7 +132,6 @@ static void InitIniCommands(SicsInterp * pInter)
|
||||
SCMD("allowexec", AllowExec);
|
||||
SCMD("AntiCollisionInstall", AntiColliderFactory);
|
||||
SCMD("ChopperAdapter", CHAdapterFactory);
|
||||
SCMD("InstallSinfox", InstallSinfox);
|
||||
SCMD("MakeBatchManager", MakeExeManager);
|
||||
SCMD("MakeChopper", ChocoFactory);
|
||||
SCMD("MakeCone", MakeCone);
|
||||
|
13
oscillate.c
13
oscillate.c
@ -15,7 +15,6 @@
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "task.h"
|
||||
#include "commandlog.h"
|
||||
#include "oscillate.h"
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
@ -31,7 +30,7 @@ static void StopOscillation(pOscillator self)
|
||||
}
|
||||
MotorSetPar(self->pMot, self->pCon, "accesscode", usUser);
|
||||
if (self->debug > 0) {
|
||||
WriteToCommandLog("oscillator>> ", "Stopping");
|
||||
Log(INFO,"com","%s","oscillator stopping");
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,16 +78,16 @@ static int OscillationTask(void *data)
|
||||
switch (status) {
|
||||
case HWFault:
|
||||
case HWPosFault:
|
||||
WriteToCommandLog("oscillator>> ",
|
||||
Log(ERROR,"com","%s:%s","oscillator:",
|
||||
"ERROR occurred in oscillation, try running motor manually to find out more");
|
||||
WriteToCommandLog("oscillator>> ",
|
||||
Log(INFO,"com","%s:%s","oscillator",
|
||||
"Trying to run other direction");
|
||||
pos = getNextPos(self);
|
||||
status = MotorRun(self->pMot, self->pCon, pos);
|
||||
if (self->debug > 0) {
|
||||
snprintf(message, 131, "Started oscillation to %f, ret code = %d",
|
||||
pos, status);
|
||||
WriteToCommandLog("oscillator>>", message);
|
||||
Log(INFO,"com","%s:%s","oscillator", message);
|
||||
}
|
||||
break;
|
||||
case HWWarn:
|
||||
@ -109,7 +108,7 @@ static int OscillationTask(void *data)
|
||||
if (self->debug > 0) {
|
||||
snprintf(message, 131, "Started oscillation to %f, ret code = %d",
|
||||
pos, status);
|
||||
WriteToCommandLog("oscillator>>", message);
|
||||
Log(INFO,"com","%s:%s","oscillator", message);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -165,7 +164,7 @@ static int StartOscillation(pOscillator self, SConnection * pCon)
|
||||
*/
|
||||
snprintf(pBueffel,sizeof(pBueffel),"Oscillate-%s", self->pMot->name);
|
||||
self->taskID = TaskRegisterN(pServ->pTasker,pBueffel,
|
||||
OscillationTask, NULL, NULL, self, 10);
|
||||
OscillationTask, NULL, NULL, self, TASK_PRIO_HIGH);
|
||||
if (self->taskID < 0) {
|
||||
SCWrite(pCon, "ERROR: failed to start oscillation task", eError);
|
||||
return 0;
|
||||
|
59
outcode.c
59
outcode.c
@ -5,26 +5,41 @@
|
||||
|
||||
Mark Koennecke, November 1996
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef POUTCODE
|
||||
#define POUTCODE
|
||||
#include "Scommon.h"
|
||||
#include "outcode.h"
|
||||
#include <strings.h>
|
||||
|
||||
static char *pCode[] = {
|
||||
"internal",
|
||||
"command",
|
||||
"hwerror",
|
||||
"inerror",
|
||||
"status",
|
||||
"value",
|
||||
"start",
|
||||
"finish",
|
||||
"event",
|
||||
"warning",
|
||||
"error",
|
||||
"hdbvalue",
|
||||
"hdbevent",
|
||||
"log",
|
||||
"logerror",
|
||||
NULL
|
||||
};
|
||||
static int iNoCodes = 15;
|
||||
#endif
|
||||
const char* OutCodeToTxt(OutCode eOut)
|
||||
{
|
||||
switch (eOut) {
|
||||
case eInternal: return "Int"; /* internal */
|
||||
case eCommand: return "Cmd"; /* reserved, not used */
|
||||
case eHWError: return "ErH"; /* reserved, used only for SICSLog */
|
||||
case eInError: return "ErI"; /* reserved, used as a mark in the handling of output codes */
|
||||
case eStatus: return "Sta"; /* reserved, deprecated */
|
||||
case eValue: return "Val"; /* value reponse: copied into Tcl */
|
||||
case eStart: return "Beg"; /* start message */
|
||||
case eFinish: return "End"; /* finish message */
|
||||
case eEvent: return "Evt"; /* some callback messages */
|
||||
case eWarning: return "Wrn"; /* warnings */
|
||||
case eError: return "Err"; /* error: copied into Tcl */
|
||||
case eHdbValue: return "HVa"; /* hipadaba value chnage */
|
||||
case eHdbEvent: return "HEv"; /* Hipadaba event */
|
||||
case eLog: return "Log"; /* log message: is always written to client */
|
||||
case eLogError: return "ErL"; /* error message to log: is always written to client */
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
|
||||
int OutCodeFromText(const char *text, OutCode *outcode)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < iNoCodes; ++i) {
|
||||
if (strcasecmp(text, pCode[i]) == 0) {
|
||||
if (outcode)
|
||||
*outcode = i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
35
outcode.h
Normal file
35
outcode.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* ------------------------------------------------------------------------
|
||||
The OutCode's for SICS have to be translated from text at several
|
||||
places in SICS. Wherever necessary such code should include this file.
|
||||
This restricts changes to Scommon.h and this file
|
||||
|
||||
Mark Koennecke, November 1996
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef POUTCODE
|
||||
#define POUTCODE
|
||||
|
||||
static char *pCode[] = {
|
||||
"internal",
|
||||
"command",
|
||||
"hwerror",
|
||||
"inerror",
|
||||
"status",
|
||||
"value",
|
||||
"start",
|
||||
"finish",
|
||||
"event",
|
||||
"warning",
|
||||
"error",
|
||||
"hdbvalue",
|
||||
"hdbevent",
|
||||
"log",
|
||||
"logerror",
|
||||
NULL
|
||||
};
|
||||
static int iNoCodes = 15;
|
||||
|
||||
const char* OutCodeToTxt(OutCode eOut);
|
||||
|
||||
int OutCodeFromText(const char *text, OutCode *outcode);
|
||||
|
||||
#endif
|
@ -41,7 +41,6 @@
|
||||
#include <time.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "servlog.h"
|
||||
#include "perfmon.h"
|
||||
#include "perfmon.i"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -125,12 +124,8 @@ int IncrementPerfMon(pPerfMon self)
|
||||
self->iCount = 0;
|
||||
self->tLast = tCurrent;
|
||||
self->tTarget = tCurrent + self->iInteg;
|
||||
if (self->iLog) {
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "PerfMon = %f", self->fCPS);
|
||||
SICSLogWrite(pBueffel, eValue);
|
||||
}
|
||||
InvokeCallBack(self->pCall, VALUECHANGE, &self->fCPS);
|
||||
traceSys("perfmon","%d:%f", self->iInteg, self->fCPS);
|
||||
LogIS(VERBOSE,SSYS,"perfmon","%d:%f", self->iInteg, self->fCPS);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -160,7 +155,7 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
||||
}
|
||||
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "Performance = %f", *fPos);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ static int pollHdb(struct __POLLDRIV *self, SConnection * pCon)
|
||||
|
||||
assert(node != NULL);
|
||||
|
||||
self->nextPoll = time(NULL) + self->pollIntervall;
|
||||
if (GetHipadabaPar(node, &newVal, pCon) == 1) {
|
||||
ReleaseHdbValue(&newVal);
|
||||
return 1;
|
||||
@ -84,7 +83,6 @@ static int pollScript(struct __POLLDRIV *self, SConnection * pCon)
|
||||
int status;
|
||||
Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics);
|
||||
|
||||
self->nextPoll = time(NULL) + self->pollIntervall;
|
||||
|
||||
MacroPush(pCon);
|
||||
status = Tcl_Eval(pTcl, (char *) self->objPointer);
|
||||
|
@ -16,6 +16,7 @@ typedef struct __POLLDRIV {
|
||||
void *objPointer; /* a pointer to the object */
|
||||
time_t nextPoll; /* next polling time */
|
||||
int pollIntervall; /* poll intervall */
|
||||
int actualPollIntervall; /* for supporting exponential backoff */
|
||||
int (*isDue) (struct __POLLDRIV * self, time_t now, SConnection * pCon);
|
||||
/* function called to determine if this object must be polled */
|
||||
int (*poll) (struct __POLLDRIV * self, SConnection * pCon);
|
||||
|
19
protocol.c
19
protocol.c
@ -12,9 +12,8 @@
|
||||
#include <conman.h>
|
||||
#include <fupa.h>
|
||||
#include <splitter.h>
|
||||
#include <outcode.c>
|
||||
#include <outcode.h>
|
||||
#include <dynstring.h>
|
||||
#include "commandlog.h"
|
||||
#include "protocol.h"
|
||||
#include <json/json.h>
|
||||
|
||||
@ -89,7 +88,6 @@ static int EnumChoice(char *pList[], int iLength, char *pInput);
|
||||
static int InitDefaultProtocol(SConnection * pCon, Protocol * pPro);
|
||||
|
||||
/* Signatures for protocol writers implemented in this file */
|
||||
int SCWriteSycamore(SConnection * pCon, char *pBuffer, int iOut);
|
||||
int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut);
|
||||
/* Signatures for protocols from conman.c*/
|
||||
extern int SCAllWrite(SConnection * self, char *buffer, int iOut);
|
||||
@ -572,19 +570,12 @@ int SCWriteJSON_String(SConnection * pCon, char *pBuffer, int iOut)
|
||||
} else {
|
||||
iRet = 0;
|
||||
}
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "Next line intended for socket: %d", iRet);
|
||||
SICSLogWrite(pBueffel, eInternal);
|
||||
SICSLogWrite(pBuffer, iOut);
|
||||
|
||||
/* write to commandlog if user or manager privilege */
|
||||
if (SCGetRights(pCon) <= usUser) {
|
||||
if (pCon->iMacro != 1) {
|
||||
WriteToCommandLogId(NULL, iRet, pBuffer);
|
||||
} else {
|
||||
if (iOut == eError || iOut == eWarning) {
|
||||
WriteToCommandLogId(NULL, iRet, pBuffer);
|
||||
}
|
||||
}
|
||||
if (SCGetRights(pCon) <= usUser && !SCinMacro(pCon)) {
|
||||
Log(INFO,"com","sock%03.3d:%s",iRet, pBuffer);
|
||||
} else {
|
||||
Log(DEBUG,"com","sock%03.3d:%s", iRet, pBuffer);
|
||||
}
|
||||
|
||||
if (SCinMacro(pCon)) {
|
||||
|
10
remob.c
10
remob.c
@ -17,9 +17,7 @@ M. Zolliker July 04
|
||||
#include "remob.h"
|
||||
#include "splitter.h"
|
||||
#include "status.h"
|
||||
#include "servlog.h"
|
||||
#include "site.h"
|
||||
#include "commandlog.h"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#define INTERRUPTMODE 0
|
||||
#define ACCESSCODE 1
|
||||
@ -31,7 +29,7 @@ typedef struct RemChannel {
|
||||
mkChannel *chan;
|
||||
int timeout;
|
||||
int incomplete;
|
||||
char line[256];
|
||||
char line[1024];
|
||||
} RemChannel;
|
||||
|
||||
typedef struct RemServer {
|
||||
@ -275,7 +273,7 @@ static int RemServerTask(void *data)
|
||||
continue;
|
||||
|
||||
if (strstr(rc->line, " ") == rc->line) {
|
||||
WriteToCommandLog("REMOB>", "infinite echo loop detected");
|
||||
Log(ERROR,"sys","%s:%s","REMOB", "infinite echo loop detected");
|
||||
continue;
|
||||
}
|
||||
if (isUser == 0) {
|
||||
@ -629,7 +627,7 @@ static int InterestCallback(int iEvent, void *pEvent, void *pUser)
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s.position = %g ", pInfo->pName,
|
||||
psCall->fVal);
|
||||
SCWrite(pInfo->pCon, buf, eValue);
|
||||
SCWrite(pInfo->pCon, buf, eEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -978,7 +976,7 @@ static RemServer *RemServerInit(char *name, char *host, int port)
|
||||
remserver->interestActive = 0;
|
||||
remserver->forwardMessages = 1;
|
||||
TaskRegisterN(pServ->pTasker,name, RemServerTask, NULL, RemServerKill,
|
||||
remserver, 1);
|
||||
remserver, TASK_PRIO_HIGH);
|
||||
return remserver;
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,7 @@ static int HeartbeatTask(void *pData)
|
||||
termination.
|
||||
|
||||
-----------------------------------------------------------------------------------*/
|
||||
#include <outcode.c>
|
||||
#include <outcode.h>
|
||||
static OutCode findOutCode(char *txt)
|
||||
{
|
||||
int i;
|
||||
|
16
scan.c
16
scan.c
@ -1201,10 +1201,10 @@ static int ScanInterest(int iEvent, void *pEventData, void *pUser)
|
||||
}
|
||||
|
||||
if (iEvent == SCANSTART) {
|
||||
SCWrite(pCon, "NewScan", eLog);
|
||||
SCWrite(pCon, "NewScan", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANEND) {
|
||||
SCWrite(pCon, "ScanEnd", eLog);
|
||||
SCWrite(pCon, "ScanEnd", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANPOINT) {
|
||||
/* allocate space */
|
||||
@ -1231,7 +1231,7 @@ static int ScanInterest(int iEvent, void *pEventData, void *pUser)
|
||||
strcat(pPtr, "}");
|
||||
oldWrite = SCGetWriteFunc(pCon);
|
||||
SCSetWriteFunc(pCon, SCOnlySockWrite);
|
||||
SCWrite(pCon, pPtr, eLog);
|
||||
SCWrite(pCon, pPtr, eEvent);
|
||||
SCSetWriteFunc(pCon, oldWrite);
|
||||
free(lData);
|
||||
free(pPtr);
|
||||
@ -1264,10 +1264,10 @@ static int ScanDynInterest(int iEvent, void *pEventData, void *pUser)
|
||||
}
|
||||
|
||||
if (iEvent == SCANSTART) {
|
||||
SCWrite(pCon, "NewScan", eLog);
|
||||
SCWrite(pCon, "NewScan", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANEND) {
|
||||
SCWrite(pCon, "ScanEnd", eLog);
|
||||
SCWrite(pCon, "ScanEnd", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANPOINT) {
|
||||
i = self->iCounts - 1;
|
||||
@ -1287,7 +1287,7 @@ static int ScanDynInterest(int iEvent, void *pEventData, void *pUser)
|
||||
}
|
||||
snprintf(pBueffel, 255, "%s.scanpoint = {%d %f %ld}",
|
||||
self->objectName, i, fVal, lVal);
|
||||
SCWrite(pCon, pBueffel, eLog);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1315,10 +1315,10 @@ static int ScanUUInterest(int iEvent, void *pEventData, void *pUser)
|
||||
}
|
||||
|
||||
if (iEvent == SCANSTART) {
|
||||
SCWrite(pCon, "NewScan", eLog);
|
||||
SCWrite(pCon, "NewScan", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANEND) {
|
||||
SCWrite(pCon, "ScanEnd", eLog);
|
||||
SCWrite(pCon, "ScanEnd", eEvent);
|
||||
return 1;
|
||||
} else if (iEvent == SCANPOINT) {
|
||||
/* allocate space */
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "sicsobj.h"
|
||||
#include "splitter.h"
|
||||
#include "initializer.h"
|
||||
#include "commandlog.h"
|
||||
#include "hipadaba.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "dynstring.h"
|
||||
@ -516,14 +515,14 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
emsg = GetHdbProp(node, eprop);
|
||||
if (emsg == NULL || con != controller->conn) {
|
||||
GetHdbPath(node, path, sizeof path);
|
||||
SCPrintf(con, eLogError,
|
||||
"ERROR: action {%s} in {%s} node %s:\nERROR: %s",
|
||||
snprintf(msg,sizeof(msg),"ERROR: action {%s} in {%s} node %s:\nERROR: %s",
|
||||
data->name, origScript, path, result);
|
||||
SCPureSockWrite(con, msg,eLogError);
|
||||
if(data != NULL && data->controller != NULL){
|
||||
traceIO(data->controller->node->name, "ERROR: action {%s} in {%s} node %s:\nERROR: %s",
|
||||
traceIO(data->controller->node->name, "ERROR: action {%s} in {%s} node %s:ERROR: %s",
|
||||
data->name, origScript, path, result);
|
||||
} else {
|
||||
traceIO("sctunknown", "ERROR: action {%s} in {%s} node %s:\nERROR: %s",
|
||||
traceIO("sctunknown", "ERROR: action {%s} in {%s} node %s:ERROR: %s",
|
||||
data->name, origScript, path, result);
|
||||
}
|
||||
}
|
||||
@ -600,7 +599,7 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
*/
|
||||
iMacro = SCinMacro(con);
|
||||
con->iMacro = 0;
|
||||
SCWrite(con, "o.k.", eWarning);
|
||||
SCPureSockWrite(con, "o.k.", eLog);
|
||||
SCsetMacro(con, iMacro);
|
||||
}
|
||||
}
|
||||
@ -637,7 +636,8 @@ static char *SctActionHandler(void *actionData, char *lastReply,
|
||||
if (send == NULL)
|
||||
send = "";
|
||||
if (controller->verbose) {
|
||||
SCPrintf(con, eLog, "%6.3f send : %s", secondsOfMinute(), send);
|
||||
snprintf(msg,sizeof(msg),"%6.3f send : %s", secondsOfMinute(), send);
|
||||
SCPureSockWrite(con, msg,eLog);
|
||||
}
|
||||
if (controller->fd != NULL) {
|
||||
fprintf(controller->fd, "%6.3f send : %s\n", secondsOfMinute(), send);
|
||||
@ -768,7 +768,9 @@ static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
|
||||
geterror = GetHdbProp(node, "geterror");
|
||||
if (geterror != NULL) {
|
||||
snprintf(error,255,"ERROR: %s", geterror);
|
||||
SCWrite(con, error, eError);
|
||||
if(con != NULL){
|
||||
SCWrite(con, error, eError);
|
||||
}
|
||||
if (mm->v->dataType == HIPTEXT) {
|
||||
if (mm->v->v.text != NULL) {
|
||||
free(mm->v->v.text);
|
||||
@ -838,7 +840,6 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
|
||||
if (script != NULL) {
|
||||
if (SctCallInContext(con, script, node, data->controller, &error) ==
|
||||
0) {
|
||||
/* SCPrintf(con, eError, "ERROR: in {%s}: %s", script, error); */
|
||||
SCPrintf(con, eError, "ERROR: %s", error); /* nicer for the user */
|
||||
SetHdbProperty(node, "target", NULL);
|
||||
SetHdbProperty(node, "requested", NULL);
|
||||
@ -1853,7 +1854,7 @@ static void SctKillController(void *c)
|
||||
|
||||
if (pServ->pTasker) {
|
||||
TaskRegisterN(pServ->pTasker,"killsct", SctDeferredTask, NULL, SctDeferredFree,
|
||||
controller, 0);
|
||||
controller, TASK_PRIO_HIGH);
|
||||
} else {
|
||||
free(controller);
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ int SerialSicsExecute(void **pData, char *pCommand,
|
||||
|
||||
/* start task */
|
||||
lTask = TaskRegisterN(pServ->pTasker,"serialwait",
|
||||
SWTask, SWSignal, NULL, &control, 1);
|
||||
SWTask, SWSignal, NULL, &control, TASK_PRIO_LOW);
|
||||
/* wait for it to end */
|
||||
TaskWait(pServ->pTasker, lTask);
|
||||
|
||||
|
610
servlog.c
610
servlog.c
@ -1,610 +0,0 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
|
||||
Implementation for the server log.
|
||||
|
||||
Is a bit tricky. Writes 1000 lines to a file, than increments
|
||||
and opens a new one. Wraps arounf after 3. This is a compromise
|
||||
between error tracking and use of diskspace.
|
||||
|
||||
|
||||
|
||||
Mark Koennecke, October 1996
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
Paul Scherrer Institut
|
||||
CH-5423 Villigen-PSI
|
||||
|
||||
|
||||
The authors hereby grant permission to use, copy, modify, distribute,
|
||||
and license this software and its documentation for any purpose, provided
|
||||
that existing copyright notices are retained in all copies and that this
|
||||
notice is included verbatim in any distributions. No written agreement,
|
||||
license, or royalty fee is required for any of the authorized uses.
|
||||
Modifications to this software may be copyrighted by their authors
|
||||
and need not follow the licensing terms described here, provided that
|
||||
the new terms are clearly indicated on the first page of each file where
|
||||
they apply.
|
||||
|
||||
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
||||
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
||||
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
||||
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
|
||||
Modified: Paul Hathaway, June 2004
|
||||
SICSLogWrite
|
||||
- no longer asserts existence of the log file, writing
|
||||
to stderr and skipping further file writes.
|
||||
- NETWrites log message (if enabled) before attempt to write to file
|
||||
- uses OpenVerifyLogFile helper function (removed duplicate code)
|
||||
-----------------------------------------------------------------------------*/
|
||||
#include <stdarg.h>
|
||||
#include "fortify.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <strlutil.h>
|
||||
|
||||
#include "ifile.h"
|
||||
#include "servlog.h"
|
||||
#include "network.h"
|
||||
|
||||
/* define this, if you do not want a server log
|
||||
|
||||
#define NOLOG 1
|
||||
*/
|
||||
/* -------------------------------------------------------------------------
|
||||
The server log output can be captured by a client. In order to implement
|
||||
this the following code is necessary.
|
||||
*/
|
||||
typedef struct __LogLog {
|
||||
pSICSLogHook pFunc;
|
||||
void *pData;
|
||||
unsigned int code_bits;
|
||||
struct __LogLog *pNext;
|
||||
struct __LogLog *pPrevious;
|
||||
} CaptureEntry, *pCaptureEntry;
|
||||
|
||||
static pCaptureEntry pCapture = NULL;
|
||||
/*------------------------------------------------------------------------*/
|
||||
#include "outcode.c" /* for pCode */
|
||||
|
||||
const char* OutCodeToTxt(OutCode eOut)
|
||||
{
|
||||
switch (eOut) {
|
||||
case eInternal: return "Int"; /* internal */
|
||||
case eCommand: return "Cmd"; /* reserved, not used */
|
||||
case eHWError: return "ErH"; /* reserved, used only for SICSLog */
|
||||
case eInError: return "ErI"; /* reserved, used as a mark in the handling of output codes */
|
||||
case eStatus: return "Sta"; /* reserved, deprecated */
|
||||
case eValue: return "Val"; /* value reponse: copied into Tcl */
|
||||
case eStart: return "Beg"; /* start message */
|
||||
case eFinish: return "End"; /* finish message */
|
||||
case eEvent: return "Evt"; /* some callback messages */
|
||||
case eWarning: return "Wrn"; /* warnings */
|
||||
case eError: return "Err"; /* error: copied into Tcl */
|
||||
case eHdbValue: return "HVa"; /* hipadaba value chnage */
|
||||
case eHdbEvent: return "HEv"; /* Hipadaba event */
|
||||
case eLog: return "Log"; /* log message: is always written to client */
|
||||
case eLogError: return "ErL"; /* error message to log: is always written to client */
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
|
||||
const char* OutCodeToText(OutCode eOut)
|
||||
{
|
||||
switch (eOut) {
|
||||
case eInternal: return "Internal";
|
||||
case eCommand: return "Command";
|
||||
case eHWError: return "HWError";
|
||||
case eInError: return "InError";
|
||||
case eStatus: return "Status";
|
||||
case eValue: return "Value";
|
||||
case eStart: return "Start";
|
||||
case eFinish: return "Finish";
|
||||
case eEvent: return "Event";
|
||||
case eWarning: return "Warning";
|
||||
case eError: return "Error";
|
||||
case eHdbValue: return "HdbValue";
|
||||
case eHdbEvent: return "HdbEvent";
|
||||
case eLog: return "Log";
|
||||
case eLogError: return "LogError";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
int OutCodeFromText(const char *text, OutCode *outcode)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < iNoCodes; ++i) {
|
||||
if (strcasecmp(text, pCode[i]) == 0) {
|
||||
if (outcode)
|
||||
*outcode = i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static unsigned int find_code_bits(const char *p1, const char *p2) {
|
||||
/* may be outcode, try find it */
|
||||
int i;
|
||||
const char *pShort;
|
||||
const char *pLong;
|
||||
size_t len = p2 - p1;
|
||||
if (len == 3 && strncasecmp(p1, "all", 3) == 0)
|
||||
return (1 << iNoCodes) - 1;
|
||||
for (i = 0; i < iNoCodes; ++i) {
|
||||
pShort = OutCodeToTxt(i);
|
||||
if (pShort && strncasecmp(p1, pShort, len) == 0)
|
||||
return 1 << i;
|
||||
pLong = OutCodeToText(i);
|
||||
if (pLong && strlen(pLong) == len) {
|
||||
if (strncasecmp(p1, pLong, len) == 0) {
|
||||
return 1 << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *AddSICSLogHook(pSICSLogHook func, const char *pCodes, void *pData)
|
||||
{
|
||||
unsigned int code_bits = 0;
|
||||
if (strcasecmp("all", pCodes) == 0)
|
||||
code_bits = (1 << iNoCodes) - 1;
|
||||
else {
|
||||
const char *p1, *p2;
|
||||
p1 = pCodes;
|
||||
while (NULL != (p2 = strchr(p1, ','))) {
|
||||
/* TODO [p1:p2) */
|
||||
code_bits |= find_code_bits(p1, p2);
|
||||
p1 = p2 + 1;
|
||||
}
|
||||
/* p1 points at the last or only code */
|
||||
/* TODO p1 */
|
||||
code_bits |= find_code_bits(p1, p1 + strlen(p1));
|
||||
}
|
||||
if (code_bits != 0) {
|
||||
pCaptureEntry pNew;
|
||||
pNew = (pCaptureEntry) malloc(sizeof(CaptureEntry));
|
||||
if (!pNew) {
|
||||
SICSLogWrite("Out of memory in LogCapture", eInternal);
|
||||
return NULL;
|
||||
}
|
||||
if (pCapture) {
|
||||
pCapture->pPrevious = pNew;
|
||||
}
|
||||
pNew->pPrevious = NULL;
|
||||
pNew->pNext = pCapture;
|
||||
pCapture = pNew;
|
||||
pNew->code_bits = code_bits;
|
||||
pNew->pFunc = func;
|
||||
pNew->pData = pData;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remove any and all hooks with this pData */
|
||||
char *RemSICSLogHook(void *pData)
|
||||
{
|
||||
pCaptureEntry pCurrent, pTemp;
|
||||
|
||||
/* find first */
|
||||
pCurrent = pCapture;
|
||||
while (pCurrent != NULL) {
|
||||
if (pData == pCurrent->pData) {
|
||||
/* relink */
|
||||
if (pCurrent->pPrevious) {
|
||||
pCurrent->pPrevious->pNext = pCurrent->pNext;
|
||||
} else {
|
||||
pCapture = pCurrent->pNext;
|
||||
}
|
||||
if (pCurrent->pNext) {
|
||||
pCurrent->pNext->pPrevious = pCurrent->pPrevious;
|
||||
}
|
||||
pTemp = pCurrent->pNext;
|
||||
/* get rid of pCurrent */
|
||||
free(pCurrent);
|
||||
pCurrent = pTemp;
|
||||
} else {
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return bitmask of any and all hooks with this pData */
|
||||
unsigned int GetSICSLogHook(void *pData)
|
||||
{
|
||||
pCaptureEntry pCurrent, pTemp;
|
||||
unsigned int code_bits = 0;
|
||||
|
||||
/* find first */
|
||||
pCurrent = pCapture;
|
||||
while (pCurrent != NULL) {
|
||||
if (pData == pCurrent->pData) {
|
||||
code_bits |= pCurrent->code_bits;
|
||||
}
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
return code_bits;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int HasLineFeed(char *pText)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = strlen(pText); i > 0; i--) {
|
||||
if (pText[i] == '\n') {
|
||||
return 1;
|
||||
}
|
||||
if (isalpha(pText[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const char* timestamp(struct timeval *tp, char delim) {
|
||||
static char ts[80];
|
||||
int year, month, day;
|
||||
int hour, min, sec, usec;
|
||||
struct timeval tv;
|
||||
struct tm *time;
|
||||
if (tp)
|
||||
tv = *tp;
|
||||
else
|
||||
gettimeofday(&tv, NULL);
|
||||
time = localtime(&tv.tv_sec);
|
||||
year = 1900 + time->tm_year;
|
||||
month = time->tm_mon + 1;
|
||||
day = time->tm_mday;
|
||||
hour = time->tm_hour;
|
||||
min = time->tm_min;
|
||||
sec = time->tm_sec;
|
||||
usec = (int) tv.tv_usec;
|
||||
snprintf(ts, 80, "%04d-%02d-%02dT%02d%c%02d%c%02d.%06d",
|
||||
year, month, day, hour, delim, min, delim, sec, usec);
|
||||
return ts;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define MAXLOG 100000
|
||||
#define MAXFILES 100
|
||||
|
||||
static FILE *fLogFile = NULL;
|
||||
static int iFile = 0;
|
||||
static int iLineCount = 0;
|
||||
static int iLogUsable = 1;
|
||||
static char filnam[1024];
|
||||
static char prevfilnam[1024];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int OpenVerifyLogFile()
|
||||
{
|
||||
char pFile[256];
|
||||
char *pChar = NULL;
|
||||
char fPath[1024];
|
||||
|
||||
pChar = getenv("SICS_INIT_LOGPATH");
|
||||
if (!pChar) {
|
||||
snprintf(fPath, sizeof(fPath) - 1, "%s/", "../log");
|
||||
} else {
|
||||
snprintf(fPath, sizeof(fPath) - 1, "%s/", pChar);
|
||||
}
|
||||
|
||||
pChar = IFindOption(pSICSOptions, "LogFileBaseName");
|
||||
if (!pChar) { /* Try to write to file "server" in */
|
||||
strcpy(pFile, "server");
|
||||
} else {
|
||||
strlcpy(pFile, pChar, sizeof(pFile) - 1);
|
||||
}
|
||||
|
||||
snprintf(filnam, sizeof(filnam) - 1, "%s%s_%19.19s.%02d.log", fPath, pFile, timestamp(NULL, '-'), iFile);
|
||||
iFile++;
|
||||
if (iFile >= MAXFILES) {
|
||||
iFile = 0;
|
||||
}
|
||||
|
||||
fLogFile = fopen(filnam, "w");
|
||||
if (!fLogFile) {
|
||||
fprintf(stderr, "ERROR: Cannot open logfile %s for writing\n", pFile);
|
||||
fLogFile = NULL;
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void SICSLogEnable(int flag)
|
||||
{
|
||||
iLogUsable = flag;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void SICSLogWriteFile(char *pText, OutCode eOut, struct timeval *tp)
|
||||
{
|
||||
pCaptureEntry pCurrent;
|
||||
int text_len;
|
||||
|
||||
#ifdef NOLOG
|
||||
return;
|
||||
#endif
|
||||
|
||||
text_len = strlen(pText);
|
||||
/* do all captured */
|
||||
pCurrent = pCapture;
|
||||
while (pCurrent) {
|
||||
if ((pCurrent->code_bits & (1 << eOut))) {
|
||||
pCurrent->pFunc(pText, eOut, pCurrent->pData);
|
||||
}
|
||||
pCurrent = pCurrent->pNext;
|
||||
}
|
||||
|
||||
if (0 == iLogUsable)
|
||||
return;
|
||||
|
||||
if (fLogFile == NULL) { /* first time of use */
|
||||
/* no options: startup or serious trouble, print to stdout */
|
||||
if (!pSICSOptions) {
|
||||
printf("WARNING: Cannot log(%s)\n", pText);
|
||||
return;
|
||||
}
|
||||
iLogUsable = OpenVerifyLogFile();
|
||||
iLineCount = 0;
|
||||
}
|
||||
|
||||
/* switch file if too many lines */
|
||||
if (iLineCount >= MAXLOG) {
|
||||
strcpy(prevfilnam, filnam);
|
||||
FILE *prevlog = fLogFile;
|
||||
|
||||
iLogUsable = OpenVerifyLogFile();
|
||||
iLineCount = 0;
|
||||
fprintf(prevlog, "%s: <<<close logfile>>> to %s\n",
|
||||
timestamp(NULL, ':'),
|
||||
filnam);
|
||||
fclose(prevlog);
|
||||
if (1 == iLogUsable) {
|
||||
fprintf(fLogFile, "%s: <<<open logfile>>> from %s\n",
|
||||
timestamp(NULL, ':'),
|
||||
prevfilnam);
|
||||
iLineCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == iLogUsable) {
|
||||
if (iLineCount == 0)
|
||||
fprintf(fLogFile, "%s: <<<open logfile>>>\n", timestamp(NULL, ':'));
|
||||
fprintf(fLogFile, "%s:%s:", timestamp(tp, ':'), OutCodeToTxt(eOut));
|
||||
fprintf(fLogFile, "%s", pText);
|
||||
if (text_len < 1 || pText[text_len - 1] != '\n')
|
||||
fprintf(fLogFile, "\n");
|
||||
fflush(fLogFile);
|
||||
iLineCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void SICSLogWriteTimeCode(char *pText, OutCode eOut, struct timeval *tp, char code)
|
||||
{
|
||||
char buf[200];
|
||||
const char *cp;
|
||||
int idx = 0;
|
||||
struct timeval tv;
|
||||
|
||||
if (tp == NULL) {
|
||||
gettimeofday(&tv, NULL);
|
||||
tp = &tv;
|
||||
}
|
||||
if (isalnum(code)) {
|
||||
buf[idx++] = code;
|
||||
buf[idx++] = ':';
|
||||
}
|
||||
cp = pText;
|
||||
while (*cp) {
|
||||
if (*cp == '\n') {
|
||||
buf[idx++] = '\n';
|
||||
buf[idx++] = '\0';
|
||||
SICSLogWriteFile(buf, eOut, tp);
|
||||
idx = 0;
|
||||
buf[idx++] = '*';
|
||||
buf[idx++] = ':';
|
||||
} else if (*cp == '\r') {
|
||||
buf[idx++] = '\\';
|
||||
buf[idx++] = 'r';
|
||||
} else if (*cp == '\t') {
|
||||
buf[idx++] = '\\';
|
||||
buf[idx++] = 't';
|
||||
} else if (*cp < ' ' || *cp > '~') {
|
||||
const char hex[] = "0123456789ABCDEF";
|
||||
buf[idx++] = '<';
|
||||
buf[idx++] = hex[(*cp >> 4) & 0xF];
|
||||
buf[idx++] = hex[(*cp) & 0xF];
|
||||
buf[idx++] = '>';
|
||||
} else {
|
||||
buf[idx++] = *cp;
|
||||
}
|
||||
cp++;
|
||||
if (idx > 132) {
|
||||
buf[idx++] = '\n';
|
||||
buf[idx++] = '\0';
|
||||
SICSLogWriteFile(buf, eOut, tp);
|
||||
idx = 0;
|
||||
buf[idx++] = '*';
|
||||
buf[idx++] = ':';
|
||||
}
|
||||
}
|
||||
/* Suppress the spurious blank lines caused by trailing newlines */
|
||||
if (idx == 2 && buf[0] == '*' && buf[1] == ':')
|
||||
return;
|
||||
if (idx > 0) {
|
||||
buf[idx++] = '\n';
|
||||
buf[idx++] = '\0';
|
||||
SICSLogWriteFile(buf, eOut, tp);
|
||||
}
|
||||
}
|
||||
|
||||
void SICSLogWriteCode(char *pText, OutCode eOut, char code)
|
||||
{
|
||||
SICSLogWriteTimeCode(pText, eOut, NULL, code);
|
||||
}
|
||||
|
||||
void SICSLogWriteTime(char *pText, OutCode eOut, struct timeval *tp)
|
||||
{
|
||||
SICSLogWriteTimeCode(pText, eOut, tp, 'L');
|
||||
}
|
||||
|
||||
void SICSLogWrite(char *pText, OutCode eOut)
|
||||
{
|
||||
SICSLogWriteTime(pText, eOut, NULL);
|
||||
}
|
||||
|
||||
void SICSLogWriteHexTime(const char *text, int count, OutCode eOut,
|
||||
struct timeval *tp)
|
||||
{
|
||||
const char hex[] = "0123456789ABCDEF";
|
||||
char addr[20], left[80], right[80];
|
||||
char *lp = left;
|
||||
char *rp = right;
|
||||
int i;
|
||||
int duplicates;
|
||||
/* Limit the output */
|
||||
if (count > 1024)
|
||||
count = 1024;
|
||||
duplicates = 0;
|
||||
for (i = 0; i < count; ++i) {
|
||||
if ((i & 0xF) == 0) {
|
||||
if (i > 0) {
|
||||
char line[132];
|
||||
snprintf(line, sizeof(line) - 1, "%-6s: %-49s | %-17s |", addr,
|
||||
left, right);
|
||||
SICSLogWriteTime(line, eOut, tp);
|
||||
}
|
||||
snprintf(addr, sizeof(addr) - 1, "0x%04X", i);
|
||||
while (i >= 16 && i + 16 < count) {
|
||||
if (memcmp(&text[i - 16], &text[i], 16) != 0)
|
||||
break;
|
||||
++duplicates;
|
||||
i += 16;
|
||||
}
|
||||
if (duplicates > 0) {
|
||||
if (duplicates > 1) {
|
||||
char line[132];
|
||||
snprintf(line, sizeof(line) - 1, "%-6s: ... (%d duplicates)",
|
||||
addr, duplicates);
|
||||
SICSLogWriteTime(line, eOut, tp);
|
||||
} else {
|
||||
char line[132];
|
||||
snprintf(line, sizeof(line) - 1, "%-6s: %-49s | %-17s |", addr,
|
||||
left, right);
|
||||
SICSLogWriteTime(line, eOut, tp);
|
||||
}
|
||||
duplicates = 0;
|
||||
}
|
||||
snprintf(addr, sizeof(addr) - 1, "0x%04X", i);
|
||||
lp = left;
|
||||
rp = right;
|
||||
}
|
||||
*lp++ = hex[(text[i] >> 4) & 0xF];
|
||||
*lp++ = hex[(text[i]) & 0xF];
|
||||
*lp++ = ' ';
|
||||
if (text[i] >= ' ' && text[i] <= '~')
|
||||
*rp++ = text[i];
|
||||
else
|
||||
*rp++ = '.';
|
||||
/* if we just did slot 7, insert an extra space */
|
||||
if ((i & 0xF) == 7) {
|
||||
*lp++ = ' ';
|
||||
*rp++ = ' ';
|
||||
}
|
||||
*lp = *rp = '\0';
|
||||
}
|
||||
if (i > 0) {
|
||||
char line[132];
|
||||
snprintf(line, sizeof(line) - 1, "%-6s: %-49s | %-17s |", addr, left,
|
||||
right);
|
||||
SICSLogWriteTime(line, eOut, tp);
|
||||
}
|
||||
}
|
||||
|
||||
void SICSLogWriteHex(const char *text, int count, OutCode eOut)
|
||||
{
|
||||
SICSLogWriteHexTime(text, count, eOut, NULL);
|
||||
}
|
||||
|
||||
void SICSLogTimePrintf(OutCode eOut, struct timeval *tp, const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[256];
|
||||
char *dyn;
|
||||
unsigned int l;
|
||||
int res;
|
||||
|
||||
va_start(ap, fmt);
|
||||
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
||||
va_end(ap);
|
||||
if (l >= sizeof buf) {
|
||||
/* we have probably a C99 conforming snprintf and
|
||||
need a larger buffer
|
||||
*/
|
||||
dyn = malloc(l + 1);
|
||||
if (dyn != NULL) {
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(dyn, l + 1, fmt, ap);
|
||||
va_end(ap);
|
||||
SICSLogWriteTime(dyn, eOut, tp);
|
||||
free(dyn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SICSLogWriteTime(buf, eOut, tp);
|
||||
return;
|
||||
}
|
||||
|
||||
void SICSLogPrintf(OutCode eOut, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[256];
|
||||
char *dyn;
|
||||
unsigned int l;
|
||||
int res;
|
||||
|
||||
va_start(ap, fmt);
|
||||
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
||||
va_end(ap);
|
||||
if (l >= sizeof buf) {
|
||||
/* we have probably a C99 conforming snprintf and
|
||||
need a larger buffer
|
||||
*/
|
||||
dyn = malloc(l + 1);
|
||||
if (dyn != NULL) {
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(dyn, l + 1, fmt, ap);
|
||||
va_end(ap);
|
||||
SICSLogWrite(dyn, eOut);
|
||||
free(dyn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SICSLogWrite(buf, eOut);
|
||||
return;
|
||||
}
|
40
servlog.h
40
servlog.h
@ -1,40 +0,0 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
The server LOG. Logs all connection requests, internal server
|
||||
errors, SW-errors, HW-problems, commands etc.
|
||||
|
||||
Additionally implements a capture command which allows to get
|
||||
log output for a client.
|
||||
|
||||
Mark Koennecke, October 1996, November 1996
|
||||
|
||||
|
||||
copyright: see implementation file
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef SICSLOG
|
||||
#define SICSLOG
|
||||
#include "Scommon.h"
|
||||
void SICSLogWrite(char *ptext, OutCode eOut);
|
||||
void SICSLogWriteTime(char *ptext, OutCode eOut, struct timeval *tp);
|
||||
void SICSLogWriteCode(char *ptext, OutCode eOut, char code);
|
||||
void SICSLogWriteTimeCode(char *ptext, OutCode eOut, struct timeval *tp, char code);
|
||||
void SICSLogWriteHex(const char *text, int count, OutCode eOut);
|
||||
void SICSLogWriteHexTime(const char *text, int count, OutCode eOut,
|
||||
struct timeval *tp);
|
||||
#if __GNUC__ > 2
|
||||
#define G_GNUC_PRINTF( format_idx, arg_idx ) \
|
||||
__attribute__((__format__ (__printf__, format_idx, arg_idx)))
|
||||
#else
|
||||
#define G_GNUC_PRINTF( format_idx, arg_idx )
|
||||
#endif
|
||||
void SICSLogPrintf(OutCode eOut, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
|
||||
void SICSLogTimePrintf(OutCode eOut, struct timeval *tp, const char *fmt,
|
||||
...) G_GNUC_PRINTF (3, 4);
|
||||
#undef G_GNUC_PRINTF
|
||||
void SICSLogEnable(int flag);
|
||||
typedef void (*pSICSLogHook)(const char *pText, OutCode eOut, void *pData);
|
||||
char *AddSICSLogHook(pSICSLogHook func, const char *pCodes, void *pData);
|
||||
char *RemSICSLogHook(void *pData);
|
||||
unsigned int GetSICSLogHook(void *pData);
|
||||
#endif
|
2
sics.h
2
sics.h
@ -36,8 +36,8 @@ typedef enum {
|
||||
#include "devexec.h"
|
||||
#include "emon.h"
|
||||
#include "nserver.h"
|
||||
#include "servlog.h"
|
||||
#include "sicsutil.h"
|
||||
#include "logv2.h"
|
||||
#include "trace.h"
|
||||
|
||||
extern pServer pServ;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "sics.h"
|
||||
#include "splitter.h"
|
||||
#include "sicscron.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
typedef struct {
|
||||
int iInterval;
|
||||
@ -237,7 +236,7 @@ int MakeCron(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
}
|
||||
pNew->stat = StatisticsNew(cmd);
|
||||
|
||||
TaskRegisterN(pServ->pTasker, cmd, CronTask, CronSignal, KillCron, pNew, 1);
|
||||
TaskRegisterN(pServ->pTasker, cmd, CronTask, CronSignal, KillCron, pNew, TASK_PRIO_LOW);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
|
@ -683,7 +683,7 @@ static int copyHM(pSICSData self, int argc, char *argv[],
|
||||
}
|
||||
pHist = (pHistMem) FindCommandData(pSics, argv[1], "HistMem");
|
||||
if (!pHist) {
|
||||
SCWrite(pCon, "ERROR: histogram memory not found in copytimebin",
|
||||
SCWrite(pCon, "ERROR: histogram memory not found in copyhm",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
@ -866,7 +866,7 @@ static int copyNode(pSICSData self, int argc, char *argv[],
|
||||
break;
|
||||
case HIPINTAR:
|
||||
case HIPINTVARAR:
|
||||
memcpy(iData+pos, node->value.v.intArray, length*sizeof(int));
|
||||
memcpy(iData, node->value.v.intArray, length*sizeof(int));
|
||||
assignType(self, pos, pos + length, INTTYPE);
|
||||
break;
|
||||
case HIPFLOATAR:
|
||||
|
@ -76,7 +76,7 @@ int SicsExit(SConnection * pCon, SicsInterp * pInterp, void *pData,
|
||||
|
||||
if (SCMatchRights(pCon, usMugger)) { /* only Muggers are allowed to do it */
|
||||
SetInterrupt(eEndServer);
|
||||
lID = TaskRegisterN(pTask,"exittask", WaitTask, NULL, NULL, NULL, 1);
|
||||
lID = TaskRegisterN(pTask,"exittask", WaitTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
TaskWait(pTask, lID);
|
||||
TaskStop(pTask);
|
||||
return 1;
|
||||
|
@ -334,7 +334,7 @@ static int GetHdbFunc(void *ms, void *userData)
|
||||
char *geterror = NULL, error[512];
|
||||
hdbValue ve;
|
||||
|
||||
node = FindHdbNode(NULL,self->name,NULL);
|
||||
node = FindHdbIntern(self->name);
|
||||
if(node != NULL){
|
||||
geterror = GetHdbProp(node,"geterror");
|
||||
if(geterror != NULL){
|
||||
@ -470,7 +470,7 @@ static int PutHdbFunc(void *ms, void *userData)
|
||||
pHdb node = NULL;
|
||||
int status;
|
||||
|
||||
node = FindHdbNode(NULL,self->name,NULL);
|
||||
node = FindHdbIntern(self->name);
|
||||
if(node != NULL){
|
||||
status = SetHipadabaPar(node,*(self->v),NULL);
|
||||
self->success = status;
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <splitter.h>
|
||||
#include "sicsobj.h"
|
||||
#include <macro.h>
|
||||
#include "commandlog.h"
|
||||
#include "arrayutil.h"
|
||||
#include "HistMem.h"
|
||||
#include "asynnet.h"
|
||||
@ -904,9 +903,7 @@ static hdbCallbackReturn SICSScriptReadCallback(pHdb node, void *userData,
|
||||
if (pCon != NULL) {
|
||||
MacroPush(pCon);
|
||||
}
|
||||
SetWriteHistory(0);
|
||||
status = Tcl_Eval(InterpGetTcl(pServ->pSics), command);
|
||||
SetWriteHistory(1);
|
||||
if (pCon != NULL) {
|
||||
MacroPop();
|
||||
}
|
||||
@ -1524,7 +1521,10 @@ pHdb AddSICSHdbMemPar(pHdb parent, char *name, int priv,
|
||||
return child;
|
||||
}
|
||||
|
||||
/*==================== access support functions ==============================*/
|
||||
/*==================== access support functions ==============================
|
||||
This has become an eierlegendewollmilchsau function. I do not know how and when
|
||||
that happened
|
||||
==============================================================================*/
|
||||
pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr,
|
||||
SConnection * pCon)
|
||||
{
|
||||
@ -1600,7 +1600,7 @@ pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr,
|
||||
SCPrintf(pCon, eError, "ERROR: parent of %s not found",
|
||||
buffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* the name must be taken from the end of relpath, as element is no longer valid */
|
||||
*namePtr = relpath + (element - buffer);
|
||||
return parent; /* parent found, and node does not yet exist */
|
||||
@ -1633,7 +1633,37 @@ pHdb FindHdbNode(char *rootpath, char *relpath, SConnection * pCon)
|
||||
{
|
||||
return FindHdbParent(rootpath, relpath, NULL, pCon);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
pHdb FindHdbIntern(char *path)
|
||||
{
|
||||
char *element, *slash;
|
||||
pHdb parent = NULL;
|
||||
pObjectDescriptor pDes = NULL;
|
||||
|
||||
element = path;
|
||||
if(strncmp(element,"/sics/",6) == 0){
|
||||
slash = strchr(element+6,'/');
|
||||
if(slash != NULL){
|
||||
*slash = '\0';
|
||||
}
|
||||
pDes = FindCommandDescriptor(pServ->pSics,element+6);
|
||||
if(pDes == NULL){
|
||||
return NULL;
|
||||
}
|
||||
parent = pDes->parNode;
|
||||
if(parent == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(slash == NULL){
|
||||
return parent;
|
||||
}
|
||||
*slash = '/';
|
||||
element = slash + 1;
|
||||
} else {
|
||||
parent = GetHipadabaRoot();
|
||||
}
|
||||
return GetHipadabaNode(parent,element);
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* This does not use strlcpy, strlcat on purpose: it caused a bug
|
||||
* There are so many length checks in the code anyway so that is
|
||||
@ -4238,7 +4268,9 @@ static hdbCallbackReturn SICSNotifyScriptCallback(pHdb node, void *userData,
|
||||
return hdbContinue;
|
||||
}
|
||||
|
||||
copyHdbValue(mm->v, &node->value);
|
||||
if(mm->v != &node->value){
|
||||
copyHdbValue(mm->v, &node->value);
|
||||
}
|
||||
status = Tcl_Eval(InterpGetTcl(pServ->pSics), script);
|
||||
if (status != TCL_OK) {
|
||||
tracePar(node->name,"ERROR: %s while evaluating updatescript %s",
|
||||
|
@ -281,6 +281,14 @@ pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr,
|
||||
* the path starts with "/sics/"
|
||||
*/
|
||||
pHdb FindHdbNode(char *rootpath, char *relpath, SConnection * pCon);
|
||||
/** FindHdbIntern finds a node. It does so without complaining
|
||||
* on the various bits which can fail. It is for internal use where the caller
|
||||
* deals with the absence of the desired node.
|
||||
* @param path the path to search. Paths starting /sics/are searched for in the object database
|
||||
* @return the found node or NULL on failure
|
||||
*/
|
||||
pHdb FindHdbIntern(char *path);
|
||||
|
||||
/** Get the absolute path of a node anchored in the
|
||||
* Hipadaba root or in a sics object
|
||||
* @param nodeArg the input node
|
||||
|
40
sicspoll.c
40
sicspoll.c
@ -9,6 +9,11 @@
|
||||
* Copyright: see COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, November-December 2006
|
||||
*
|
||||
* Implemented exponential backoff up to 6 minutes when polling fails. This in order to
|
||||
* reduce the number of error messages in the logs if something is MIA
|
||||
*
|
||||
* Mark Koennecke, November 2016
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -109,7 +114,33 @@ void SicsPollSignal(void *pData, int iSignal, void *pSigData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
This function implements the exponential backoff when there is a failure
|
||||
in polling
|
||||
------------------------------------------------------------------------*/
|
||||
static void advancePoll(pPollDriv poll, int status)
|
||||
{
|
||||
if(status == 1) {
|
||||
/* success */
|
||||
poll->actualPollIntervall = poll->pollIntervall;
|
||||
} else {
|
||||
/*
|
||||
poll error, backoff
|
||||
*/
|
||||
if(poll->actualPollIntervall < poll->pollIntervall){
|
||||
poll->actualPollIntervall = 2 * poll->pollIntervall;
|
||||
} else {
|
||||
poll->actualPollIntervall = 2 * poll->actualPollIntervall;
|
||||
/*
|
||||
poll at least every 6 minutes
|
||||
*/
|
||||
if(poll->actualPollIntervall > 360){
|
||||
poll->actualPollIntervall = 360;
|
||||
}
|
||||
}
|
||||
}
|
||||
poll->nextPoll = time(NULL) + poll->actualPollIntervall;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int PollTask(void *data)
|
||||
{
|
||||
@ -141,7 +172,8 @@ static int PollTask(void *data)
|
||||
poll = (pPollDriv) LLDnodePtr(self->pollList);
|
||||
if (status != 0 && poll != NULL) {
|
||||
if (poll->isDue(poll, now, self->pCon)) {
|
||||
poll->poll(poll, self->pCon);
|
||||
status = poll->poll(poll, self->pCon);
|
||||
advancePoll(poll,status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,6 +344,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
driv->pollIntervall = iVal;
|
||||
driv->actualPollIntervall = iVal;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
@ -346,6 +379,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
status = driv->poll(driv, pCon);
|
||||
advancePoll(driv,status);
|
||||
if (status != 1) {
|
||||
SCWrite(pCon, "ERROR: polling object", eError);
|
||||
return 0;
|
||||
@ -379,7 +413,7 @@ int InstallSICSPoll(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
pNew->pCon = defCon;
|
||||
pNew->nPoll = 3;
|
||||
|
||||
TaskRegisterN(pServ->pTasker,"sicspoll", PollTask, SicsPollSignal, NULL, pNew, 10);
|
||||
TaskRegisterN(pServ->pTasker,"sicspoll", PollTask, SicsPollSignal, NULL, pNew, TASK_PRIO_HIGH);
|
||||
|
||||
if (argc > 1) {
|
||||
AddCommand(pSics, argv[1], SICSPollWrapper, killSicsPoll, pNew);
|
||||
|
@ -292,7 +292,7 @@ static void printPollList(pSicsPoll self, SConnection *pCon){
|
||||
pNew->pCon = defCon;
|
||||
pNew->nPoll = 3;
|
||||
|
||||
TaskRegister(pServ->pTasker,PollTask,SicsPollSignal,NULL,pNew, 10);
|
||||
TaskRegister(pServ->pTasker,PollTask,SicsPollSignal,NULL,pNew, TASK_PRIO_HIGH);
|
||||
|
||||
if(argc > 1){
|
||||
AddCommand(pSics,argv[1],SICSPollWrapper,
|
||||
|
6
sicvar.c
6
sicvar.c
@ -363,19 +363,19 @@ static int VarInterestCallback(int iEvent, void *pEvent, void *pUser)
|
||||
case veInt:
|
||||
VarGetInt(pVar, &iVal);
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "%s = %d", pVar->name, iVal);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
status = 1;
|
||||
break;
|
||||
case veFloat:
|
||||
VarGetFloat(pVar, &fVal);
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "%s = %f", pVar->name, fVal);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
status = 1;
|
||||
break;
|
||||
case veText:
|
||||
VarGetText(pVar, &pText);
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "%s = %s", pVar->name, pText);
|
||||
SCWrite(pCon, pBueffel, eValue);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
if (pText) {
|
||||
free(pText);
|
||||
}
|
||||
|
@ -50,8 +50,8 @@
|
||||
#include "fortify.h"
|
||||
#include "conman.h"
|
||||
#include "modriv.h"
|
||||
#include "servlog.h"
|
||||
#include "splitter.h"
|
||||
#include "logv2.h"
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static float SimRandom(void)
|
||||
{
|
||||
@ -175,7 +175,7 @@ static int SimFix(void *self, int iError, float fNew)
|
||||
return MOTREDO;
|
||||
}
|
||||
|
||||
SICSLogWrite("Simulated Motor dying randomly", eHWError);
|
||||
Log(ERROR,"dev","%s","Simulated Motor dying randomly");
|
||||
if (fRand < 0.3333) {
|
||||
return MOTOK;
|
||||
} else if (fRand < 0.66666) {
|
||||
|
5
simev.c
5
simev.c
@ -43,10 +43,9 @@
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <strlutil.h>
|
||||
|
||||
#include "logv2.h"
|
||||
#include "fortify.h"
|
||||
#include "conman.h"
|
||||
#include "servlog.h"
|
||||
#include "fortify.h"
|
||||
|
||||
#include "evdriver.h"
|
||||
@ -200,7 +199,7 @@ static int SimFix(pEVDriver self, int iError)
|
||||
return DEVREDO;
|
||||
}
|
||||
|
||||
SICSLogWrite("Simulated Environment device dying randomly", eHWError);
|
||||
Log(ERROR,"dev","%s","Simulated Environment device dying randomly");
|
||||
if (fRand < 0.3333) {
|
||||
return DEVOK;
|
||||
} else if (fRand < 0.66666) {
|
||||
|
115
sinfox.h
115
sinfox.h
@ -1,115 +0,0 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef ANSTO_SINFOX
|
||||
#define ANSTO_SINFOX
|
||||
#include <sics.h>
|
||||
#include <conman.h>
|
||||
|
||||
typedef struct __Sinfox {
|
||||
pObjectDescriptor pDes; /* required as first field */
|
||||
const char *buildVersion;
|
||||
const char *configName;
|
||||
const char *configVersion;
|
||||
const char *description;
|
||||
const char *instrument;
|
||||
const char *schemaVersion;
|
||||
Tcl_Interp *tTcl;
|
||||
} Sinfox;
|
||||
|
||||
typedef struct __Sinfox *pSinfox;
|
||||
|
||||
#ifndef SICSSITE /* Avoid duplicate declaration in site_ansto.c */
|
||||
|
||||
const int iNumInfoKeys = 6;
|
||||
char *pInfoKeys[7] = {
|
||||
"buildVersion",
|
||||
"configName",
|
||||
"configVersion",
|
||||
"description",
|
||||
"instrument",
|
||||
"schemaVersion",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int iNumCommandKeys = 3;
|
||||
char *pCommandKeys[4] = {
|
||||
"argument",
|
||||
"device",
|
||||
"interface",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int iNumDeviceKeys = 3;
|
||||
char *pDeviceKeys[4] = {
|
||||
"attribute",
|
||||
"command",
|
||||
"interface",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int iNumDeviceTypes = 24;
|
||||
char *pDeviceTypes[25] = {
|
||||
"4-circle-calculus",
|
||||
"anticollider",
|
||||
"chopper",
|
||||
"chopperadaptor",
|
||||
"connection",
|
||||
"crystalselector",
|
||||
"environment monitor",
|
||||
"environment_controller",
|
||||
"gpib",
|
||||
"hklscan",
|
||||
"hmcontrol",
|
||||
"lin2ang",
|
||||
"local maximum detector",
|
||||
"maximizer",
|
||||
"mesure",
|
||||
"motor",
|
||||
"mulmot",
|
||||
"omega2theta",
|
||||
"rs232 controller",
|
||||
"scanobject",
|
||||
"sicsvariable",
|
||||
"singlecounter",
|
||||
"velocityselector",
|
||||
"xytable",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int iNumIFaces = 4;
|
||||
char *pIFaces[5] = {
|
||||
"callback",
|
||||
"countable",
|
||||
"drivable",
|
||||
"environment",
|
||||
NULL
|
||||
};
|
||||
|
||||
const int iNumServerKeys = 10;
|
||||
char *pServerKeys[11] = {
|
||||
"help",
|
||||
"list",
|
||||
"command",
|
||||
"connection",
|
||||
"device",
|
||||
"devicetype",
|
||||
"experiment",
|
||||
"group",
|
||||
"interface",
|
||||
"key",
|
||||
NULL
|
||||
};
|
||||
|
||||
#endif /* SICSSITE */
|
||||
|
||||
/*--------------------- lifecycle -------------------------------------- */
|
||||
int InstallSinfox(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
void DeleteSinfox(void *pSelf);
|
||||
|
||||
/*--------------------- operations --------------------------------------*/
|
||||
int SinfoxAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#endif /* ANSTO_SINFOX */
|
@ -201,18 +201,18 @@ size_t get_size_of_files(char *glob) {
|
||||
while (read(pipefd[0], &buff, 1) > 0) {
|
||||
DynStringConcatChar(s, buff);
|
||||
if (buff == '\n') {
|
||||
SICSLogWrite(GetCharArray(s), eLog);
|
||||
Log(DEBUG,"sys","%s",GetCharArray(s));
|
||||
int this_size = atoi(GetCharArray(s));
|
||||
total_size += this_size;
|
||||
DynStringClear(s);
|
||||
}
|
||||
}
|
||||
if (GetDynStringLength(s) > 0)
|
||||
SICSLogWrite(GetCharArray(s), eLogError);
|
||||
Log(DEBUG,"sys","%s",GetCharArray(s));
|
||||
DeleteDynString(s);
|
||||
close(pipefd[0]);
|
||||
waitpid(child_pid, NULL, 0);
|
||||
SICSLogPrintf(eLog, "Total size of files \"%s\" is %ldK", glob, total_size);
|
||||
Log(DEBUG,"sys", "Total size of files \"%s\" is %ldK", glob, (long int)total_size);
|
||||
return total_size;
|
||||
}
|
||||
}
|
||||
@ -260,7 +260,7 @@ void generate_stack_trace(int full, int dump) {
|
||||
while (read(pipefd[0], &buff, 1) > 0) {
|
||||
DynStringConcatChar(s, buff);
|
||||
}
|
||||
SICSLogWrite(GetCharArray(s), eLogError);
|
||||
Log(DEBUG,"sys","%s",GetCharArray(s));
|
||||
DeleteDynString(s);
|
||||
close(pipefd[0]);
|
||||
waitpid(child_pid, NULL, 0);
|
||||
@ -319,4 +319,5 @@ int Ansto_Stack_Trace(SConnection *pCon, SicsInterp * pSics, void *pData, int ar
|
||||
else
|
||||
mode = 1;
|
||||
stack_trace(mode);
|
||||
return 1;
|
||||
}
|
||||
|
@ -113,11 +113,11 @@ static int StateInterest(int iEvent, void *pEvent, void *pUser)
|
||||
}
|
||||
if (iEvent == STSTART) {
|
||||
snprintf(buffer, 255, "STARTED = %s", device);
|
||||
SCWrite(pCon, buffer, eWarning);
|
||||
SCWrite(pCon, buffer, eEvent);
|
||||
}
|
||||
if (iEvent == STEND) {
|
||||
snprintf(buffer, 255, "FINISH = %s", device);
|
||||
SCWrite(pCon, buffer, eWarning);
|
||||
SCWrite(pCon, buffer, eEvent);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -205,11 +205,11 @@ static int StateHdbInterest(int iEvent, void *pEvent, void *pUser)
|
||||
path = GetHipadabaPath(node);
|
||||
if (iEvent == STSTART) {
|
||||
snprintf(buffer, 1024, "%s STARTED", path);
|
||||
SCWrite(pCon, buffer, eWarning);
|
||||
SCWrite(pCon, buffer, eEvent);
|
||||
}
|
||||
if (iEvent == STEND) {
|
||||
snprintf(buffer, 1024, "%s FINISH", path);
|
||||
SCWrite(pCon, buffer, eWarning);
|
||||
SCWrite(pCon, buffer, eEvent);
|
||||
}
|
||||
if (path != NULL) {
|
||||
free(path);
|
||||
|
11
status.c
11
status.c
@ -216,7 +216,7 @@ static int StatusCallback(int iEvent, void *pEvent, void *pUser)
|
||||
}
|
||||
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "status = %s", pText[(int) eCode]);
|
||||
SCWrite(pCon, pBueffel, eLog);
|
||||
SCWrite(pCon, pBueffel, eEvent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -391,11 +391,16 @@ static int CheckCountStatus(void *message, void *userData)
|
||||
pTaskHead it;
|
||||
CountTaskData *countTask = NULL;
|
||||
|
||||
/*
|
||||
This function shall never induce an interrupt
|
||||
*/
|
||||
SCSetInterrupt(pServ->dummyCon,eContinue);
|
||||
|
||||
if(*status == eCounting){
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
countTask = (CountTaskData *)GetTaskData(it);
|
||||
if(countTask != NULL && countTask->id == COUNTID){
|
||||
testStatus = countTask->pCount->CheckCountStatus(countTask->obj,pServ->dummyCon);
|
||||
testStatus = countTask->pCount->ReadStatus(countTask->obj,pServ->dummyCon);
|
||||
if(testStatus == HWNoBeam){
|
||||
*status = eOutOfBeam;
|
||||
}
|
||||
@ -504,5 +509,5 @@ static int StatusTask(void *data)
|
||||
void InitStatus(void)
|
||||
{
|
||||
BuildStatusChain();
|
||||
TaskRegisterN(pServ->pTasker,"statustask",StatusTask, NULL, NULL, NULL,1);
|
||||
TaskRegisterN(pServ->pTasker,"statustask",StatusTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
}
|
||||
|
@ -296,10 +296,10 @@ static int cleanRestoreErr(pRestoreObj self, SConnection * pCon, int hard)
|
||||
}
|
||||
if (errMsg) {
|
||||
SCWrite(pCon, errMsg, eError);
|
||||
LLDstringDelete(newErrList);
|
||||
LLDdeleteString(newErrList);
|
||||
} else {
|
||||
/* swap lists */
|
||||
LLDstringDelete(self->errList);
|
||||
LLDdeleteString(self->errList);
|
||||
self->errList = newErrList;
|
||||
SCPrintf(pCon, eLog, "CleanErr: %d pairs in, %d pairs out", count_in, count_ex);
|
||||
}
|
||||
@ -397,5 +397,5 @@ void StatusFileDirty(void)
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void StatusFileInit(void)
|
||||
{
|
||||
TaskRegisterN(pServ->pTasker, "statusfile", StatusFileTask, NULL, NULL, NULL, 0);
|
||||
TaskRegisterN(pServ->pTasker, "statusfile", StatusFileTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
}
|
||||
|
280
task.h
280
task.h
@ -1,26 +1,57 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
T A S K
|
||||
|
||||
This is a portable task switching module. Tasks are maintained in a
|
||||
T A S K
|
||||
|
||||
This is a portable task switching module. Tasks are maintained in a
|
||||
circular list and switched in between. Waiting for some task to end,
|
||||
a yield and a primitive form of inter task communication is implemented.
|
||||
|
||||
|
||||
Mark Koennecke, September 1997
|
||||
|
||||
extended to suuport task groups
|
||||
extended to support task groups
|
||||
Mark Koennecke, December 2012
|
||||
|
||||
|
||||
copyright: see implementation file
|
||||
-----------------------------------------------------------------------------*/
|
||||
#ifndef TASKOMAT
|
||||
#define TASKOMAT
|
||||
|
||||
typedef long TaskTaskID;
|
||||
typedef long TaskGroupID;
|
||||
extern TaskTaskID TaskUnknownTaskID, TaskBadTaskID;
|
||||
extern TaskGroupID TaskUnknownGroupID, TaskBadGroupID;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef enum eTaskLogLevel {
|
||||
eTaskLogNone = 0,
|
||||
eTaskLogDebug = 1,
|
||||
eTaskLogInfo = 2,
|
||||
eTaskLogWarning = 3,
|
||||
eTaskLogError = 4,
|
||||
eTaskLogFatal = 5
|
||||
} eTaskLogLevel;
|
||||
typedef void (*TaskLogFunc) (eTaskLogLevel, const char *buf);
|
||||
/*
|
||||
A TaskLogFunc can be registered for logging activity within the task module.
|
||||
*/
|
||||
/*
|
||||
* Use these values for the Task Priority
|
||||
*/
|
||||
#define TASK_PRIO_LOW 10
|
||||
#define TASK_PRIO_MED 30
|
||||
#define TASK_PRIO_HIGH 50
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct __TaskHead *pTaskHead;
|
||||
typedef struct __TaskMan *pTaskMan;
|
||||
typedef struct __TaskQueue *pTaskQueue;
|
||||
typedef struct __TaskMessage *pTaskMessage;
|
||||
/*
|
||||
two data structure used internally and defined in task.c
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef int (*TaskFunc) (void *pData);
|
||||
|
||||
/*
|
||||
/*
|
||||
a task function must be implemented by each task. This function will be
|
||||
called when it is the tasks turn to execute. This function obtains a
|
||||
called when it is the tasks turn to execute. This function obtains a
|
||||
pointer to a user defined data structure as parameter. If the task is going
|
||||
to end, it has to return 0. It's data structure will be removed by a
|
||||
KillFunction of the type defined below. If the task is
|
||||
@ -28,9 +59,15 @@ typedef int (*TaskFunc) (void *pData);
|
||||
1.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef int (*TaskMsgFunc) (void *pData, pTaskMessage pMsg);
|
||||
|
||||
/*
|
||||
* Like the TaskFunc but with a message extracted from the task queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef void (*TaskKillFunc) (void *pData);
|
||||
/*
|
||||
Each task using private data structures must define this functions. It's
|
||||
Each task using private data structures must define this functions. It's
|
||||
task is to clear the private data structure of the task and free all memory
|
||||
associated with it. This function will be called automatically by the
|
||||
Tasker when a task finishes or when the whole Tasker is shut down.
|
||||
@ -41,23 +78,17 @@ typedef void (*SignalFunc) (void *pUser, int iSignal, void *pSigData);
|
||||
/*
|
||||
A SignalFunction can be implemented by each task. It is the means of
|
||||
inter task communication. The first parameter is a pointer to the
|
||||
tasks private datastructure. Further parameters are an integer signal ID
|
||||
and a pointer to a datastructure for this signal. The meaning of signal
|
||||
tasks private datastructure. Further parameters are an integer signal ID
|
||||
and a pointer to a datastructure for this signal. The meaning of signal
|
||||
ID's and signal data structures is up to the client of this code.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
typedef struct __TaskHead *pTaskHead;
|
||||
typedef struct __TaskMan *pTaskMan;
|
||||
/*
|
||||
two data structure used internally and defined in task.c
|
||||
*/
|
||||
/*===========================================================================
|
||||
ALL FUNTIONS RETURN 0 on FAILURE, 1 ON SUCCESS WHEN NOT MENTIONED
|
||||
OTHERWISE
|
||||
============================================================================*/
|
||||
int TaskerInit(pTaskMan * self);
|
||||
/*
|
||||
Initalises a Task Manager.
|
||||
Initalises a Task Manager.
|
||||
*/
|
||||
int TaskerDelete(pTaskMan * self);
|
||||
/*
|
||||
@ -65,7 +96,7 @@ int TaskerDelete(pTaskMan * self);
|
||||
tasks and the TaskManager.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
long TaskRegister(pTaskMan self, TaskFunc pTaskRun,
|
||||
TaskTaskID TaskRegister(pTaskMan self, TaskFunc pTaskRun,
|
||||
SignalFunc pSignalFunc,
|
||||
TaskKillFunc pKillFunc, void *pData, int iPriority);
|
||||
/*
|
||||
@ -75,16 +106,16 @@ long TaskRegister(pTaskMan self, TaskFunc pTaskRun,
|
||||
a SignalFunction [Optional, can be NULL]
|
||||
a KillFunction for task private data.
|
||||
[Optional, can be NULL]
|
||||
a pointer to task private data
|
||||
a pointer to task private data
|
||||
[Optional, can be NULL]
|
||||
a priority for this task. This is currently unused.
|
||||
a priority for this task. This is currently unused.
|
||||
On Success a positive value denoting the ID of the task is returned.
|
||||
On error a negative value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||
SignalFunc pSignalFunc,
|
||||
TaskKillFunc pKillFunc, void *pData, int iPriority);
|
||||
TaskTaskID TaskRegisterN(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
|
||||
void *pData, int iPriority);
|
||||
/*
|
||||
This call enter a new task into the system. The caller has to
|
||||
specify:
|
||||
@ -92,12 +123,37 @@ long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||
a SignalFunction [Optional, can be NULL]
|
||||
a KillFunction for task private data.
|
||||
[Optional, can be NULL]
|
||||
a pointer to task private data
|
||||
a pointer to task private data
|
||||
[Optional, can be NULL]
|
||||
a priority for this task. This is currently unused.
|
||||
a priority for this task. This is currently unused.
|
||||
On Success a positive value denoting the ID of the task is returned.
|
||||
On error a negative value is returned.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
TaskTaskID TaskRegisterD(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
|
||||
void *pData, int iPriority, double delay);
|
||||
/*
|
||||
This call enters a new task into the system.
|
||||
The task will start running after the given delay in seconds.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
TaskTaskID TaskRegisterP(pTaskMan self, char *name, TaskFunc pTaskRun,
|
||||
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
|
||||
void *pData, int iPriority, double delay, double period);
|
||||
/*
|
||||
This call enters a new task into the system.
|
||||
The task will run after delay seconds and then every period seconds.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
TaskTaskID TaskRegisterQ(pTaskMan self, char *name, TaskMsgFunc pTaskRun,
|
||||
SignalFunc pSignalFunc, TaskKillFunc pKillFunc,
|
||||
void *pData, int iPriority);
|
||||
/*
|
||||
This call enters a new task with queue into the system.
|
||||
As for TaskRegisterN except the task function signature has
|
||||
a message pointer.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int TaskSchedule(pTaskMan self);
|
||||
/*
|
||||
@ -110,27 +166,27 @@ int TaskStop(pTaskMan self);
|
||||
*/
|
||||
/*------------------------------------------------------------------------*/
|
||||
int TaskContinue(pTaskMan self);
|
||||
/*
|
||||
/*
|
||||
Continues an task switching session interrupted by TaskStop. After this
|
||||
the apopriate TaskYield, TaskSchedule or wahtever has to be called.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int TaskWait(pTaskMan self, long lID);
|
||||
int TaskWait(pTaskMan self, TaskTaskID taskID);
|
||||
/*
|
||||
Waits until the task specified by lID has finished. lID is obtained from
|
||||
a call to TaskRegister.
|
||||
Waits until the task specified by taskID has finished. taskID is obtained
|
||||
from a call to TaskRegister.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int TaskYield(pTaskMan self);
|
||||
/*
|
||||
does one cycle of the task loop and returns to the caller.This call allows
|
||||
other tasks to execute while a task executes a lengthy calculation.
|
||||
other tasks to execute while a task executes a lengthy calculation.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
|
||||
/*
|
||||
Invokes each Task's signal function with parameters iSignal and
|
||||
pSigData.
|
||||
pSigData.
|
||||
*/
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData);
|
||||
@ -148,7 +204,7 @@ int TaskSignal(pTaskMan self, int iSignal, void *pSigData);
|
||||
returns 1 when task name is running, 0 else
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int isTaskIDRunning(pTaskMan self, long lID);
|
||||
int isTaskIDRunning(pTaskMan self, TaskTaskID taskID);
|
||||
/*
|
||||
returns 1 when task name is running, 0 else
|
||||
*/
|
||||
@ -160,13 +216,13 @@ char *des;
|
||||
|
||||
for(it = TaskIteratorStart(self); it != NULL; it = TaskIteratorNext(it)){
|
||||
des = TaskDescription(it);
|
||||
}
|
||||
}
|
||||
|
||||
There are two limitations of the implementation here:
|
||||
|
||||
- Never, ever delete the Iterator it
|
||||
- Do your iteration in one go or abandon it mid iteration. If another task
|
||||
gets in between and registers new tasks or removes one, then the whole
|
||||
- Do your iteration in one go or abandon it mid iteration. If another task
|
||||
gets in between and registers new tasks or removes one, then the whole
|
||||
iterator may be messed up.
|
||||
=============================================================================*/
|
||||
|
||||
@ -179,17 +235,30 @@ pTaskHead TaskIteratorNext(pTaskHead it);
|
||||
Steps to the next element in the task list. Returns NULL when node.
|
||||
Do NOT delete the returned pointer!
|
||||
*/
|
||||
pTaskHead TaskIteratorCurrent(pTaskMan self);
|
||||
pTaskHead TaskIteratorByName(pTaskMan self, const char* name);
|
||||
pTaskHead TaskIteratorByID(pTaskMan self, TaskTaskID taskID);
|
||||
/*
|
||||
Gets the task iterator for either the current, named or numbered task
|
||||
Do NOT delete the returned pointer!
|
||||
*/
|
||||
|
||||
char *TaskDescription(pTaskHead it);
|
||||
/*
|
||||
get a description of the task at the current iterator
|
||||
You are responsible for deleting the returned character array.
|
||||
*/
|
||||
long GetTaskID(pTaskHead it);
|
||||
|
||||
char *TaskDetail(pTaskHead it);
|
||||
/*
|
||||
get a detailed description of the task at the current iterator
|
||||
You are responsible for deleting the returned character array.
|
||||
*/
|
||||
TaskTaskID GetTaskID(pTaskHead it);
|
||||
/*
|
||||
get the ID of the current task
|
||||
*/
|
||||
long GetGroupID(pTaskHead it);
|
||||
TaskGroupID GetGroupID(pTaskHead it);
|
||||
/*
|
||||
get the group ID of the current task
|
||||
*/
|
||||
@ -202,36 +271,147 @@ const void *GetTaskData(pTaskHead it);
|
||||
Get the user data for the current task. Do not free the returned pointer!
|
||||
*/
|
||||
/*=============================================================================
|
||||
Task Groups. The implementation has the limit that any given task can
|
||||
Task Groups. The implementation has the limit that any given task can
|
||||
only be member of one task group
|
||||
===============================================================================*/
|
||||
long GetTaskGroupID(pTaskMan self);
|
||||
TaskGroupID GetTaskGroupID(pTaskMan self);
|
||||
/*
|
||||
get the ID for a task group
|
||||
*/
|
||||
void AddTaskToGroup(pTaskMan self, long taskID, long groupID);
|
||||
void AddTaskToGroup(pTaskMan self, TaskTaskID taskID, TaskGroupID groupID);
|
||||
/*
|
||||
Add taskID to the task group groupID
|
||||
*/
|
||||
int isTaskGroupRunning(pTaskMan self, long groupID);
|
||||
int isTaskGroupRunning(pTaskMan self, TaskGroupID groupID);
|
||||
/*
|
||||
Returns 1 when the task group is still running, 0 else
|
||||
*/
|
||||
|
||||
typedef struct{
|
||||
pTaskMan tasker;
|
||||
long groupID;
|
||||
} TaskGroupData, *pTaskGroupData;
|
||||
|
||||
int TaskGroupTask(void *data);
|
||||
/*
|
||||
This is a task function which implements the common task of waiting
|
||||
This is a task function which implements the common task of waiting
|
||||
for a group of tasks to finish. It expects as data a TaskGroupData
|
||||
structure.
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, long groupID);
|
||||
int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, TaskGroupID groupID);
|
||||
/*
|
||||
signal only tasks in the group groupID
|
||||
*/
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void TaskSetLogFunc(TaskLogFunc);
|
||||
TaskLogFunc TaskGetLogFunc(void);
|
||||
eTaskLogLevel TaskSetLogLevel(eTaskLogLevel thresh);
|
||||
eTaskLogLevel TaskGetLogLevel(void);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskGetStack(pTaskMan self, pTaskHead it[]);
|
||||
/*
|
||||
* Returns the current stack depth of tasks and, if provided, fills the array
|
||||
* of iterators. The iterators start at it[0] and can be used to get
|
||||
* information about each task.
|
||||
*/
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void TaskRunMeAfter(pTaskMan self, double delay);
|
||||
/*
|
||||
* Run this task once in <delay> seconds
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void TaskRunMeEvery(pTaskMan self, double delay);
|
||||
/*
|
||||
* Run this task every <delay> seconds from now on
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
double TaskRunMyPeriod(pTaskMan self);
|
||||
/*
|
||||
* Return this task run period in seconds
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskQueue TaskQueueAlloc(void);
|
||||
/*
|
||||
* Task Queue constructor
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueFree(pTaskQueue);
|
||||
/*
|
||||
* Task Queue destructor
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueCount(pTaskQueue);
|
||||
/*
|
||||
* Returns the message count on the Task Queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueSend(pTaskQueue, pTaskMessage);
|
||||
/*
|
||||
* Pushes a Task Message onto the tail of the Task Queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueSendID(pTaskMan self, TaskTaskID taskID, pTaskMessage);
|
||||
/*
|
||||
* Pushes a Task Message onto the tail of the Task Queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskMessage TaskQueueRecv(pTaskQueue);
|
||||
/*
|
||||
* Pops a Task Message off the head of the given Task Queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskMessage TaskQueueRecvMine(pTaskMan self);
|
||||
/*
|
||||
* Pops a Task Message off the head of the owner's Task Queue
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueSet(pTaskMan self, TaskTaskID taskID, pTaskQueue);
|
||||
/*
|
||||
* Sets the Task Queue of the task
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskQueueRem(pTaskMan self, TaskTaskID taskID);
|
||||
/*
|
||||
* Clears the Task Queue of the task
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskQueue TaskQueueGet(pTaskMan self, TaskTaskID taskID);
|
||||
/*
|
||||
* Gets the Task Queue of the specified task
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskQueue TaskQueueGetMine(pTaskMan self);
|
||||
/*
|
||||
* Gets the Task Queue of the current task
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
pTaskMessage TaskMessageAlloc(size_t mSize, int mType);
|
||||
/*
|
||||
* Constructor for a Task Message of the requested size and type
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskMessageFree(pTaskMessage);
|
||||
/*
|
||||
* Destructor for the Task Message
|
||||
* returne 0=success, -1=fail
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int TaskMessageGetType(pTaskMessage self);
|
||||
/*
|
||||
* Get the type of the Task Message
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void TaskMessageSetType(pTaskMessage self, int mType);
|
||||
/*
|
||||
* Set the type of the Task Message
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void * TaskMessageGetData(pTaskMessage self);
|
||||
/*
|
||||
* Get the data pointer from the message
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void TaskMessageSetData(pTaskMessage self, void *mData);
|
||||
/*
|
||||
* Set the data pointer in the message
|
||||
*/
|
||||
/*--------------------------------------------------------------------------*/
|
||||
#endif
|
||||
|
304
taskobj.c
304
taskobj.c
@ -2,7 +2,7 @@
|
||||
* This is the SICS interface object to the tasker module
|
||||
*
|
||||
* copyright: GPL
|
||||
*
|
||||
*
|
||||
* Mark Koennecke, December 2012
|
||||
*/
|
||||
#include <sics.h>
|
||||
@ -15,6 +15,37 @@ typedef struct {
|
||||
char *scriptName;
|
||||
SConnection *con;
|
||||
} TclFunc, *pTclFunc;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
void TaskObjLogFunc(eTaskLogLevel lvl, const char *buf)
|
||||
{
|
||||
unsigned int severity;
|
||||
|
||||
switch (lvl) {
|
||||
case eTaskLogNone:
|
||||
return;
|
||||
case eTaskLogInfo:
|
||||
severity = INFO;
|
||||
break;
|
||||
case eTaskLogDebug:
|
||||
severity = DEBUG;
|
||||
break;
|
||||
case eTaskLogWarning:
|
||||
severity = WARN;
|
||||
break;
|
||||
case eTaskLogError:
|
||||
severity = ERROR;
|
||||
break;
|
||||
case eTaskLogFatal:
|
||||
severity = FATAL;
|
||||
break;
|
||||
default:
|
||||
severity = DEBUG;
|
||||
break;
|
||||
}
|
||||
Log(severity, "task","%s",(char *)buf);
|
||||
return;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
@ -28,8 +59,8 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
SCWrite(pCon,"ERROR: out of memory in ListCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
|
||||
"Task", "Start_Time", "ID");
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s",
|
||||
"Task", "Start_Time", "ID");
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
@ -39,8 +70,8 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pPtr = stptok(pPtr,time,sizeof(time),"|");
|
||||
pPtr = stptok(pPtr,id,sizeof(id),"|");
|
||||
pPtr = stptok(pPtr,gid,sizeof(gid),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s %10s",
|
||||
name,time,id,gid);
|
||||
snprintf(buffer,sizeof(buffer),"%20s %20s %12s %10s",
|
||||
name,time,id,gid);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
@ -51,6 +82,103 @@ static int ListCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int PerfCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
pDynString result = NULL;
|
||||
char buffer[256], *pDes, *pPtr, name[80];
|
||||
char runs[80], waits[80], yields[80], cpu[80], wall[80], yield[80];
|
||||
pTaskHead it = NULL;
|
||||
|
||||
result = CreateDynString(128,128);
|
||||
if(result == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in PerfCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
"Task", "Runs", "Waits", "Yields", "Processor", "Elapsed", "Yield");
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
pDes = TaskDetail(it);
|
||||
if(pDes != NULL){
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,runs,sizeof(runs),"|");
|
||||
pPtr = stptok(pPtr,waits,sizeof(waits),"|");
|
||||
pPtr = stptok(pPtr,yields,sizeof(yields),"|");
|
||||
pPtr = stptok(pPtr,cpu,sizeof(cpu),"|");
|
||||
pPtr = stptok(pPtr,wall,sizeof(wall),"|");
|
||||
pPtr = stptok(pPtr,yield,sizeof(yield),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
name,runs,waits,yields,cpu,wall,yield);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result),eValue);
|
||||
DeleteDynString(result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int StackCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
pDynString result = NULL;
|
||||
char buffer[256], *pDes, *pPtr, name[80];
|
||||
char runs[80], waits[80], yields[80], cpu[80], wall[80], yield[80];
|
||||
pTaskHead it = NULL;
|
||||
pTaskHead *stack = NULL;
|
||||
int i, stackDepth;
|
||||
|
||||
result = CreateDynString(128,128);
|
||||
if(result == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in StackCmd", eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
"Task", "Runs", "Waits", "Yields", "Processor", "Elapsed", "Yield");
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
stackDepth = TaskGetStack(pServ->pTasker, NULL);
|
||||
if (stackDepth <= 0) {
|
||||
SCWrite(pCon,"No task stack", eValue);
|
||||
DeleteDynString(result);
|
||||
return 0;
|
||||
}
|
||||
stack = calloc(stackDepth, sizeof(pTaskHead));
|
||||
if (stack == NULL) {
|
||||
SCWrite(pCon,"ERROR: out of memory in StackCmd", eError);
|
||||
DeleteDynString(result);
|
||||
return 0;
|
||||
}
|
||||
stackDepth = TaskGetStack(pServ->pTasker, stack);
|
||||
for (i = 0; i < stackDepth; ++i) {
|
||||
it = stack[i];
|
||||
pDes = TaskDetail(it);
|
||||
if(pDes != NULL){
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,runs,sizeof(runs),"|");
|
||||
pPtr = stptok(pPtr,waits,sizeof(waits),"|");
|
||||
pPtr = stptok(pPtr,yields,sizeof(yields),"|");
|
||||
pPtr = stptok(pPtr,cpu,sizeof(cpu),"|");
|
||||
pPtr = stptok(pPtr,wall,sizeof(wall),"|");
|
||||
pPtr = stptok(pPtr,yield,sizeof(yield),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%18s %16s %16s %16s %16s %16s %16s",
|
||||
name,runs,waits,yields,cpu,wall,yield);
|
||||
DynStringConcat(result,buffer);
|
||||
DynStringConcatChar(result,'\n');
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result),eValue);
|
||||
DeleteDynString(result);
|
||||
free(stack);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
@ -74,6 +202,126 @@ static int KillCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int InfoCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
char buffer[256];
|
||||
char *pArgs = NULL, *pPtr;
|
||||
char task_task[20], task_name[80], task_info[80];
|
||||
pTaskHead it = NULL;
|
||||
|
||||
if (nPar < 1) {
|
||||
SCWrite(pCon,"Info.args: NULL", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SCMatchRights(pCon,usMugger)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pArgs = par[0]->value.v.text;
|
||||
pPtr = pArgs;
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
pPtr = stptok(pPtr, task_task, sizeof(task_task), "/");
|
||||
if (strcasecmp(task_task, "task") != 0) {
|
||||
SCPrintf(pCon, eError, "ERROR: task info must start with /task/, not %s in %s",
|
||||
task_task, pArgs);
|
||||
return 0;
|
||||
}
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (pPtr && *pPtr == '/') ++pPtr;
|
||||
if (strcasecmp(task_name, "count") == 0) {
|
||||
int count = 0;
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)){
|
||||
++count;
|
||||
}
|
||||
SCPrintf(pCon, eValue, "Task.Count = %d", count);
|
||||
return 1;
|
||||
} else if (strcasecmp(task_name, "list") == 0) {
|
||||
int count = 0;
|
||||
pDynString result = CreateDynString(100, 100);
|
||||
char txt[80], *pDes;
|
||||
for(it = TaskIteratorStart(pServ->pTasker); it != NULL; it = TaskIteratorNext(it)) {
|
||||
pDes = TaskDescription(it);
|
||||
if (pDes != NULL) {
|
||||
char buffer[256], *pPtr, name[80], time[80], id[80], gid[80];
|
||||
pPtr = stptok(pDes,name,sizeof(name),"|");
|
||||
pPtr = stptok(pPtr,time,sizeof(time),"|");
|
||||
pPtr = stptok(pPtr,id,sizeof(id),"|");
|
||||
snprintf(buffer,sizeof(buffer),"%s", id);
|
||||
if (count++ > 0)
|
||||
DynStringConcatChar(result,' ');
|
||||
DynStringConcat(result, buffer);
|
||||
free(pDes);
|
||||
}
|
||||
}
|
||||
SCWrite(pCon,GetCharArray(result), eValue);
|
||||
DeleteDynString(result);
|
||||
return 1;
|
||||
} else if (strcasecmp(task_name, "current") == 0) {
|
||||
it = TaskIteratorCurrent(pServ->pTasker);
|
||||
} else if (strcasecmp(task_name, "by-id") == 0) {
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (*pPtr == '/') ++pPtr;
|
||||
it = TaskIteratorByID(pServ->pTasker, atol(task_name));
|
||||
} else if (strcasecmp(task_name, "by-name") == 0) {
|
||||
pPtr = stptok(pPtr, task_name, sizeof(task_name), "/");
|
||||
while (*pPtr == '/') ++pPtr;
|
||||
it = TaskIteratorByName(pServ->pTasker, task_name);
|
||||
} else {
|
||||
SCPrintf(pCon, eError, "ERROR: expected current, by-name or by-id in %s", pArgs);
|
||||
return 0;
|
||||
}
|
||||
if (it == NULL) {
|
||||
SCPrintf(pCon, eError, "ERROR: task not found in %s", pArgs);
|
||||
return 0;
|
||||
}
|
||||
pPtr = stptok(pPtr, task_info, sizeof(task_info), "/");
|
||||
if (strcasecmp(task_info, "all") == 0) {
|
||||
char *pDet, *pDes;
|
||||
pDes = TaskDescription(it);
|
||||
pDet = TaskDetail(it);
|
||||
SCPrintf(pCon, eValue, "%s %s", pDes, pDet);
|
||||
free(pDes);
|
||||
free(pDet);
|
||||
} else {
|
||||
SCPrintf(pCon, eLog, "Info.args: %s", par[0]->value.v.text);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int LogCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar)
|
||||
{
|
||||
|
||||
if (nPar < 1) {
|
||||
SCWrite(pCon,"ERROR: need log level (none,debug,info,warning,error,fatal)", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SCMatchRights(pCon,usMugger)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcasecmp("None", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogNone);
|
||||
} else if (strcasecmp("Debug", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogDebug);
|
||||
} else if (strcasecmp("Info", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogInfo);
|
||||
} else if (strcasecmp("Warning", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogWarning);
|
||||
} else if (strcasecmp("Error", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogError);
|
||||
} else if (strcasecmp("Fatal", par[0]->value.v.text) == 0) {
|
||||
TaskSetLogLevel(eTaskLogFatal);
|
||||
}
|
||||
TaskSetLogFunc((TaskLogFunc) TaskObjLogFunc);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int TclTaskFunction(void *pData)
|
||||
{
|
||||
@ -85,11 +333,11 @@ static int TclTaskFunction(void *pData)
|
||||
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
assert(pTcl != NULL);
|
||||
|
||||
|
||||
MacroPush(self->con);
|
||||
status = Tcl_Eval(pTcl, self->scriptName);
|
||||
MacroPop();
|
||||
/*
|
||||
/*
|
||||
traceSys("task","Executed %s with results %d and %s",self->scriptName, status,
|
||||
Tcl_GetStringResult(pTcl));
|
||||
*/
|
||||
@ -150,21 +398,21 @@ static int RunCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
data->scriptName = strdup(par[0]->value.v.text);
|
||||
TaskRegisterN(pServ->pTasker,
|
||||
data->scriptName,
|
||||
TclTaskFunction,
|
||||
TclFuncSignal,
|
||||
KillTclFunc,
|
||||
data, 0);
|
||||
TclTaskFunction,
|
||||
TclFuncSignal,
|
||||
KillTclFunc,
|
||||
data, TASK_PRIO_HIGH);
|
||||
traceSys("task","Started task %s",data->scriptName);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
pHdb cmd = NULL, node;
|
||||
|
||||
|
||||
pNew = SetupSICSOBJ(pCon,pSics,pData,argc,argv);
|
||||
if(pNew == NULL){
|
||||
return 0;
|
||||
@ -172,7 +420,9 @@ int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
|
||||
MakeSICSFunc(ListCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "perf", usSpy,
|
||||
MakeSICSFunc(PerfCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
|
||||
MakeSICSFunc(KillCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
@ -186,7 +436,7 @@ int TaskOBJFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("script",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -195,7 +445,7 @@ void InitTaskOBJ()
|
||||
{
|
||||
pSICSOBJ pNew = NULL;
|
||||
pHdb cmd = NULL, node;
|
||||
|
||||
|
||||
|
||||
pNew = MakeSICSOBJv("task", "TaskOBJ", HIPNONE, usInternal);
|
||||
if (pNew == NULL) {
|
||||
@ -205,7 +455,25 @@ void InitTaskOBJ()
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "ps", usSpy,
|
||||
MakeSICSFunc(ListCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "perf", usSpy,
|
||||
MakeSICSFunc(PerfCmd));
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "stack", usSpy,
|
||||
MakeSICSFunc(StackCmd));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "info", usSpy,
|
||||
MakeSICSFunc(InfoCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("args",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "log", usSpy,
|
||||
MakeSICSFunc(LogCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
SetHdbProperty(cmd,"priv","spy");
|
||||
node = MakeSICSHdbPar("level",usSpy,MakeHdbText("banana"));
|
||||
AddHipadabaChild(cmd,node,NULL);
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode, "kill", usSpy,
|
||||
MakeSICSFunc(KillCmd));
|
||||
SetHdbProperty(cmd,"type","command");
|
||||
@ -222,5 +490,5 @@ void InitTaskOBJ()
|
||||
|
||||
AddCommand(pServ->pSics,
|
||||
"task", InterInvokeSICSOBJ, KillSICSOBJ, pNew);
|
||||
|
||||
|
||||
}
|
||||
|
13
telnet.c
13
telnet.c
@ -12,7 +12,6 @@
|
||||
#include "sics.h"
|
||||
#include "passwd.h"
|
||||
#include "telnet.h"
|
||||
#include "commandlog.h"
|
||||
#include "fortify.h"
|
||||
#define LOGINWAIT 300
|
||||
/* 300 == 5 minutes to wait for valid username password */
|
||||
@ -165,7 +164,7 @@ int TelnetTaskOld(void *pData)
|
||||
iRet = IsValidUser(pUser, pPasswd);
|
||||
if (iRet < 0) {
|
||||
snprintf(pBuffer,sizeof(pBuffer)-1, "SYSTEM ATTACK by %s / %s", pUser, pPasswd);
|
||||
SICSLogWrite(pBuffer, eInternal);
|
||||
Log(FATAL,"sys","%s",pBuffer);
|
||||
SCWrite(self->pCon,
|
||||
"I do not know you, I do not let you in", eError);
|
||||
SendGA(self->pCon);
|
||||
@ -175,8 +174,7 @@ int TelnetTaskOld(void *pData)
|
||||
NETInfo(self->pCon->pSock, pHost, 131);
|
||||
snprintf(pBuffer,sizeof(pBuffer)-1, "Accepted connection on socket %d from %s",
|
||||
self->pCon->pSock->sockid, pHost);
|
||||
SICSLogWrite(pBuffer, eInternal);
|
||||
WriteToCommandLog("SYS >", pBuffer);
|
||||
Log(INFO,"com",pBuffer);
|
||||
SendWelcome(self->pCon);
|
||||
SCSetRights(self->pCon, iRet);
|
||||
self->iLogin = 1;
|
||||
@ -226,6 +224,7 @@ int TelnetTask(void *pData)
|
||||
if (SCActive(self->pCon)) {
|
||||
return 1;
|
||||
} else {
|
||||
Log(INFO,"sys","Handle %d disconnected", self->pCon->sockHandle);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -237,6 +236,7 @@ int TelnetTask(void *pData)
|
||||
if (self->iLogin) { /* handle normal command */
|
||||
/* check for logoff */
|
||||
if (strstr(pPtr, "logoff") != NULL) {
|
||||
Log(INFO,"sys","Handle %d logging off", self->pCon->sockHandle);
|
||||
ANETclose(self->pCon->sockHandle);
|
||||
free(pPtr);
|
||||
self->pCon->iEnd = 1;
|
||||
@ -273,7 +273,7 @@ int TelnetTask(void *pData)
|
||||
iRet = IsValidUser(pUser, pPasswd);
|
||||
if (iRet < 0) {
|
||||
snprintf(pBuffer,sizeof(pBuffer)-1, "SYSTEM ATTACK by %s / %s", pUser, pPasswd);
|
||||
SICSLogWrite(pBuffer, eInternal);
|
||||
Log(FATAL,"sys","%s",pBuffer);
|
||||
SCWrite(self->pCon,
|
||||
"I do not know you, I do not let you in", eError);
|
||||
SendGA(self->pCon);
|
||||
@ -282,8 +282,7 @@ int TelnetTask(void *pData)
|
||||
} else {
|
||||
snprintf(pBuffer,sizeof(pBuffer)-1, "Accepted telnet connection on handle %d",
|
||||
self->pCon->sockHandle);
|
||||
SICSLogWrite(pBuffer, eInternal);
|
||||
WriteToCommandLog("SYS >", pBuffer);
|
||||
Log(INFO,"sys","%s",pBuffer);
|
||||
SendWelcome(self->pCon);
|
||||
SCSetRights(self->pCon, iRet);
|
||||
self->iLogin = 1;
|
||||
|
@ -500,12 +500,12 @@ proc schneggestatus {} {
|
||||
if {$runtime > $starttime} {
|
||||
sct writestatus evalcheck
|
||||
}
|
||||
return busy
|
||||
return run
|
||||
}
|
||||
evalcheck {
|
||||
set tst [hval /sics/farm/schneggerunning]
|
||||
if {$tst == 1} {
|
||||
return busy
|
||||
return run
|
||||
} else {
|
||||
return idle
|
||||
}
|
||||
|
92
trace.c
92
trace.c
@ -21,6 +21,10 @@
|
||||
* Enhanced to write time stamps any ten minutes.
|
||||
*
|
||||
* Mark Koennecke, October 2013
|
||||
*
|
||||
* Modified to write to the new joined log
|
||||
*
|
||||
* Mark Koennecke, February 2016
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
@ -203,20 +207,22 @@ static int strrepc(char *pszStr, char cFrom, char cTo)
|
||||
/*-----------------------------------------------------------------*/
|
||||
void traceprint(char *sub, char *id, char *data)
|
||||
{
|
||||
char *mysub, *myid, *mydata;
|
||||
|
||||
if(logFD != NULL && filter(sub,id)){
|
||||
mysub = strdup(sub);
|
||||
myid = strdup(id);
|
||||
mydata = strdup(data);
|
||||
strrepc(mydata,'\n',':');
|
||||
strrepc(mysub,':','@');
|
||||
strrepc(myid,':','@');
|
||||
fprintf(logFD,"%s:%s:%lf:%s\n",mysub,myid,DoubleTime(),mydata);
|
||||
free(mysub);
|
||||
free(myid);
|
||||
free(mydata);
|
||||
unsigned int severity;
|
||||
|
||||
if(strstr(data,"ERROR") != NULL){
|
||||
severity = ERROR;
|
||||
} else if(strstr(data,"WARNING") != NULL){
|
||||
severity = WARN;
|
||||
} else if(strstr(sub,"com") != NULL){
|
||||
severity = INFO;
|
||||
} else if(strstr(sub,"sys") != NULL){
|
||||
severity = INFO;
|
||||
} else if(strstr(sub,"par") != NULL){
|
||||
severity = VERBOSE;
|
||||
} else {
|
||||
severity = DEBUG;
|
||||
}
|
||||
Log(severity,sub,"%s:%s",id,data);
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
void traceIO(char *id, char *format, ...)
|
||||
@ -270,32 +276,6 @@ void traceDevice(char *id, char *format, ...)
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
void traceCommand(char *id, char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buffer[1024], *buf = NULL;
|
||||
int len;
|
||||
|
||||
if(logFD != NULL && filter("com","id")){
|
||||
va_start(argptr,format);
|
||||
len = vsnprintf(buffer, sizeof(buffer),format,argptr);
|
||||
va_end(argptr);
|
||||
if(len >= sizeof(buffer)){
|
||||
buf = malloc(len+1);
|
||||
if(buf != NULL){
|
||||
memset(buf,0,len+1);
|
||||
va_start(argptr,format);
|
||||
len = vsnprintf(buf, len+1,format,argptr);
|
||||
va_end(argptr);
|
||||
traceprint("com",id,buf);
|
||||
free(buf);
|
||||
}
|
||||
} else {
|
||||
traceprint("com",id,buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------*/
|
||||
void tracePar(char *id, char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
@ -468,7 +448,7 @@ static int TraceLog(pSICSOBJ ccmd, SConnection * con,
|
||||
}
|
||||
if(traceStamperID < 0){
|
||||
traceStamperID = TaskRegisterN(pServ->pTasker,"tracestamper",
|
||||
TraceLogTask, NULL, NULL, NULL, 1);
|
||||
TraceLogTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -511,7 +491,7 @@ static int TraceAppend(pSICSOBJ ccmd, SConnection * con,
|
||||
hdbInit = 1;
|
||||
}
|
||||
TaskRegisterN(pServ->pTasker,"tracestamper",
|
||||
TraceLogTask, NULL, NULL, NULL, 1);
|
||||
TraceLogTask, NULL, NULL, NULL, TASK_PRIO_HIGH);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -539,12 +519,13 @@ static int TraceFilter(pSICSOBJ ccmd, SConnection * con,
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static void KillTrace(void *data)
|
||||
{
|
||||
if(logFD != NULL){
|
||||
fclose(logFD);
|
||||
free(logfile);
|
||||
logFD = NULL;
|
||||
logfile = NULL;
|
||||
}
|
||||
|
||||
/* if(logFD != NULL){ */
|
||||
/* fclose(logFD); */
|
||||
/* free(logfile); */
|
||||
/* logFD = NULL; */
|
||||
/* logfile = NULL; */
|
||||
/* } */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------------*/
|
||||
void MakeTrace(void)
|
||||
@ -558,13 +539,13 @@ void MakeTrace(void)
|
||||
return;
|
||||
}
|
||||
|
||||
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||
"log", usMugger, MakeSICSFunc(TraceLog));
|
||||
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
|
||||
/* cmd = AddSICSHdbPar(ccmd->objectNode, */
|
||||
/* "log", usMugger, MakeSICSFunc(TraceLog)); */
|
||||
/* AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText("")); */
|
||||
|
||||
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||
"append", usMugger, MakeSICSFunc(TraceAppend));
|
||||
AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText(""));
|
||||
/* cmd = AddSICSHdbPar(ccmd->objectNode, */
|
||||
/* "append", usMugger, MakeSICSFunc(TraceAppend)); */
|
||||
/* AddSICSHdbPar(cmd, "filename", usMugger, MakeHdbText("")); */
|
||||
|
||||
|
||||
cmd = AddSICSHdbPar(ccmd->objectNode,
|
||||
@ -577,4 +558,9 @@ void MakeTrace(void)
|
||||
|
||||
AddCommand(pServ->pSics, "trace", InterInvokeSICSOBJ, KillTrace, ccmd);
|
||||
|
||||
/*
|
||||
This is a really ugly hack to make tracing happen while we are switching
|
||||
to the logging system
|
||||
*/
|
||||
logFD = (FILE*) 27;
|
||||
}
|
||||
|
1
trace.h
1
trace.h
@ -26,7 +26,6 @@
|
||||
#endif
|
||||
void traceIO(char *id, char *format, ...) G_GNUC_PRINTF (2, 3);
|
||||
void traceDevice(char *id, char *format, ...) G_GNUC_PRINTF (2, 3);
|
||||
void traceCommand(char *id, char *format, ...) G_GNUC_PRINTF (2, 3);
|
||||
void tracePar(char *id, char *format, ...) G_GNUC_PRINTF (2, 3);
|
||||
void traceSys(char *id, char *format, ...) G_GNUC_PRINTF (2, 3);
|
||||
void traceprint(char *sub, char *id,char *data);
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
/* for logging */
|
||||
#include "sics.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
/* an uninterruptable version of select. M.Z. Oct 2008 */
|
||||
|
||||
@ -29,7 +28,7 @@ int uselect(int nfds,
|
||||
}
|
||||
result = pselect(nfds, readfds, writefds, exceptfds, tmoPtr, &sigmask);
|
||||
if (result < 0 && errno == EINTR) {
|
||||
WriteToCommandLog("SYS>", "pselect was interrupted!");
|
||||
Log(WARN,"sys", "%s", "pselect was interrupted!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
1
varlog.c
1
varlog.c
@ -56,7 +56,6 @@
|
||||
#include "lld.h"
|
||||
#include "sics.h"
|
||||
#include "varlog.h"
|
||||
#include "commandlog.h"
|
||||
#include "circular.h"
|
||||
#include "sicsdata.h"
|
||||
|
||||
|
4
velo.c
4
velo.c
@ -903,10 +903,10 @@ static int RotationInterest(int iEvent, void *pData, void *pUser)
|
||||
|
||||
if (iEvent == ROTSTART) {
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "%s Starting", pDat->pName);
|
||||
SCWrite(pDat->pCon, pBueffel, eWarning);
|
||||
SCWrite(pDat->pCon, pBueffel, eEvent);
|
||||
} else if (iEvent == ROTMOVE) {
|
||||
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.rpm = %f", pDat->pName, *fVal);
|
||||
SCWrite(pDat->pCon, pBueffel, eWarning);
|
||||
SCWrite(pDat->pCon, pBueffel, eEvent);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -45,9 +45,9 @@
|
||||
#include <strlutil.h>
|
||||
#include "fortify.h"
|
||||
#include "conman.h"
|
||||
#include "servlog.h"
|
||||
#include "stringdict.h"
|
||||
#include "event.h"
|
||||
#include "logv2.h"
|
||||
typedef struct __VelSelDriv *pVelSelDriv;
|
||||
|
||||
#include "velodriv.h"
|
||||
@ -190,7 +190,7 @@ static int SimFix(pVelSelDriv self, int iError)
|
||||
return VELOREDO;
|
||||
}
|
||||
|
||||
SICSLogWrite("Selector dying randomly", eHWError);
|
||||
Log(ERROR,"dev","%s","Selector dying randomly");
|
||||
if (fRand < 0.3333) {
|
||||
return VELOOK;
|
||||
} else if (fRand < 0.66666) {
|
||||
|
Reference in New Issue
Block a user