in src/generic/log.c [467:763]
int Web_LogDest(ClientData clientData,
Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[])
{
LogData *logData = NULL;
int idx;
int iCurArg;
static TCLCONST char *params[] = { "-maxchar",
"-format",
NULL
};
enum params
{ MAXCHAR, FORMAT };
static TCLCONST char *subCommands[] = {
WEB_LOG_SUBCMD_ADD,
WEB_LOG_SUBCMD_DELETE,
WEB_LOG_SUBCMD_NAMES,
WEB_LOG_SUBCMD_LEVELS,
NULL
};
enum subCommands
{ ADD, DELETE, NAMES, LEVELS };
/* --------------------------------------------------------------------------
* check for internal data
* ----------------------------------------------------------------------- */
WebAssertData(interp, clientData, "Web_LogDest", TCL_ERROR)
logData = (LogData *) clientData;
/* --------------------------------------------------------------------------
* check arguments
* ----------------------------------------------------------------------- */
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
return TCL_ERROR;
}
/* --------------------------------------------------------------------------
* scan for options
* ----------------------------------------------------------------------- */
if (Tcl_GetIndexFromObj(interp, objv[1], subCommands, "option", 0, &idx)
!= TCL_OK)
return TCL_ERROR;
/* --------------------------------------------------------------------------
* switch on subcommand
* ----------------------------------------------------------------------- */
switch ((enum subCommands) idx) {
case ADD:{
/* ------------------------------------------------------------------------
* ok, add sytnax is as follows:
* web::logdest add [-format bla -maxchar 100] level {type specific stuff}
* 0 1 2 j j+1
* --------------------------------------------------------------------- */
char *name = NULL;
char *format = NULL;
LogLevel *logLevel = NULL;
LogPlugIn *logPlugIn = NULL;
ClientData logPlugInData = NULL;
LogDest *logDest = NULL;
Tcl_Obj *tcloTmp;
long maxCharInMsg = -1;
int iUnknown = 0;
/* argdbg(objc,objv,stdout); */
iCurArg =
argIndexOfFirstArg(objc - 1, &(objv[1]), params, NULL) + 1;
/* check for known options */
iUnknown =
argHasOnlyAccepted(objc - 1, &(objv[1]), params, iCurArg - 1);
if (iUnknown > 0) {
/* let Tcl format the error message */
Tcl_GetIndexFromObj(interp, objv[iUnknown + 1], params,
"option", 0, &idx);
return TCL_ERROR;
}
/* check for -format */
if ((tcloTmp = argValueOfKey(objc, objv, (char *)params[FORMAT])) != NULL) {
format = allocAndSet(Tcl_GetString(tcloTmp));
}
else {
format = allocAndSet(WEB_LOG_DEFAULTFORMAT);
}
/* check for -maxchar */
if ((tcloTmp =
argValueOfKey(objc, objv, (char *)params[MAXCHAR])) != NULL) {
if (Tcl_GetLongFromObj(interp, tcloTmp, &maxCharInMsg) ==
TCL_ERROR) {
LOG_MSG(interp, WRITE_LOG | SET_RESULT, __FILE__,
__LINE__, "web::logdest", WEBLOG_INFO,
"cannot read long from -maxchar \"",
Tcl_GetString(tcloTmp), "\"", NULL);
return TCL_ERROR;
}
}
/* ------------------------------------------------------------------------
* now iCurArg is level, iCurArg+1 is type, (+2 is type specific)
* --------------------------------------------------------------------- */
if ((iCurArg + 1) >= objc) {
Tcl_WrongNumArgs(interp, 1, objv, WEB_LOG_USAGE_LOGDEST_ADD);
WebFreeIfNotNull(format);
return TCL_ERROR;
}
/* ------------------------------------------------------------------------
* get handler for type
* --------------------------------------------------------------------- */
logPlugIn = (LogPlugIn *) getFromHashTable(logData->listOfPlugIns,
Tcl_GetString(objv
[iCurArg
+ 1]));
if (logPlugIn == NULL) {
Tcl_SetResult(interp, "no log handler of type \"", NULL);
Tcl_AppendResult(interp, Tcl_GetString(objv[iCurArg + 1]),
"\" registered", NULL);
WebFreeIfNotNull(format);
return TCL_ERROR;
}
/* ------------------------------------------------------------------------
* parse level
* --------------------------------------------------------------------- */
logLevel =
parseLogLevel(interp, Tcl_GetString(objv[iCurArg]), "user",
-1);
if (logLevel == NULL) {
WebFreeIfNotNull(format);
return TCL_ERROR;
}
/* ------------------------------------------------------------------------
* call constructor
* --------------------------------------------------------------------- */
if ((logPlugInData =
logPlugIn->constructor(interp,
clientData, objc - (iCurArg + 1),
&(objv[iCurArg + 1]))) == NULL) {
destroyLogLevel(logLevel, NULL);
WebFreeIfNotNull(name);
WebFreeIfNotNull(format);
return TCL_ERROR;
}
/* ------------------------------------------------------------------------
* ok, make the logDest
* --------------------------------------------------------------------- */
logDest = createLogDest();
if (logDest == NULL) {
Tcl_SetResult(interp, "cannot create log destination", NULL);
destroyLogLevel(logLevel, NULL);
WebFreeIfNotNull(name);
WebFreeIfNotNull(format);
return TCL_ERROR;
}
logDest->filter = logLevel;
logDest->format = format;
logDest->plugIn = logPlugIn;
logDest->plugInData = logPlugInData;
logDest->maxCharInMsg = maxCharInMsg;
logDest->keep = logData->keep;
/* ----------------------------------------------------------
* and add to list
* ---------------------------------------------------------- */
name = insertIntoDestList(logData, logDest);
if (name == NULL) {
Tcl_SetResult(interp, "cannot append new log destination to list", NULL);
destroyLogDest(logDest, interp);
destroyLogLevel(logLevel, NULL);
WebFreeIfNotNull(format);
return TCL_ERROR;
}
Tcl_SetResult(interp, name, Tcl_Free);
return TCL_OK;
}
case NAMES:{
Tcl_ResetResult(interp);
if (logData->listOfDests != NULL) {
int i;
LogDest ** logDests = logData->listOfDests;
for (i = 0; i < logData->destSize; i++) {
if (logDests[i] != NULL) {
char *name = createLogName(LOG_DEST_PREFIX, i);
if (name != NULL) {
Tcl_AppendElement(interp, name);
Tcl_Free(name);
}
}
}
}
return TCL_OK;
}
case LEVELS:{
int namesIsFirst = TCL_OK;
LogDest *logDest = NULL;
Tcl_SetResult(interp, "", NULL);
if (logData->listOfDests != NULL) {
int i;
LogDest ** logDests = logData->listOfDests;
for (i = 0; i < logData->destSize; i++) {
if (logDests[i] != NULL) {
char * name = createLogName(LOG_DEST_PREFIX, i);
if (namesIsFirst == TCL_ERROR)
Tcl_AppendResult(interp, "\n", NULL);
else
namesIsFirst = TCL_ERROR;
logDest = logDests[i];
Tcl_AppendResult(interp,
name, " ",
logDest->filter->facility, ".",
getSeverityName(logDest->filter->
minSeverity), "-",
getSeverityName(logDest->filter->
maxSeverity), NULL);
Tcl_Free(name);
}
}
}
return TCL_OK;
}
case DELETE:{
/* 0 1 2 */
/* web::loglogDest delete logDest1 */
switch (objc) {
case 3: {
LogDest ** logDests = logData->listOfDests;
if (!strcmp("-requests", Tcl_GetString(objv[2]))) {
/* special case: delete all destinations NOT created during web::initializer */
int i;
for (i = 0; i < logData->destSize; i++) {
if (logDests[i] != NULL && !logDests[i]->keep) {
destroyLogDest(logDests[i], interp);
logDests[i] = NULL;
}
}
return TCL_OK;
} else {
int inx = getIndexFromLogName(LOG_DEST_PREFIX"%d", Tcl_GetString(objv[2]));
if (inx < 0
|| inx >= logData->destSize
|| logDests[inx] == NULL) {
Tcl_SetResult(interp, "no such log destination \"", NULL);
Tcl_AppendResult(interp, Tcl_GetString(objv[2]), "\"",
NULL);
return TCL_ERROR;
}
destroyLogDest(logDests[inx], interp);
logDests[inx] = NULL;
return TCL_OK;
break;
}
}
case 2:
/* --------------------------------------------------------
* no argument --> resets the list
* -------------------------------------------------------- */
if (logData->listOfDests != NULL) {
int i;
LogDest ** logDests = logData->listOfDests;
for (i = 0; i < logData->destSize; i++) {
if (logDests[i] != NULL) {
destroyLogDest(logDests[i], interp);
logDests[i] = NULL;
}
}
}
return TCL_OK;
break;
default:
Tcl_WrongNumArgs(interp, 1, objv, "delete ?destname?");
return TCL_ERROR;
}
break;
}
default:
return TCL_OK;
}
}