From 64b212c4a0cede68d383279b5c78585f7614f3ec Mon Sep 17 00:00:00 2001 From: Ferdi Franceschini Date: Fri, 24 Apr 2015 13:36:59 +1000 Subject: [PATCH 01/39] Resolved a conflict that was missed during 'git merge' conflict resolution. --- drive.c | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/drive.c b/drive.c index f0554a96..4f6f5118 100644 --- a/drive.c +++ b/drive.c @@ -39,7 +39,6 @@ #include #include #include -#include #include "fortify.h" #include "sics.h" #include "drive.h" @@ -302,11 +301,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } -<<<<<<< HEAD - /* interpret arguments as pairs (name, value) and check */ -======= - /* interprete arguments as pairs name value and try to start */ ->>>>>>> master + /* 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]); @@ -316,25 +311,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget); if (iRet == TCL_ERROR) { SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); -<<<<<<< HEAD - SetStatus(eOld); - return 0; - } else if (!isfinite(dTarget)) { - snprintf(pBueffel, 511, - "ERROR: target %s value for %s is not a finite number", - argv[i + 1], argv[i]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - } - /* interpret arguments as pairs (name, value) and try to start */ - for (i = 1; i < argc; i += 2) { - iRet = Tcl_GetDouble(tcl_interp, argv[i + 1], &dTarget); - if (iRet == TCL_ERROR) { - SCWrite(pCon, Tcl_GetStringResult(tcl_interp), eError); -======= StopExe(GetExecutor(), "ALL"); ->>>>>>> master return 0; } iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget); @@ -377,11 +354,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, ClearExecutor(GetExecutor()); return 0; } -<<<<<<< HEAD SCWrite(pCon, "Driving finished successfully", eValue); -======= - SCWrite(pCon, "Driving finished sucessfully", eValue); ->>>>>>> master return 1; } @@ -418,11 +391,7 @@ int RunWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } -<<<<<<< HEAD /* interpret arguments as pairs name value and try to start */ -======= - /* interprete arguments as pairs name value and try to start */ ->>>>>>> master for (i = 1; i < argc; i += 2) { if (argv[i + 1] == NULL) { snprintf(pBueffel,511, "ERROR: no value found for driving %s", argv[i]); From 7643c51d7495368cab08f250e49d1f268e79fd7e Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Fri, 26 Jun 2015 11:32:05 +0200 Subject: [PATCH 02/39] Fix for multicountersec coordination issues implemented --- countersec.c | 29 +++++++++++++++++++- multicountersec.c | 70 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 8 deletions(-) diff --git a/countersec.c b/countersec.c index 2ec4f3e8..d2f5229d 100644 --- a/countersec.c +++ b/countersec.c @@ -77,7 +77,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){ @@ -150,6 +150,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) { @@ -559,6 +561,28 @@ 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; + + mm = GetHdbUpdateMessage(message); + if (mm != NULL) { + if(strcmp(node->value.v.text,"starting") == 0) { + v = *mm->v; + if(strstr(v.v.text,"run") == 0 && strstr(v.v.text,"error") == 0) { + return hdbAbort; + } + } + } + + return hdbContinue; +} /*--------------------------------------------------------------------------*/ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) { @@ -644,6 +668,9 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) if (child == NULL) { return NULL; } + AppendHipadabaCallback(child, + MakeHipadabaCallback(SecStatusCallback, NULL, + NULL)); AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("error", usInternal, MakeHdbText("None")); diff --git a/multicountersec.c b/multicountersec.c index c94b2c0f..dc477ddd 100644 --- a/multicountersec.c +++ b/multicountersec.c @@ -119,7 +119,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 +130,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 +174,70 @@ static void startMultiCounting(pHdb self, SConnection *pCon) } } + v = MakeHdbInt(slaveID); + UpdateHipadabaPar(sID,v,pCon); + + v = MakeHdbInt(-100); + 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 != -100){ + return 1; + } + + + 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 +246,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 +474,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; } From a3605ea96bdbe87f5917666aef3d17e510f55108 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 30 Jun 2015 15:03:06 +0200 Subject: [PATCH 03/39] MultiCounterSec revised now passes self test --- countersec.c | 14 +++++++++++++- multicountersec.c | 26 ++++++++++++++++++++++---- status.c | 5 +++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/countersec.c b/countersec.c index d2f5229d..8e3a6459 100644 --- a/countersec.c +++ b/countersec.c @@ -45,21 +45,33 @@ static void SecCounterSetError(pCounter self, char *text) /*---------------------------------------------------------------------------*/ 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; } diff --git a/multicountersec.c b/multicountersec.c index dc477ddd..b45e519b 100644 --- a/multicountersec.c +++ b/multicountersec.c @@ -17,6 +17,10 @@ #include #include #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); @@ -177,7 +189,7 @@ static void startMultiCounting(pHdb self, SConnection *pCon) v = MakeHdbInt(slaveID); UpdateHipadabaPar(sID,v,pCon); - v = MakeHdbInt(-100); + v = MakeHdbInt(slaveSTARTING); UpdateHipadabaPar(mID,v,pCon); } @@ -195,10 +207,16 @@ static int checkSlavesStarted(pCounter self, SConnection *pCon) mID = GetHipadabaNode(self->objectNode,"masterID"); assert(mID != NULL); - if(mID->value.v.intValue != -100){ + 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); diff --git a/status.c b/status.c index c850e698..5cbef9a6 100644 --- a/status.c +++ b/status.c @@ -391,6 +391,11 @@ 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); From 7ccbf7e0bd43cfd90b6acac80b0e661795992e82 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 29 Jul 2015 17:46:34 +1000 Subject: [PATCH 04/39] Change LLDstringDelete to LLDdeleteString --- SCinter.c | 2 +- lld_str.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/SCinter.c b/SCinter.c index 1d5cd1a4..87695dc8 100644 --- a/SCinter.c +++ b/SCinter.c @@ -1035,7 +1035,7 @@ static void printList(SConnection * pCon, int listID) static void freeList(int listID) { do { - LLDstringDelete(listID); + LLDdeleteString(listID); } while (0 != LLDnodePtr2First(listID)); LLDdelete(listID); } diff --git a/lld_str.h b/lld_str.h index 61280471..a3274759 100644 --- a/lld_str.h +++ b/lld_str.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 ) From 0db57b9baecec5b04a07c4cc95de90f638b261d8 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 29 Jul 2015 17:47:15 +1000 Subject: [PATCH 05/39] Reference count async queue transactions so we can put them of task message queues --- asyncprotocol.h | 1 + asyncqueue.c | 53 +++++++++++++++++++++++++++++++++++-------------- asyncqueue.h | 10 ++++++++++ 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/asyncprotocol.h b/asyncprotocol.h index 5e79e968..24549ad3 100644 --- a/asyncprotocol.h +++ b/asyncprotocol.h @@ -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, ... */ diff --git a/asyncqueue.c b/asyncqueue.c index e1a91337..fc075718 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -89,27 +89,36 @@ static const char *state_name(AsyncState the_state) return ""; } +/* + * 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); } } @@ -735,9 +744,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) diff --git a/asyncqueue.h b/asyncqueue.h index 669916c3..7ae70579 100644 --- a/asyncqueue.h +++ b/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 From eff54a5fd97dfb2016360b4d38f19818e90b6d47 Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Wed, 29 Jul 2015 17:47:46 +1000 Subject: [PATCH 06/39] Implement task priorities and message queues --- background.c | 6 +- commandlog.c | 2 +- conman.c | 10 +- devexec.c | 3 +- devser.c | 2 +- diffscan.c | 2 +- interface.c | 4 +- nread.c | 16 +- nserver.c | 17 +- nxupdate.c | 2 +- oscillate.c | 2 +- remob.c | 2 +- scriptcontext.c | 4 +- serialwait.c | 2 +- sicscron.c | 2 +- sicsexit.c | 2 +- sicspoll.c | 2 +- sicspoll.tc | 2 +- status.c | 2 +- statusfile.c | 6 +- task.c | 1014 ++++++++++++++++++++++++++++++++++++++++------- task.h | 280 ++++++++++--- taskobj.c | 304 +++++++++++++- trace.c | 21 +- 24 files changed, 1440 insertions(+), 269 deletions(-) diff --git a/background.c b/background.c index 6adac099..70b142a4 100644 --- a/background.c +++ b/background.c @@ -28,6 +28,7 @@ static void KillBckTask(void *data) if (self->command) { free(self->command); } + free(self); } /*---------------------------------------------------------------------------*/ @@ -44,6 +45,7 @@ static int BackgroundTask(void *data) /*----------------------------------------------------------------------------*/ int BackgroundCommand(SConnection * pCon, char *command) { + long lID; pBckTask self = NULL; self = calloc(1, sizeof(BckTask)); @@ -58,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; } @@ -76,7 +79,6 @@ int BackgroundAction(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon, "ERROR: out of memory starting task", eError); return 0; } - SCSendOK(pCon); return 1; } diff --git a/commandlog.c b/commandlog.c index 64b5c896..06d5bd54 100644 --- a/commandlog.c +++ b/commandlog.c @@ -491,7 +491,7 @@ int CommandLog(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, "ERROR: autologging is already active", eError); return 0; } - TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, 1); + TaskRegisterN(pServ->pTasker, "autologger", AutoTask, NULL, NULL, NULL, TASK_PRIO_HIGH); SCSendOK(pCon); iAutoActive = 1; return 1; diff --git a/conman.c b/conman.c index 49fa8e03..e4a1234d 100644 --- a/conman.c +++ b/conman.c @@ -452,7 +452,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; @@ -467,7 +470,6 @@ SConnection *SCCopyConnection(SConnection * pCon) result->contextStack = -1; result->iList = -1; result->runLevel = pCon->runLevel; - result->data = pCon->data; return result; } @@ -2272,7 +2274,7 @@ int LogCapture(SConnection * pCon, SicsInterp * pSics, void *pData, if (code_bits & (1 << i)) { if (GetDynStringLength(buffer) > 0) DynStringConcatChar(buffer, ','); - DynStringConcat(buffer, OutCodeToTxt(i)); + DynStringConcat(buffer, (char *)OutCodeToTxt(i)); } } SCPrintf(pCon, eLog, "getlog %s", GetCharArray(buffer)); @@ -2291,7 +2293,7 @@ int LogCapture(SConnection * pCon, SicsInterp * pSics, void *pData, if (code_bits & (1 << i)) { if (GetDynStringLength(buffer) > 0) DynStringConcatChar(buffer, ','); - DynStringConcat(buffer, OutCodeToTxt(i)); + DynStringConcat(buffer, (char *)OutCodeToTxt(i)); } } SCPrintf(pCon, eLog, "getlog %s", GetCharArray(buffer)); diff --git a/devexec.c b/devexec.c index 0cc9268f..e1f3e7b5 100644 --- a/devexec.c +++ b/devexec.c @@ -250,7 +250,6 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes, char *overwriteOption; float oldVal; long taskID; - pTaskGroupData taskGroup = NULL; assert(self); assert(pDes); @@ -329,7 +328,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; diff --git a/devser.c b/devser.c index fc1f90b2..60908d6c 100644 --- a/devser.c +++ b/devser.c @@ -311,7 +311,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; } diff --git a/diffscan.c b/diffscan.c index 87e1b616..a696b6ae 100644 --- a/diffscan.c +++ b/diffscan.c @@ -475,7 +475,7 @@ 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); diff --git a/interface.c b/interface.c index d661b2c3..48807701 100644 --- a/interface.c +++ b/interface.c @@ -284,7 +284,7 @@ long StartDriveTask(void *obj, SConnection *pCon, char *name, float fTarget) DriveTaskFunc, DriveTaskSignal, KillDriveTaskData, - taskData,0); + taskData, TASK_PRIO_HIGH); } /*--------------------------------------------------------------------------*/ pICountable GetCountableInterface(void *pObject) @@ -430,7 +430,7 @@ long StartCountTask(void *obj, SConnection *pCon, char *name) CountTaskFunc, CountTaskSignal, KillCountTaskData, - taskData,0); + taskData, TASK_PRIO_HIGH); } /*--------------------------------------------------------------------------*/ diff --git a/nread.c b/nread.c index 3cb546e3..a492aecc 100644 --- a/nread.c +++ b/nread.c @@ -224,9 +224,9 @@ static int NetReadAccept(pNetRead self, mkChannel * pSock) } 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; } @@ -377,8 +377,8 @@ static int TelnetAccept(pNetRead self, mkChannel * pSock) /* 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 { @@ -896,8 +896,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); @@ -1127,7 +1127,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; @@ -1343,7 +1343,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); diff --git a/nserver.c b/nserver.c index e72917c6..5e2b0fcf 100644 --- a/nserver.c +++ b/nserver.c @@ -43,8 +43,6 @@ extern int openDevexecLog(); /* in devexec.c */ extern int NetWatchTask(void *pData); /* in nwatch.c */ -/* ========================= Less dreadful file statics =================== */ - /*------------------------------------------------------------------------*/ static void StopExit(void) { @@ -116,13 +114,14 @@ 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); @@ -183,7 +182,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 */ @@ -245,17 +244,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 */ @@ -467,7 +466,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 { diff --git a/nxupdate.c b/nxupdate.c index cc7e6cb6..bdf39965 100644 --- a/nxupdate.c +++ b/nxupdate.c @@ -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; diff --git a/oscillate.c b/oscillate.c index 8a5228d0..19bc8e1d 100644 --- a/oscillate.c +++ b/oscillate.c @@ -165,7 +165,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; diff --git a/remob.c b/remob.c index 3aa384ea..ceae8026 100644 --- a/remob.c +++ b/remob.c @@ -954,7 +954,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; } diff --git a/scriptcontext.c b/scriptcontext.c index f9a5d926..1add98d7 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -523,7 +523,7 @@ static char *SctActionHandler(void *actionData, char *lastReply, traceIO(data->controller->node->name, "ERROR: action {%s} in {%s} node %s:\nERROR: %s", data->name, origScript, path, result); } else { - traceIO("sctunknown", "reply:%s", "ERROR: action {%s} in {%s} node %s:\nERROR: %s", + traceIO("sctunknown", "ERROR: action {%s} in {%s} node %s:\nERROR: %s", data->name, origScript, path, result); } } @@ -1842,7 +1842,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); } diff --git a/serialwait.c b/serialwait.c index bb73952f..fd21aa75 100644 --- a/serialwait.c +++ b/serialwait.c @@ -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); diff --git a/sicscron.c b/sicscron.c index da2ec5d3..0ad5ae63 100644 --- a/sicscron.c +++ b/sicscron.c @@ -237,7 +237,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; } diff --git a/sicsexit.c b/sicsexit.c index 130f5fb0..e6e56750 100644 --- a/sicsexit.c +++ b/sicsexit.c @@ -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; diff --git a/sicspoll.c b/sicspoll.c index 0601199a..33be09ff 100644 --- a/sicspoll.c +++ b/sicspoll.c @@ -379,7 +379,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); diff --git a/sicspoll.tc b/sicspoll.tc index ea2eb738..bbcf9f7d 100644 --- a/sicspoll.tc +++ b/sicspoll.tc @@ -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, diff --git a/status.c b/status.c index c850e698..a8ec242e 100644 --- a/status.c +++ b/status.c @@ -504,5 +504,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); } diff --git a/statusfile.c b/statusfile.c index 84eb343c..d1593d13 100644 --- a/statusfile.c +++ b/statusfile.c @@ -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); } diff --git a/task.c b/task.c index 396f782d..20fb1380 100644 --- a/task.c +++ b/task.c @@ -1,47 +1,93 @@ /*------------------------------------------------------------------------ - T A S K E R - + T A S K E R + Implementation of a portable task switcher. - + Mark Koennecke, September 1997 - + copyleft, 1997. - + NO WARRANTIES OF ANY KIND WHATSOEVER TAKEN BY ME OR MY EMPLOYER. YOU ARE AT YOUR OWN! - Reworked to have a task name, stop by task name and better listing. + Reworked to have a task name, stop by task name and better listing. Mark Koennecke, December 2012 + + Reworked to implement priorities and message queues + + Douglas Clowes, July 2015 ----------------------------------------------------------------------------*/ #include +#include #include #include +#include #include #include "fortify.h" #include "task.h" #define READY 1 #define WAITING 2 #define YIELDING 3 +#define DERFUNCT 4 #define IDUNDEFINED 0L #define TASKMAGIC 777111999 + +typedef unsigned long long LoopCounter; +/*--------------------------------------------------------------------------*/ +struct __TaskTaskID { + long lID; +}; + +struct __TaskGroupID { + long lID; +}; + +typedef struct{ + pTaskMan tasker; + TaskGroupID groupID; +} TaskGroupData, *pTaskGroupData; + +TaskTaskID TaskUnknownTaskID = 0; +TaskGroupID TaskUnknownGroupID = 0; + +TaskTaskID TaskBadTaskID = -1; +TaskGroupID TaskBadGroupID = -1; /*--------------------------------------------------------------------------*/ typedef struct __TaskHead { long magic; - long lID; - long groupID; + TaskTaskID taskID; + TaskGroupID groupID; int iStatus; - long lWait; + int iPrioBase; + TaskTaskID waitTarget; char *name; time_t start_time; + double startRunTime; + double lastRunTime; + double nextRunTime; + double nextRunPeriod; TaskFunc pRun; + TaskMsgFunc pMsgRun; SignalFunc pSignal; void *pData; TaskKillFunc pKill; pTaskHead pNext; pTaskHead pPrevious; + pTaskQueue pQueue; + LoopCounter numRuns; + LoopCounter numWaits; + LoopCounter numYields; + double startWallTime; + double accumulatedWallTime; + double startYieldTime; + double accumulatedYieldTime; + double startProcessorTime; + double accumulatedProcessorTime; + int isActive; + int isLogged; } TaskHead; typedef struct __TaskMan { @@ -49,20 +95,93 @@ typedef struct __TaskMan { int iStop; pTaskHead pCurrent; /* Think trice before you interfere with this! */ pTaskHead pHead; + int stackPointer; + TaskTaskID stackStack[20]; } TaskMan; + +static TaskLogFunc TaskLogWrite = NULL; +static eTaskLogLevel TaskLogLevel = eTaskLogNone; + +static int LOGGING_AT(pTaskMan self, eTaskLogLevel level) { + if (TaskLogWrite == NULL) + return 0; + if (TaskLogLevel == eTaskLogNone) + return 0; + if (level < TaskLogLevel) + return 0; + return 1; +} + +static int TaskLogPrint(eTaskLogLevel lvl, const char *fmt, ...) +{ + va_list ap; + char buf[256]; + int l; + + if (TaskLogWrite == NULL || TaskLogLevel == eTaskLogNone || lvl < TaskLogLevel) { + return 0; + } + + va_start(ap, fmt); + l = vsnprintf(buf, sizeof buf, fmt, ap); + va_end(ap); + if (l <= 0) + return l; + if (l >= sizeof buf) { + char *dyn; + /* 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); + TaskLogWrite(lvl, dyn); + free(dyn); + return l; + } + } + TaskLogWrite(lvl, buf); + return l; +} + +void TaskLogStack(pTaskMan self, eTaskLogLevel typ); /*--------------------------------------------------------------------------- -The 7 below solves a subtle bug which occurs when a groupID in user code -has been initialized to 0 and starting fails. Then it seems as if this -group keeps running. As there will always be some task running at 0. +The 7 below solves a subtle bug which occurs when a groupID in user code +has been initialized to 0 and starting fails. Then it seems as if this +group keeps running. As there will always be some task running at 0. ----------------------------------------------------------------------------*/ static long lIDMama = 7L; #define TASKERID 123399 /*---------------------------------------------------------------------------*/ +static double DoubleTime(void) +{ + struct timeval now; + /* the resolution of this function is usec, if the machine supports this + and the mantissa of a double is 51 bits or more (31 for sec and 20 for mic$ + */ + gettimeofday(&now, NULL); + return now.tv_sec + now.tv_usec / 1e6; +} +/*-------------------------------------------------------------------------*/ +static double DoubleTimeCPU(void) +{ + struct timespec now; + /* the resolution of this function is usec, if the machine supports this + and the mantissa of a double is 51 bits or more (31 for sec and 20 for mic$ + */ + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now); + return now.tv_sec + now.tv_nsec / 1e9; +} + +/*---------------------------------------------------------------------------*/ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal, void *pData, TaskKillFunc pKill) { pTaskHead pNew = NULL; + TaskTaskID newID; pNew = (pTaskHead) malloc(sizeof(TaskHead)); if (!pNew) { @@ -73,18 +192,20 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal, pNew->magic = TASKMAGIC; pNew->name = strdup(name); pNew->start_time = time(NULL); + pNew->startRunTime = DoubleTime(); pNew->pRun = pTask; pNew->pSignal = pSignal; pNew->pData = pData; pNew->pKill = pKill; lIDMama++; - pNew->lID = lIDMama; - pNew->iStatus = READY; - pNew->groupID = IDUNDEFINED; - - if(lIDMama < 0){ + if(lIDMama < 7){ lIDMama = 7; } + newID = lIDMama; + pNew->taskID = newID; + pNew->iStatus = READY; + pNew->groupID = TaskUnknownGroupID; + pNew->waitTarget = TaskUnknownTaskID; return pNew; } @@ -119,6 +240,74 @@ static int DummyTask(void *pData) return 1; } +/*--------------------------------------------------------------------------*/ +static double makeTaskActive(pTaskHead self) +{ + double now = DoubleTime(); + + self->isActive = 1; + self->startWallTime = now; + self->startProcessorTime = DoubleTimeCPU(); + return now; +} + +/*--------------------------------------------------------------------------*/ +static double makeTaskIdle(pTaskHead self) +{ + double now = DoubleTime(); + + self->accumulatedWallTime += now - self->startWallTime; + self->accumulatedProcessorTime += DoubleTimeCPU() - self->startProcessorTime; + self->isActive = 0; + return now; +} + +/*--------------------------------------------------------------------------*/ +static int makeTaskRun(pTaskMan self) +{ + int iRet; + LoopCounter numWaits; + LoopCounter numYields; + double start, elapsed; + pTaskHead pThis = self->pCurrent; + start = makeTaskActive(pThis); + numWaits = pThis->numWaits; + numYields = pThis->numYields; + if (pThis->pRun) + iRet = pThis->pRun(pThis->pData); + else if (pThis->pMsgRun) { + pTaskMessage pMsg = TaskQueueRecvMine(self); + if (pMsg) { + iRet = pThis->pMsgRun(pThis->pData, pMsg); + TaskMessageFree(pMsg); + } else { + /* TODO: should not happen */ + } + } else { + /* TODO: this should not happen */ + } + pThis->isLogged = 0; /* reset this after each run */ + pThis->lastRunTime = start; + pThis->numRuns++; + elapsed = makeTaskIdle(pThis) - start; + if (LOGGING_AT(self, eTaskLogDebug)) { + if (pThis->numWaits != numWaits) + TaskLogPrint(eTaskLogDebug, "TaskWaited: %s waited %lld times in %fS", + pThis->name, + pThis->numWaits - numWaits, + elapsed); + if (pThis->numYields != numYields) + TaskLogPrint(eTaskLogDebug, "TaskYielded: %s yielded %lld times in %fS", + pThis->name, + pThis->numYields - numYields, + elapsed); + if (pThis->numWaits != numWaits || pThis->numYields != numYields) + if (self->stackPointer > 0) + TaskLogStack(self, eTaskLogDebug); + } + return iRet; +} + /*--------------------------------------------------------------------------*/ int TaskerInit(pTaskMan * self) { @@ -170,26 +359,20 @@ int TaskerDelete(pTaskMan * pData) *pData = NULL; return 1; } -/*----------------------- temporary for backwards compatability -------------*/ -long TaskRegister(pTaskMan self,TaskFunc pTask, SignalFunc pSignal, - TaskKillFunc pKill, void *pData, int iPriority) -{ - return TaskRegisterN(self,"Unknown", pTask, pSignal, pKill, pData, iPriority); -} /*---------------------------------------------------------------------------*/ -long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal, +static pTaskHead taskConstructor(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal, TaskKillFunc pKill, void *pData, int iPriority) { pTaskHead pNew = NULL; assert(self); assert(self->iID == TASKERID); - assert(pTask); pNew = MakeTaskHead(name, pTask, pSignal, pData, pKill); if (!pNew) { - return -1; + return NULL; } + pNew->iPrioBase = iPriority; /* link it in */ if (self->pCurrent->pNext) { @@ -199,7 +382,68 @@ long TaskRegisterN(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal pNew->pNext = self->pCurrent->pNext; self->pCurrent->pNext = pNew; - return pNew->lID; + if (LOGGING_AT(self, eTaskLogDebug)) { + TaskLogPrint(eTaskLogDebug, "TaskStart: %s (ID = %ld, Prio = %d)", + pNew->name, pNew->taskID, pNew->iPrioBase); + } + return pNew; +} +/*----------------------- temporary for backwards compatability -------------*/ +TaskTaskID TaskRegister(pTaskMan self,TaskFunc pTask, SignalFunc pSignal, + TaskKillFunc pKill, void *pData, int iPriority) +{ + pTaskHead pNew; + assert(pTask); + pNew = taskConstructor(self, "Unknown", pTask, pSignal, pKill, pData, iPriority); + return pNew ? pNew->taskID : TaskBadTaskID; +} +/*---------------------------------------------------------------------------*/ +TaskTaskID TaskRegisterN(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal, + TaskKillFunc pKill, void *pData, int iPriority) +{ + pTaskHead pNew; + assert(pTask); + pNew = taskConstructor(self, name, pTask, pSignal, pKill, pData, iPriority); + return pNew ? pNew->taskID : TaskBadTaskID; +} +/*---------------------------------------------------------------------------*/ +TaskTaskID TaskRegisterQ(pTaskMan self, char *name, TaskMsgFunc pTask, SignalFunc pSignal, + TaskKillFunc pKill, void *pData, int iPriority) +{ + pTaskHead pNew; + assert(pTask); + pNew = taskConstructor(self, name, NULL, pSignal, pKill, pData, iPriority); + if (pNew) { + pNew->pMsgRun = pTask; + pNew->pQueue = TaskQueueAlloc(); + } + return pNew ? pNew->taskID : TaskBadTaskID; +} +/*---------------------------------------------------------------------------*/ +TaskTaskID TaskRegisterD(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal, + TaskKillFunc pKill, void *pData, int iPriority, double delay) +{ + pTaskHead pNew; + assert(pTask); + pNew = taskConstructor(self, name, pTask, pSignal, pKill, pData, iPriority); + if (pNew) { + pNew->nextRunTime = DoubleTime() + delay; + } + return pNew ? pNew->taskID : TaskBadTaskID; +} +/*---------------------------------------------------------------------------*/ +TaskTaskID TaskRegisterP(pTaskMan self, char *name, TaskFunc pTask, SignalFunc pSignal, + TaskKillFunc pKill, void *pData, int iPriority, + double delay, double period) +{ + pTaskHead pNew; + assert(pTask); + pNew = taskConstructor(self, name, pTask, pSignal, pKill, pData, iPriority); + if (pNew) { + pNew->nextRunTime = DoubleTime() + delay; + pNew->nextRunPeriod = period; + } + return pNew ? pNew->taskID : TaskBadTaskID; } /*-------------------------------------------------------------------------*/ static void IncrTaskPointer(pTaskMan self) @@ -211,91 +455,110 @@ static void IncrTaskPointer(pTaskMan self) } /*-------------------------------------------------------------------------*/ -static int TaskExist(pTaskMan self, long lID) +static int TaskExist(pTaskMan self, TaskTaskID taskID) { - pTaskHead pCur = self->pHead; - while (pCur != NULL) { - if (pCur->lID == lID) { - return 1; + if (taskID == TaskBadTaskID || taskID == TaskUnknownTaskID) { + return 0; + } else { + pTaskHead pCur = self->pHead; + while (pCur != NULL) { + if (pCur->taskID == taskID) { + return 1; + } + pCur = pCur->pNext; } - pCur = pCur->pNext; + return 0; } - return 0; } +/*--------------------------------------------------------------------------*/ +static void TaskPush(pTaskMan self) +{ + makeTaskIdle(self->pCurrent); + self->stackStack[self->stackPointer] = self->pCurrent->taskID; + self->stackPointer++; +} +/*--------------------------------------------------------------------------*/ +static void TaskPop(pTaskMan self) +{ + makeTaskActive(self->pCurrent); + self->stackPointer--; +} +/*--------------------------------------------------------------------------*/ +static void TaskPrune(pTaskMan self) +{ + pTaskHead pThis; + pThis = self->pHead; /* start this at the dummy */ + while (pThis->pNext) { + if (pThis->pNext->iStatus == DERFUNCT) { + pTaskHead pThat = pThis->pNext; + if (LOGGING_AT(self, eTaskLogDebug)) + TaskLogPrint(eTaskLogDebug, + "TaskEnd: %s (ID=%ld,Loops=%lld,Waits=%lld,Yields=%lld,CPU=%f,Wall=%f,Yield=%f,Up=%f)", + pThat->name, + pThat->taskID, + pThat->numRuns, + pThat->numWaits, + pThat->numYields, + pThat->accumulatedProcessorTime, + pThat->accumulatedWallTime, + pThat->accumulatedYieldTime, + (double) (DoubleTime() - pThat->startRunTime) + ); + DeleteTaskHead(pThat); /* unlink and delete it */ + } + pThis = pThis->pNext; /* Note: not the same as pThat above */ + } +} +/*--------------------------------------------------------------------------*/ +static void TaskLoop(pTaskMan self) +{ + int iRet; + pTaskHead pThis; /* The current task on entry, or dummy */ + pTaskHead pThat; /* The task we are thinking of running next */ + pThis = self->pCurrent; + while (self->iStop == 0) { + pThat = self->pCurrent; + if (pThat->iStatus != READY) { + /* Not ready: do nothing */ + } else if (pThat->pQueue && TaskQueueCount(pThat->pQueue) == 0) { + /* Have Queue, but is empty: do nothing */ + } else if (pThat->nextRunTime > 0.0 && DoubleTime() < pThat->nextRunTime) { + /* Have due time but not there yet: do nothing */ + } else if (pThis->iPrioBase <= pThat->iPrioBase) { + if (pThat->nextRunTime > 0.0) { + /* Do this now so the task can override it during the run */ + if (pThat->nextRunPeriod > 0) { + double now = DoubleTime(); + pThat->nextRunTime += pThat->nextRunPeriod; + if (now > pThat->nextRunTime) + pThat->nextRunTime = now + pThat->nextRunPeriod; + } else { + pThat->nextRunTime = 0.0; + } + } + iRet = makeTaskRun(self); + if (iRet == 0) { + pThat->iStatus = DERFUNCT; + } + } + IncrTaskPointer(self); + if (self->pCurrent == pThis) + break; + } + TaskPrune(self); +} /*--------------------------------------------------------------------------*/ int TaskSchedule(pTaskMan self) { int iRet; - pTaskHead pTemp; assert(self); assert(self->iID == TASKERID); /* forever, until stop is called somehow */ - while (self->iStop == 0) { - if (self->pCurrent->iStatus == READY) { - iRet = self->pCurrent->pRun(self->pCurrent->pData); - if (iRet != 1) { - pTemp = self->pCurrent; - IncrTaskPointer(self); - DeleteTaskHead(pTemp); - } else { - IncrTaskPointer(self); - } - } else { - IncrTaskPointer(self); - } - } - return 1; -} - -/*-----------------------------------------------------------------*/ -int TaskWait(pTaskMan self, long lID) -{ - int iRet; - long lTest; - pTaskHead pTemp, pEnd; - - assert(self); - assert(self->iID == TASKERID); - - /* Cycle until lID is killed. Stop is obeyed as well */ - pEnd = self->pCurrent; - pEnd->iStatus = WAITING; - IncrTaskPointer(self); - while (self->iStop == 0) { - if ((self->pCurrent != pEnd) && (self->pCurrent->iStatus == READY) - && self->pCurrent != NULL) - /* omit ourselves! */ - { - iRet = self->pCurrent->pRun(self->pCurrent->pData); - if (iRet != 1) { - pTemp = self->pCurrent; - lTest = pTemp->lID; - IncrTaskPointer(self); - DeleteTaskHead(pTemp); - if (lTest == lID) { - goto ente; - } - } else { - IncrTaskPointer(self); - } - } else { - IncrTaskPointer(self); - } - if (self->pCurrent == self->pHead) { - if (!TaskExist(self, lID)) - goto ente; - } - } - -ente: - /* task ended, we need to continue to pEnd before we are done */ - while (self->pCurrent != pEnd) { - IncrTaskPointer(self); - } - pEnd->iStatus = READY; + while (self->iStop == 0) + TaskLoop(self); return 1; } @@ -303,34 +566,81 @@ ente: int TaskYield(pTaskMan self) { int iRet; - long lTest; - pTaskHead pTemp, pEnd; + double deltaTime; + pTaskHead pTemp, pThis; + extern void generate_stack_trace(int full, int dump); assert(self); assert(self->iID == TASKERID); /* Cycle until back at ourselves */ - pEnd = self->pCurrent; - pEnd->iStatus = WAITING; - IncrTaskPointer(self); - while ((self->iStop == 0) && (self->pCurrent != pEnd)) { - if ((self->pCurrent != pEnd) && (self->pCurrent->iStatus == READY)) - /* omit ourselves! */ - { - iRet = self->pCurrent->pRun(self->pCurrent->pData); - if (iRet != 1) { - pTemp = self->pCurrent; - lTest = pTemp->lID; - IncrTaskPointer(self); - DeleteTaskHead(pTemp); - } else { - IncrTaskPointer(self); + pThis = self->pCurrent; + pThis->iStatus = WAITING; + TaskPush(self); + self->pCurrent->numYields++; + if (LOGGING_AT(self, eTaskLogWarning)) { + if (pThis->iPrioBase > TASK_PRIO_LOW) { + if (!pThis->isLogged) { + pThis->isLogged = 1; + TaskLogPrint(eTaskLogWarning, "TaskYield: Unexpected Yield (not TASK_PRIO_LOW)"); + TaskLogStack(self, eTaskLogWarning); + generate_stack_trace(1, 0); } - } else { - IncrTaskPointer(self); } } - pEnd->iStatus = READY; + pThis->startYieldTime = DoubleTime(); + TaskLoop(self); + deltaTime = DoubleTime() - pThis->startYieldTime; + if (pThis->iPrioBase > TASK_PRIO_LOW && deltaTime > 0.250) { + if (LOGGING_AT(self, eTaskLogDebug)) { + TaskLogPrint(eTaskLogWarning, "TaskYield: Excessive Yield Time %fS in %s", + deltaTime, pThis->name); + } + } + pThis->accumulatedYieldTime += deltaTime; + pThis->iStatus = READY; + TaskPop(self); + return 1; +} + +/*-----------------------------------------------------------------*/ +int TaskWait(pTaskMan self, TaskTaskID taskID) +{ + int iRet; + pTaskHead pTemp, pThis; + extern void generate_stack_trace(int full, int dump); + + assert(self); + assert(self->iID == TASKERID); + + /* Cycle until taskID is killed. Stop is obeyed as well */ + pThis = self->pCurrent; + pThis->iStatus = WAITING; + pThis->waitTarget = taskID; + TaskPush(self); + self->pCurrent->numWaits++; + if (LOGGING_AT(self, eTaskLogWarning)) { + if (pThis->iPrioBase > TASK_PRIO_LOW) { + if (!pThis->isLogged) { + pThis->isLogged = 1; + TaskLogPrint(eTaskLogWarning, "TaskWait: Unexpected Wait (not TASK_PRIO_LOW)"); + TaskLogStack(self, eTaskLogWarning); + generate_stack_trace(1, 0); + } + } + } + pTemp = TaskIteratorByID(self, taskID); + if (pTemp && pTemp->iPrioBase < pThis->iPrioBase) { + /* Inverted priority */ + TaskLogPrint(eTaskLogError, "TaskWait: Bad Wait: Priority Inverted waiter(%s:%d) > target(%s:%d)", + pThis->name, pThis->iPrioBase, pTemp->name, pTemp->iPrioBase); + pTemp->iPrioBase = pThis->iPrioBase; + } + while (self->iStop == 0 && TaskExist(self, taskID)) + TaskLoop(self); + pThis->waitTarget = TaskUnknownTaskID; + pThis->iStatus = READY; + TaskPop(self); return 1; } @@ -397,8 +707,8 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData) pNext = pCurrent->pNext; if (pCurrent->pRun == pTaskRun && pCurrent->pData == pData) { if(pCurrent == self->pCurrent){ - /* cannot kill myself */ - return; + /* cannot kill myself */ + return; } /* unlink */ if (pCurrent->pPrevious != NULL) { @@ -408,7 +718,7 @@ void TaskRemove(pTaskMan self, TaskFunc pTaskRun, void *pData) pCurrent->pNext->pPrevious = pCurrent->pPrevious; } if(pCurrent->name != NULL){ - free(pCurrent->name); + free(pCurrent->name); } free(pCurrent); } @@ -430,10 +740,10 @@ int StopTask(pTaskMan self, char *name) pNext = pCurrent->pNext; if (strcmp(pCurrent->name,name) == 0) { if(self->pCurrent == pCurrent){ - /** - * cannot kill myself - */ - return 0; + /** + * cannot kill myself + */ + return 0; } /* unlink */ if (pCurrent->pPrevious != NULL) { @@ -443,7 +753,7 @@ int StopTask(pTaskMan self, char *name) pCurrent->pNext->pPrevious = pCurrent->pPrevious; } if(pCurrent->name != NULL){ - free(pCurrent->name); + free(pCurrent->name); } free(pCurrent); } @@ -470,7 +780,7 @@ int isTaskRunning(pTaskMan self, char *name) return 0; } /*-----------------------------------------------------------------------------*/ -int isTaskIDRunning(pTaskMan self, long lID) +int isTaskIDRunning(pTaskMan self, TaskTaskID taskID) { int iRet; pTaskHead pCurrent, pNext; @@ -482,7 +792,7 @@ int isTaskIDRunning(pTaskMan self, long lID) while (pNext != NULL) { pCurrent = pNext; pNext = pCurrent->pNext; - if (pCurrent->lID == lID) { + if (pCurrent->taskID == taskID) { return 1; } } @@ -501,10 +811,48 @@ pTaskHead TaskIteratorNext(pTaskHead it) { if(it != NULL && it->magic == TASKMAGIC){ return it->pNext; - } + } return NULL; } /*-----------------------------------------------------------------------------*/ +pTaskHead TaskIteratorCurrent(pTaskMan self) +{ + if (self == NULL) return NULL; + assert(self->iID == TASKERID); + + return self->pCurrent; +} +/*-----------------------------------------------------------------------------*/ +pTaskHead TaskIteratorByName(pTaskMan self, const char* name) +{ + pTaskHead it; + if (self == NULL) return NULL; + assert(self->iID == TASKERID); + + it = self->pHead->pNext; /* skip dummy task */ + while (it) { + if (strcasecmp(it->name, name) == 0) + break; + it = it->pNext; + } + return it; +} +/*-----------------------------------------------------------------------------*/ +pTaskHead TaskIteratorByID(pTaskMan self, TaskTaskID taskID) +{ + pTaskHead it; + if (self == NULL) return NULL; + assert(self->iID == TASKERID); + + it = self->pHead->pNext; /* skip dummy task */ + while (it) { + if (it->taskID == taskID) + break; + it = it->pNext; + } + return it; +} +/*-----------------------------------------------------------------------------*/ char *TaskDescription(pTaskHead it) { char *result; @@ -514,7 +862,7 @@ char *TaskDescription(pTaskHead it) if(it == NULL){ return NULL; } - + length = strlen(it->name) + 120; result = malloc(length*sizeof(char)); if(result == NULL){ @@ -526,22 +874,87 @@ char *TaskDescription(pTaskHead it) length = strlen(result); tm = localtime((const time_t *)&it->start_time); - strftime(result+length,100,"%F-%k-%m-%S",tm); + strftime(result+length,100,"%F-%H-%M-%S",tm); length = strlen(result); - snprintf(result+length,120-20,"|%ld", it->lID); + snprintf(result+length,120-20,"|%ld", it->taskID); length = strlen(result); snprintf(result+length,120-40,"|%.0ld ", it->groupID); return result; } -/*------------------------------------------------------------------------------*/ -long GetTaskID(pTaskHead it) +/*-----------------------------------------------------------------------------*/ +char *TaskDetail(pTaskHead it) { - return it->lID; + char *result; + int length; + const struct tm *tm; + + if(it == NULL){ + return NULL; + } + + length = strlen(it->name) + 120; + result = malloc(length*sizeof(char)); + if(result == NULL){ + return NULL; + } + memset(result,0,length*sizeof(char)); + strcpy(result,it->name); + + length = strlen(result); + snprintf(result+length,120-20,"|%lld", it->numRuns); + length = strlen(result); + snprintf(result+length,120-20,"|%lld", it->numWaits); + length = strlen(result); + snprintf(result+length,120-20,"|%lld", it->numYields); + length = strlen(result); + snprintf(result+length,120-20,"|%.6f", it->accumulatedProcessorTime); + length = strlen(result); + snprintf(result+length,120-40,"|%.6f", it->accumulatedWallTime); + length = strlen(result); + snprintf(result+length,120-40,"|%.6f", it->accumulatedYieldTime); + + return result; + } /*------------------------------------------------------------------------------*/ -long GetGroupID(pTaskHead it) +int TaskGetStack(pTaskMan self, pTaskHead it[]) +{ + if (it != NULL) { + int i; + for (i = 0; i < self->stackPointer; ++i) { + pTaskHead pTemp; + it[i] = NULL; + for (pTemp = self->pHead->pNext; pTemp; pTemp = pTemp->pNext) { + if (pTemp->taskID == self->stackStack[i]) { + it[i] = pTemp; + break; + } + } + } + } + return self->stackPointer; +} +/*------------------------------------------------------------------------------*/ +void TaskLogStack(pTaskMan self, eTaskLogLevel typ) +{ + if (LOGGING_AT(self, typ)) { + int i, count; + pTaskHead it[20]; + count = TaskGetStack(self, it); + for (i = 0; i < count; ++i) { + TaskLogPrint(typ, "TaskStack[%02d]: %s", i, it[count - 1 - i]->name); + } + } +} +/*------------------------------------------------------------------------------*/ +TaskTaskID GetTaskID(pTaskHead it) +{ + return it->taskID; +} +/*------------------------------------------------------------------------------*/ +TaskGroupID GetGroupID(pTaskHead it) { return it->groupID; } @@ -560,13 +973,18 @@ const void *GetTaskData(pTaskHead it) } } /*------------------------------------------------------------------------------*/ -long GetTaskGroupID(pTaskMan self) +TaskGroupID GetTaskGroupID(pTaskMan self) { + TaskGroupID newGroupID; lIDMama++; - return lIDMama; + if(lIDMama < 7){ + lIDMama = 7; + } + newGroupID = lIDMama; + return newGroupID; } /*-------------------------------------------------------------------------------*/ -void AddTaskToGroup(pTaskMan self, long taskID, long groupID) +void AddTaskToGroup(pTaskMan self, TaskTaskID taskID, TaskGroupID groupID) { pTaskHead pCurrent, pNext; @@ -577,7 +995,7 @@ void AddTaskToGroup(pTaskMan self, long taskID, long groupID) while (pNext != NULL) { pCurrent = pNext; pNext = pCurrent->pNext; - if (pCurrent->lID == taskID) { + if (pCurrent->taskID == taskID) { pCurrent->groupID = groupID; return; } @@ -587,12 +1005,13 @@ void AddTaskToGroup(pTaskMan self, long taskID, long groupID) This simply checks if there are any more tasks with the desired groupID in the list. If none, then all sub tasks have finished. -----------------------------------------------------------------------------------*/ -int isTaskGroupRunning(pTaskMan self, long groupID) +int isTaskGroupRunning(pTaskMan self, TaskGroupID groupID) { pTaskHead pCurrent, pNext; if (self == NULL) return 0; - if (groupID == IDUNDEFINED) return 0; + if (groupID == TaskUnknownGroupID || groupID == TaskBadGroupID) + return 0; assert(self->iID == TASKERID); @@ -600,7 +1019,7 @@ int isTaskGroupRunning(pTaskMan self, long groupID) while (pNext != NULL) { pCurrent = pNext; pNext = pCurrent->pNext; - if (pCurrent->groupID != IDUNDEFINED && pCurrent->groupID == groupID) { + if (pCurrent->groupID == groupID) { return 1; } } @@ -611,10 +1030,10 @@ int TaskGroupTask(void *data) { pTaskGroupData self = (pTaskGroupData)data; - return isTaskGroupRunning(self->tasker,self->groupID); + return isTaskGroupRunning(self->tasker,self->groupID); } /*-------------------------------------------------------------------------------*/ -int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, long groupID) +int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, TaskGroupID groupID) { pTaskHead pTemp, pEnd; @@ -633,3 +1052,308 @@ int TaskSignalGroup(pTaskMan self, int iSignal, void *pSigData, long groupID) return 1; } +/*-------------------------------------------------------------------------------*/ +void TaskSetLogFunc(TaskLogFunc logFunc) +{ + TaskLogWrite = logFunc; +} +/*-------------------------------------------------------------------------------*/ +TaskLogFunc TaskGetLogFunc(void) +{ + return TaskLogWrite; +} +/*-------------------------------------------------------------------------------*/ +eTaskLogLevel TaskSetLogLevel(eTaskLogLevel logLevel) +{ + eTaskLogLevel old = TaskLogLevel; + TaskLogLevel = logLevel; + return old; +} +/*-------------------------------------------------------------------------------*/ +eTaskLogLevel TaskGetLogLevel(void) +{ + return TaskLogLevel; +} +/*-------------------------------------------------------------------------------*/ +int TaskQueueSet(pTaskMan self, TaskTaskID taskID, pTaskQueue pQueue) +{ + pTaskHead pt = TaskIteratorByID(self, taskID); + if (pt) { + pt->pQueue = pQueue; + return 1; + } + return 0; +} + +/*-------------------------------------------------------------------------------*/ +int TaskQueueRem(pTaskMan self, TaskTaskID taskID) +{ + pTaskHead pt = TaskIteratorByID(self, taskID); + if (pt) { + pt->pQueue = NULL; + return 1; + } + return 0; +} +/*-------------------------------------------------------------------------------*/ +pTaskQueue TaskQueueGet(pTaskMan self, TaskTaskID taskID) +{ + pTaskHead pt = TaskIteratorByID(self, taskID); + if (pt) { + return pt->pQueue; + } + return NULL; +} + +/*-------------------------------------------------------------------------------*/ +pTaskQueue TaskQueueGetMine(pTaskMan self) +{ + pTaskHead pt = self->pCurrent; + if (pt) { + return pt->pQueue; + } + return NULL; +} + +#define MAGIC_Q 12334 +#define MAGIC_M 32441 + +typedef struct __TaskQueue { + int magic; + int count; + pTaskMessage head; + pTaskMessage tail; +} TaskQueue; + +typedef struct __TaskMessage { + int magic; + int mType; + pTaskMessage next; + pTaskMessage prev; + pTaskQueue owner; + TaskTaskID lSenderID; + void *pData; +} TaskMessage; + +/*-------------------------------------------------------------------------------*/ +static pTaskQueue taskQueueInit(pTaskQueue self) +{ + if (self) { + if (self->magic == MAGIC_Q) { + /* TODO */; + } + self->magic = MAGIC_Q; + self->count = 0; + self->head = NULL; + self->tail = NULL; + } + return self; +} + +/*-------------------------------------------------------------------------------*/ +void TaskRunMeAfter(pTaskMan self, double delay) +{ + pTaskHead pThis = self->pCurrent; + pThis->nextRunTime = DoubleTime() + delay; + pThis->nextRunPeriod = 0.0; +} +/*-------------------------------------------------------------------------------*/ +void TaskRunMeEvery(pTaskMan self, double delay) +{ + pTaskHead pThis = self->pCurrent; + pThis->nextRunTime = DoubleTime() + delay; + pThis->nextRunPeriod = delay; +} +/*-------------------------------------------------------------------------------*/ +double TaskRunMyPeriod(pTaskMan self) +{ + pTaskHead pThis = self->pCurrent; + return pThis->nextRunPeriod; +} +/*-------------------------------------------------------------------------------*/ +pTaskQueue TaskQueueAlloc(void) +{ + pTaskQueue self = (pTaskQueue) calloc(1, sizeof(TaskQueue)); + if (self) { + self = taskQueueInit(self); + } + return self; +} + +/*-------------------------------------------------------------------------------*/ +int TaskQueueFree(pTaskQueue self) +{ + if (self == NULL) { + /* TODO */ + return -1; + } + if (self->magic != MAGIC_Q) { + /* TODO */ + return -1; + } + if (self->count != 0 || self->head || self->tail) { + /* TODO */ + return -1; + } + self->magic = 0; + return 0; +} + +/*-------------------------------------------------------------------------------*/ +int TaskQueueCount(pTaskQueue self) { + if (self == NULL) { + /* TODO */ + return 0; + } + if (self->magic != MAGIC_Q) { + /* TODO */ + return 0; + } + return self->count; +} + +/*-------------------------------------------------------------------------------*/ +int TaskQueueSend(pTaskQueue the_q, pTaskMessage the_m) +{ + if (the_q == NULL || the_m == NULL) { + /* TODO */ + return 0; + } + if (the_q->magic != MAGIC_Q || the_m->magic != MAGIC_M) { + /* TODO */ + return 0; + } + if (the_q->head) { + the_m->prev = the_q->tail; + the_q->tail->next = the_m; + } else { + the_q->head = the_m; + the_m->prev = NULL; + } + the_q->tail = the_m; + the_m->next = NULL; + the_q->count++; + the_m->owner = the_q; + return the_q->count; +} + +/*-------------------------------------------------------------------------------*/ +int TaskQueueSendID(pTaskMan self, TaskTaskID taskID, pTaskMessage the_m) +{ + pTaskQueue the_q = TaskQueueGet(self, taskID); + + if (the_q == NULL) + return 0; + + return TaskQueueSend(the_q, the_m); +} + +/*-------------------------------------------------------------------------------*/ +pTaskMessage TaskQueueRecv(pTaskQueue self) +{ + pTaskMessage m; + if (self == NULL) { + /* TODO */ + return NULL; + } + if (self->magic != MAGIC_Q) { + /* TODO */ + return NULL; + } + if (self->count <= 0 || !self->head || !self->tail) { + /* TODO */ + return NULL; + } + self->count--; + m = self->head; + self->head = self->head->next; + if (self->head == NULL) { + self->tail = NULL; + if (self->count) { + /* TODO */ + self->count = 0; + } + } + m->next = m->prev = NULL; + return m; +} + +/*-------------------------------------------------------------------------------*/ +pTaskMessage TaskQueueRecvMine(pTaskMan self) +{ + return TaskQueueRecv(self->pCurrent->pQueue); +} +/*-------------------------------------------------------------------------------*/ +static pTaskMessage taskMessageInit(pTaskMessage self, int mType) +{ + if (self) { + if (self->magic == MAGIC_M) { + /* TODO */; + } + self->magic = MAGIC_M; + self->next = NULL; + self->prev = NULL; + self->owner = NULL; + self->mType = mType; + self->pData = NULL; + } + return self; +} + +/*-------------------------------------------------------------------------------*/ +pTaskMessage TaskMessageAlloc(size_t mSize, int mType) +{ + pTaskMessage self = (pTaskMessage) calloc(1, sizeof(TaskMessage) + mSize); + if (self) { + self = taskMessageInit(self, mType); + TaskMessageSetData(self, &self[1]); /* pointer to data beyond this structure */ + } + return self; +} + +/*-------------------------------------------------------------------------------*/ +int TaskMessageFree(pTaskMessage self) { + if (self == NULL) { + /* TODO */ + return -1; + } + if (self->magic != MAGIC_M) { + /* TODO */ + } + if (self->pData) { + /* TODO */ + } + self->magic = 0; + free(self); + return 0; +} + +/*-------------------------------------------------------------------------------*/ +int TaskMessageGetType(pTaskMessage self) +{ + if (self) + return self->mType; + return 0; +} + +/*-------------------------------------------------------------------------------*/ +void TaskMessageSetType(pTaskMessage self, int mType) +{ + if (self) + self->mType = mType; +} + +/*-------------------------------------------------------------------------------*/ +void * TaskMessageGetData(pTaskMessage self) +{ + if (self) + return self->pData; + return NULL; +} + +/*-------------------------------------------------------------------------------*/ +void TaskMessageSetData(pTaskMessage self, void *pData) +{ + if (self) + self->pData = pData; +} diff --git a/task.h b/task.h index 03d6636c..d95f5fd2 100644 --- a/task.h +++ b/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 seconds + */ +/*--------------------------------------------------------------------------*/ +void TaskRunMeEvery(pTaskMan self, double delay); +/* + * Run this task every 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 diff --git a/taskobj.c b/taskobj.c index 3a3757b8..9f2cd2b8 100644 --- a/taskobj.c +++ b/taskobj.c @@ -2,7 +2,7 @@ * This is the SICS interface object to the tasker module * * copyright: GPL - * + * * Mark Koennecke, December 2012 */ #include @@ -15,6 +15,37 @@ typedef struct { char *scriptName; SConnection *con; } TclFunc, *pTclFunc; + +/*-------------------------------------------------------------------------*/ +void TaskObjLogFunc(eTaskLogLevel lvl, const char *buf) +{ + OutCode eOut; + + switch (lvl) { + case eTaskLogNone: + return; + case eTaskLogInfo: + eOut = eValue; + break; + case eTaskLogDebug: + eOut = eValue; + break; + case eTaskLogWarning: + eOut = eWarning; + break; + case eTaskLogError: + eOut = eError; + break; + case eTaskLogFatal: + eOut = eError; + break; + default: + eOut = eValue; + break; + } + SICSLogWrite(buf, eOut); + 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); - + } diff --git a/trace.c b/trace.c index db2dade1..aa1da596 100644 --- a/trace.c +++ b/trace.c @@ -191,15 +191,11 @@ static int strrepc(char *pszStr, char cFrom, char cTo) /*----------------------------------------------------------------*/ - while( 0 != ( ptr = strchr( pszStr, cFrom ) ) ) - - { /* WHILE cFrom occurs in pszStr */ - - pszStr[ (int) ptr - (int) pszStr ] = cTo ; - - /*- Replace next cFrom with cTo */ - - iReturn++ ; /*- count */ + for (ptr = pszStr; ptr && *ptr; ++ptr) { + if (*ptr == cFrom) { + *ptr = cTo; + ++iReturn; + } } return( iReturn ) ; @@ -286,12 +282,13 @@ void traceCommand(char *id, char *format, ...) va_end(argptr); if(len >= sizeof(buffer)){ buf = malloc(len+1); - memset(buf,0,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); @@ -471,7 +468,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); } } } @@ -514,7 +511,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; } From 8394e52393db154e1878a7e9c1c4d447ba23f752 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 8 Sep 2015 08:30:11 +0200 Subject: [PATCH 07/39] Fixed comment in countersec.c --- countersec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/countersec.c b/countersec.c index 2ec4f3e8..9ddbcb1a 100644 --- a/countersec.c +++ b/countersec.c @@ -192,6 +192,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]; } From 0d58ba2ef7ba04b8d73de05d61b86d27b438212e Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Mon, 7 Dec 2015 14:38:11 +0100 Subject: [PATCH 08/39] Some bug fixes: - 0.0 rather then -777.77 for a missing value in four circle - No error output in TAS --- fourmess.c | 2 +- interface.c | 2 +- interface.h | 2 +- sicshipadaba.c | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fourmess.c b/fourmess.c index 0fc084db..d5090529 100644 --- a/fourmess.c +++ b/fourmess.c @@ -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) { diff --git a/interface.c b/interface.c index 6f84a604..3430fb37 100644 --- a/interface.c +++ b/interface.c @@ -260,7 +260,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; } diff --git a/interface.h b/interface.h index 6753084e..3af14a9c 100644 --- a/interface.h +++ b/interface.h @@ -64,7 +64,7 @@ int running; 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 (*Pause)(void *self, SConnection *pCon); diff --git a/sicshipadaba.c b/sicshipadaba.c index 2de8ab68..81c2d024 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -4238,7 +4238,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", From a630a30294f77792d34c21ba57a6d4774291fcf8 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 26 Jan 2016 11:50:32 +0100 Subject: [PATCH 09/39] Some things about make_gen --- make_gen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make_gen b/make_gen index bbba4864..7018008d 100644 --- a/make_gen +++ b/make_gen @@ -47,7 +47,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\ singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.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 MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o From b1cda3f579b7af69663c6f7adf220f68a144813e Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Wed, 3 Feb 2016 10:43:36 +0100 Subject: [PATCH 10/39] First incarnation of the logging code --- logv2.c | 486 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ logv2.h | 60 +++++++ make_gen | 2 +- ofac.c | 1 + 4 files changed, 548 insertions(+), 1 deletion(-) create mode 100644 logv2.c create mode 100644 logv2.h diff --git a/logv2.c b/logv2.c new file mode 100644 index 00000000..93cc567d --- /dev/null +++ b/logv2.c @@ -0,0 +1,486 @@ +/* + 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 +#include +#include +#include +#include +#include +#include +#include +#include +/*============================================================================== + 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]; + +/*================ The default log level =======================================*/ +static unsigned int globalLogLevel = 7; +/*========= The list of sub systems for which full logging is enabled ==========*/ +static int subList; +/*================== Callback management =======================================*/ +typedef struct { + LogCallback func; + void *userData; +} LogCBData; + +static int callbackList; +/*----------------------------------------------------------------------------*/ +static void formatTimeStamp(char *buffer, unsigned int bufferLength, unsigned int small) +{ + struct timeval tv; + struct tm *time; + int year, month, day, hour, min, sec, usec; + char delim = '-'; + + gettimeofday(&tv, NULL); + time = localtime(&tv.tv_sec); + 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(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; +} +/*----------------------------------------------------------------------------*/ +static void LogClose(void *data) +{ + if(logFile != NULL){ + fclose(logFile); + } + logFile = NULL; + lineCount = 0; + strcpy(logFilename,"undefined"); +} +/*----------------------------------------------------------------------------*/ +static void checkLogFile(void) +{ + char *filename = NULL; + + /* + close when full + */ + if(logFile != NULL && lineCount >= MAXFILELINES){ + LogClose(NULL); + } + + /* + start a new log file + */ + if(logFile == NULL){ + filename = makeLogFileName(); + if(filename != NULL){ + logFile = fopen(filename,"w"); + strncpy(logFilename,filename,sizeof(logFilename)); + free(filename); + } + } +} +/*----------------------------------------------------------------------------*/ +static void writeLog(char *logMessage) +{ + int nChar; + + if(logMessage == NULL){ + return; + } + + + if(logFile != NULL){ + nChar = fprintf(logFile,"%s\n",logMessage); + lineCount++; + } + +} +/*----------------------------------------------------------------------------*/ +static unsigned int logFilter(unsigned int severity, const char *subsystem) +{ + int status; + char buffer[1024]; + + /* + If it is in the list of enabled subsystems, everything is logged + */ + status = LLDnodePtr2First(subList); + while (status == 1) { + LLDstringData(subList, buffer); + if(strcmp(buffer,subsystem) == 0) { + return 0; + } + status = LLDnodePtr2Next(subList); + } + + /* + test against the global log level + */ + if(severity >= globalLogLevel){ + return 1; + } + return 0; +} +/*=============================================================================*/ +static 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); +} +/*---------------------------------------------------------------------------- +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, + 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); + } + +} +/*----------------------------------------------------------------------------*/ +void Log(unsigned int severity, const char *subsystem,const char *format,...) +{ + char severityTXT[60]; + char timeStamp[132]; + char logData[2024], logLine[3072]; + char *dynMessage = NULL, *logMessage, *fullMessage = NULL; + va_list ap; + int dataLength; + + + formatSeverity(severity,severityTXT,sizeof(severityTXT)); + formatTimeStamp(timeStamp,sizeof(timeStamp),0); + + checkLogFile(); + + /* + 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; + } + } + + notifyListeners(severity,subsystem,timeStamp, logMessage); + + + if(logFilter(severity,subsystem) == 1){ + if(dynMessage != NULL){ + free(dynMessage); + } + return; + } + + fullMessage = formatLogLine(timeStamp,severityTXT,subsystem, + logMessage, logLine, sizeof(logLine)); + + writeLog(fullMessage); + + + /* + clean up + */ + if(dynMessage != NULL){ + free(dynMessage); + } + if(fullMessage != logLine){ + free(fullMessage); + } + +} +/*--------------------------------------------------------------------------------*/ +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; +} +/*------------------------------------------------------------------------------*/ +static void DisableSub(char *sub) +{ + int status; + char buffer[1024]; + + status = LLDnodePtr2First(subList); + while (status == 1) { + LLDstringData(subList, buffer); + if(strcmp(buffer,sub) == 0) { + LLDstringDelete(subList); + } + status = LLDnodePtr2Next(subList); + } +} +/*------------------------------------------------------------------------------*/ +static pDynString ListEnabled(void) +{ + int status; + char buffer[1024]; + pDynString result = CreateDynString(64,64); + + if(result == NULL){ + return NULL; + } + + status = LLDnodePtr2First(subList); + while (status == 1) { + LLDstringData(subList, buffer); + DynStringConcat(result,buffer); + DynStringConcatChar(result,':'); + status = LLDnodePtr2Next(subList); + } + 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; + 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)); + 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; + } + LLDstringAppend(subList,argv[2]); + SCSendOK(pCon); + } else { + SCWrite(pCon,"ERROR: need subsystem argument for enable",eError); + return 0; + } + }else if (strcmp(argv[1],"disable") == 0) { + if(argc > 2){ + DisableSub(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 Logv2Init(void) +{ + subList = LLDstringCreate(); + callbackList = LLDcreate(sizeof(LogCBData)); + strcpy(logTemplate,"unconfiguredLogTemplate"); + + AddCmd("log", LogAction); + AddCommand(pServ->pSics,"logconfig", LogConfigAction, + LogClose, NULL); +} diff --git a/logv2.h b/logv2.h new file mode 100644 index 00000000..f8779bf6 --- /dev/null +++ b/logv2.h @@ -0,0 +1,60 @@ +/* + 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 + +#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 */ + +/* 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,...); + +/* 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); + +#endif diff --git a/make_gen b/make_gen index f44212af..b69e32c9 100644 --- a/make_gen +++ b/make_gen @@ -47,7 +47,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\ singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \ messagepipe.o sicsget.o remoteobject.o pmacprot.o charbychar.o binprot.o \ - cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o + cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o logv2.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/ofac.c b/ofac.c index ad08da80..e6bcdec5 100644 --- a/ofac.c +++ b/ofac.c @@ -55,6 +55,7 @@ static void InitGeneral(void) INIT(MakeTrace); INIT(InitTaskOBJ); INIT(RemoteObjectInit); + INIT(Logv2Init); INIT(SiteInit); /* site specific initializations */ } From 66466c1c0f7d2b208a30ea3aa0d8d58930b5ac09 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Thu, 11 Feb 2016 13:40:31 +0100 Subject: [PATCH 11/39] This is the first working version of the new logging system. Some work in fine tuning still needs to be done. But is reasonably OK now. --- SCinter.c | 15 +- SICSmain.c | 5 +- asyncprotocol.c | 11 +- asyncqueue.c | 89 +++---- commandlog.c | 652 ------------------------------------------------ commandlog.h | 22 -- conman.c | 339 +++++++------------------ counter.c | 2 +- danu.c | 2 +- devexec.c | 1 - evcontroller.c | 3 +- exebuf.c | 1 - exeman.c | 4 +- histmem.c | 4 +- intserv.c | 1 - logv2.c | 37 ++- logv2.h | 9 + macro.c | 29 ++- make_gen | 6 +- maximize.c | 1 - motor.c | 1 - network.c | 13 +- nread.c | 42 ++-- nserver.c | 5 +- nxscript.c | 2 + obdes.c | 7 +- ofac.c | 2 - oscillate.c | 11 +- outcode.c | 59 +++-- outcode.h | 35 +++ perfmon.c | 7 +- protocol.c | 18 +- remob.c | 6 +- remoteobject.c | 2 +- scan.c | 16 +- scriptcontext.c | 15 +- servlog.c | 610 -------------------------------------------- servlog.h | 40 --- sics.h | 2 +- sicscron.c | 1 - sicsget.c | 2 +- sicshipadaba.c | 3 - sicvar.c | 6 +- simdriv.c | 4 +- simev.c | 5 +- sinfox.c | 2 +- stack_trace.c | 8 +- statemon.c | 8 +- status.c | 2 +- taskobj.c | 16 +- telnet.c | 11 +- trace.c | 59 +++-- uselect.c | 3 +- varlog.c | 1 - velo.c | 4 +- velosim.c | 4 +- 56 files changed, 420 insertions(+), 1845 deletions(-) delete mode 100644 commandlog.c delete mode 100644 commandlog.h create mode 100644 outcode.h delete mode 100644 servlog.c delete mode 100644 servlog.h diff --git a/SCinter.c b/SCinter.c index 87695dc8..698ab222 100644 --- a/SCinter.c +++ b/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,7 +294,7 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText) assert(self); assert(pCon); - /* write info to Log */ + /* write info to Log if (pCon->sockHandle >= 0) { snprintf(pBueffel,1023, "Executing -> %s <- from socket %d", pText, pCon->sockHandle); @@ -306,6 +304,11 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText) SICSLogWrite(pBueffel, eCommand); } + TODO: disabled for now. This is a duplication of what is logged in SCInvoke. + + Mark Koennecke, February 2016 + */ + if(strstr(pText,tclescape) == pText){ return TclExecFunc(pCon,self,NULL,pText); } @@ -361,7 +364,7 @@ int InterpExecute(SicsInterp * self, SConnection * pCon, char *pText) * log in history if succesfull */ if(iRet == 1){ - WriteCommandHistory(pText); + Log(DEBUG,"history","%s",pText); } diff --git a/SICSmain.c b/SICSmain.c index 3df779cc..bf707aaa 100644 --- a/SICSmain.c +++ b/SICSmain.c @@ -22,7 +22,8 @@ #include #include #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 diff --git a/asyncprotocol.c b/asyncprotocol.c index cdfeae05..f9aa909b 100644 --- a/asyncprotocol.c +++ b/asyncprotocol.c @@ -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; } diff --git a/asyncqueue.c b/asyncqueue.c index f42684e8..ed16849f 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -207,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) @@ -222,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); @@ -240,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 */ @@ -251,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 */ @@ -264,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; @@ -280,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 @@ -290,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); } @@ -310,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 */ @@ -323,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; @@ -344,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; @@ -393,10 +393,7 @@ 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); } } } @@ -504,9 +501,7 @@ 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); } if (myCmd->retries > 0) { --myCmd->retries; @@ -530,7 +525,7 @@ 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); @@ -542,7 +537,7 @@ 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; @@ -572,9 +567,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", + "Received:%s:%s", self->queue_name,myCmd->tran->inp_buf); } PopCommand(self); break; @@ -582,18 +576,10 @@ 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 */ + Log(ERROR,"ASQUIO","SENT:%s:Received:%s",myCmd->tran->out_buf, myCmd->tran->inp_buf); break; } } @@ -601,30 +587,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; } @@ -638,7 +620,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)); @@ -657,7 +639,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)); @@ -679,7 +661,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)); @@ -714,7 +696,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; } @@ -733,7 +715,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; @@ -831,9 +813,8 @@ 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); + Log(DEBUG,"ASQUIO" + "Output Trace on AsyncQueue %s:%s", unit->queue->queue_name, buffer); } sock = AsyncUnitGetSocket(unit); iRet = NETWrite(sock, buffer, buflen); @@ -1399,7 +1380,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; } diff --git a/commandlog.c b/commandlog.c deleted file mode 100644 index 06d5bd54..00000000 --- a/commandlog.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#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, TASK_PRIO_HIGH); - 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; -} diff --git a/commandlog.h b/commandlog.h deleted file mode 100644 index 82293f79..00000000 --- a/commandlog.h +++ /dev/null @@ -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 diff --git a/conman.c b/conman.c index 0046f3c0..37609650 100644 --- a/conman.c +++ b/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 */ @@ -660,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); } @@ -748,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 { @@ -762,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) { @@ -827,56 +800,69 @@ 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; - - 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 + */ + 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(INFO,"notify",buffer); + } + break; + case eHdbEvent: + case eHdbValue: + Log(INFO,"notify","%s",buffer); + break; + case eLog: + Log(INFO,"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)){ + Log(ERROR,"com","sock%03.3d:%s",self->sockHandle,buffer); + } + break; + case eWarning: + if(!SCinMacro(self)){ + Log(WARN,"com","sock%03.3d:%s",self->sockHandle,buffer); + } + break; + case eValue: + if(!SCinMacro(self)){ + Log(INFO,"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) { @@ -891,13 +877,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); @@ -918,10 +898,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); @@ -946,10 +923,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); @@ -986,11 +960,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); /* @@ -999,8 +969,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)); @@ -1078,9 +1047,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); @@ -1138,7 +1105,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 */ @@ -1212,12 +1179,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); @@ -1694,7 +1657,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; } } @@ -1739,7 +1702,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; } } @@ -1840,10 +1803,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); } @@ -2004,19 +1967,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); @@ -2279,114 +2232,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: @@ -2437,7 +2285,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; @@ -2516,22 +2364,11 @@ 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 { diff --git a/counter.c b/counter.c index d01de97c..72c8aeac 100644 --- a/counter.c +++ b/counter.c @@ -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; } /*------------------------------------------------------------------------*/ diff --git a/danu.c b/danu.c index f19410e8..2fbce6d0 100644 --- a/danu.c +++ b/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; } diff --git a/devexec.c b/devexec.c index 8fd81cea..dcea95e0 100644 --- a/devexec.c +++ b/devexec.c @@ -67,7 +67,6 @@ #include "devexec.h" #include "status.h" #include "lld.h" -#include "commandlog.h" #include "ifile.h" /* diff --git a/evcontroller.c b/evcontroller.c index f1120b5c..e5542976 100644 --- a/evcontroller.c +++ b/evcontroller.c @@ -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 */ diff --git a/exebuf.c b/exebuf.c index aefa8b7c..e76855cf 100644 --- a/exebuf.c +++ b/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 */ diff --git a/exeman.c b/exeman.c index 55ae402a..359a990d 100644 --- a/exeman.c +++ b/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) { diff --git a/histmem.c b/histmem.c index 8e106428..e7923999 100644 --- a/histmem.c +++ b/histmem.c @@ -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; diff --git a/intserv.c b/intserv.c index e0a92e0f..1e9c7d20 100644 --- a/intserv.c +++ b/intserv.c @@ -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" diff --git a/logv2.c b/logv2.c index 93cc567d..cc10b6c4 100644 --- a/logv2.c +++ b/logv2.c @@ -24,9 +24,11 @@ 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 = 7; +static unsigned int globalLogLevel = 4; /*========= The list of sub systems for which full logging is enabled ==========*/ static int subList; /*================== Callback management =======================================*/ @@ -79,7 +81,7 @@ static char *makeLogFileName(void) return filename; } /*----------------------------------------------------------------------------*/ -static void LogClose(void *data) +void LogClose(void *data) { if(logFile != NULL){ fclose(logFile); @@ -93,6 +95,10 @@ static void checkLogFile(void) { char *filename = NULL; + if(logDisabled || logConfigured == 0){ + return; + } + /* close when full */ @@ -116,11 +122,21 @@ static void checkLogFile(void) 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); @@ -134,6 +150,11 @@ static unsigned int logFilter(unsigned int severity, const char *subsystem) int status; char buffer[1024]; + if(logDisabled || logConfigured == 0){ + return 1; + } + + /* If it is in the list of enabled subsystems, everything is logged */ @@ -146,12 +167,14 @@ static unsigned int logFilter(unsigned int severity, const char *subsystem) status = LLDnodePtr2Next(subList); } + /* test against the global log level */ - if(severity >= globalLogLevel){ + if(severity > globalLogLevel){ return 1; } + return 0; } /*=============================================================================*/ @@ -246,7 +269,7 @@ void Log(unsigned int severity, const char *subsystem,const char *format,...) { char severityTXT[60]; char timeStamp[132]; - char logData[2024], logLine[3072]; + char logData[2024], logLine[3072], *pPtr = NULL; char *dynMessage = NULL, *logMessage, *fullMessage = NULL; va_list ap; int dataLength; @@ -415,6 +438,7 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, } 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); @@ -474,6 +498,11 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, return 1; } /*-----------------------------------------------------------------------------*/ +void DisableLog(void) +{ + logDisabled = 1; +} +/*-----------------------------------------------------------------------------*/ void Logv2Init(void) { subList = LLDstringCreate(); diff --git a/logv2.h b/logv2.h index f8779bf6..5029e6fc 100644 --- a/logv2.h +++ b/logv2.h @@ -57,4 +57,13 @@ typedef void (*LogCallback)(unsigned int severity, const char *timeStamp, void RegisterLogCallback(LogCallback func, void *userData); void RemoveLogCallback(LogCallback func); +/* + *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); + #endif diff --git a/macro.c b/macro.c index d7b39ad1..a27a84fc 100644 --- a/macro.c +++ b/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); } @@ -604,7 +608,7 @@ int InternalFileEval(SConnection * pCon, SicsInterp * pInter, void *pData, The output code is optional and and defaults to eStatus. ---------------------------------------------------------------------------*/ -#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); diff --git a/make_gen b/make_gen index b69e32c9..7abeb42d 100644 --- a/make_gen +++ b/make_gen @@ -10,7 +10,7 @@ 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 \ @@ -21,7 +21,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.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\ 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\ @@ -47,7 +47,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ histmemsec.o sansbc.o sicsutil.o strlutil.o genbinprot.o trace.o\ singlebinb.o taskobj.o sctcomtask.o tasmono.o multicountersec.o \ messagepipe.o sicsget.o remoteobject.o pmacprot.o charbychar.o binprot.o \ - cnvrt.o tclClock.o tclDate.o tclUnixTime.o stack_trace.o logv2.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 diff --git a/maximize.c b/maximize.c index 8be3b4ec..f74e1bf6 100644 --- a/maximize.c +++ b/maximize.c @@ -50,7 +50,6 @@ #include "motor.h" #define MAXPTS 100 -#define DEBUG 0 typedef struct __MAXIMIZE { pObjectDescriptor pDes; diff --git a/motor.c b/motor.c index 458614f0..76ec8b00 100644 --- a/motor.c +++ b/motor.c @@ -56,7 +56,6 @@ #include "motor.h" #include "splitter.h" #include "status.h" -#include "servlog.h" #include "tclmotdriv.h" #include "site.h" /*------------------------------------------------------------------------- diff --git a/network.c b/network.c index 944ecacf..b77e382a 100644 --- a/network.c +++ b/network.c @@ -52,7 +52,6 @@ #include #include #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 ------------------------------------ diff --git a/nread.c b/nread.c index 476ab22f..2b68f8a5 100644 --- a/nread.c +++ b/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,7 +217,7 @@ 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; @@ -266,9 +264,7 @@ static int NetReadRead(pNetRead self, pNetItem pItem) 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 +359,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,8 +367,7 @@ 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; } @@ -467,9 +462,6 @@ 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); if (iInt == eEndServer) { TaskStop(self->pMain->pTasker); } @@ -627,7 +619,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 +698,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)); } /* @@ -1043,8 +1035,6 @@ static int testAndInvokeInterrupt(pCommandCBData self, int handle) 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 +1105,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; @@ -1301,8 +1291,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 +1312,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 +1325,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; } @@ -1356,7 +1345,6 @@ 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); } /*------------------------------------------------------------------------------------*/ diff --git a/nserver.c b/nserver.c index 5e2b0fcf..6d004c29 100644 --- a/nserver.c +++ b/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" @@ -124,7 +124,6 @@ int InitServer(char *file, pServer * pServ) 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 { @@ -265,7 +264,6 @@ int InitServer(char *file, pServer * pServ) strcpy(pBueffel, "restore"); SCInvoke(self->dummyCon, self->pSics, pBueffel); } - SetWriteHistory(1); INIT(StatusFileInit); @@ -376,6 +374,7 @@ void StopServer(pServer self) free(self); + LogClose(NULL); } /*------------------------------------------------------------------------*/ diff --git a/nxscript.c b/nxscript.c index 242ca32d..d624fdd1 100644 --- a/nxscript.c +++ b/nxscript.c @@ -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); diff --git a/obdes.c b/obdes.c index ce0b9bb6..54130cb9 100644 --- a/obdes.c +++ b/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; diff --git a/ofac.c b/ofac.c index e6bcdec5..df88921e 100644 --- a/ofac.c +++ b/ofac.c @@ -43,7 +43,6 @@ static void InitGeneral(void) INIT(LogSetupInit); INIT(InstallBackground); INIT(MakeProtocol); - INIT(CommandLogInit); INIT(UdpInit); INIT(HelpInit); INIT(AddTestProt); @@ -92,7 +91,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); diff --git a/oscillate.c b/oscillate.c index 19bc8e1d..5034d6b7 100644 --- a/oscillate.c +++ b/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; diff --git a/outcode.c b/outcode.c index 7b7f8f77..ab15f912 100644 --- a/outcode.c +++ b/outcode.c @@ -5,26 +5,41 @@ Mark Koennecke, November 1996 ----------------------------------------------------------------------------*/ -#ifndef POUTCODE -#define POUTCODE +#include "Scommon.h" +#include "outcode.h" +#include -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; +} diff --git a/outcode.h b/outcode.h new file mode 100644 index 00000000..a75be751 --- /dev/null +++ b/outcode.h @@ -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 diff --git a/perfmon.c b/perfmon.c index cc5c54c1..82abad67 100644 --- a/perfmon.c +++ b/perfmon.c @@ -41,7 +41,6 @@ #include #include "fortify.h" #include "sics.h" -#include "servlog.h" #include "perfmon.h" #include "perfmon.i" /*-------------------------------------------------------------------------*/ @@ -125,10 +124,6 @@ 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); } @@ -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; } diff --git a/protocol.c b/protocol.c index cf62e8e2..61188038 100644 --- a/protocol.c +++ b/protocol.c @@ -12,9 +12,8 @@ #include #include #include -#include +#include #include -#include "commandlog.h" #include "protocol.h" #include @@ -572,19 +571,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)) { diff --git a/remob.c b/remob.c index 55a3ae01..35eb4d98 100644 --- a/remob.c +++ b/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 @@ -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; } diff --git a/remoteobject.c b/remoteobject.c index 0e78a3a4..ffcf0609 100644 --- a/remoteobject.c +++ b/remoteobject.c @@ -476,7 +476,7 @@ static int HeartbeatTask(void *pData) termination. -----------------------------------------------------------------------------------*/ -#include +#include static OutCode findOutCode(char *txt) { int i; diff --git a/scan.c b/scan.c index 4e989264..0493471d 100644 --- a/scan.c +++ b/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 */ diff --git a/scriptcontext.c b/scriptcontext.c index f6deac5b..7d68abc6 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -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); @@ -838,7 +838,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); diff --git a/servlog.c b/servlog.c deleted file mode 100644 index 90ab59a8..00000000 --- a/servlog.c +++ /dev/null @@ -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 -#include "fortify.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#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: <<>> to %s\n", - timestamp(NULL, ':'), - filnam); - fclose(prevlog); - if (1 == iLogUsable) { - fprintf(fLogFile, "%s: <<>> from %s\n", - timestamp(NULL, ':'), - prevfilnam); - iLineCount++; - } - } - - if (1 == iLogUsable) { - if (iLineCount == 0) - fprintf(fLogFile, "%s: <<>>\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; -} diff --git a/servlog.h b/servlog.h deleted file mode 100644 index 99fafc0a..00000000 --- a/servlog.h +++ /dev/null @@ -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 diff --git a/sics.h b/sics.h index 9dce3623..f3108bee 100644 --- a/sics.h +++ b/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; diff --git a/sicscron.c b/sicscron.c index 0ad5ae63..d6740881 100644 --- a/sicscron.c +++ b/sicscron.c @@ -20,7 +20,6 @@ #include "sics.h" #include "splitter.h" #include "sicscron.h" -#include "commandlog.h" typedef struct { int iInterval; diff --git a/sicsget.c b/sicsget.c index f4feb803..a97fad46 100644 --- a/sicsget.c +++ b/sicsget.c @@ -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 = FindHdbNode(NULL,self->name,pServ->dummyCon); if(node != NULL){ geterror = GetHdbProp(node,"geterror"); if(geterror != NULL){ diff --git a/sicshipadaba.c b/sicshipadaba.c index b10a9a92..ae8d4e3e 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -38,7 +38,6 @@ #include #include "sicsobj.h" #include -#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(); } diff --git a/sicvar.c b/sicvar.c index dbf496d8..56ca48e9 100644 --- a/sicvar.c +++ b/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); } diff --git a/simdriv.c b/simdriv.c index 0f123a6a..66b088c3 100644 --- a/simdriv.c +++ b/simdriv.c @@ -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) { diff --git a/simev.c b/simev.c index 84349012..03535470 100644 --- a/simev.c +++ b/simev.c @@ -43,10 +43,9 @@ #include #include #include - +#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) { diff --git a/sinfox.c b/sinfox.c index 8b7874ad..833e2d83 100644 --- a/sinfox.c +++ b/sinfox.c @@ -14,7 +14,7 @@ #include /* incl. SCWrite */ #include #include -#include +#include #include #include "sinfox.h" diff --git a/stack_trace.c b/stack_trace.c index 911994ca..56f8dce5 100644 --- a/stack_trace.c +++ b/stack_trace.c @@ -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, (long int)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); diff --git a/statemon.c b/statemon.c index 56b0ca8e..06171088 100644 --- a/statemon.c +++ b/statemon.c @@ -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); diff --git a/status.c b/status.c index db5c61a9..32556b6e 100644 --- a/status.c +++ b/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; } diff --git a/taskobj.c b/taskobj.c index 371e177d..fa69befe 100644 --- a/taskobj.c +++ b/taskobj.c @@ -19,31 +19,31 @@ typedef struct { /*-------------------------------------------------------------------------*/ void TaskObjLogFunc(eTaskLogLevel lvl, const char *buf) { - OutCode eOut; + unsigned int severity; switch (lvl) { case eTaskLogNone: return; case eTaskLogInfo: - eOut = eValue; + severity = INFO; break; case eTaskLogDebug: - eOut = eValue; + severity = DEBUG; break; case eTaskLogWarning: - eOut = eWarning; + severity = WARN; break; case eTaskLogError: - eOut = eError; + severity = ERROR; break; case eTaskLogFatal: - eOut = eError; + severity = FATAL; break; default: - eOut = eValue; + severity = DEBUG; break; } - SICSLogWrite((char *)buf, eOut); + Log(severity, "task","%s",(char *)buf); return; } /*-------------------------------------------------------------------------*/ diff --git a/telnet.c b/telnet.c index fe23e39d..41d3171a 100644 --- a/telnet.c +++ b/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; @@ -273,7 +271,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 +280,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,"com","%s",pBuffer); SendWelcome(self->pCon); SCSetRights(self->pCon, iRet); self->iLogin = 1; diff --git a/trace.c b/trace.c index a9ae51ee..f9e8af9f 100644 --- a/trace.c +++ b/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 @@ -203,20 +207,34 @@ static int strrepc(char *pszStr, char cFrom, char cTo) /*-----------------------------------------------------------------*/ void traceprint(char *sub, char *id, char *data) { - char *mysub, *myid, *mydata; + /* 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); + /* 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,"par") != NULL){ + severity = INFO; + } else { + severity = DEBUG; } + Log(severity,sub,"%s:%s",id,data); } /*-----------------------------------------------------------------*/ void traceIO(char *id, char *format, ...) @@ -558,13 +576,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 +595,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; } diff --git a/uselect.c b/uselect.c index 8f8f9cfb..73246825 100644 --- a/uselect.c +++ b/uselect.c @@ -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; } diff --git a/varlog.c b/varlog.c index 910acaa2..633ebe34 100644 --- a/varlog.c +++ b/varlog.c @@ -56,7 +56,6 @@ #include "lld.h" #include "sics.h" #include "varlog.h" -#include "commandlog.h" #include "circular.h" #include "sicsdata.h" diff --git a/velo.c b/velo.c index 500d60e2..0f509f22 100644 --- a/velo.c +++ b/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; } diff --git a/velosim.c b/velosim.c index 32eb85bc..cef52133 100644 --- a/velosim.c +++ b/velosim.c @@ -45,9 +45,9 @@ #include #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) { From 0da0380c8a1229b224ff2debdb4e122fa3c6c526 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Mon, 15 Feb 2016 11:38:23 +0100 Subject: [PATCH 12/39] Fine tuning of second generation motor and counter parameter update messages Changed paramete rupdates to verbose severity --- countersec.c | 14 ++++++++++++-- motorsec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ trace.c | 2 +- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/countersec.c b/countersec.c index 42ee582c..98da93ac 100644 --- a/countersec.c +++ b/countersec.c @@ -39,6 +39,7 @@ 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); } } @@ -98,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, @@ -106,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; @@ -308,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) @@ -338,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); } /*--------------------------------------------------------------------------*/ @@ -585,15 +591,19 @@ static hdbCallbackReturn SecStatusCallback(pHdb node, void *userData, { 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) { - v = *mm->v; 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; @@ -684,7 +694,7 @@ pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) return NULL; } AppendHipadabaCallback(child, - MakeHipadabaCallback(SecStatusCallback, NULL, + MakeHipadabaCallback(SecStatusCallback, pRes, NULL)); AddHipadabaChild(node, child, NULL); diff --git a/motorsec.c b/motorsec.c index d33e7076..3bb14849 100644 --- a/motorsec.c +++ b/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; } } @@ -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); diff --git a/trace.c b/trace.c index f9e8af9f..2ae4c3d1 100644 --- a/trace.c +++ b/trace.c @@ -230,7 +230,7 @@ void traceprint(char *sub, char *id, char *data) } else if(strstr(sub,"com") != NULL){ severity = INFO; } else if(strstr(sub,"par") != NULL){ - severity = INFO; + severity = VERBOSE; } else { severity = DEBUG; } From 40382b2b8ccabb04fd6586adcf4f7c02072faea7 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 1 Mar 2016 09:42:16 +0100 Subject: [PATCH 13/39] Further enhancements to the new logging system I removed traceCommand because I needed a more fine grained control of what goes into the log. --- conman.c | 178 ++++++++---------------------------------------- exebuf.c | 2 +- logv2.c | 4 +- logv2.h | 16 +++++ make_gen | 4 +- makefile_slinux | 2 +- nread.c | 5 +- trace.c | 39 ++--------- trace.h | 1 - 9 files changed, 60 insertions(+), 191 deletions(-) diff --git a/conman.c b/conman.c index 37609650..6bb165c9 100644 --- a/conman.c +++ b/conman.c @@ -803,9 +803,18 @@ static int isOK(const char *buffer) /*--------------------------------------------------------------------------*/ static void testAndWriteLog(SConnection * self, char *buffer, int iOut) { + unsigned int severity; + /* 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); @@ -836,24 +845,32 @@ static void testAndWriteLog(SConnection * self, char *buffer, int iOut) Log(INFO,"notify","%s",buffer); break; case eLog: - Log(INFO,"com","sock%03.3d:%s",self->sockHandle,buffer); + 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)){ - Log(ERROR,"com","sock%03.3d:%s",self->sockHandle,buffer); + 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)){ - Log(WARN,"com","sock%03.3d:%s",self->sockHandle,buffer); + 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(INFO,"com","sock%03.3d:%s",self->sockHandle,buffer); + Log(severity,"com","sock%03.3d:%s",self->sockHandle,buffer); } break; default: @@ -1223,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 @@ -1326,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)); @@ -1401,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); @@ -1416,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) { @@ -1831,7 +1707,11 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand) return 0; } strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN); - traceCommand(ConID(self),"in:%s", pCommand); + 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 */ diff --git a/exebuf.c b/exebuf.c index e76855cf..aed2278d 100644 --- a/exebuf.c +++ b/exebuf.c @@ -301,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) { diff --git a/logv2.c b/logv2.c index cc10b6c4..891f1ea7 100644 --- a/logv2.c +++ b/logv2.c @@ -145,7 +145,7 @@ static void writeLog(char *logMessage) } /*----------------------------------------------------------------------------*/ -static unsigned int logFilter(unsigned int severity, const char *subsystem) +unsigned int logFilter(unsigned int severity, const char *subsystem) { int status; char buffer[1024]; @@ -178,7 +178,7 @@ static unsigned int logFilter(unsigned int severity, const char *subsystem) return 0; } /*=============================================================================*/ -static void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength) +void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength) { static const char *severityText[] = {"FATAL", "ERROR", diff --git a/logv2.h b/logv2.h index 5029e6fc..ebd05881 100644 --- a/logv2.h +++ b/logv2.h @@ -57,6 +57,13 @@ typedef void (*LogCallback)(unsigned int severity, const char *timeStamp, 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); /* *Disable logging in support of the nolog option in SICSmain.c */ @@ -66,4 +73,13 @@ void DisableLog(void); */ 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); + #endif diff --git a/make_gen b/make_gen index 7abeb42d..b2b60a46 100644 --- a/make_gen +++ b/make_gen @@ -21,7 +21,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.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 udpquieck.o fourtable.o\ + uubuffer.o udpquieck.o fourtable.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\ @@ -53,7 +53,7 @@ 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 diff --git a/makefile_slinux b/makefile_slinux index 995207fe..900eb7ff 100644 --- a/makefile_slinux +++ b/makefile_slinux @@ -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 diff --git a/nread.c b/nread.c index 2b68f8a5..d23ced32 100644 --- a/nread.c +++ b/nread.c @@ -262,7 +262,6 @@ 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); Log(ERROR,"com","sock%03.3d:INTERRUPT", pItem->pCon->pSock->sockid); if (iInt == eEndServer) { @@ -461,7 +460,7 @@ static int TelnetRead(pNetRead self, pNetItem pItem) } } TaskSignal(self->pMain->pTasker, SICSINT, &iInt); - traceCommand(ConID(pItem->pCon),"interrupt: %d",iInt); + Log(ERROR,"com","%s:interrupt: %d", ConID(pItem->pCon),iInt); if (iInt == eEndServer) { TaskStop(self->pMain->pTasker); } @@ -1031,7 +1030,7 @@ 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); diff --git a/trace.c b/trace.c index 2ae4c3d1..45d39423 100644 --- a/trace.c +++ b/trace.c @@ -288,32 +288,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; @@ -557,12 +531,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) diff --git a/trace.h b/trace.h index 24a266d5..d2265798 100644 --- a/trace.h +++ b/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); From 5a388ab741b9e052c04cfb30cd6de7cd59b3011f Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 8 Mar 2016 11:36:29 +0100 Subject: [PATCH 14/39] Made all sub systems for logging lower case Log filtering is now based on an array of severitys per subsystem Added a LogIS call which takes an integer for the subsystem Added a LogTS call which allows to specify a user supplied time stamp --- asyncprotocol.c | 10 +- asyncqueue.c | 64 ++++----- conman.c | 15 +- logv2.c | 366 ++++++++++++++++++++++++++++++++++-------------- logv2.h | 42 ++++++ network.c | 2 +- 6 files changed, 347 insertions(+), 152 deletions(-) diff --git a/asyncprotocol.c b/asyncprotocol.c index f9aa909b..4c3db696 100644 --- a/asyncprotocol.c +++ b/asyncprotocol.c @@ -81,7 +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) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncProtocol::defaultPrepareTxn"); + Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::defaultPrepareTxn"); return 0; } memcpy(txn->out_buf, cmd, cmd_len + 1); @@ -90,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) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncProtocol::defaultPrepareTxn", + Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::defaultPrepareTxn", eError); return 0; } @@ -173,7 +173,7 @@ static char *decodeTerminator(char *code) count = strlen(code); pResult = (char *) malloc(count + 1); if (!pResult) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncProtocol::decodeTerminator", + Log(ERROR,"asquio","%s","Out of memory in AsyncProtocol::decodeTerminator", eError); return NULL; } @@ -328,7 +328,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp * pSics, self = (pAsyncProtocol) malloc(sizeof(AsyncProtocol)); if (self == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncProtocolCreate"); + Log(ERROR,"asquio","%s","Out of memory in AsyncProtocolCreate"); return NULL; } memset(self, 0, sizeof(AsyncProtocol)); @@ -339,7 +339,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp * pSics, pKFunc = AsyncProtocolKill; iRet = AddCommand(pSics, (char *) protocolName, pFunc, pKFunc, self); if (!iRet) { - Log(ERROR,"ASQUIO","%s","AddCommand failed in AsyncProtocolCreate"); + Log(ERROR,"asquio","%s","AddCommand failed in AsyncProtocolCreate"); AsyncProtocolKill(self); return NULL; } diff --git a/asyncqueue.c b/asyncqueue.c index ed16849f..74b18538 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -207,7 +207,7 @@ static void AQ_Notify(pAsyncQueue self, int event) { pAsyncUnit unit; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function:%s:%s", 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) @@ -222,7 +222,7 @@ static int TimedReconnect(void *cntx, int mode) self->nw_tmr = 0; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function: %s:%s\n", self->queue_name, + Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name, __func__); AQ_Purge(self); @@ -240,7 +240,7 @@ static int TimedReconnect(void *cntx, int mode) if (iRet < 0) { snprintf(line, 132, "Failed reconnect on AsyncQueue '%s'", self->queue_name); - Log(DEBUG,"ASQUIO","%s",line); + Log(DEBUG,"asquio","%s",line); /* Timer for retry */ NetWatchSetMode(self->nw_ctx, 0); /* implement an exponential backoff within limits */ @@ -251,12 +251,12 @@ static int TimedReconnect(void *cntx, int mode) self->retryTimer = 16000; AQ_SetTimer(self, self->retryTimer, TimedReconnect, self); - Log(DEBUG,"ASQUIO", "In %s:%s: state %s => eAsyncWaiting", + 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); - Log(DEBUG,"ASQUIO", "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 */ @@ -264,11 +264,11 @@ static int TimedReconnect(void *cntx, int mode) return 1; } NetWatchSetMode(self->nw_ctx, nwatch_read); - Log(DEBUG,"ASQUIO", "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); - Log(DEBUG,"ASQUIO","%s",line); + Log(DEBUG,"asquio","%s",line); AQ_Purge(self); AQ_Notify(self, AQU_RECONNECT); return 1; @@ -280,7 +280,7 @@ static int AQ_Reconnect(pAsyncQueue self) char line[132]; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function: %s:%s\n", self->queue_name, + Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name, __func__); /* * Remove any old timer @@ -290,7 +290,7 @@ static int AQ_Reconnect(pAsyncQueue self) if (self->state == eAsyncConnected) { self->state = eAsyncIdle; - Log(DEBUG,"ASQUIO", "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); } @@ -310,12 +310,12 @@ static int AQ_Reconnect(pAsyncQueue self) self->retryTimer = 125; /* initial delay */ AQ_SetTimer(self, self->retryTimer, TimedReconnect, self); - Log(DEBUG,"ASQUIO", "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); - Log(DEBUG,"ASQUIO", "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 */ @@ -323,11 +323,11 @@ static int AQ_Reconnect(pAsyncQueue self) return iRet; } NetWatchSetMode(self->nw_ctx, nwatch_read); - Log(DEBUG,"ASQUIO", "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); - Log(DEBUG,"ASQUIO",line); + Log(DEBUG,"asquio",line); AQ_Purge(self); AQ_Notify(self, AQU_RECONNECT); return 1; @@ -344,7 +344,7 @@ static int StartCommand(pAsyncQueue self) int iRet = 0; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function: %s:%s\n", self->queue_name, + Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name, __func__); if (myCmd == NULL) return OKOK; @@ -393,7 +393,7 @@ static int StartCommand(pAsyncQueue self) } else if (iRet > 0) { struct timeval tv; gettimeofday(&tv, NULL); - Log(ERROR, "ASQUIO","%d unsolicited chars in AsyncQueue %s",iRet, self->queue_name); + Log(ERROR, "asquio","%d unsolicited chars in AsyncQueue %s",iRet, self->queue_name); } } } @@ -501,7 +501,7 @@ static int CommandTimeout(void *cntx, int mode) if (self->trace) { struct timeval tv; gettimeofday(&tv, NULL); - Log(DEBUG,"ASQUIO", "Timeout Trace on AsyncQueue %s", self->queue_name); + Log(DEBUG,"asquio", "Timeout Trace on AsyncQueue %s", self->queue_name); } if (myCmd->retries > 0) { --myCmd->retries; @@ -525,7 +525,7 @@ static int DelayedStart(void *cntx, int mode) { pAsyncQueue self = (pAsyncQueue) cntx; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function: %s:%s\n", self->queue_name, + Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name, __func__); self->nw_tmr = 0; StartCommand(self); @@ -537,7 +537,7 @@ static int MyCallback(void *context, int mode) pAsyncQueue self = (pAsyncQueue) context; if (self->state != eAsyncConnected) - Log(DEBUG,"ASQUIO", "Function: %s:%s\n", self->queue_name, + Log(DEBUG,"asquio", "Function: %s:%s\n", self->queue_name, __func__); if (mode & nwatch_read) { int iRet; @@ -567,7 +567,7 @@ static int MyCallback(void *context, int mode) if (self->trace) { struct timeval tv; gettimeofday(&tv, NULL); - Log(INFO, "ASQUIO", + Log(INFO, "asquio", "Received:%s:%s", self->queue_name,myCmd->tran->inp_buf); } PopCommand(self); @@ -576,10 +576,10 @@ static int MyCallback(void *context, int mode) int excess = nchars - 1 - i; struct timeval tv; gettimeofday(&tv, NULL); - Log(ERROR,"ASQUIO", + Log(ERROR,"asquio", "Protocol error %d in AsyncQueue %s", iRet, self->queue_name); - Log(ERROR,"ASQUIO","SENT:%s:Received:%s",myCmd->tran->out_buf, myCmd->tran->inp_buf); + Log(ERROR,"asquio","SENT:%s:Received:%s",myCmd->tran->out_buf, myCmd->tran->inp_buf); break; } } @@ -587,7 +587,7 @@ static int MyCallback(void *context, int mode) int excess = nchars - 1 - i; struct timeval tv; gettimeofday(&tv, NULL); - Log(ERROR, "ASQUIO", "%d excess chars in AsyncQueue %s", + Log(ERROR, "asquio", "%d excess chars in AsyncQueue %s", excess, self->queue_name); /* TODO: handle unsolicited */ } @@ -595,7 +595,7 @@ static int MyCallback(void *context, int mode) int excess = nchars - 1 - i; struct timeval tv; gettimeofday(&tv, NULL); - Log(ERROR, "ASQUIO", "%d unsolicited chars in AsyncQueue %s", + Log(ERROR, "asquio", "%d unsolicited chars in AsyncQueue %s", excess, self->queue_name); /* TODO: handle unsolicited input */ } @@ -603,10 +603,10 @@ static int MyCallback(void *context, int mode) } if (mode & nwatch_write) { char line[132]; - Log(DEBUG,"ASQUIO", "Writeable socket callback on AsyncQueue %s", + Log(DEBUG,"asquio", "Writeable socket callback on AsyncQueue %s", self->queue_name); NetWatchSetMode(self->nw_ctx, nwatch_read); - Log(DEBUG,"ASQUIO", "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; } @@ -620,7 +620,7 @@ int AsyncUnitEnqueueHead(pAsyncUnit unit, pAsyncTxn context) assert(unit && unit->queue && unit->queue->protocol); myCmd = (pAQ_Cmd) malloc(sizeof(AQ_Cmd)); if (myCmd == NULL) { - Log(ERROR,"ASQUIO","Out of memory in AsyncUnitEnqueHead", eError); + Log(ERROR,"asquio","Out of memory in AsyncUnitEnqueHead", eError); return 0; } memset(myCmd, 0, sizeof(AQ_Cmd)); @@ -639,7 +639,7 @@ int AsyncUnitEnqueueTxn(pAsyncUnit unit, pAsyncTxn pTxn) assert(unit && unit->queue && unit->queue->protocol); myCmd = (pAQ_Cmd) malloc(sizeof(AQ_Cmd)); if (myCmd == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncUnitEnqueueTxn"); + Log(ERROR,"asquio","%s","Out of memory in AsyncUnitEnqueueTxn"); return 0; } memset(myCmd, 0, sizeof(AQ_Cmd)); @@ -661,7 +661,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, assert(unit); myTxn = (pAsyncTxn) malloc(sizeof(AsyncTxn)); if (myTxn == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncUnitPrepareTxn", eError); + Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn", eError); return NULL; } memset(myTxn, 0, sizeof(AsyncTxn)); @@ -696,7 +696,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, } else { myTxn->out_buf = (char *) malloc(cmd_len + 5); if (myTxn->out_buf == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncUnitPrepareTxn"); + Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn"); free(myTxn); return NULL; } @@ -715,7 +715,7 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, else { myTxn->inp_buf = malloc(rsp_len + 1); if (myTxn->inp_buf == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncUnitPrepareTxn", eError); + Log(ERROR,"asquio","%s","Out of memory in AsyncUnitPrepareTxn", eError); free(myTxn->out_buf); free(myTxn); return NULL; @@ -813,7 +813,7 @@ int AsyncUnitWrite(pAsyncUnit unit, void *buffer, int buflen) if (unit->queue->trace) { struct timeval tv; gettimeofday(&tv, NULL); - Log(DEBUG,"ASQUIO" + Log(DEBUG,"asquio" "Output Trace on AsyncQueue %s:%s", unit->queue->queue_name, buffer); } sock = AsyncUnitGetSocket(unit); @@ -1380,7 +1380,7 @@ int AsyncUnitCreateHost(const char *host, const char *port, unit = (pAsyncUnit) malloc(sizeof(AsyncUnit)); if (unit == NULL) { - Log(ERROR,"ASQUIO","%s","Out of memory in AsyncUnitCreateHost", eError); + Log(ERROR,"asquio","%s","Out of memory in AsyncUnitCreateHost", eError); *handle = NULL; return 0; } diff --git a/conman.c b/conman.c index 6bb165c9..0932bcfa 100644 --- a/conman.c +++ b/conman.c @@ -829,7 +829,7 @@ static void testAndWriteLog(SConnection * self, char *buffer, int iOut) Log(ERROR,"dev","%s",buffer); break; case eStatus: - Log(DEBUG,"IO","%s",buffer); + Log(DEBUG,"io","%s",buffer); break; case eEvent: if(strstr(buffer,"ERROR") != NULL){ @@ -1707,10 +1707,15 @@ int SCInvoke(SConnection * self, SicsInterp * pInter, char *pCommand) return 0; } strlcpy(pCopy->deviceID, pBueffel, SCDEVIDLEN); - if(SCGetRights(self) > usUser){ - Log(DEBUG,"com","%s:in:%s", ConID(self),pCommand); - } else { - Log(INFO,"com", "%s:in:%s", ConID(self),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); diff --git a/logv2.c b/logv2.c index 891f1ea7..ed62131b 100644 --- a/logv2.c +++ b/logv2.c @@ -28,9 +28,11 @@ static unsigned int logDisabled = 0; static int unsigned logConfigured = 0; /*================ The default log level =======================================*/ -static unsigned int globalLogLevel = 4; +static unsigned int globalLogLevel = INFO; + /*========= The list of sub systems for which full logging is enabled ==========*/ -static int subList; +unsigned int logEnabledArray[MAXSUB ]; + /*================== Callback management =======================================*/ typedef struct { LogCallback func; @@ -94,6 +96,8 @@ void LogClose(void *data) static void checkLogFile(void) { char *filename = NULL; + char *oldLogFile = NULL; + char timeStamp[132]; if(logDisabled || logConfigured == 0){ return; @@ -103,6 +107,10 @@ static void checkLogFile(void) close when full */ if(logFile != NULL && lineCount >= MAXFILELINES){ + oldLogFile = strdup(logFilename); + filename = makeLogFileName(); + formatTimeStamp(timeStamp,sizeof(timeStamp),0); + fprintf(logFile,"%s:sys:%d:Next logfile %s\n",timeStamp,INFO,filename); LogClose(NULL); } @@ -110,10 +118,16 @@ static void checkLogFile(void) start a new log file */ if(logFile == NULL){ - filename = makeLogFileName(); + if(filename == NULL){ + filename = makeLogFileName(); + } if(filename != NULL){ logFile = fopen(filename,"w"); strncpy(logFilename,filename,sizeof(logFilename)); + if(oldLogFile != NULL){ + fprintf(logFile,"%s:sys:%d:Previous logfile %s\n",timeStamp,INFO,oldLogFile); + free(oldLogFile); + } free(filename); } } @@ -144,39 +158,6 @@ static void writeLog(char *logMessage) } } -/*----------------------------------------------------------------------------*/ -unsigned int logFilter(unsigned int severity, const char *subsystem) -{ - int status; - char buffer[1024]; - - if(logDisabled || logConfigured == 0){ - return 1; - } - - - /* - If it is in the list of enabled subsystems, everything is logged - */ - status = LLDnodePtr2First(subList); - while (status == 1) { - LLDstringData(subList, buffer); - if(strcmp(buffer,subsystem) == 0) { - return 0; - } - status = LLDnodePtr2Next(subList); - } - - - /* - test against the global log level - */ - if(severity > globalLogLevel){ - return 1; - } - - return 0; -} /*=============================================================================*/ void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength) { @@ -194,6 +175,99 @@ void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLeng } 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; +} +/*=============================================================================*/ +static unsigned 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) +{ + int status; + char buffer[1024]; + unsigned int sub; + + if(logDisabled || logConfigured == 0){ + 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 @@ -251,7 +325,7 @@ void RemoveLogCallback(LogCallback func) } /*----------------------------------------------------------------------------*/ static void notifyListeners(unsigned int severity, const char *subsystem, - char *timeStamp, char *logData) + const char *timeStamp, char *logData) { int status; LogCBData lcb; @@ -264,22 +338,52 @@ static void notifyListeners(unsigned int severity, const char *subsystem, } } -/*----------------------------------------------------------------------------*/ -void Log(unsigned int severity, const char *subsystem,const char *format,...) +/*-------------------------------------------------------------------------------*/ +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) == 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 severityTXT[60]; char timeStamp[132]; - char logData[2024], logLine[3072], *pPtr = NULL; - char *dynMessage = NULL, *logMessage, *fullMessage = NULL; + char subText[30]; + char logData[2024], *logMessage = NULL; + char *dynMessage = NULL; va_list ap; int dataLength; - formatSeverity(severity,severityTXT,sizeof(severityTXT)); + formatSubsystem(subsystem,subText,sizeof(subText)); formatTimeStamp(timeStamp,sizeof(timeStamp),0); - checkLogFile(); - /* 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 @@ -299,89 +403,117 @@ void Log(unsigned int severity, const char *subsystem,const char *format,...) } } - notifyListeners(severity,subsystem,timeStamp, logMessage); + LogInternal(timeStamp, severity, subText,logMessage); + - - if(logFilter(severity,subsystem) == 1){ - if(dynMessage != NULL){ - free(dynMessage); - } - return; - } - - fullMessage = formatLogLine(timeStamp,severityTXT,subsystem, - logMessage, logLine, sizeof(logLine)); - - writeLog(fullMessage); - - - /* - clean up - */ if(dynMessage != NULL){ free(dynMessage); } - if(fullMessage != logLine){ - free(fullMessage); - } + } -/*--------------------------------------------------------------------------------*/ -static unsigned int sevFromText(const char *txt) +/*-------------------------------------------------------------------------------*/ +void LogTS(const char *timeStamp, unsigned int severity, unsigned int subsystem,const char *format,...) { - 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; + char subText[30]; + char logData[2024], *logMessage = NULL; + char *dynMessage = NULL; + va_list ap; + int dataLength; + + + formatSubsystem(subsystem,subText,sizeof(subText)); + + /* + 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; } - sev++; } - sev++; /* starting at 1 rather then 0 */ - return sev; -} -/*------------------------------------------------------------------------------*/ -static void DisableSub(char *sub) -{ - int status; - char buffer[1024]; + + LogInternal((char *)timeStamp, severity, subText,logMessage); - status = LLDnodePtr2First(subList); - while (status == 1) { - LLDstringData(subList, buffer); - if(strcmp(buffer,sub) == 0) { - LLDstringDelete(subList); - } - status = LLDnodePtr2Next(subList); + + if(dynMessage != NULL){ + free(dynMessage); } + + +} +/*----------------------------------------------------------------------------*/ +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(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; - char buffer[1024]; + int status, i; + char buffer[1024], sub[30], sev[30]; pDynString result = CreateDynString(64,64); if(result == NULL){ return NULL; } - - status = LLDnodePtr2First(subList); - while (status == 1) { - LLDstringData(subList, buffer); - DynStringConcat(result,buffer); + + for(i = 0; i < MAXSUB; i++){ + formatSeverity(logEnabledArray[i],sev,sizeof(sev)); + formatSubsystem(i,sub,sizeof(sub)); + DynStringConcat(result,sub); DynStringConcatChar(result,':'); - status = LLDnodePtr2Next(subList); + DynStringConcat(result,sev); + DynStringConcatChar(result,'\n'); } return result; } + /*============================================================================ The Interpreter Interface ==============================================================================*/ @@ -417,7 +549,7 @@ static int LogAction(SConnection * pCon, SicsInterp * pSics, static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { - unsigned int sev; + unsigned int sev, sub; char buffer[64]; pDynString result = NULL; @@ -470,7 +602,13 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon,"ERROR: subsystem name to long",eError); return 0; } - LLDstringAppend(subList,argv[2]); + 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); @@ -478,7 +616,12 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, } }else if (strcmp(argv[1],"disable") == 0) { if(argc > 2){ - DisableSub(argv[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); @@ -505,11 +648,16 @@ void DisableLog(void) /*-----------------------------------------------------------------------------*/ void Logv2Init(void) { - subList = LLDstringCreate(); - callbackList = LLDcreate(sizeof(LogCBData)); + 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; + } } diff --git a/logv2.h b/logv2.h index ebd05881..fb60c6dd 100644 --- a/logv2.h +++ b/logv2.h @@ -12,6 +12,9 @@ #define __LOGV2 #include +/* + severity codes +*/ #define FATAL 1 #define ERROR 2 #define WARN 3 @@ -20,6 +23,23 @@ #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 @@ -28,6 +48,24 @@ */ 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(const char *timeStamp, unsigned int severity, unsigned int subsystem,const char *format,...); + + + /* 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 @@ -82,4 +120,8 @@ void LogClose(void *data); void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength); + +extern unsigned int logEnabledArray[]; +#define logEnabled(subsystem,severity) (severity <= logEnabledArray[subsystem]) + #endif diff --git a/network.c b/network.c index b77e382a..f0d75550 100644 --- a/network.c +++ b/network.c @@ -75,7 +75,7 @@ static void NetError(const char pText[]) severity = WARN; } - Log(severity,"IO","%s", pText); + Log(severity,"io","%s", pText); } /* ---------------------------- Local ------------------------------------ From ac2d66c61e23e2e6a6164632b0a6c25b21dc7e4c Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 8 Mar 2016 11:51:55 +0100 Subject: [PATCH 15/39] Improved the interface of the LogTS function --- logv2.c | 31 ++++++++++++++++++------------- logv2.h | 3 ++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/logv2.c b/logv2.c index ed62131b..6023f760 100644 --- a/logv2.c +++ b/logv2.c @@ -9,7 +9,6 @@ */ #include #include -#include #include #include #include @@ -41,15 +40,20 @@ typedef struct { static int callbackList; /*----------------------------------------------------------------------------*/ -static void formatTimeStamp(char *buffer, unsigned int bufferLength, unsigned int small) +static void formatTimeStamp(struct timeval *tp, + char *buffer, unsigned int bufferLength, unsigned int small) { - struct timeval tv; 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; + } - gettimeofday(&tv, NULL); - time = localtime(&tv.tv_sec); time = localtime(&tv.tv_sec); year = 1900 + time->tm_year; month = time->tm_mon + 1; @@ -73,7 +77,7 @@ static char *makeLogFileName(void) char *filename = NULL; unsigned int length; - formatTimeStamp(timeStamp,sizeof(timeStamp),1); + formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),1); length = strlen(logTemplate) + strlen(timeStamp) + 30; filename = malloc(length*sizeof(char)); if(filename != NULL){ @@ -109,8 +113,8 @@ static void checkLogFile(void) if(logFile != NULL && lineCount >= MAXFILELINES){ oldLogFile = strdup(logFilename); filename = makeLogFileName(); - formatTimeStamp(timeStamp,sizeof(timeStamp),0); - fprintf(logFile,"%s:sys:%d:Next logfile %s\n",timeStamp,INFO,filename); + formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),0); + fprintf(logFile,"%s:sys:INFO:Next logfile %s\n",timeStamp,filename); LogClose(NULL); } @@ -125,7 +129,7 @@ static void checkLogFile(void) logFile = fopen(filename,"w"); strncpy(logFilename,filename,sizeof(logFilename)); if(oldLogFile != NULL){ - fprintf(logFile,"%s:sys:%d:Previous logfile %s\n",timeStamp,INFO,oldLogFile); + fprintf(logFile,"%s:sys:INFO:Previous logfile %s\n",timeStamp,oldLogFile); free(oldLogFile); } free(filename); @@ -382,7 +386,7 @@ void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...) formatSubsystem(subsystem,subText,sizeof(subText)); - formatTimeStamp(timeStamp,sizeof(timeStamp),0); + formatTimeStamp(NULL, timeStamp,sizeof(timeStamp),0); /* If we have enough space put the logData into our generous buffer. Else @@ -413,9 +417,9 @@ void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...) } /*-------------------------------------------------------------------------------*/ -void LogTS(const char *timeStamp, unsigned int severity, unsigned int subsystem,const char *format,...) +void LogTS(struct timeval *tv, unsigned int severity, unsigned int subsystem,const char *format,...) { - char subText[30]; + char subText[30], timeStamp[256]; char logData[2024], *logMessage = NULL; char *dynMessage = NULL; va_list ap; @@ -423,6 +427,7 @@ void LogTS(const char *timeStamp, unsigned int severity, unsigned int subsystem, formatSubsystem(subsystem,subText,sizeof(subText)); + formatTimeStamp(tv, timeStamp,sizeof(timeStamp),0); /* If we have enough space put the logData into our generous buffer. Else @@ -462,7 +467,7 @@ void Log(unsigned int severity, const char *subsystem,const char *format,...) int dataLength; - formatTimeStamp(timeStamp,sizeof(timeStamp),0); + formatTimeStamp(NULL,timeStamp,sizeof(timeStamp),0); /* If we have enough space put the logData into our generous buffer. Else diff --git a/logv2.h b/logv2.h index fb60c6dd..dc523bba 100644 --- a/logv2.h +++ b/logv2.h @@ -11,6 +11,7 @@ #ifndef __LOGV2 #define __LOGV2 #include +#include /* severity codes @@ -62,7 +63,7 @@ void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...) * \param format The format string for the message * \param ... The data to format */ -void LogTS(const char *timeStamp, unsigned int severity, unsigned int subsystem,const char *format,...); +void LogTS(struct timeval *tv, unsigned int severity, unsigned int subsystem,const char *format,...); From 18816067db0eae84448ac5975fb60250344867fe Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Mon, 14 Mar 2016 09:43:27 +0100 Subject: [PATCH 16/39] Added hex logging back again. Added it back in in AsyncQueue --- asyncqueue.c | 27 +++++++++++++++++----- hexString.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hexString.h | 18 +++++++++++++++ logv2.c | 17 ++++++++++++++ logv2.h | 10 +++++++- 5 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 hexString.c create mode 100644 hexString.h diff --git a/asyncqueue.c b/asyncqueue.c index 74b18538..4b949afc 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -22,7 +22,7 @@ #include "asyncqueue.h" #include "nwatch.h" #include - +#include typedef struct __async_command AQ_Cmd, *pAQ_Cmd; @@ -394,6 +394,7 @@ static int StartCommand(pAsyncQueue self) struct timeval tv; gettimeofday(&tv, NULL); Log(ERROR, "asquio","%d unsolicited chars in AsyncQueue %s",iRet, self->queue_name); + LogHex(&tv,ERROR,SASQIO,reply,iRet); } } } @@ -502,6 +503,7 @@ static int CommandTimeout(void *cntx, int mode) struct timeval tv; gettimeofday(&tv, NULL); 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; @@ -532,6 +534,17 @@ static int DelayedStart(void *cntx, int mode) 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; @@ -567,8 +580,8 @@ static int MyCallback(void *context, int mode) if (self->trace) { struct timeval tv; gettimeofday(&tv, NULL); - Log(INFO, "asquio", - "Received:%s:%s", self->queue_name,myCmd->tran->inp_buf); + 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; @@ -579,7 +592,10 @@ static int MyCallback(void *context, int mode) Log(ERROR,"asquio", "Protocol error %d in AsyncQueue %s", iRet, self->queue_name); - Log(ERROR,"asquio","SENT:%s:Received:%s",myCmd->tran->out_buf, myCmd->tran->inp_buf); + 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; } } @@ -813,8 +829,7 @@ int AsyncUnitWrite(pAsyncUnit unit, void *buffer, int buflen) if (unit->queue->trace) { struct timeval tv; gettimeofday(&tv, NULL); - Log(DEBUG,"asquio" - "Output Trace on AsyncQueue %s:%s", unit->queue->queue_name, buffer); + LogHexPrefix(&tv,DEBUG,"Output Trace on AsyncQueue", buffer, buflen); } sock = AsyncUnitGetSocket(unit); iRet = NETWrite(sock, buffer, buflen); diff --git a/hexString.c b/hexString.c new file mode 100644 index 00000000..8b67b826 --- /dev/null +++ b/hexString.c @@ -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> 4); + retval[i*2+1] = nibbleToChar(bytes[i] & 0x0f); + } + retval[i] = '\0'; + return retval; +} diff --git a/hexString.h b/hexString.h new file mode 100644 index 00000000..d72a25dd --- /dev/null +++ b/hexString.h @@ -0,0 +1,18 @@ +/* + * hexString.h + * byteutils + * + * Created by Richard Murphy on 3/7/10. + * Copyright 2010 McKenzie-Murphy. All rights reserved. + * + */ + +#include +#include +#include + +uint8_t +*hexStringToBytes(char *inhex); + +char +*bytesToHexString(uint8_t *bytes, size_t buflen); diff --git a/logv2.c b/logv2.c index 6023f760..8ac06b87 100644 --- a/logv2.c +++ b/logv2.c @@ -15,6 +15,7 @@ #include #include #include +#include /*============================================================================== some static fields which control log file rotation ===============================================================================*/ @@ -456,6 +457,22 @@ void LogTS(struct timeval *tv, unsigned int severity, unsigned int subsystem,con } +} +/*----------------------------------------------------------------------------*/ +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,...) diff --git a/logv2.h b/logv2.h index dc523bba..4220ab81 100644 --- a/logv2.h +++ b/logv2.h @@ -64,7 +64,15 @@ void LogIS(unsigned int severity, unsigned int subsystem,const char *format,...) * \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 From 1b2022a5e9b4c7f63d67fa9c13eed4cf301e435d Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 15 Mar 2016 11:24:50 +0100 Subject: [PATCH 17/39] There has been a continuous problem that the counter:CheckStatus function called from the status task messed up count processing. This has now been resolved in this way: - A new function ReadStatus and a lastStatus filed have been added to the countable interface. - CountTaskFunc updates the lastStatus field. - ReadStatus just returns that field. - ReadStatus is now being called by the status task. --- interface.c | 14 +++++++++++++- interface.h | 2 ++ make_gen | 2 +- status.c | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/interface.c b/interface.c index bd6bd70f..4cb59ea9 100644 --- a/interface.c +++ b/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; } @@ -378,6 +389,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){ diff --git a/interface.h b/interface.h index 3af14a9c..db99c1f0 100644 --- a/interface.h +++ b/interface.h @@ -62,11 +62,13 @@ typedef struct { int ID; int running; + int lastStatus; int (*Halt)(void *self); void (*SetCountParameters)(void *self, float fPreset, 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); diff --git a/make_gen b/make_gen index b2b60a46..f4f8cad0 100644 --- a/make_gen +++ b/make_gen @@ -21,7 +21,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.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 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\ diff --git a/status.c b/status.c index 32556b6e..6b55e785 100644 --- a/status.c +++ b/status.c @@ -400,7 +400,7 @@ static int CheckCountStatus(void *message, void *userData) 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; } From 019dc111311c9e71e4594e1c81784418e585e79c Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 15 Mar 2016 11:35:18 +0100 Subject: [PATCH 18/39] Made pCountInt->lastStatus handling work in diffscan --- diffscan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/diffscan.c b/diffscan.c index a696b6ae..8f421e24 100644 --- a/diffscan.c +++ b/diffscan.c @@ -278,6 +278,7 @@ static int StartDiffScan(pDiffScan self, pScanData pScan, if (status != OKOK) { return 0; } + pCount->pCountInt->lastStatus = HWBusy; return 1; } @@ -482,6 +483,7 @@ int RunDiffScan(pDiffScan self, pScanData pScan, pCount = (pCounter) self->scanObject->pCounterData; pCount->pCountInt->Halt(pCount); InvokeCallBack(self->scanObject->pCall, SCANEND, self->scanObject); + pCount->pCountInt->lastStatus = HWIdle; return 1; } From 96114fc803c0bdf38eba474d8a98dc7629fe4ddb Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Wed, 13 Apr 2016 09:18:13 +0200 Subject: [PATCH 19/39] Added the generation of incomensurate reflections for 0,0,0 in fourmess Applied Douglas task deletion patch Fixed a bug with repeated motor failures in interface.c --- fourmess.c | 15 +++++++++++++++ interface.c | 2 ++ task.c | 24 +++++++++++++++--------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/fourmess.c b/fourmess.c index 20bf2e73..c4f0964f 100644 --- a/fourmess.c +++ b/fourmess.c @@ -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; diff --git a/interface.c b/interface.c index 4cb59ea9..9e3a6efe 100644 --- a/interface.c +++ b/interface.c @@ -241,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); diff --git a/task.c b/task.c index 20fb1380..e2bc4094 100644 --- a/task.c +++ b/task.c @@ -214,22 +214,28 @@ static pTaskHead MakeTaskHead(char *name, TaskFunc pTask, SignalFunc pSignal, static void DeleteTaskHead(pTaskHead self) { assert(self); + void *pData; - if (self->pKill) { - if (self->pData) { - self->pKill(self->pData); - } - } - if(self->name != NULL){ - free(self->name); - } - /* unlink */ + /* unlink first to prevent double handling when Kill calls Yield*/ if (self->pPrevious != NULL) { self->pPrevious->pNext = self->pNext; } if (self->pNext != NULL) { self->pNext->pPrevious = self->pPrevious; } + + + if (self->pKill) { + if (self->pData) { + pData = self->pData; + self->pData = NULL; + self->pKill(pData); + } + } + if(self->name != NULL){ + free(self->name); + } + memset(self,0,sizeof(TaskHead)); free(self); } From e476d19040ea7bd1dbcfa2bb3fbfac37c399525a Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Thu, 14 Apr 2016 14:20:30 +0200 Subject: [PATCH 20/39] Fixed an issue with sget throwing excessive error messages when testing for the presence of a Hdb node --- sicsget.c | 2 +- sicshipadaba.c | 37 +++++++++++++++++++++++++++++++++++-- sicshipadaba.h | 8 ++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/sicsget.c b/sicsget.c index a97fad46..117af0d5 100644 --- a/sicsget.c +++ b/sicsget.c @@ -334,7 +334,7 @@ static int GetHdbFunc(void *ms, void *userData) char *geterror = NULL, error[512]; hdbValue ve; - node = FindHdbNode(NULL,self->name,pServ->dummyCon); + node = FindHdbIntern(self->name); if(node != NULL){ geterror = GetHdbProp(node,"geterror"); if(geterror != NULL){ diff --git a/sicshipadaba.c b/sicshipadaba.c index ae8d4e3e..3e7df068 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -1521,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) { @@ -1597,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 */ @@ -1630,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 diff --git a/sicshipadaba.h b/sicshipadaba.h index 527fb250..5b456c19 100644 --- a/sicshipadaba.h +++ b/sicshipadaba.h @@ -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 From 7f6b31e0983c1b31a3a1d86c40d4faef0c40afa5 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 10 May 2016 11:29:09 +0200 Subject: [PATCH 21/39] Some more fine tuning of log output Corrected a misleading warning in motorsec.c Fixed a core dump caused by copyNode in sicsdata.c. Was caused by a bad call to getPointer. --- conman.c | 4 ++-- logv2.h | 1 - motorsec.c | 2 +- sicsdata.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/conman.c b/conman.c index 0932bcfa..b11a1798 100644 --- a/conman.c +++ b/conman.c @@ -307,7 +307,7 @@ SConnection *SCCreateDummyConnection(SicsInterp * pSics) pRes->iUserRights = usInternal; pRes->iGrab = 0; - Log(INFO,"SYS","%s","Accepted dummy connection "); + /* Log(INFO,"SYS","%s","Accepted dummy connection "); */ return pRes; } @@ -837,7 +837,7 @@ static void testAndWriteLog(SConnection * self, char *buffer, int iOut) }else if(strstr(buffer,"WARNING") != NULL) { Log(WARN,"notify",buffer); } else { - Log(INFO,"notify",buffer); + Log(DEBUG,"notify",buffer); } break; case eHdbEvent: diff --git a/logv2.h b/logv2.h index 4220ab81..aa2bd82a 100644 --- a/logv2.h +++ b/logv2.h @@ -129,7 +129,6 @@ void LogClose(void *data); void formatSeverity(unsigned int severity, char *buffer, unsigned int bufferLength); - extern unsigned int logEnabledArray[]; #define logEnabled(subsystem,severity) (severity <= logEnabledArray[subsystem]) diff --git a/motorsec.c b/motorsec.c index 3bb14849..f6ee04c3 100644 --- a/motorsec.c +++ b/motorsec.c @@ -324,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); + SCWrite(pCon,"WARNING: Position repositioned",eLog); status = checkPosition(self, pCon); } else if (strstr(v.v.text, "restart") != NULL) { SCPrintf(pCon,eLog,"WARNING: restarting motor %s", self->name); diff --git a/sicsdata.c b/sicsdata.c index 8ccd7d63..ea556363 100644 --- a/sicsdata.c +++ b/sicsdata.c @@ -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: From cb6c80d0e63b966f69b1c56f32c03fdef759726e Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Thu, 12 May 2016 09:45:26 +0200 Subject: [PATCH 22/39] Improved repositioning message in motorsec.c --- motorsec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motorsec.c b/motorsec.c index f6ee04c3..efa7637b 100644 --- a/motorsec.c +++ b/motorsec.c @@ -324,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 repositioned",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); From 0b41bcde0361ed941e2366a014cee15c69e40fc9 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Fri, 13 May 2016 09:13:52 +0200 Subject: [PATCH 23/39] Increased sysTrace messages to INFO level --- trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/trace.c b/trace.c index 45d39423..fea2cdc6 100644 --- a/trace.c +++ b/trace.c @@ -229,6 +229,8 @@ void traceprint(char *sub, char *id, char *data) 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 { From fdb443441ab949bb30fb31d6e813848ec9cffb1f Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Fri, 13 May 2016 16:32:18 +0200 Subject: [PATCH 24/39] - more AsconStatus states - enhancements in binprot - make Logger public (logger.h) - added lscprot (50 ms write delay for lakeshore models) - additonal bug fixes --- ascon.c | 3 +- ascon.h | 1 + binprot.c | 50 +++++++++++++++++++++------ devser.c | 1 + logger.c | 21 +++++------- logger.h | 15 +++++++- lscprot.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ make_gen | 2 +- ofac.c | 1 + remob.c | 2 +- 10 files changed, 169 insertions(+), 28 deletions(-) create mode 100644 lscprot.c diff --git a/ascon.c b/ascon.c index 1eb23b90..42906fb7 100644 --- a/ascon.c +++ b/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. */ diff --git a/ascon.h b/ascon.h index c7f81933..2571fd8c 100644 --- a/ascon.h +++ b/ascon.h @@ -17,6 +17,7 @@ typedef struct Ascon Ascon; typedef enum { AsconOffline, AsconUnconnected, + AsconConnectPending, AsconPending, AsconReady, AsconFailure /* codes after this indicate also failure */ diff --git a/binprot.c b/binprot.c index 99261994..f65511ae 100644 --- a/binprot.c +++ b/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 skip 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); diff --git a/devser.c b/devser.c index 076ee6ae..b3888e51 100644 --- a/devser.c +++ b/devser.c @@ -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"; diff --git a/logger.c b/logger.c index bcf7c682..4534ce40 100644 --- a/logger.c +++ b/logger.c @@ -15,18 +15,6 @@ Markus Zolliker, Sept 2004 #include #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); diff --git a/logger.h b/logger.h index a8404c4e..2f9ab189 100644 --- a/logger.h +++ b/logger.h @@ -10,7 +10,20 @@ Markus Zolliker, Sept 2004 #include -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); diff --git a/lscprot.c b/lscprot.c new file mode 100644 index 00000000..c6b24828 --- /dev/null +++ b/lscprot.c @@ -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); +} diff --git a/make_gen b/make_gen index f4f8cad0..cbdd5be6 100644 --- a/make_gen +++ b/make_gen @@ -45,7 +45,7 @@ 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 stack_trace.o logv2.o outcode.o diff --git a/ofac.c b/ofac.c index df88921e..5d2f1f77 100644 --- a/ofac.c +++ b/ofac.c @@ -51,6 +51,7 @@ static void InitGeneral(void) INIT(AddBinProtocol); INIT(AddPMACProtocoll); INIT(AddCharByCharProtocoll); + INIT(AddLscProtocol); INIT(MakeTrace); INIT(InitTaskOBJ); INIT(RemoteObjectInit); diff --git a/remob.c b/remob.c index 35eb4d98..44995006 100644 --- a/remob.c +++ b/remob.c @@ -29,7 +29,7 @@ typedef struct RemChannel { mkChannel *chan; int timeout; int incomplete; - char line[256]; + char line[1024]; } RemChannel; typedef struct RemServer { From 097b93aa8b3a1f9cbdcaa5dc5eab71f89b8881af Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Tue, 17 May 2016 11:30:38 +0200 Subject: [PATCH 25/39] Added a loglsisten command for listening into the log --- loglisten.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ logv2.c | 2 +- make_gen | 2 +- ofac.c | 1 + 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 loglisten.c diff --git a/loglisten.c b/loglisten.c new file mode 100644 index 00000000..111b251a --- /dev/null +++ b/loglisten.c @@ -0,0 +1,95 @@ +/** + * This is a means to listen into the stream of log messages from the logv2 + * logging system. + * + * Mark Koennecke, May 2016 + */ +#include +#include +#include + +/* + 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; + + 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); +} diff --git a/logv2.c b/logv2.c index 8ac06b87..4cbdf83f 100644 --- a/logv2.c +++ b/logv2.c @@ -202,7 +202,7 @@ static unsigned int sevFromText(const char *txt) return sev; } /*=============================================================================*/ -static unsigned int subsystemFromText(const char *text) +int subsystemFromText(const char *text) { int i; static const char *subText[] = {"sys", diff --git a/make_gen b/make_gen index f4f8cad0..07887aa0 100644 --- a/make_gen +++ b/make_gen @@ -14,7 +14,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.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 \ diff --git a/ofac.c b/ofac.c index df88921e..9220920e 100644 --- a/ofac.c +++ b/ofac.c @@ -55,6 +55,7 @@ static void InitGeneral(void) INIT(InitTaskOBJ); INIT(RemoteObjectInit); INIT(Logv2Init); + INIT(LogListenInit); INIT(SiteInit); /* site specific initializations */ } From 1f23c19e1c9f999a72655fe21531edbbe5e2f831 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Wed, 18 May 2016 11:33:59 +0200 Subject: [PATCH 26/39] Added a feature which allows suppression of certain log messages. For example TRANSACT messages --- logv2.c | 36 +++++++++++++++++++++++++++++++++--- logv2.h | 2 +- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/logv2.c b/logv2.c index 4cbdf83f..11096a28 100644 --- a/logv2.c +++ b/logv2.c @@ -32,6 +32,8 @@ static unsigned int globalLogLevel = INFO; /*========= The list of sub systems for which full logging is enabled ==========*/ unsigned int logEnabledArray[MAXSUB ]; +/*========== A list of entries to suppress =====================================*/ +int suppressList; /*================== Callback management =======================================*/ typedef struct { @@ -243,7 +245,7 @@ void formatSubsystem(unsigned int sub, char *buffer, unsigned int bufferLength) strncpy(buffer,subText[sub],bufferLength); } /*----------------------------------------------------------------------------*/ -unsigned int logFilter(unsigned int severity, const char *subsystem) +unsigned int logFilter(unsigned int severity, const char *subsystem, const char *logMessage) { int status; char buffer[1024]; @@ -253,6 +255,18 @@ unsigned int logFilter(unsigned int severity, const char *subsystem) return 1; } + /* + test if it is in the suppression list + */ + status = LLDnodePtr2First(suppressList); + while (status == 1) { + LLDstringData(suppressList, buffer); + if(strstr(logMessage,buffer) != NULL){ + return 1; + } + status = LLDnodePtr2Next(suppressList); + } + /* If it is in the list of enabled subsystems, everything is logged @@ -356,7 +370,7 @@ static void LogInternal(char *timeText, unsigned int severity, const char *subsy notifyListeners(severity,subsystem,timeText, logMessage); - if(logFilter(severity,subsystem) == 1){ + if(logFilter(severity,subsystem,(const char *)logMessage) == 1){ return; } @@ -655,6 +669,21 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon,GetCharArray(result),eValue); DeleteDynString(result); } + }else if (strcmp(argv[1],"suppress") == 0) { + if(argc > 2){ + /* + The 1024 is related to the size of the buffer in logFilter + */ + if(strlen(argv[2]) >= 1024) { + SCWrite(pCon,"ERROR: string to suppress to long",eError); + return 0; + } + LLDstringAppend(suppressList,argv[2]); + SCSendOK(pCon); + } else { + SCWrite(pCon,"ERROR: need text to suppress",eError); + return 0; + } } else { SCPrintf(pCon,eError,"ERROR: unknown keyword %s",argv[1]); return 0; @@ -672,7 +701,8 @@ void Logv2Init(void) { int i; - callbackList = LLDcreate(sizeof(LogCBData)); + callbackList = LLDcreate(sizeof(LogCBData)); + suppressList = LLDstringCreate(); strcpy(logTemplate,"unconfiguredLogTemplate"); AddCmd("log", LogAction); diff --git a/logv2.h b/logv2.h index aa2bd82a..07a84f10 100644 --- a/logv2.h +++ b/logv2.h @@ -110,7 +110,7 @@ void RemoveLogCallback(LogCallback func); * \param subsystem the subsystem of the message * \return 1 when filtered, 0 else */ -unsigned int logFilter(unsigned int severity, const char *subsystem); +unsigned int logFilter(unsigned int severity, const char *subsystem, const char *logMessage); /* *Disable logging in support of the nolog option in SICSmain.c */ From 294195c872a3076bcc9e1827d64188d820494b6a Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Wed, 18 May 2016 11:58:52 +0200 Subject: [PATCH 27/39] Removed the suppression list again from logv2.c for fear of performance issues. I rather implemented the suppression of TRANSACT messages in macro.c --- logv2.c | 29 +++-------------------------- macro.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/logv2.c b/logv2.c index 11096a28..9528f214 100644 --- a/logv2.c +++ b/logv2.c @@ -32,8 +32,6 @@ static unsigned int globalLogLevel = INFO; /*========= The list of sub systems for which full logging is enabled ==========*/ unsigned int logEnabledArray[MAXSUB ]; -/*========== A list of entries to suppress =====================================*/ -int suppressList; /*================== Callback management =======================================*/ typedef struct { @@ -256,15 +254,10 @@ unsigned int logFilter(unsigned int severity, const char *subsystem, const char } /* - test if it is in the suppression list + suppress empty messages */ - status = LLDnodePtr2First(suppressList); - while (status == 1) { - LLDstringData(suppressList, buffer); - if(strstr(logMessage,buffer) != NULL){ - return 1; - } - status = LLDnodePtr2Next(suppressList); + if(strlen(logMessage) < 1) { + return 1; } @@ -669,21 +662,6 @@ static int LogConfigAction(SConnection * pCon, SicsInterp * pSics, SCWrite(pCon,GetCharArray(result),eValue); DeleteDynString(result); } - }else if (strcmp(argv[1],"suppress") == 0) { - if(argc > 2){ - /* - The 1024 is related to the size of the buffer in logFilter - */ - if(strlen(argv[2]) >= 1024) { - SCWrite(pCon,"ERROR: string to suppress to long",eError); - return 0; - } - LLDstringAppend(suppressList,argv[2]); - SCSendOK(pCon); - } else { - SCWrite(pCon,"ERROR: need text to suppress",eError); - return 0; - } } else { SCPrintf(pCon,eError,"ERROR: unknown keyword %s",argv[1]); return 0; @@ -702,7 +680,6 @@ void Logv2Init(void) int i; callbackList = LLDcreate(sizeof(LogCBData)); - suppressList = LLDstringCreate(); strcpy(logTemplate,"unconfiguredLogTemplate"); AddCmd("log", LogAction); diff --git a/macro.c b/macro.c index a27a84fc..0adebdf7 100644 --- a/macro.c +++ b/macro.c @@ -1083,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... */ @@ -1091,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; @@ -1101,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; } From 8254c1303cbd8ef0ebd90cb1ff62913b1d1fc63d Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Thu, 9 Jun 2016 14:44:57 +0200 Subject: [PATCH 28/39] Added a log message at everz start of a driving or counting operation. Together with the already existing stop messages this allows for performance analysis. --- interface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface.c b/interface.c index 9e3a6efe..84942f76 100644 --- a/interface.c +++ b/interface.c @@ -297,6 +297,8 @@ 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, @@ -451,6 +453,8 @@ 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, From 7ca7876dbe540b6b4d9f4b1bdb41334a4bf42940 Mon Sep 17 00:00:00 2001 From: Koennecke Mark Date: Fri, 1 Jul 2016 10:57:35 +0200 Subject: [PATCH 29/39] Reduced severity of perfmon log message in order to reduce log clutter --- perfmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/perfmon.c b/perfmon.c index 82abad67..d86c8ddf 100644 --- a/perfmon.c +++ b/perfmon.c @@ -125,7 +125,7 @@ int IncrementPerfMon(pPerfMon self) self->tLast = tCurrent; self->tTarget = tCurrent + self->iInteg; 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; } From 7e764b100bbe357545c37935a15981193dc781ed Mon Sep 17 00:00:00 2001 From: koennecke Date: Tue, 2 Aug 2016 11:19:41 +0200 Subject: [PATCH 30/39] Fixed a typo in an error message in sicsdata.c --- sicsdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sicsdata.c b/sicsdata.c index ea556363..e589a916 100644 --- a/sicsdata.c +++ b/sicsdata.c @@ -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; } From fd5451e8fdfdfc88f0ae4090d6cc6e48981deae2 Mon Sep 17 00:00:00 2001 From: koennecke Date: Tue, 25 Oct 2016 17:03:21 +0200 Subject: [PATCH 31/39] Enhanced comments in asynnet Changed required privilege for chnaging the threshold from manager to user in counter.c Changed an output code in macro.c --- asynnet.c | 7 ++++++- counter.c | 2 +- macro.c | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/asynnet.c b/asynnet.c index 67f4d7c6..beac28c0 100644 --- a/asynnet.c +++ b/asynnet.c @@ -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; diff --git a/counter.c b/counter.c index 72c8aeac..32fd8312 100644 --- a/counter.c +++ b/counter.c @@ -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; diff --git a/macro.c b/macro.c index 0adebdf7..cf68f1bb 100644 --- a/macro.c +++ b/macro.c @@ -605,7 +605,7 @@ 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.h" From d0fe079b719564a00796806932508ddd586c89ca Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 7 Nov 2016 09:48:47 +0100 Subject: [PATCH 32/39] Fixed an issue where an unresetted geterror in combination with a null connection causes to many log messages. --- scriptcontext.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scriptcontext.c b/scriptcontext.c index 7d68abc6..ce63ccf4 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -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); From f2aa76b3961236a1d66ca54805db70814696bebb Mon Sep 17 00:00:00 2001 From: koennecke Date: Thu, 10 Nov 2016 14:41:38 +0100 Subject: [PATCH 33/39] Fixed a wrong sequence of starts in multicounter Suppressed excessive connection messages from asynnet --- conman.c | 5 +++-- multicounter.c | 25 ++++++++++++++++++++++--- nread.c | 7 ++++++- telnet.c | 4 +++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/conman.c b/conman.c index b11a1798..cb22490d 100644 --- a/conman.c +++ b/conman.c @@ -2193,6 +2193,7 @@ int SCTaskFunction(void *pData) if (SCActive(self)) { return 1; } else { + Log(INFO,"sys","Handle %d disconnected", self->sockHandle); return 0; } } @@ -2223,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; } @@ -2257,8 +2259,7 @@ int SCTaskFunction(void *pData) 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); diff --git a/multicounter.c b/multicounter.c index 2e190df9..a1279e72 100644 --- a/multicounter.c +++ b/multicounter.c @@ -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); diff --git a/nread.c b/nread.c index d23ced32..90f9c700 100644 --- a/nread.c +++ b/nread.c @@ -1343,7 +1343,12 @@ static int TelnetAcceptCB(int handle, void *userData) /*------------------------------------------------------------------------------------*/ static void NREADlog(int level, char *txt, void *userData) { - traceSys("anet","%s",txt); + /* + suppress the connection messages + */ + if(level != ANETCON){ + traceSys("anet","%s",txt); + } } /*------------------------------------------------------------------------------------*/ diff --git a/telnet.c b/telnet.c index 41d3171a..d3706b28 100644 --- a/telnet.c +++ b/telnet.c @@ -224,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; } } @@ -235,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; @@ -280,7 +282,7 @@ int TelnetTask(void *pData) } else { snprintf(pBuffer,sizeof(pBuffer)-1, "Accepted telnet connection on handle %d", self->pCon->sockHandle); - Log(INFO,"com","%s",pBuffer); + Log(INFO,"sys","%s",pBuffer); SendWelcome(self->pCon); SCSetRights(self->pCon, iRet); self->iLogin = 1; From c39f96c253928e327905c9e6d6b1617995278d43 Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 21 Nov 2016 13:37:10 +0100 Subject: [PATCH 34/39] Removed some dead code in SCinter Loglisten showed to much stuff, no filtering. Filtering added. --- SCinter.c | 14 -------------- loglisten.c | 5 +++++ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/SCinter.c b/SCinter.c index 698ab222..283580f0 100644 --- a/SCinter.c +++ b/SCinter.c @@ -294,20 +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); - } - - TODO: disabled for now. This is a duplication of what is logged in SCInvoke. - - Mark Koennecke, February 2016 - */ if(strstr(pText,tclescape) == pText){ return TclExecFunc(pCon,self,NULL,pText); diff --git a/loglisten.c b/loglisten.c index 111b251a..a7785ceb 100644 --- a/loglisten.c +++ b/loglisten.c @@ -28,6 +28,11 @@ static void LogListenCallback(unsigned int severity, const char *timeStamp, ListenEntry current; int status, cleanupNeeded = 0; + if(logFilter(severity,subsystem,message) == 1) { + return; + } + + status = LLDnodePtr2First(listenerList); while(status != 0){ LLDnodeDataTo(listenerList,¤t); From e5ecf5218e9649fca4cef2bd5bf585cbe0ca1bed Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 21 Nov 2016 14:18:52 +0100 Subject: [PATCH 35/39] Removed an unnecessary field from the connection structure --- conman.h | 1 - 1 file changed, 1 deletion(-) diff --git a/conman.h b/conman.h index 85c4f319..89cf400a 100644 --- a/conman.h +++ b/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 */ From 3fda3d9864d6f365eb2b0fb87ecc5ea098d3bfdc Mon Sep 17 00:00:00 2001 From: koennecke Date: Thu, 24 Nov 2016 13:49:07 +0100 Subject: [PATCH 36/39] Added exponential backoff when errors occur in sicspoll --- polldriv.c | 2 -- polldriv.h | 1 + sicspoll.c | 38 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/polldriv.c b/polldriv.c index de89f650..ce27b387 100644 --- a/polldriv.c +++ b/polldriv.c @@ -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); diff --git a/polldriv.h b/polldriv.h index 3100dba0..5ca12ca1 100644 --- a/polldriv.h +++ b/polldriv.h @@ -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); diff --git a/sicspoll.c b/sicspoll.c index 33be09ff..c26f93af 100644 --- a/sicspoll.c +++ b/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 @@ -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; From 6f4ae14e8fa51cac8b5a4886f1a32f2e5fc4b319 Mon Sep 17 00:00:00 2001 From: koennecke Date: Fri, 25 Nov 2016 08:31:18 +0100 Subject: [PATCH 37/39] Removed some dead code from trace.c --- trace.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/trace.c b/trace.c index fea2cdc6..1d645753 100644 --- a/trace.c +++ b/trace.c @@ -207,20 +207,6 @@ 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){ From 7fa5a5e8fa2b6efee0920fcfb5f0055e535e1292 Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 12 Dec 2016 11:43:24 +0100 Subject: [PATCH 38/39] Removed obsolete sinfox command Removed last traces of sycamore protocol --- make_gen | 2 +- ofac.c | 1 - protocol.c | 1 - sinfox.c | 1150 ---------------------------------------------------- sinfox.h | 115 ------ 5 files changed, 1 insertion(+), 1268 deletions(-) delete mode 100644 sinfox.c delete mode 100644 sinfox.h diff --git a/make_gen b/make_gen index f0be7c03..9d3a5d06 100644 --- a/make_gen +++ b/make_gen @@ -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 \ diff --git a/ofac.c b/ofac.c index bb4f6503..0576da22 100644 --- a/ofac.c +++ b/ofac.c @@ -132,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); diff --git a/protocol.c b/protocol.c index 61188038..c95e8bc2 100644 --- a/protocol.c +++ b/protocol.c @@ -88,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); diff --git a/sinfox.c b/sinfox.c deleted file mode 100644 index 833e2d83..00000000 --- a/sinfox.c +++ /dev/null @@ -1,1150 +0,0 @@ -/*-------------------------------------------------------------------------- - ANSTO Server Info Command Object - Paul Hathaway, January, 2005 - Copyright: See copyright.txt -----------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include /* incl. SCWrite */ -#include -#include -#include -#include -#include "sinfox.h" - -/*----------------------------------------------------------------------- - * External Interface defined in sinfox.h includes - * struct pSinfox - * int InstallSinfox(SConnection *pCon, SicsInterp *pSics, void *pData, - * int argc, char *argv[]); - * void DeleteSinfox(void *pSelf); - * int SinfoxAction(SConnection *pCon, SicsInterp *pSics, void *pData, - * int argc, char *argv[]); - * and lists of option keys - *-----------------------------------------------------------------------*/ - -/* Core module functions */ -static pSinfox CreateSinfox(void); -static int SinfoxInit(SicsInterp * pSics, char *infofile); -static int SinfoxHelp(pSinfox pSin, SicsInterp * pSics); -static int SinfoxReset(pSinfox pSin, SicsInterp * pSics); -static int SinfoxSetDesc(pSinfox pSin, SicsInterp * pSics, - char *objName, char *pDesc); -static int SinfoxSetGrp(pSinfox pSin, SicsInterp * pSics, - char *objName, char *pGrp); -static int SinfoxSetKey(pSinfox pSin, SicsInterp * pSics, - char *objName, char *keyName, char *eltValue); -static int SinfoxReadKey(pSinfox pSin, SicsInterp * pSics, - char *objName, char *fileName); -static int SinfoxList(pSinfox pSin, SicsInterp * pSics, SConnection * pCon, - char *pObjName, char *pKeyName, char *pEltName); -static int SinfoxEnumerate(pSinfox pSin, SicsInterp * pSics, - SConnection * pCon, char *keyName); -static int SinfoxShow(pSinfox pSin, SicsInterp * pSics, SConnection * pCon, - char *keyName, char *eltName); -static int SinfoxDevice(pSinfox pSin, SicsInterp * pSics, - SConnection * pCon, char *devName, char *keyName, - char *eltName); -static int SinfoxGetGrp(pSinfox pSin, SicsInterp * pSics, char *objName); - -/* Utility functions */ -static int EnumChoice(char *pList[], int iLength, char *pInput); -static int LinkVar(char *tcl_var_name, char *pAddress, int link_flags); -static void setOKE(char *obj, char *key, char *elt, - char *oVal, char *kVal, char *eVal); -static int isNameDevice(char *name); -static int isNameCommand(char *name); -static int isObjectDevice(CommandList * pObj); -static int isObjectCommand(CommandList * pObj); -static void addToList(Tcl_Interp * tTcl, Tcl_Obj * tList, char *prefix, - char *sVal); -static void addPairsToList(Tcl_Interp * tTcl, Tcl_Obj * tList, - IPair * pList); -static void RemoveWhiteSpace(char *pText); - -/*--------------------------------------------------------------------------*/ -pSinfox CreateSinfox(void) -{ - int i; - pSinfox pNew = NULL; - SicsInterp *pSics; - Tcl_Interp *tTcl; - - pNew = (pSinfox) malloc(sizeof(Sinfox)); - if (!pNew) { - return NULL; - } - pNew->pDes = CreateDescriptor("sinfox"); - if (!pNew->pDes) { - free(pNew); - return NULL; - } - pSics = GetInterpreter(); - tTcl = (Tcl_Interp *) (pSics->pTcl); - pNew->tTcl = tTcl; - /* LinkVar("server::configName",pNew->configName,TCL_LINK_STRING); */ - pNew->buildVersion = Tcl_GetVar(tTcl, - "::server::buildVersion", - TCL_GLOBAL_ONLY); - pNew->configName = - Tcl_GetVar(tTcl, "::server::configName", TCL_GLOBAL_ONLY); - pNew->configVersion = - Tcl_GetVar(tTcl, "::server::configVersion", TCL_GLOBAL_ONLY); - pNew->description = - Tcl_GetVar(tTcl, "::server::description", TCL_GLOBAL_ONLY); - pNew->instrument = - Tcl_GetVar(tTcl, "::server::instrument", TCL_GLOBAL_ONLY); - pNew->schemaVersion = - Tcl_GetVar(tTcl, "::server::schemaVersion", TCL_GLOBAL_ONLY); - pNew->pDes->pKeys = NULL; - return pNew; -} - -/*-------------------------------------------------------------------------*/ -void DeleteSinfox(void *self) -{ - int i; - pSinfox pOld = (pSinfox) self; - - if (NULL == pOld) { - return; - } - if (pOld->buildVersion) { - free((void *) (pOld->buildVersion)); - } - if (pOld->configName) { - free((void *) (pOld->configName)); - } - if (pOld->configVersion) { - free((void *) (pOld->configVersion)); - } - if (pOld->description) { - free((void *) (pOld->description)); - } - if (pOld->instrument) { - free((void *) (pOld->instrument)); - } - if (pOld->schemaVersion) { - free((void *) (pOld->schemaVersion)); - } - if (pOld->pDes) { - DeleteDescriptor(pOld->pDes); - } - free(pOld); -} - -/*--------------------------------------------------------------------------*/ -int InstallSinfox(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) -{ - pSinfox pNew = NULL; - pNew = CreateSinfox(); - if (NULL == pNew) { - SCWrite(pCon, "No memory to create Sinfox", eError); - return 0; - } - AddCommand(pSics, "sinfox", SinfoxAction, DeleteSinfox, pNew); - SCSendOK(pCon); - return 1; -} - -/*--------------------------------------------------------------------------*/ -static int SinfoxInit(SicsInterp * pSics, char *infofile) -{ - SConnection *pCon = NULL; - char pBuf[1024]; - int iRet; - - /* create a connection */ - pCon = SCCreateDummyConnection(pSics); - if (!pCon) { - return 0; - } - /* - pCon->iFiles = 1; - pCon->pFiles[0] = stdout; - */ - - /* evaluate the file */ - sprintf(pBuf, "fileeval %s", infofile); - iRet = InterpExecute(pSics, pCon, pBuf); - /* - pCon->iFiles = 0; - */ - SCDeleteConnection(pCon); - - return iRet; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxHelp(pSinfox pSin, SicsInterp * pSics) -{ - Tcl_SetResult((Tcl_Interp *) (pSics->pTcl), "Sinfox Help", TCL_VOLATILE); - return 1; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxReset(pSinfox pSin, SicsInterp * pSics) -{ - int i; - - pSin->buildVersion = Tcl_GetVar(pSin->tTcl, - "::server::buildVersion", - TCL_GLOBAL_ONLY); - pSin->configName = - Tcl_GetVar(pSin->tTcl, "::server::configName", TCL_GLOBAL_ONLY); - pSin->configVersion = - Tcl_GetVar(pSin->tTcl, "::server::configVersion", TCL_GLOBAL_ONLY); - pSin->description = - Tcl_GetVar(pSin->tTcl, "::server::description", TCL_GLOBAL_ONLY); - pSin->instrument = - Tcl_GetVar(pSin->tTcl, "::server::instrument", TCL_GLOBAL_ONLY); - pSin->schemaVersion = - Tcl_GetVar(pSin->tTcl, "::server::schemaVersion", TCL_GLOBAL_ONLY); - - Tcl_SetResult(pSin->tTcl, "{Sinfox Reset}", TCL_VOLATILE); - return 1; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxSetDesc(pSinfox pSin, SicsInterp * pSics, - char *objName, char *pDesc) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - char pBuf[256]; - - memset(pBuf, 0, 256); - pCurrent = pSics->pCList; - - pCurrent = FindCommand(pSics, objName); - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - SetDescriptorDescription(pDes, pDesc); - sprintf(pBuf, "description=%s", pDesc); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 1; - } - } - sprintf(pBuf, "error=unable to set %s.description to %s", objName, - pDesc); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 0; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxSetGrp(pSinfox pSin, SicsInterp * pSics, - char *objName, char *pGrp) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - char pBuf[256]; - - memset(pBuf, 0, 256); - pCurrent = pSics->pCList; - - pCurrent = FindCommand(pSics, objName); - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - SetDescriptorGroup(pDes, pGrp); - sprintf(pBuf, "group=%s", pGrp); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 1; - } - } - sprintf(pBuf, "error=unable to set %s.group to %s", objName, pGrp); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 0; -} - -static int SinfoxGetGrp(pSinfox pSin, SicsInterp * pSics, char *objName) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - char pBuf[256]; - - pBuf[0] = '\0'; - pCurrent = pSics->pCList; - - pCurrent = FindCommand(pSics, objName); - if (NULL == pCurrent) { - sprintf(pBuf, "%s.group=none", objName); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 1; - } else { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - sprintf(pBuf, "%s.group=%s", objName, GetDescriptorGroup(pDes)); - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return 1; - } - } - return 0; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxSetKey(pSinfox pSin, SicsInterp * pSics, - char *objName, char *keyName, char *eltValue) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - int bOK = 0; - char *obj; - char pBuf[256]; - memset(pBuf, 0, 256); - - obj = strdup(objName); - strtolower(obj); - - if (0 == strcmp(obj, "server")) { /* sinfox object is surrogate for server object inside SICS */ - free(obj); - obj = strdup("sinfox"); - } else { - free(obj); - obj = strdup(objName); - } - - pCurrent = pSics->pCList; - pCurrent = FindCommand(pSics, obj); - - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - strtolower(keyName); - strtolower(eltValue); - pDes->pKeys = IFSetOption(pDes->pKeys, keyName, eltValue); - if (NULL != pDes->pKeys) { - bOK = 1; - } - } - } - - if (bOK == 1) { - sprintf(pBuf, "%s.%s=%s", - pCurrent->pName, pDes->pKeys->name, pDes->pKeys->value); - } else { - sprintf(pBuf, "error=unable to set %s.%s to %s", - obj, keyName, eltValue); - } - - Tcl_SetObjResult(pSin->tTcl, Tcl_NewStringObj(pBuf, strlen(pBuf))); - return bOK; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxReadKey(pSinfox pSin, SicsInterp * pSics, - char *objName, char *fileName) -{ - static FILE *fKeyFile = NULL; - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - char pBuf[256]; - char pName[132]; - char pValue[132]; - char *pPos; - int iLen; - - memset(pBuf, 0, 256); - - pCurrent = pSics->pCList; - pCurrent = FindCommand(pSics, objName); - - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - fKeyFile = fopen(fileName, "r"); - if (NULL == fKeyFile) { - return 0; - } - - while (!feof(fKeyFile)) { - fgets(pBuf, 255, fKeyFile); - if (feof(fKeyFile)) - continue; - - if (pBuf[0] == '#') - continue; - - pPos = strchr(pBuf, '='); - if (!pPos) - continue; - - iLen = pPos - pBuf; - strncpy(pName, pBuf, iLen); /* strlcpy is wrong here */ - pName[iLen] = '\0'; - strcpy(pValue, (pPos + 1)); - RemoveWhiteSpace(pName); - RemoveWhiteSpace(pValue); - strtolower(pName); - strtolower(pValue); - - pDes->pKeys = IFAddOption(pDes->pKeys, pName, pValue); - if (NULL == pDes->pKeys) - return 0; - } - - fclose(fKeyFile); - return 1; - } - } - return 0; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxList(pSinfox pSin, SicsInterp * pSics, SConnection * pCon, - char *pObjName, char *pKeyName, char *pEltName) -{ - int iRet; - char *objName; - char *keyName = NULL; - char *eltName = NULL; - CommandList *pObj = NULL; - - objName = strdup(pObjName); - strtolower(objName); - if (NULL != pKeyName) { - keyName = strdup(pKeyName); - strtolower(keyName); - } - if (NULL != pEltName) { - eltName = strdup(pEltName); - strtolower(eltName); - } - - /* check if objName is an interfaceName */ - iRet = EnumChoice(pIFaces, iNumIFaces, objName); - if (-1 < iRet) { - if ((0 == strcmp(keyName, "device")) || keyName == NULL) { /* format as sinfox list server interface interfaceName */ - setOKE(objName, keyName, eltName, "server", "interface", objName); - } else if (0 == strcmp(keyName, "command")) { /* todo: not yet implemented */ - return SinfoxHelp(pSin, pSics); - } - } - - /* check if objName is commandName */ - /* check if objName is a deviceName */ - pObj = FindCommand(pSics, objName); - if (NULL != pObj) { - if (1 == isObjectDevice(pObj)) { - return SinfoxDevice(pSin, pSics, pCon, objName, keyName, eltName); - } else { /* command */ - return 0; - iRet = EnumChoice(pCommandKeys, iNumCommandKeys, keyName); - switch (iRet) { - case 1: /* argument */ - /* todo: not yet implemented */ - case 2: /* device */ - /* todo: secondary: not yet implemented */ - case 3: /* interface */ - /* todo: secondary: not yet implemented */ - default: /* sinfox list server command commandName */ - setOKE(objName, keyName, eltName, "server", "command", objName); - break; - } - } - } - - if (0 == strcmp(objName, "server")) { - iRet = EnumChoice(pServerKeys, iNumServerKeys, keyName); - /* if invalid (iRet < 0) then default to "help" command */ - switch (iRet) { - /* cases that have no eltName argument */ - case 1: /* list */ - case 3: /* connection */ - case 6: /* experiment */ - case 9: /* key */ - return SinfoxEnumerate(pSin, pSics, pCon, keyName); - break; - /* cases that are not fully implemented */ - case 2: /* command */ - case 4: /* device */ - case 5: /* deviceType */ - case 7: /* group */ - case 8: /* interface */ - return SinfoxShow(pSin, pSics, pCon, keyName, eltName); - break; - /* fully functional cases */ - case 0: /* help */ - default: - return SinfoxHelp(pSin, pSics); - break; - } - return 1; - } - return 0; -} - -/*------------------------------------------------------------------------*/ -/* Retrieve a list of elements from CommandList matching criteria */ -static int SinfoxEnumerate(pSinfox pSin, SicsInterp * pSics, - SConnection * pCon, char *keyName) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - Tcl_Interp *tTcl; - Tcl_Obj *tList; - IPair *pOption = NULL; - IPair *pGroups = NULL; - pSicsVariable pSVar = NULL; - int iRet; - char pBuf[256], *pPtr = NULL; - int checkDeviceTypes[iNumDeviceTypes]; - - pCurrent = pSics->pCList; - tTcl = (Tcl_Interp *) (pSics->pTcl); - tList = Tcl_NewListObj(0, NULL); - memset(pBuf, 0, 256); - - iRet = EnumChoice(pServerKeys, iNumServerKeys, keyName); - /* if invalid (iRet < 0) then default to "help" command */ - switch (iRet) { - /* cases that have no eltName argument - not fully implemented */ - case 1: /* list */ - addToList(tTcl, tList, "buildVersion", (char *) (pSin->buildVersion)); - addToList(tTcl, tList, "configName", (char *) (pSin->configName)); - addToList(tTcl, tList, "configVersion", - (char *) (pSin->configVersion)); - addToList(tTcl, tList, "description", (char *) (pSin->description)); - addToList(tTcl, tList, "instrument", (char *) (pSin->instrument)); - addToList(tTcl, tList, "schemaVersion", - (char *) (pSin->schemaVersion)); - addPairsToList(tTcl, tList, pSin->pDes->pKeys); - addPairsToList(tTcl, tList, pSICSOptions); - break; - case 2: /* command */ - while (pCurrent) { - if (1 == isObjectCommand(pCurrent)) { - strcpy(pBuf, pCurrent->pName); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - pCurrent = pCurrent->pNext; - } - break; - case 3: /* connection */ - sprintf(pBuf, "%d", SCGetRights(pCon)); - addToList(tTcl, tList, "userAccessLevel", pBuf); - addToList(tTcl, tList, "protocol", GetProtocolName(pCon)); - break; - case 6: /* experiment */ - while (pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - strcpy(pBuf, pDes->name); - strtolower(pBuf); - if (0 == strcmp(pBuf, "sicsvariable")) { - pSVar = FindVariable(pSics, pCurrent->pName); - addToList(tTcl, tList, pCurrent->pName, pSVar->text); - } - } - pCurrent = pCurrent->pNext; - } - break; - case 9: /* key */ - for (iRet = 0; iRet < iNumServerKeys; iRet++) { - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pServerKeys[iRet], - strlen(pServerKeys - [iRet]))); - } - break; - /* cases that have not specified eltName */ - case 4: /* device */ - while (pCurrent) { - if (1 == isObjectDevice(pCurrent)) { - strcpy(pBuf, pCurrent->pName); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - pCurrent = pCurrent->pNext; - } - break; - case 5: /* deviceType */ - for (iRet = 0; iRet < iNumDeviceTypes; iRet++) { - checkDeviceTypes[iRet] = 0; - } - while (pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - strcpy(pBuf, pDes->name); - strtolower(pBuf); - iRet = EnumChoice(pDeviceTypes, iNumDeviceTypes, pBuf); - if (-1 < iRet) { - if (1 != checkDeviceTypes[iRet]) { - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - checkDeviceTypes[iRet] = 1; - } - } - } - pCurrent = pCurrent->pNext; - } - break; - case 7: /* group */ - pCurrent = pSics->pCList; - /* Always add default group "none" */ - pGroups = IFAddOption(pGroups, "none", "OK"); - Tcl_ListObjAppendElement(tTcl, tList, Tcl_NewStringObj("none", 4)); - while (pCurrent) { - if (1 == isObjectDevice(pCurrent)) { - pDes = FindDescriptor(pCurrent->pData); - if ((pPtr = IFindOption(pDes->pKeys, "group")) != NULL) { - strcpy(pBuf, pPtr); - strtolower(pBuf); - if (NULL == IFindOption(pGroups, pBuf)) { - pGroups = IFAddOption(pGroups, pBuf, "OK"); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - } - } - pCurrent = pCurrent->pNext; - } - if (NULL != pGroups) { - IFDeleteOptions(pGroups); - } - break; - case 8: /* interface */ - for (iRet = 0; iRet < iNumIFaces; iRet++) { - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pIFaces[iRet], - strlen(pIFaces[iRet]))); - } - break; - /* special cases */ - case 0: /* help */ - default: - return SinfoxHelp(pSin, pSics); - break; - } - Tcl_SetObjResult(tTcl, tList); - return 1; -} - -/*------------------------------------------------------------------------*/ -static int SinfoxShow(pSinfox pSin, SicsInterp * pSics, SConnection * pCon, - char *keyName, char *eltName) -{ - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - Tcl_Interp *tTcl; - Tcl_Obj *tList; - int iRet, iType; - char pBuf[256]; - char *pTmp; - char *pElt; - - pCurrent = pSics->pCList; - tTcl = (Tcl_Interp *) (pSics->pTcl); - tList = Tcl_NewListObj(0, NULL); - memset(pBuf, 0, 256); - - if (NULL == eltName) { - return SinfoxEnumerate(pSin, pSics, pCon, keyName); - } - pElt = strdup(eltName); - strtolower(pElt); - - iRet = EnumChoice(pServerKeys, iNumServerKeys, keyName); - /* if invalid (iRet < 0) then default to "help" command */ - switch (iRet) { - case 2: /* command */ - case 4: /* device - list deviceName {attribute|command|interface} */ - //addToList(tTcl,tList,pElt,"is being searched for"); - pCurrent = FindCommand(pSics, pElt); - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - //addToList(tTcl,tList,"debug2","descriptor found"); - if (1 == isObjectDevice(pCurrent)) { - if (NULL != pDes->name) { - strcpy(pBuf, pDes->name); - strtolower(pBuf); - addToList(tTcl, tList, "devicetype", pBuf); - } - if ((pTmp = IFindOption(pDes->pKeys, "group")) != NULL) { - strcpy(pBuf, pTmp); - strtolower(pBuf); - addToList(tTcl, tList, "group", pBuf); - } - } - if ((pTmp = IFindOption(pDes->pKeys, "description")) != NULL) { - strcpy(pBuf, pTmp); - strtolower(pBuf); - addToList(tTcl, tList, "description", pBuf); - } - //addToList(tTcl,tList,"debug3","default fields processed"); - if (NULL != pDes->pKeys) { - addPairsToList(tTcl, tList, pDes->pKeys); - } - } - } - //addToList(tTcl,tList,"debug4","device show finished"); - break; - case 5: /* devicetype */ - iRet = EnumChoice(pDeviceTypes, iNumDeviceTypes, pElt); - if (0 > iRet) { - if ((0 == strcmp(pElt, "all")) || (0 == strcmp(pElt, "*"))) { - Tcl_SetVar(tTcl, "name", keyName, 0); - return SinfoxEnumerate(pSin, pSics, pCon, keyName); - } - } else { - while (pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - strcpy(pBuf, pDes->name); - strtolower(pBuf); - if (0 == strcmp(pElt, pBuf)) { - strcpy(pBuf, pCurrent->pName); - strtolower(pBuf); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - } - pCurrent = pCurrent->pNext; - } - } - break; - case 7: /* group */ - if ((0 == strcmp(pElt, "all")) || (0 == strcmp(pElt, "*"))) { - Tcl_SetVar(tTcl, "name", keyName, 0); - return SinfoxEnumerate(pSin, pSics, pCon, keyName); - } - while (NULL != pCurrent) { - if (1 == isObjectDevice(pCurrent)) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - if ((pTmp = IFindOption(pDes->pKeys, "group")) == NULL) { - strcpy(pBuf, "none"); - } else { - strcpy(pBuf, pTmp); - strtolower(pBuf); - } - if (0 == strcmp(pElt, pBuf)) { - strcpy(pBuf, pCurrent->pName); - strtolower(pBuf); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - } - } - pCurrent = pCurrent->pNext; - } - break; - case 8: /* interface */ - iRet = EnumChoice(pIFaces, iNumIFaces, pElt); - if (0 > iRet) { - if ((0 == strcmp(pElt, "all")) || (0 == strcmp(pElt, "*"))) { - Tcl_SetVar(tTcl, "name", keyName, 0); - return SinfoxEnumerate(pSin, pSics, pCon, keyName); - } - } else { - switch (iRet) { - case 0: /* callback */ - iType = CALLBACKINTERFACE; - break; - case 1: /* countable */ - iType = COUNTID; - break; - case 2: /* drivable */ - iType = DRIVEID; - break; - case 3: /* environment */ - iType = ENVIRINTERFACE; - break; - default: /* interface not recognised */ - Tcl_SetObjResult(tTcl, tList); - return 1; - break; - } - while (pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - if (NULL != pDes->GetInterface(pDes, iType)) { - strcpy(pBuf, pCurrent->pName); - strtolower(pBuf); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - } - pCurrent = pCurrent->pNext; - } - } - break; - default: - addToList(tTcl, tList, "error", "unknown key"); - break; - } - Tcl_SetObjResult(tTcl, tList); - return 1; -} - -/*-------------------------------------------------------------------------*/ -static int SinfoxDevice(pSinfox pSin, SicsInterp * pSics, - SConnection * pCon, char *devName, char *keyName, - char *eltName) -{ - int i, iRet, iType; - Tcl_Obj *tList; - char pBuf[256]; - char *pTmp; - CommandList *pCurrent; - pObjectDescriptor pDes = NULL; - - memset(pBuf, 0, 256); - pCurrent = pSics->pCList; - tList = Tcl_NewListObj(0, NULL); - pCurrent = FindCommand(pSics, devName); -/* debug */ - addToList(pSin->tTcl, tList, "dev", devName); - addToList(pSin->tTcl, tList, "key", keyName); - addToList(pSin->tTcl, tList, "elt", eltName); -/*-------*/ - iRet = EnumChoice(pDeviceKeys, iNumDeviceKeys, keyName); - switch (iRet) { - case 2: /* interface */ - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - for (i = 0; i < iNumIFaces; i++) { - switch (i) { - case 0: /* callback */ - iType = CALLBACKINTERFACE; - break; - case 1: /* countable */ - iType = COUNTID; - break; - case 2: /* drivable */ - iType = DRIVEID; - break; - case 3: /* environment */ - iType = ENVIRINTERFACE; - break; - default: /* interface not recognised */ - Tcl_SetObjResult(pSin->tTcl, tList); - return 0; - break; - } - if (NULL != pDes->GetInterface(pDes, iType)) { - strcpy(pBuf, pIFaces[i]); - Tcl_ListObjAppendElement(pSin->tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } - } - } - } - break; - case 0: /* attribute */ - if (NULL == eltName) { - return SinfoxShow(pSin, pSics, pCon, "device", devName); - } else { - if (NULL != pCurrent) { - pDes = FindDescriptor(pCurrent->pData); - if (NULL != pDes) { - pTmp = IFindOption(pDes->pKeys, eltName); - if (NULL != pTmp) { - strcpy(pBuf, pTmp); - addToList(pSin->tTcl, tList, eltName, pTmp); - } - } - } - } - break; - case 1: /* command */ - /* todo: secondary: not yet implemented */ - default: /* sinfox list server device deviceName */ - return SinfoxShow(pSin, pSics, pCon, "device", devName); - break; - } - Tcl_SetObjResult(pSin->tTcl, tList); - return 1; -} - -/*-------------------------------------------------------------------------*/ -int SinfoxAction(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) -{ - int iRet; - char **argx; - FuPaResult PaRes; - pSinfox pSin = NULL; - - const int iNumCmds = 8; - FuncTemplate CommandTemplate[] = { - {"help", 0, {0, 0}}, - {"list", 3, {FUPATEXT, FUPATEXT, FUPAOPT}}, - {"setdesc", 2, {FUPATEXT, FUPATEXT}}, - {"setgrp", 2, {FUPATEXT, FUPATEXT}}, - {"setkey", 3, {FUPATEXT, FUPATEXT, FUPATEXT}}, - {"reset", 0, {0, 0}}, - {"readkey", 2, {FUPATEXT, FUPATEXT}}, - {"getgrp", 1, {FUPATEXT}}, - {NULL} - }; - - assert(pCon); - assert(pSics); - pSin = (pSinfox) pData; - assert(pSin); - - /* You need to have User level access rights to use this facility */ - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - - /* parse function args */ - argtolower(argc, argv); - argx = &argv[1]; - iRet = - EvaluateFuPa((pFuncTemplate) & CommandTemplate, iNumCmds, argc - 1, - argx, &PaRes); - /* if invalid (iRet < 0) then default to "help" command */ - switch (iRet) { - case 1: /* list */ - if (1 == PaRes.Arg[2].iVal) { - iRet = SinfoxList(pSin, pSics, pCon, - PaRes.Arg[0].text, PaRes.Arg[1].text, - PaRes.Arg[2].text); - } else { - iRet = SinfoxList(pSin, pSics, pCon, - PaRes.Arg[0].text, PaRes.Arg[1].text, NULL); - } - return iRet; - break; - case 2: /* setdesc */ - return SinfoxSetDesc(pSin, pSics, - PaRes.Arg[0].text, PaRes.Arg[1].text); - break; - case 3: /* setgrp */ - return SinfoxSetGrp(pSin, pSics, PaRes.Arg[0].text, PaRes.Arg[1].text); - break; - case 4: /* setkey */ - return SinfoxSetKey(pSin, pSics, - PaRes.Arg[0].text, PaRes.Arg[1].text, - PaRes.Arg[2].text); - break; - case 5: /* reset */ - return SinfoxReset(pSin, pSics); - break; - case 6: /* readkey */ - return SinfoxReadKey(pSin, pSics, - PaRes.Arg[0].text, PaRes.Arg[1].text); - break; - case 7: /*getgrp */ - return SinfoxGetGrp(pSin, pSics, PaRes.Arg[0].text); - break; - case 0: /* help */ - default: - return SinfoxHelp(pSin, pSics); - break; - } - return 1; -} - -/*-------------------------------------------------------------------------*/ -static int EnumChoice(char *pList[], int iLength, char *pInput) -{ - int i; - int iRet = -1; - - for (i = 0; i < iLength; i++) { - if (0 == strcmp(pInput, pList[i])) { - iRet = i; - break; - } - } - return iRet; -} - -/*-------------------------------------------------------------------------*/ -static int LinkVar(char *tcl_var_name, char *pAddress, int link_flags) -{ - SicsInterp *pSics = NULL; - Tcl_Interp *pTcl = NULL; - int tcl_flags = TCL_LINK_INT; - - pSics = GetInterpreter(); - pTcl = (Tcl_Interp *) (pSics->pTcl); - /* tcl_flags = f(link_flags) */ - switch (link_flags) { - case TCL_LINK_INT: - break; - case TCL_LINK_DOUBLE: - case TCL_LINK_BOOLEAN: - case TCL_LINK_STRING: - tcl_flags = link_flags; - break; - default: - return 0; - } - Tcl_LinkVar(pTcl, tcl_var_name, pAddress, tcl_flags); - return 1; -} - -/*-------------------------------------------------------------------------*/ -static void setOKE(char *obj, char *key, char *elt, char *oVal, char *kVal, - char *eVal) -{ - char *eBuf; - char *kBuf; - char *oBuf; - eBuf = strdup(eVal); - kBuf = strdup(kVal); - oBuf = strdup(oVal); - free(elt); - elt = eBuf; - free(key); - key = kBuf; - free(obj); - obj = oBuf; -} - -/*-------------------------------------------------------------------------*/ -static int isNameDevice(char *name) -{ - SicsInterp *pSics; - CommandList *pObj = NULL; - Dummy *pDum = NULL; - - pSics = GetInterpreter(); - pObj = FindCommand(pSics, name); - if (NULL != pObj) { - pDum = (Dummy *) pObj->pData; - if (NULL != pDum) { - if (NULL != pDum->pDescriptor->GetInterface(pDum, DRIVEID)) - return 1; - if (NULL != pDum->pDescriptor->GetInterface(pDum, COUNTID)) - return 1; - if (NULL != pDum->pDescriptor->GetInterface(pDum, ENVIRINTERFACE)) - return 1; - } - } - return 0; -} - -/*-------------------------------------------------------------------------*/ -static int isNameCommand(char *name) -{ - SicsInterp *pSics; - CommandList *pObj = NULL; - Dummy *pDum = NULL; - - pSics = GetInterpreter(); - pObj = FindCommand(pSics, name); - if (NULL != pObj) { - pDum = (Dummy *) pObj->pData; - if (NULL != pDum) { - if (NULL != pDum->pDescriptor->GetInterface(pDum, DRIVEID)) - return 0; - if (NULL != pDum->pDescriptor->GetInterface(pDum, COUNTID)) - return 0; - if (NULL != pDum->pDescriptor->GetInterface(pDum, ENVIRINTERFACE)) - return 0; - } - return 1; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ -static int isObjectDevice(CommandList * pObj) -{ - Dummy *pDum = NULL; - if (NULL != pObj) { - pDum = (Dummy *) pObj->pData; - if (NULL != pDum) { - if (NULL != pDum->pDescriptor->GetInterface(pDum, DRIVEID)) - return 1; - if (NULL != pDum->pDescriptor->GetInterface(pDum, COUNTID)) - return 1; - if (NULL != pDum->pDescriptor->GetInterface(pDum, ENVIRINTERFACE)) - return 1; - } - } - return 0; -} - -/*-------------------------------------------------------------------------*/ -static int isObjectCommand(CommandList * pObj) -{ - Dummy *pDum = NULL; - if (NULL != pObj) { - pDum = (Dummy *) pObj->pData; - if (NULL != pDum) { - if (NULL != pDum->pDescriptor->GetInterface(pDum, DRIVEID)) - return 0; - if (NULL != pDum->pDescriptor->GetInterface(pDum, COUNTID)) - return 0; - if (NULL != pDum->pDescriptor->GetInterface(pDum, ENVIRINTERFACE)) - return 0; - } - return 1; - } - return 0; -} - -/*-------------------------------------------------------------------------*/ -static void addToList(Tcl_Interp * tTcl, Tcl_Obj * tList, char *prefix, - char *sVal) -{ - char pBuf[256]; - if (NULL != sVal) { - memset(pBuf, 0, 256); - sprintf(pBuf, "%s=%s", prefix, sVal); - Tcl_ListObjAppendElement(tTcl, tList, - Tcl_NewStringObj(pBuf, strlen(pBuf))); - } -} - -/*-------------------------------------------------------------------------*/ -static void addPairsToList(Tcl_Interp * tTcl, Tcl_Obj * tList, - IPair * pList) -{ - IPair *pCurrent; - if (NULL != pList) { - pCurrent = pList; - while (NULL != pCurrent) { - addToList(tTcl, tList, pCurrent->name, pCurrent->value); - pCurrent = pCurrent->pNext; - } - } -} - -/*--------------------------------------------------------------------------*/ -static void RemoveWhiteSpace(char *pText) -{ - int i, ii, i3; - char *pPtr; - - if (NULL == pText) - return; - - /* find start */ - i = 0; - while (isspace(pText[i])) { - i++; - } - - /* find end */ - ii = strlen(pText); - ii--; - while ((isspace(pText[ii])) || (pText[ii] == '\n')) { - ii--; - } - - /* copy it */ - pPtr = pText; - for (i3 = i; i3 < (ii + 1); i3++) { - *pPtr = pText[i3]; - pPtr++; - } - *pPtr = '\0'; -} diff --git a/sinfox.h b/sinfox.h deleted file mode 100644 index c256c259..00000000 --- a/sinfox.h +++ /dev/null @@ -1,115 +0,0 @@ -/*--------------------------------------------------------------------------- -----------------------------------------------------------------------------*/ -#ifndef ANSTO_SINFOX -#define ANSTO_SINFOX -#include -#include - -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 */ From 1c9b490da939bf7a3a6c5a4a2a08eb6475807acb Mon Sep 17 00:00:00 2001 From: koennecke Date: Tue, 13 Dec 2016 14:02:27 +0100 Subject: [PATCH 39/39] Fixed excessive magic errors originating from sicsget:PutHdbFunc --- sicsget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sicsget.c b/sicsget.c index 117af0d5..0b17fc2c 100644 --- a/sicsget.c +++ b/sicsget.c @@ -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;