FreeRDP
Loading...
Searching...
No Matches
FileAppender.c
1
20#include <winpr/config.h>
21
22#include "FileAppender.h"
23#include "Message.h"
24
25#include <winpr/crt.h>
26#include <winpr/environment.h>
27#include <winpr/file.h>
28#include <winpr/path.h>
29
30typedef struct
31{
32 wLogAppender common;
33
34 char* FileName;
35 char* FilePath;
36 char* FullFileName;
37 FILE* FileDescriptor;
38} wLogFileAppender;
39
40static BOOL WLog_FileAppender_SetOutputFileName(wLogFileAppender* appender, const char* filename)
41{
42 WINPR_ASSERT(appender);
43 WINPR_ASSERT(filename);
44
45 appender->FileName = _strdup(filename);
46
47 return appender->FileName != nullptr;
48}
49
50static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender, const char* filepath)
51{
52 appender->FilePath = _strdup(filepath);
53
54 return appender->FilePath != nullptr;
55}
56
57static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
58{
59 wLogFileAppender* fileAppender = nullptr;
60
61 if (!log || !appender)
62 return FALSE;
63
64 fileAppender = (wLogFileAppender*)appender;
65
66 if (!fileAppender->FilePath)
67 {
68 fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
69
70 if (!fileAppender->FilePath)
71 return FALSE;
72 }
73
74 if (!fileAppender->FileName)
75 {
76 fileAppender->FileName = (char*)malloc(MAX_PATH);
77
78 if (!fileAppender->FileName)
79 return FALSE;
80
81 (void)sprintf_s(fileAppender->FileName, MAX_PATH, "%" PRIu32 ".log", GetCurrentProcessId());
82 }
83
84 if (!fileAppender->FullFileName)
85 {
86 fileAppender->FullFileName =
87 GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
88
89 if (!fileAppender->FullFileName)
90 return FALSE;
91 }
92
93 if (!winpr_PathFileExists(fileAppender->FilePath))
94 {
95 if (!winpr_PathMakePath(fileAppender->FilePath, nullptr))
96 return FALSE;
97
98 UnixChangeFileMode(fileAppender->FilePath, 0xFFFF);
99 }
100
101 fileAppender->FileDescriptor = winpr_fopen(fileAppender->FullFileName, "a+");
102
103 return fileAppender->FileDescriptor != nullptr;
104}
105
106static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender)
107{
108 wLogFileAppender* fileAppender = nullptr;
109
110 if (!log || !appender)
111 return FALSE;
112
113 fileAppender = (wLogFileAppender*)appender;
114
115 if (!fileAppender->FileDescriptor)
116 return TRUE;
117
118 (void)fclose(fileAppender->FileDescriptor);
119 fileAppender->FileDescriptor = nullptr;
120 return TRUE;
121}
122
123static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender,
124 const wLogMessage* cmessage)
125{
126 if (!log || !appender || !cmessage)
127 return FALSE;
128
129 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
130 FILE* fp = fileAppender->FileDescriptor;
131
132 if (!fp)
133 return FALSE;
134
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);
138 (void)fflush(fp); /* slow! */
139 return TRUE;
140}
141
142static int g_DataId = 0;
143
144static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
145 const wLogMessage* message)
146{
147 int DataId = 0;
148 char* FullFileName = nullptr;
149
150 if (!log || !appender || !message)
151 return FALSE;
152
153 DataId = g_DataId++;
154 FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
155 WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
156 free(FullFileName);
157 return TRUE;
158}
159
160static int g_ImageId = 0;
161
162static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
163 const wLogMessage* message)
164{
165 int ImageId = 0;
166 char* FullFileName = nullptr;
167
168 if (!log || !appender || !message)
169 return FALSE;
170
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);
175 free(FullFileName);
176 return TRUE;
177}
178
179static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value)
180{
181 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
182
183 /* Just check the value string is not empty */
184 if (!value || (strnlen(value, 2) == 0))
185 return FALSE;
186
187 if (!strcmp("outputfilename", setting))
188 return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value);
189
190 if (!strcmp("outputfilepath", setting))
191 return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value);
192
193 return FALSE;
194}
195
196static void WLog_FileAppender_Free(wLogAppender* appender)
197{
198 wLogFileAppender* fileAppender = nullptr;
199
200 if (appender)
201 {
202 fileAppender = (wLogFileAppender*)appender;
203 free(fileAppender->FileName);
204 free(fileAppender->FilePath);
205 free(fileAppender->FullFileName);
206 free(fileAppender);
207 }
208}
209
210wLogAppender* WLog_FileAppender_New(WINPR_ATTR_UNUSED wLog* log)
211{
212 LPSTR env = nullptr;
213 LPCSTR name = nullptr;
214 DWORD nSize = 0;
215 wLogFileAppender* FileAppender = nullptr;
216 FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender));
217
218 if (!FileAppender)
219 return nullptr;
220
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);
231
232 if (nSize)
233 {
234 BOOL status = 0;
235 env = (LPSTR)malloc(nSize);
236
237 if (!env)
238 goto error_free;
239
240 if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
241 {
242 free(env);
243 goto error_free;
244 }
245
246 status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
247 free(env);
248
249 if (!status)
250 goto error_free;
251 }
252
253 name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
254 nSize = GetEnvironmentVariableA(name, nullptr, 0);
255
256 if (nSize)
257 {
258 BOOL status = FALSE;
259 env = (LPSTR)malloc(nSize);
260
261 if (!env)
262 goto error_output_file_name;
263
264 if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
265 status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
266 free(env);
267
268 if (!status)
269 goto error_output_file_name;
270 }
271
272 return (wLogAppender*)FileAppender;
273error_output_file_name:
274 free(FileAppender->FilePath);
275error_free:
276 free(FileAppender);
277 return nullptr;
278}