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 appender->FileName = _strdup(filename);
43
44 if (!appender->FileName)
45 return FALSE;
46
47 return TRUE;
48}
49
50static BOOL WLog_FileAppender_SetOutputFilePath(wLogFileAppender* appender, const char* filepath)
51{
52 appender->FilePath = _strdup(filepath);
53
54 if (!appender->FilePath)
55 return FALSE;
56
57 return TRUE;
58}
59
60static BOOL WLog_FileAppender_Open(wLog* log, wLogAppender* appender)
61{
62 wLogFileAppender* fileAppender = NULL;
63
64 if (!log || !appender)
65 return FALSE;
66
67 fileAppender = (wLogFileAppender*)appender;
68
69 if (!fileAppender->FilePath)
70 {
71 fileAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
72
73 if (!fileAppender->FilePath)
74 return FALSE;
75 }
76
77 if (!fileAppender->FileName)
78 {
79 fileAppender->FileName = (char*)malloc(MAX_PATH);
80
81 if (!fileAppender->FileName)
82 return FALSE;
83
84 (void)sprintf_s(fileAppender->FileName, MAX_PATH, "%" PRIu32 ".log", GetCurrentProcessId());
85 }
86
87 if (!fileAppender->FullFileName)
88 {
89 fileAppender->FullFileName =
90 GetCombinedPath(fileAppender->FilePath, fileAppender->FileName);
91
92 if (!fileAppender->FullFileName)
93 return FALSE;
94 }
95
96 if (!winpr_PathFileExists(fileAppender->FilePath))
97 {
98 if (!winpr_PathMakePath(fileAppender->FilePath, 0))
99 return FALSE;
100
101 UnixChangeFileMode(fileAppender->FilePath, 0xFFFF);
102 }
103
104 fileAppender->FileDescriptor = winpr_fopen(fileAppender->FullFileName, "a+");
105
106 if (!fileAppender->FileDescriptor)
107 return FALSE;
108
109 return TRUE;
110}
111
112static BOOL WLog_FileAppender_Close(wLog* log, wLogAppender* appender)
113{
114 wLogFileAppender* fileAppender = NULL;
115
116 if (!log || !appender)
117 return FALSE;
118
119 fileAppender = (wLogFileAppender*)appender;
120
121 if (!fileAppender->FileDescriptor)
122 return TRUE;
123
124 (void)fclose(fileAppender->FileDescriptor);
125 fileAppender->FileDescriptor = NULL;
126 return TRUE;
127}
128
129static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender,
130 const wLogMessage* cmessage)
131{
132 if (!log || !appender || !cmessage)
133 return FALSE;
134
135 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
136 FILE* fp = fileAppender->FileDescriptor;
137
138 if (!fp)
139 return FALSE;
140
141 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
142 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix, sizeof(prefix));
143 (void)fprintf(fp, "%s%s\n", prefix, cmessage->TextString);
144 (void)fflush(fp); /* slow! */
145 return TRUE;
146}
147
148static int g_DataId = 0;
149
150static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
151 const wLogMessage* message)
152{
153 int DataId = 0;
154 char* FullFileName = NULL;
155
156 if (!log || !appender || !message)
157 return FALSE;
158
159 DataId = g_DataId++;
160 FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
161 WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
162 free(FullFileName);
163 return TRUE;
164}
165
166static int g_ImageId = 0;
167
168static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
169 const wLogMessage* message)
170{
171 int ImageId = 0;
172 char* FullFileName = NULL;
173
174 if (!log || !appender || !message)
175 return FALSE;
176
177 ImageId = g_ImageId++;
178 FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
179 WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
180 message->ImageHeight, message->ImageBpp);
181 free(FullFileName);
182 return TRUE;
183}
184
185static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value)
186{
187 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
188
189 /* Just check the value string is not empty */
190 if (!value || (strnlen(value, 2) == 0))
191 return FALSE;
192
193 if (!strcmp("outputfilename", setting))
194 return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value);
195
196 if (!strcmp("outputfilepath", setting))
197 return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value);
198
199 return FALSE;
200}
201
202static void WLog_FileAppender_Free(wLogAppender* appender)
203{
204 wLogFileAppender* fileAppender = NULL;
205
206 if (appender)
207 {
208 fileAppender = (wLogFileAppender*)appender;
209 free(fileAppender->FileName);
210 free(fileAppender->FilePath);
211 free(fileAppender->FullFileName);
212 free(fileAppender);
213 }
214}
215
216wLogAppender* WLog_FileAppender_New(WINPR_ATTR_UNUSED wLog* log)
217{
218 LPSTR env = NULL;
219 LPCSTR name = NULL;
220 DWORD nSize = 0;
221 wLogFileAppender* FileAppender = NULL;
222 FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender));
223
224 if (!FileAppender)
225 return NULL;
226
227 FileAppender->common.Type = WLOG_APPENDER_FILE;
228 FileAppender->common.Open = WLog_FileAppender_Open;
229 FileAppender->common.Close = WLog_FileAppender_Close;
230 FileAppender->common.WriteMessage = WLog_FileAppender_WriteMessage;
231 FileAppender->common.WriteDataMessage = WLog_FileAppender_WriteDataMessage;
232 FileAppender->common.WriteImageMessage = WLog_FileAppender_WriteImageMessage;
233 FileAppender->common.Free = WLog_FileAppender_Free;
234 FileAppender->common.Set = WLog_FileAppender_Set;
235 name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
236 nSize = GetEnvironmentVariableA(name, NULL, 0);
237
238 if (nSize)
239 {
240 BOOL status = 0;
241 env = (LPSTR)malloc(nSize);
242
243 if (!env)
244 goto error_free;
245
246 if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
247 {
248 free(env);
249 goto error_free;
250 }
251
252 status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
253 free(env);
254
255 if (!status)
256 goto error_free;
257 }
258
259 name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
260 nSize = GetEnvironmentVariableA(name, NULL, 0);
261
262 if (nSize)
263 {
264 BOOL status = FALSE;
265 env = (LPSTR)malloc(nSize);
266
267 if (!env)
268 goto error_output_file_name;
269
270 if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
271 status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
272 free(env);
273
274 if (!status)
275 goto error_output_file_name;
276 }
277
278 return (wLogAppender*)FileAppender;
279error_output_file_name:
280 free(FileAppender->FilePath);
281error_free:
282 free(FileAppender);
283 return NULL;
284}