src/generic/logtofile.c (87 lines of code) (raw):

/* * logtofile.c -- plugin for log module of websh3 * nca-073-9 * * Copyright (c) 1996-2000 by Netcetera AG. * Copyright (c) 2001 by Apache Software Foundation. * All rights reserved. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * @(#) $Id$ * */ #include <tcl.h> #include <stdio.h> #include <string.h> #include "macros.h" #include "logtofile.h" #include "webutl.h" /* args */ /* ---------------------------------------------------------------------------- * createLogToFileData -- * ------------------------------------------------------------------------- */ LogToFileData *createLogToFileData() { LogToFileData *logToFileData; logToFileData = WebAllocInternalData(LogToFileData); logToFileData->channel = NULL; logToFileData->fileName = NULL; logToFileData->isBuffered = TCL_OK; return logToFileData; } /* ---------------------------------------------------------------------------- * destroyLogToFileData -- * ------------------------------------------------------------------------- */ int destroyLogToFileData(Tcl_Interp * interp, LogToFileData * logToFileData) { if ((interp == NULL) || (logToFileData == NULL)) return TCL_ERROR; WebFreeIfNotNull(logToFileData->fileName); if (Tcl_Close(interp, logToFileData->channel) != TCL_OK) { Tcl_AppendResult(interp, "destroyLogToFileData -- error closing channel for \"", logToFileData->fileName, "\"", NULL); return TCL_ERROR; } WebFreeIfNotNull(logToFileData); return TCL_OK; } /* ---------------------------------------------------------------------------- * constructor * ------------------------------------------------------------------------- */ ClientData createLogToFile(Tcl_Interp * interp, ClientData clientData, int objc, Tcl_Obj * CONST objv[]) { LogToFileData *logToFileData = NULL; int iCurArg; char *fileName = NULL; Tcl_Channel channel; LogData * logData = (LogData *) clientData; /* -------------------------------------------------------------------------- * syntax is: file ?-unbuffered? fileName * 0 1 2 * ----------------------------------------------------------------------- */ if ((objc < 2) || (objc > 4)) { Tcl_WrongNumArgs(interp, 1, objv, WEB_LOGTOFILE_USAGE); return NULL; } if (strcmp(Tcl_GetString(objv[0]), "file") != 0) { Tcl_SetResult(interp, WEB_LOGTOFILE_USAGE, NULL); return NULL; } /* -------------------------------------------------------------------------- * do we have the filename ? * ----------------------------------------------------------------------- */ iCurArg = argIndexOfFirstArg(objc, objv, NULL, NULL); if (iCurArg >= objc) { Tcl_SetResult(interp, WEB_LOGTOFILE_USAGE, NULL); return NULL; } fileName = Tcl_GetString(objv[iCurArg]); /* -------------------------------------------------------------------------- * try to open channel * ----------------------------------------------------------------------- */ channel = Tcl_OpenFileChannel(interp, fileName, "a", logData->requestData->filePermissions); if (channel == NULL) return NULL; /* -------------------------------------------------------------------------- * everything ok so far. Get memory * ----------------------------------------------------------------------- */ logToFileData = createLogToFileData(); if (logToFileData == NULL) { Tcl_SetResult(interp, "cannot alloc memory for internal data.", NULL); WebFreeIfNotNull(fileName); return NULL; } /* -------------------------------------------------------------------------- * and set values * ----------------------------------------------------------------------- */ logToFileData->channel = channel; logToFileData->fileName = allocAndSet(fileName); if (argKeyExists(objc, objv, WEB_LOGTOFILE_SWITCH_UNBUFFERED) == TCL_OK) logToFileData->isBuffered = TCL_ERROR; else logToFileData->isBuffered = TCL_OK; return (ClientData) logToFileData; } /* ---------------------------------------------------------------------------- * destructor * ------------------------------------------------------------------------- */ int destroyLogToFile(Tcl_Interp * interp, ClientData clientData) { return destroyLogToFileData(interp, (LogToFileData *) clientData); } /* ---------------------------------------------------------------------------- * logToFile * ------------------------------------------------------------------------- */ int logToFile(Tcl_Interp * interp, ClientData clientData, char *msg) { LogToFileData *logToFileData; int res; if ((interp == NULL) || (clientData == NULL) || (msg == NULL)) return TCL_ERROR; logToFileData = (LogToFileData *) clientData; Tcl_Seek(logToFileData->channel, 0, SEEK_END); res = Tcl_WriteChars(logToFileData->channel, msg, -1); if (res < 0) return TCL_ERROR; if (logToFileData->isBuffered == TCL_ERROR) return Tcl_Flush(logToFileData->channel); return TCL_OK; }