101 lines
2.5 KiB
C
101 lines
2.5 KiB
C
/**
|
|
* This is a means to listen into the stream of log messages from the logv2
|
|
* logging system.
|
|
*
|
|
* Mark Koennecke, May 2016
|
|
*/
|
|
#include <sics.h>
|
|
#include <logv2.h>
|
|
#include <lld.h>
|
|
|
|
/*
|
|
From logv2.c
|
|
*/
|
|
extern int subsystemFromText(const char *text);
|
|
/*=============================================================================*/
|
|
static int listenerList;
|
|
static int callbackRegistered = 0;
|
|
|
|
typedef struct {
|
|
SConnection *pCon;
|
|
char subsystem[64];
|
|
} ListenEntry;
|
|
/*-----------------------------------------------------------------------------*/
|
|
static void LogListenCallback(unsigned int severity, const char *timeStamp,
|
|
const char *subsystem,
|
|
const char *message, void *userData)
|
|
{
|
|
ListenEntry current;
|
|
int status, cleanupNeeded = 0;
|
|
|
|
if(logFilter(severity,subsystem,message) == 1) {
|
|
return;
|
|
}
|
|
|
|
|
|
status = LLDnodePtr2First(listenerList);
|
|
while(status != 0){
|
|
LLDnodeDataTo(listenerList,¤t);
|
|
if(strcmp(current.subsystem,subsystem) == 0) {
|
|
if(SCisConnected(current.pCon)){
|
|
SCPureSockWrite(current.pCon,(char *)message,eValue);
|
|
} else {
|
|
cleanupNeeded = 1;
|
|
}
|
|
}
|
|
status = LLDnodePtr2Next(listenerList);
|
|
}
|
|
|
|
/*
|
|
lld lists sometimes get confused when deleting nodes on the fly.
|
|
This is why this has been put into a separate loop
|
|
*/
|
|
if(cleanupNeeded){
|
|
status = LLDnodePtr2First(listenerList);
|
|
while(status != 0){
|
|
LLDnodeDataTo(listenerList,¤t);
|
|
if(!SCisConnected(current.pCon)){
|
|
SCDeleteConnection(current.pCon);
|
|
LLDnodeDelete(listenerList);
|
|
}
|
|
status = LLDnodePtr2Next(listenerList);
|
|
}
|
|
}
|
|
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
static int LogListenAction(SConnection * pCon, SicsInterp * pSics,
|
|
void *pData, int argc, char *argv[])
|
|
{
|
|
ListenEntry listLog;
|
|
|
|
if(argc < 2){
|
|
SCWrite(pCon,"ERROR: need subsystem argument for loglisten", eError);
|
|
return 0;
|
|
}
|
|
|
|
if(subsystemFromText(argv[1]) < 0){
|
|
SCPrintf(pCon,eError, "ERROR: invalid subsystem %s specified", argv[1]);
|
|
return 0;
|
|
}
|
|
|
|
|
|
listLog.pCon = SCCopyConnection(pCon);
|
|
strncpy(listLog.subsystem,argv[1],sizeof(listLog.subsystem));
|
|
LLDnodeAppendFrom(listenerList,&listLog);
|
|
|
|
if(!callbackRegistered){
|
|
RegisterLogCallback(LogListenCallback,NULL);
|
|
callbackRegistered = 1;
|
|
}
|
|
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------------*/
|
|
void LogListenInit(void)
|
|
{
|
|
listenerList = LLDcreate(sizeof(ListenEntry));
|
|
AddCmd("loglisten", LogListenAction);
|
|
}
|