FreeRDP
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 
30 typedef struct
31 {
32  WLOG_APPENDER_COMMON();
33 
34  char* FileName;
35  char* FilePath;
36  char* FullFileName;
37  FILE* FileDescriptor;
38 } wLogFileAppender;
39 
40 static 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 
50 static 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 
60 static 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 
112 static 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 
129 static BOOL WLog_FileAppender_WriteMessage(wLog* log, wLogAppender* appender, wLogMessage* message)
130 {
131  FILE* fp = NULL;
132  char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
133  wLogFileAppender* fileAppender = NULL;
134 
135  if (!log || !appender || !message)
136  return FALSE;
137 
138  fileAppender = (wLogFileAppender*)appender;
139  fp = fileAppender->FileDescriptor;
140 
141  if (!fp)
142  return FALSE;
143 
144  message->PrefixString = prefix;
145  WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
146  (void)fprintf(fp, "%s%s\n", message->PrefixString, message->TextString);
147  (void)fflush(fp); /* slow! */
148  return TRUE;
149 }
150 
151 static int g_DataId = 0;
152 
153 static BOOL WLog_FileAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
154  wLogMessage* message)
155 {
156  int DataId = 0;
157  char* FullFileName = NULL;
158 
159  if (!log || !appender || !message)
160  return FALSE;
161 
162  DataId = g_DataId++;
163  FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
164  WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
165  free(FullFileName);
166  return TRUE;
167 }
168 
169 static int g_ImageId = 0;
170 
171 static BOOL WLog_FileAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
172  wLogMessage* message)
173 {
174  int ImageId = 0;
175  char* FullFileName = NULL;
176 
177  if (!log || !appender || !message)
178  return FALSE;
179 
180  ImageId = g_ImageId++;
181  FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
182  WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
183  message->ImageHeight, message->ImageBpp);
184  free(FullFileName);
185  return TRUE;
186 }
187 
188 static BOOL WLog_FileAppender_Set(wLogAppender* appender, const char* setting, void* value)
189 {
190  wLogFileAppender* fileAppender = (wLogFileAppender*)appender;
191 
192  /* Just check the value string is not empty */
193  if (!value || (strnlen(value, 2) == 0))
194  return FALSE;
195 
196  if (!strcmp("outputfilename", setting))
197  return WLog_FileAppender_SetOutputFileName(fileAppender, (const char*)value);
198 
199  if (!strcmp("outputfilepath", setting))
200  return WLog_FileAppender_SetOutputFilePath(fileAppender, (const char*)value);
201 
202  return FALSE;
203 }
204 
205 static void WLog_FileAppender_Free(wLogAppender* appender)
206 {
207  wLogFileAppender* fileAppender = NULL;
208 
209  if (appender)
210  {
211  fileAppender = (wLogFileAppender*)appender;
212  free(fileAppender->FileName);
213  free(fileAppender->FilePath);
214  free(fileAppender->FullFileName);
215  free(fileAppender);
216  }
217 }
218 
219 wLogAppender* WLog_FileAppender_New(wLog* log)
220 {
221  LPSTR env = NULL;
222  LPCSTR name = NULL;
223  DWORD nSize = 0;
224  wLogFileAppender* FileAppender = NULL;
225  FileAppender = (wLogFileAppender*)calloc(1, sizeof(wLogFileAppender));
226 
227  if (!FileAppender)
228  return NULL;
229 
230  FileAppender->Type = WLOG_APPENDER_FILE;
231  FileAppender->Open = WLog_FileAppender_Open;
232  FileAppender->Close = WLog_FileAppender_Close;
233  FileAppender->WriteMessage = WLog_FileAppender_WriteMessage;
234  FileAppender->WriteDataMessage = WLog_FileAppender_WriteDataMessage;
235  FileAppender->WriteImageMessage = WLog_FileAppender_WriteImageMessage;
236  FileAppender->Free = WLog_FileAppender_Free;
237  FileAppender->Set = WLog_FileAppender_Set;
238  name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
239  nSize = GetEnvironmentVariableA(name, NULL, 0);
240 
241  if (nSize)
242  {
243  BOOL status = 0;
244  env = (LPSTR)malloc(nSize);
245 
246  if (!env)
247  goto error_free;
248 
249  if (GetEnvironmentVariableA(name, env, nSize) != nSize - 1)
250  {
251  free(env);
252  goto error_free;
253  }
254 
255  status = WLog_FileAppender_SetOutputFilePath(FileAppender, env);
256  free(env);
257 
258  if (!status)
259  goto error_free;
260  }
261 
262  name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
263  nSize = GetEnvironmentVariableA(name, NULL, 0);
264 
265  if (nSize)
266  {
267  BOOL status = FALSE;
268  env = (LPSTR)malloc(nSize);
269 
270  if (!env)
271  goto error_output_file_name;
272 
273  if (GetEnvironmentVariableA(name, env, nSize) == nSize - 1)
274  status = WLog_FileAppender_SetOutputFileName(FileAppender, env);
275  free(env);
276 
277  if (!status)
278  goto error_output_file_name;
279  }
280 
281  return (wLogAppender*)FileAppender;
282 error_output_file_name:
283  free(FileAppender->FilePath);
284 error_free:
285  free(FileAppender);
286  return NULL;
287 }