diff options
Diffstat (limited to 'winpr/libwinpr/utils/wlog/FileAppender.c')
-rw-r--r-- | winpr/libwinpr/utils/wlog/FileAppender.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/winpr/libwinpr/utils/wlog/FileAppender.c b/winpr/libwinpr/utils/wlog/FileAppender.c new file mode 100644 index 0000000..7afc658 --- /dev/null +++ b/winpr/libwinpr/utils/wlog/FileAppender.c @@ -0,0 +1,287 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <winpr/config.h> + +#include "FileAppender.h" +#include "Message.h" + +#include <winpr/crt.h> +#include <winpr/environment.h> +#include <winpr/file.h> +#include <winpr/path.h> + +typedef struct +{ + WLOG_APPENDER_COMMON(); + + char* FileName; + char* FilePath; + char* FullFileName; + FILE* FileDescriptor; +} wLogFileAppender; + +static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender, const char* filename) +{ + appender->FileName = _strdup(filename); + + if (!appender->FileName) + return FALSE; + + return TRUE; +} + +static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender, const char* filepath) +{ + appender->FilePath = _strdup(filepath); + + if (!appender->FilePath) + return FALSE; + + return TRUE; +} + +static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender) +{ + wLogFileAppender* fileAppender = NULL; + + if (!log || !appender) + return FALSE; + + fileAppender = (wLogFileAppender*)appender; + + if (!fileAppender->FilePath) + { + fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog"); + + if (!fileAppender->FilePath) + return FALSE; + } + + if (!fileAppender->FileName) + { + fileAppender->FileName = (char*)malloc(MAX_PATH); + + if (!fileAppender->FileName) + return FALSE; + + sprintf_s(fileAppender->FileName, MAX_PATH, "%" PRIu32 ".log", GetCurrentProcessId()); + } + + if (!fileAppender->FullFileName) + { + fileAppender->FullFileName = + GetCombinedPath(fileAppender->FilePath, fileAppender->FileName); + + if (!fileAppender->FullFileName) + return FALSE; + } + + if (!winpr_PathFileExists(fileAppender->FilePath)) + { + if (!winpr_PathMakePath(fileAppender->FilePath, 0)) + return FALSE; + + UnixChangeFileMode(fileAppender->FilePath, 0xFFFF); + } + + fileAppender->FileDescriptor = winpr_fopen(fileAppender->FullFileName, "a+"); + + if (!fileAppender->FileDescriptor) + return FALSE; + + return TRUE; +} + +static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender) +{ + wLogFileAppender* fileAppender = NULL; + + if (!log || !appender) + return FALSE; + + fileAppender = (wLogFileAppender*)appender; + + if (!fileAppender->FileDescriptor) + return TRUE; + + fclose(fileAppender->FileDescriptor); + fileAppender->FileDescriptor = NULL; + return TRUE; +} + +static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message) +{ + FILE* fp = NULL; + char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 }; + wLogFileAppender* fileAppender = NULL; + + if (!log || !appender || !message) + return FALSE; + + fileAppender = (wLogFileAppender*)appender; + fp = fileAppender->FileDescriptor; + + if (!fp) + return FALSE; + + message->PrefixString = prefix; + WLog_Layout_GetMessagePrefix(log, appender->Layout, message); + fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); + fflush(fp); /* slow! */ + return TRUE; +} + +static int g_DataId = 0; + +static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) +{ + int DataId = 0; + char* FullFileName = NULL; + + if (!log || !appender || !message) + return FALSE; + + DataId = g_DataId++; + FullFileName = WLog_Message_GetOutputFileName(DataId, "dat"); + WLog_DataMessage_Write(FullFileName, message->Data, message->Length); + free(FullFileName); + return TRUE; +} + +static int g_ImageId = 0; + +static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) +{ + int ImageId = 0; + char* FullFileName = NULL; + + if (!log || !appender || !message) + return FALSE; + + ImageId = g_ImageId++; + FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp"); + WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth, + message->ImageHeight, message->ImageBpp); + free(FullFileName); + return TRUE; +} + +static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value) +{ + wLogFileAppender* fileAppender = (wLogFileAppender*)appender; + + /* Just check the value string is not empty */ + if (!value || (strnlen(value, 2) == 0)) + return FALSE; + + if (!strcmp("outputfilename", setting)) + return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value); + + if (!strcmp("outputfilepath", setting)) + return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value); + + return FALSE; +} + +static void WLog_FileAppender_Free(wLogAppender* appender) +{ + wLogFileAppender* fileAppender = NULL; + + if (appender) + { + fileAppender = (wLogFileAppender*)appender; + free(fileAppender->FileName); + free(fileAppender->FilePath); + free(fileAppender->FullFileName); + free(fileAppender); + } +} + +wLogAppender* WLog_FileAppender_New(wLog* log) +{ + LPSTR env = NULL; + LPCSTR name = NULL; + DWORD nSize = 0; + wLogFileAppender* FileAppender = NULL; + FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender)); + + if (!FileAppender) + return NULL; + + FileAppender->Type = WLOG_APPENDER_FILE; + FileAppender->Open = WLog_FileAppender_Open; + FileAppender->Close = WLog_FileAppender_Close; + FileAppender->WriteMessage = WLog_FileAppender_WriteMessage; + FileAppender->WriteDataMessage = WLog_FileAppender_WriteDataMessage; + FileAppender->WriteImageMessage = WLog_FileAppender_WriteImageMessage; + FileAppender->Free = WLog_FileAppender_Free; + FileAppender->Set = WLog_FileAppender_Set; + name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH"; + nSize = GetEnvironmentVariableA(name, NULL, 0); + + if (nSize) + { + BOOL status = 0; + env = (LPSTR)malloc(nSize); + + if (!env) + goto error_free; + + if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1) + { + free(env); + goto error_free; + } + + status = WLog_FileAppender_SetOutputFilePath(FileAppender, env); + free(env); + + if (!status) + goto error_free; + } + + name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME"; + nSize = GetEnvironmentVariableA(name, NULL, 0); + + if (nSize) + { + BOOL status = FALSE; + env = (LPSTR)malloc(nSize); + + if (!env) + goto error_output_file_name; + + if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1) + status = WLog_FileAppender_SetOutputFileName(FileAppender, env); + free(env); + + if (!status) + goto error_output_file_name; + } + + return (wLogAppender*)FileAppender; +error_output_file_name: + free(FileAppender->FilePath); +error_free: + free(FileAppender); + return NULL; +} |