20#include <winpr/config.h>
22#include "FileAppender.h"
26#include <winpr/environment.h>
27#include <winpr/file.h>
28#include <winpr/path.h>
40static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender,
const char* filename)
42 WINPR_ASSERT(appender);
43 WINPR_ASSERT(filename);
45 appender->FileName = _strdup(filename);
47 return appender->FileName !=
nullptr;
50static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender,
const char* filepath)
52 appender->FilePath = _strdup(filepath);
54 return appender->FilePath !=
nullptr;
57static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
59 wLogFileAppender* fileAppender =
nullptr;
61 if (!log || !appender)
64 fileAppender = (wLogFileAppender*)appender;
66 if (!fileAppender->FilePath)
68 fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP,
"wlog");
70 if (!fileAppender->FilePath)
74 if (!fileAppender->FileName)
76 fileAppender->FileName = (
char*)malloc(MAX_PATH);
78 if (!fileAppender->FileName)
81 (void)sprintf_s(fileAppender->FileName, MAX_PATH,
"%" PRIu32
".log", GetCurrentProcessId());
84 if (!fileAppender->FullFileName)
86 fileAppender->FullFileName =
87 GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
89 if (!fileAppender->FullFileName)
93 if (!winpr_PathFileExists(fileAppender->FilePath))
95 if (!winpr_PathMakePath(fileAppender->FilePath,
nullptr))
98 UnixChangeFileMode(fileAppender->FilePath, 0xFFFF);
101 fileAppender->FileDescriptor = winpr_fopen(fileAppender->FullFileName,
"a+");
103 return fileAppender->FileDescriptor !=
nullptr;
106static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender)
108 wLogFileAppender* fileAppender =
nullptr;
110 if (!log || !appender)
113 fileAppender = (wLogFileAppender*)appender;
115 if (!fileAppender->FileDescriptor)
118 (void)fclose(fileAppender->FileDescriptor);
119 fileAppender->FileDescriptor =
nullptr;
123static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender,
126 if (!log || !appender || !cmessage)
129 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
130 FILE* fp = fileAppender->FileDescriptor;
135 char prefix[WLOG_MAX_PREFIX_SIZE] = WINPR_C_ARRAY_INIT;
136 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix,
sizeof(prefix));
137 (void)fprintf(fp,
"%s%s\n", prefix, cmessage->TextString);
142static int g_DataId = 0;
144static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
147 if (!log || !appender || !message)
150 const int DataId = g_DataId++;
151 char* FullFileName = WLog_Message_GetOutputFileName(DataId,
"dat");
152 WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
157static int g_ImageId = 0;
159static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
162 if (!log || !appender || !message)
165 const int ImageId = g_ImageId++;
166 char* FullFileName = WLog_Message_GetOutputFileName(ImageId,
"bmp");
167 WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
168 message->ImageHeight, message->ImageBpp);
173static BOOL WLog_FileAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
175 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
178 if (!value || (strnlen(value, 2) == 0))
181 if (!strcmp(
"outputfilename", setting))
182 return WLog_FileAppender_SetOutputFileName(fileAppender, (
const char*)value);
184 if (!strcmp(
"outputfilepath", setting))
185 return WLog_FileAppender_SetOutputFilePath(fileAppender, (
const char*)value);
190static void WLog_FileAppender_Free(wLogAppender* appender)
192 wLogFileAppender* fileAppender =
nullptr;
196 fileAppender = (wLogFileAppender*)appender;
197 free(fileAppender->FileName);
198 free(fileAppender->FilePath);
199 free(fileAppender->FullFileName);
204wLogAppender* WLog_FileAppender_New(WINPR_ATTR_UNUSED wLog* log)
207 LPCSTR name =
nullptr;
209 wLogFileAppender* FileAppender =
nullptr;
210 FileAppender = (wLogFileAppender*)calloc(1,
sizeof(wLogFileAppender));
215 FileAppender->common.Type = WLOG_APPENDER_FILE;
216 FileAppender->common.Open = WLog_FileAppender_Open;
217 FileAppender->common.Close = WLog_FileAppender_Close;
218 FileAppender->common.WriteMessage = WLog_FileAppender_WriteMessage;
219 FileAppender->common.WriteDataMessage = WLog_FileAppender_WriteDataMessage;
220 FileAppender->common.WriteImageMessage = WLog_FileAppender_WriteImageMessage;
221 FileAppender->common.Free = WLog_FileAppender_Free;
222 FileAppender->common.Set = WLog_FileAppender_Set;
223 name =
"WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
224 nSize = GetEnvironmentVariableA(name,
nullptr, 0);
229 env = (LPSTR)malloc(nSize);
234 if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
240 status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
247 name =
"WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
248 nSize = GetEnvironmentVariableA(name,
nullptr, 0);
253 env = (LPSTR)malloc(nSize);
256 goto error_output_file_name;
258 if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
259 status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
263 goto error_output_file_name;
266 return (wLogAppender*)FileAppender;
267error_output_file_name:
268 free(FileAppender->FilePath);