FreeRDP
Loading...
Searching...
No Matches
BinaryAppender.c
1
22#include <winpr/config.h>
23
24#include "BinaryAppender.h"
25#include <winpr/crt.h>
26#include <winpr/assert.h>
27#include <winpr/file.h>
28#include <winpr/path.h>
29#include <winpr/stream.h>
30
31typedef struct
32{
33 wLogAppender common;
34
35 char* FileName;
36 char* FilePath;
37 char* FullFileName;
38 FILE* FileDescriptor;
39} wLogBinaryAppender;
40
41static BOOL WLog_BinaryAppender_Open(wLog* log, wLogAppender* appender)
42{
43 wLogBinaryAppender* binaryAppender = nullptr;
44 if (!log || !appender)
45 return FALSE;
46
47 binaryAppender = (wLogBinaryAppender*)appender;
48 if (!binaryAppender->FileName)
49 {
50 binaryAppender->FileName = (char*)malloc(MAX_PATH);
51 if (!binaryAppender->FileName)
52 return FALSE;
53 (void)sprintf_s(binaryAppender->FileName, MAX_PATH, "%" PRIu32 ".wlog",
54 GetCurrentProcessId());
55 }
56
57 if (!binaryAppender->FilePath)
58 {
59 binaryAppender->FilePath = GetKnownSubPath(KNOWN_PATH_TEMP, "wlog");
60 if (!binaryAppender->FilePath)
61 return FALSE;
62 }
63
64 if (!binaryAppender->FullFileName)
65 {
66 binaryAppender->FullFileName =
67 GetCombinedPath(binaryAppender->FilePath, binaryAppender->FileName);
68 if (!binaryAppender->FullFileName)
69 return FALSE;
70 }
71
72 if (!winpr_PathFileExists(binaryAppender->FilePath))
73 {
74 if (!winpr_PathMakePath(binaryAppender->FilePath, nullptr))
75 return FALSE;
76 UnixChangeFileMode(binaryAppender->FilePath, 0xFFFF);
77 }
78
79 binaryAppender->FileDescriptor = winpr_fopen(binaryAppender->FullFileName, "a+");
80
81 return binaryAppender->FileDescriptor != nullptr;
82}
83
84static BOOL WLog_BinaryAppender_Close(WINPR_ATTR_UNUSED wLog* log, wLogAppender* appender)
85{
86 wLogBinaryAppender* binaryAppender = nullptr;
87
88 if (!appender)
89 return FALSE;
90
91 binaryAppender = (wLogBinaryAppender*)appender;
92 if (!binaryAppender->FileDescriptor)
93 return TRUE;
94
95 if (binaryAppender->FileDescriptor)
96 (void)fclose(binaryAppender->FileDescriptor);
97
98 binaryAppender->FileDescriptor = nullptr;
99
100 return TRUE;
101}
102
103static BOOL WLog_BinaryAppender_WriteMessage(wLog* log, wLogAppender* appender,
104 const wLogMessage* message)
105{
106 FILE* fp = nullptr;
107 wStream* s = nullptr;
108 size_t MessageLength = 0;
109 size_t FileNameLength = 0;
110 size_t FunctionNameLength = 0;
111 size_t TextStringLength = 0;
112 BOOL ret = TRUE;
113 wLogBinaryAppender* binaryAppender = nullptr;
114
115 if (!log || !appender || !message)
116 return FALSE;
117
118 binaryAppender = (wLogBinaryAppender*)appender;
119
120 fp = binaryAppender->FileDescriptor;
121
122 if (!fp)
123 return FALSE;
124
125 FileNameLength = strnlen(message->FileName, INT_MAX);
126 FunctionNameLength = strnlen(message->FunctionName, INT_MAX);
127 TextStringLength = strnlen(message->TextString, INT_MAX);
128
129 MessageLength =
130 16 + (4 + FileNameLength + 1) + (4 + FunctionNameLength + 1) + (4 + TextStringLength + 1);
131
132 if ((MessageLength > UINT32_MAX) || (FileNameLength > UINT32_MAX) ||
133 (FunctionNameLength > UINT32_MAX) || (TextStringLength > UINT32_MAX))
134 return FALSE;
135
136 s = Stream_New(nullptr, MessageLength);
137 if (!s)
138 return FALSE;
139
140 Stream_Write_UINT32(s, (UINT32)MessageLength);
141
142 Stream_Write_UINT32(s, message->Type);
143 Stream_Write_UINT32(s, message->Level);
144
145 WINPR_ASSERT(message->LineNumber <= UINT32_MAX);
146 Stream_Write_UINT32(s, (UINT32)message->LineNumber);
147
148 Stream_Write_UINT32(s, (UINT32)FileNameLength);
149 Stream_Write(s, message->FileName, FileNameLength + 1);
150
151 Stream_Write_UINT32(s, (UINT32)FunctionNameLength);
152 Stream_Write(s, message->FunctionName, FunctionNameLength + 1);
153
154 Stream_Write_UINT32(s, (UINT32)TextStringLength);
155 Stream_Write(s, message->TextString, TextStringLength + 1);
156
157 Stream_SealLength(s);
158
159 if (fwrite(Stream_Buffer(s), MessageLength, 1, fp) != 1)
160 ret = FALSE;
161
162 Stream_Free(s, TRUE);
163
164 return ret;
165}
166
167static BOOL WLog_BinaryAppender_WriteDataMessage(WINPR_ATTR_UNUSED wLog* log,
168 WINPR_ATTR_UNUSED wLogAppender* appender,
169 WINPR_ATTR_UNUSED const wLogMessage* message)
170{
171 return TRUE;
172}
173
174static BOOL WLog_BinaryAppender_WriteImageMessage(WINPR_ATTR_UNUSED wLog* log,
175 WINPR_ATTR_UNUSED wLogAppender* appender,
176 WINPR_ATTR_UNUSED const wLogMessage* message)
177{
178 return TRUE;
179}
180
181static BOOL WLog_BinaryAppender_Set(wLogAppender* appender, const char* setting, void* value)
182{
183 wLogBinaryAppender* binaryAppender = (wLogBinaryAppender*)appender;
184
185 /* Just check if the value string is longer than 0 */
186 if (!value || (strnlen(value, 2) == 0))
187 return FALSE;
188
189 if (!strcmp("outputfilename", setting))
190 {
191 binaryAppender->FileName = _strdup((const char*)value);
192 if (!binaryAppender->FileName)
193 return FALSE;
194 }
195 else if (!strcmp("outputfilepath", setting))
196 {
197 binaryAppender->FilePath = _strdup((const char*)value);
198 if (!binaryAppender->FilePath)
199 return FALSE;
200 }
201 else
202 return FALSE;
203
204 return TRUE;
205}
206
207static void WLog_BinaryAppender_Free(wLogAppender* appender)
208{
209 wLogBinaryAppender* binaryAppender = nullptr;
210 if (appender)
211 {
212 binaryAppender = (wLogBinaryAppender*)appender;
213 free(binaryAppender->FileName);
214 free(binaryAppender->FilePath);
215 free(binaryAppender->FullFileName);
216 free(binaryAppender);
217 }
218}
219
220wLogAppender* WLog_BinaryAppender_New(WINPR_ATTR_UNUSED wLog* log)
221{
222 wLogBinaryAppender* BinaryAppender = (wLogBinaryAppender*)calloc(1, sizeof(wLogBinaryAppender));
223 if (!BinaryAppender)
224 return nullptr;
225
226 BinaryAppender->common.Type = WLOG_APPENDER_BINARY;
227 BinaryAppender->common.Open = WLog_BinaryAppender_Open;
228 BinaryAppender->common.Close = WLog_BinaryAppender_Close;
229 BinaryAppender->common.WriteMessage = WLog_BinaryAppender_WriteMessage;
230 BinaryAppender->common.WriteDataMessage = WLog_BinaryAppender_WriteDataMessage;
231 BinaryAppender->common.WriteImageMessage = WLog_BinaryAppender_WriteImageMessage;
232 BinaryAppender->common.Free = WLog_BinaryAppender_Free;
233 BinaryAppender->common.Set = WLog_BinaryAppender_Set;
234
235 return &BinaryAppender->common;
236}