summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/utils/wlog/FileAppender.c
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/utils/wlog/FileAppender.c')
-rw-r--r--winpr/libwinpr/utils/wlog/FileAppender.c287
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;
+}