diff --git a/conman.c b/conman.c index 04ef37a3..1b47579c 100644 --- a/conman.c +++ b/conman.c @@ -82,6 +82,10 @@ extern pServer pServ; #include "outcode.c" /* text for OutCode */ +int KillCapture(SConnection * pCon); + +int LogCapture(SConnection * pCon, SicsInterp * pInter, void *pData, + int argc, char *argv[]); /*------ Max Size of Command Stack */ #define MAXSTACK 1024 @@ -2113,6 +2117,83 @@ int ConSicsAction(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } +static void hookFunc(const char *pText, OutCode eOut, void*pData) +{ + SConnection *pCon = (SConnection *) pData; + int text_len = strlen(pText); + + ANETwrite(pCon->sockHandle, pText, text_len); + if (pText[text_len - 1] != '\n') + ANETwrite(pCon->sockHandle, "\n", 1); +} + +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[]) +{ + char pBueffel[512]; + int i; + + /* 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) { + KillCapture(pCon); + return 1; + } else if (strcmp(argv[1], "all") == 0) { + AddSICSLogHook(hookFunc, "all", pCon); + return 1; + } else if (argc == 2) { + /* must be outcode, try find it */ + AddSICSLogHook(hookFunc, argv[1], pCon); + return 1; + } else { + /* make it a list */ + int i, 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]); + } + AddSICSLogHook(hookFunc, pBuff, pCon); + if (pBuff != pBueffel) + free(pBuff); + return 1; + } + return 0; +} /*--------------------------------------------------------------------------*/ int SCTaskFunction(void *pData) { diff --git a/servlog.c b/servlog.c index a4e0ec47..250e2189 100644 --- a/servlog.c +++ b/servlog.c @@ -59,7 +59,6 @@ #include #include "ifile.h" -#include "conman.h" #include "servlog.h" #include "network.h" @@ -72,15 +71,16 @@ this the following code is necessary. */ typedef struct __LogLog { - SConnection *pCon; - OutCode iOut; - int iAllFlag; + 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 */ static char* OutCodeToTxt(OutCode eOut) { @@ -104,14 +104,68 @@ static char* OutCodeToTxt(OutCode eOut) return "???"; } -int KillCapture(SConnection * pCon) +static unsigned int find_code_bits(const char *p1, const char *p2) { + /* must be outcode, try find it */ + int i; + int len = p2 - p1; + if (len == 3 && strncasecmp(p1, "all", 3)) + return ~0; + for (i = 0; i < iNoCodes; ++i) { + if (pCode[i] != NULL && strlen(pCode[i]) == len) { + if (strncasecmp(p1, pCode[i], 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 = ~0; + 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 (pCon == pCurrent->pCon) { + if (pData == pCurrent->pData) { /* relink */ if (pCurrent->pPrevious) { pCurrent->pPrevious->pNext = pCurrent->pNext; @@ -129,88 +183,10 @@ int KillCapture(SConnection * pCon) pCurrent = pCurrent->pNext; } } - return 1; + return NULL; } -/* ------------------------------------------------------------------------ - the command function: - Syntax: - Kill kills all logging - Log OutCode starts loggin OutCode events - All starts logging all events --------------------------------------------------------------------------- */ -#include "outcode.c" /* for pCode */ - -int LogCapture(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) -{ - pCaptureEntry pNew = NULL; - char pBueffel[512]; - int i; - - /* 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) { - KillCapture(pCon); - return 1; - } else if (strcmp(argv[1], "all") == 0) { - pNew = (pCaptureEntry) malloc(sizeof(CaptureEntry)); - if (!pNew) { - SICSLogWrite("Out of memory in LogCapture", eInternal); - return 0; - } - if (pCapture) { - pCapture->pPrevious = pNew; - } - pNew->pPrevious = NULL; - pNew->pNext = pCapture; - pCapture = pNew; - pNew->iAllFlag = 1; - pNew->pCon = pCon; - return 1; - } else { - /* must be outcode, try find it */ - i = 0; - while (pCode[i] != NULL) { - if (strcmp(argv[1], pCode[i]) == 0) { - break; - } - i++; - } - if (i > iNoCodes) { - snprintf(pBueffel,sizeof(pBueffel)-1, "OutPutCode %s not recognized in %s", argv[1], - argv[0]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - /* create a new one */ - pNew = (pCaptureEntry) malloc(sizeof(CaptureEntry)); - if (!pNew) { - SICSLogWrite("Out of memory in LogCapture", eInternal); - return 0; - } - if (pCapture) { - pCapture->pPrevious = pNew; - } - pNew->pPrevious = NULL; - pNew->pNext = pCapture; - pCapture = pNew; - pNew->iAllFlag = 0; - pNew->pCon = pCon; - pNew->iOut = i; - return 1; - } - return 0; -} - /*--------------------------------------------------------------------------*/ static int HasLineFeed(char *pText) { @@ -310,10 +286,8 @@ static void SICSLogWriteFile(char *pText, OutCode eOut, struct timeval *tp) /* do all captured */ pCurrent = pCapture; while (pCurrent) { - if ((pCurrent->iOut == eOut) || (pCurrent->iAllFlag == 1)) { - ANETwrite(pCurrent->pCon->sockHandle, pText, text_len); - if (pText[text_len - 1] != '\n') - ANETwrite(pCurrent->pCon->sockHandle, "\n", 1); + if ((pCurrent->code_bits & (1 << eOut))) { + pCurrent->pFunc(pText, eOut, pCurrent->pData); } pCurrent = pCurrent->pNext; } diff --git a/servlog.h b/servlog.h index ebe788d1..08c147e7 100644 --- a/servlog.h +++ b/servlog.h @@ -31,8 +31,7 @@ void SICSLogTimePrintf(OutCode eOut, struct timeval *tp, const char *fmt, ...) G_GNUC_PRINTF (3, 4); #undef G_GNUC_PRINTF void SICSLogEnable(int flag); -int KillCapture(SConnection * pCon); - -int LogCapture(SConnection * pCon, SicsInterp * pInter, void *pData, - int argc, char *argv[]); +typedef void (*pSICSLogHook)(const char *pText, OutCode eOut, void *pData); +char *AddSICSLogHook(pSICSLogHook func, const char *pCodes, void *pData); +char *RemSICSLogHook(void *pData); #endif