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,
148 char* FullFileName =
nullptr;
150 if (!log || !appender || !message)
154 FullFileName = WLog_Message_GetOutputFileName(DataId,
"dat");
155 WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
160static int g_ImageId = 0;
162static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
166 char* FullFileName =
nullptr;
168 if (!log || !appender || !message)
171 ImageId = g_ImageId++;
172 FullFileName = WLog_Message_GetOutputFileName(ImageId,
"bmp");
173 WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
174 message->ImageHeight, message->ImageBpp);
179static BOOL WLog_FileAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
181 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
184 if (!value || (strnlen(value, 2) == 0))
187 if (!strcmp(
"outputfilename", setting))
188 return WLog_FileAppender_SetOutputFileName(fileAppender, (
const char*)value);
190 if (!strcmp(
"outputfilepath", setting))
191 return WLog_FileAppender_SetOutputFilePath(fileAppender, (
const char*)value);
196static void WLog_FileAppender_Free(wLogAppender* appender)
198 wLogFileAppender* fileAppender =
nullptr;
202 fileAppender = (wLogFileAppender*)appender;
203 free(fileAppender->FileName);
204 free(fileAppender->FilePath);
205 free(fileAppender->FullFileName);
210wLogAppender* WLog_FileAppender_New(WINPR_ATTR_UNUSED wLog* log)
213 LPCSTR name =
nullptr;
215 wLogFileAppender* FileAppender =
nullptr;
216 FileAppender = (wLogFileAppender*)calloc(1,
sizeof(wLogFileAppender));
221 FileAppender->common.Type = WLOG_APPENDER_FILE;
222 FileAppender->common.Open = WLog_FileAppender_Open;
223 FileAppender->common.Close = WLog_FileAppender_Close;
224 FileAppender->common.WriteMessage = WLog_FileAppender_WriteMessage;
225 FileAppender->common.WriteDataMessage = WLog_FileAppender_WriteDataMessage;
226 FileAppender->common.WriteImageMessage = WLog_FileAppender_WriteImageMessage;
227 FileAppender->common.Free = WLog_FileAppender_Free;
228 FileAppender->common.Set = WLog_FileAppender_Set;
229 name =
"WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
230 nSize = GetEnvironmentVariableA(name,
nullptr, 0);
235 env = (LPSTR)malloc(nSize);
240 if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
246 status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
253 name =
"WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
254 nSize = GetEnvironmentVariableA(name,
nullptr, 0);
259 env = (LPSTR)malloc(nSize);
262 goto error_output_file_name;
264 if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
265 status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
269 goto error_output_file_name;
272 return (wLogAppender*)FileAppender;
273error_output_file_name:
274 free(FileAppender->FilePath);