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 if (!log || !appender || !message)
148 return FALSE;
149
150 const int DataId = g_DataId++;
151 char* FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
152 WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
153 free(FullFileName);
154 return TRUE;
155}
156
157static int g_ImageId = 0;
158
159static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
160 const wLogMessage* message)
161{
162 if (!log || !appender || !message)
163 return FALSE;
164
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);
169 free(FullFileName);
170 return TRUE;
171}
172
173static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value)
174{
175 wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
176
177 /* Just check the value string is not empty */
178 if (!value || (strnlen(value, 2) == 0))
179 return FALSE;
180
181 if (!strcmp("outputfilename", setting))
182 return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value);
183
184 if (!strcmp("outputfilepath", setting))
185 return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value);
186
187 return FALSE;
188}
189
190static void WLog_FileAppender_Free(wLogAppender* appender)
191{
192 wLogFileAppender* fileAppender = nullptr;
193
194 if (appender)
195 {
196 fileAppender = (wLogFileAppender*)appender;
197 free(fileAppender->FileName);
198 free(fileAppender->FilePath);
199 free(fileAppender->FullFileName);
200 free(fileAppender);
201 }
202}
203
204wLogAppender* WLog_FileAppender_New(WINPR_ATTR_UNUSED wLog* log)
205{
206 LPSTR env = nullptr;
207 LPCSTR name = nullptr;
208 DWORD nSize = 0;
209 wLogFileAppender* FileAppender = nullptr;
210 FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender));
211
212 if (!FileAppender)
213 return nullptr;
214
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);
225
226 if (nSize)
227 {
228 BOOL status = 0;
229 env = (LPSTR)malloc(nSize);
230
231 if (!env)
232 goto error_free;
233
234 if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
235 {
236 free(env);
237 goto error_free;
238 }
239
240 status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
241 free(env);
242
243 if (!status)
244 goto error_free;
245 }
246
247 name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
248 nSize = GetEnvironmentVariableA(name, nullptr, 0);
249
250 if (nSize)
251 {
252 BOOL status = FALSE;
253 env = (LPSTR)malloc(nSize);
254
255 if (!env)
256 goto error_output_file_name;
257
258 if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
259 status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
260 free(env);
261
262 if (!status)
263 goto error_output_file_name;
264 }
265
266 return (wLogAppender*)FileAppender;
267error_output_file_name:
268 free(FileAppender->FilePath);
269error_free:
270 free(FileAppender);
271 return nullptr;
272}