Coverage Report

Created: 2025-07-01 06:46

/src/FreeRDP/winpr/libwinpr/utils/wlog/ConsoleAppender.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * WinPR Logger
4
 *
5
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
20
#include <winpr/config.h>
21
22
#include "ConsoleAppender.h"
23
#include "Message.h"
24
25
#ifdef ANDROID
26
#include <android/log.h>
27
#endif
28
29
0
#define WLOG_CONSOLE_DEFAULT 0
30
0
#define WLOG_CONSOLE_STDOUT 1
31
0
#define WLOG_CONSOLE_STDERR 2
32
0
#define WLOG_CONSOLE_DEBUG 4
33
34
typedef struct
35
{
36
  WLOG_APPENDER_COMMON();
37
38
  int outputStream;
39
} wLogConsoleAppender;
40
41
static BOOL WLog_ConsoleAppender_Open(WINPR_ATTR_UNUSED wLog* log,
42
                                      WINPR_ATTR_UNUSED wLogAppender* appender)
43
0
{
44
0
  return TRUE;
45
0
}
46
47
static BOOL WLog_ConsoleAppender_Close(WINPR_ATTR_UNUSED wLog* log,
48
                                       WINPR_ATTR_UNUSED wLogAppender* appender)
49
0
{
50
0
  return TRUE;
51
0
}
52
53
static BOOL WLog_ConsoleAppender_WriteMessage(wLog* log, wLogAppender* appender,
54
                                              wLogMessage* message)
55
0
{
56
0
  FILE* fp = NULL;
57
0
  char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
58
0
  wLogConsoleAppender* consoleAppender = NULL;
59
0
  if (!appender)
60
0
    return FALSE;
61
62
0
  consoleAppender = (wLogConsoleAppender*)appender;
63
64
0
  message->PrefixString = prefix;
65
0
  WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
66
67
#ifdef _WIN32
68
  if (consoleAppender->outputStream == WLOG_CONSOLE_DEBUG)
69
  {
70
    OutputDebugStringA(message->PrefixString);
71
    OutputDebugStringA(message->TextString);
72
    OutputDebugStringA("\n");
73
74
    return TRUE;
75
  }
76
#endif
77
#ifdef ANDROID
78
  (void)fp;
79
  android_LogPriority level;
80
  switch (message->Level)
81
  {
82
    case WLOG_TRACE:
83
      level = ANDROID_LOG_VERBOSE;
84
      break;
85
    case WLOG_DEBUG:
86
      level = ANDROID_LOG_DEBUG;
87
      break;
88
    case WLOG_INFO:
89
      level = ANDROID_LOG_INFO;
90
      break;
91
    case WLOG_WARN:
92
      level = ANDROID_LOG_WARN;
93
      break;
94
    case WLOG_ERROR:
95
      level = ANDROID_LOG_ERROR;
96
      break;
97
    case WLOG_FATAL:
98
      level = ANDROID_LOG_FATAL;
99
      break;
100
    case WLOG_OFF:
101
      level = ANDROID_LOG_SILENT;
102
      break;
103
    default:
104
      level = ANDROID_LOG_FATAL;
105
      break;
106
  }
107
108
  if (level != ANDROID_LOG_SILENT)
109
    __android_log_print(level, log->Name, "%s%s", message->PrefixString, message->TextString);
110
111
#else
112
0
  switch (consoleAppender->outputStream)
113
0
  {
114
0
    case WLOG_CONSOLE_STDOUT:
115
0
      fp = stdout;
116
0
      break;
117
0
    case WLOG_CONSOLE_STDERR:
118
0
      fp = stderr;
119
0
      break;
120
0
    default:
121
0
      switch (message->Level)
122
0
      {
123
0
        case WLOG_TRACE:
124
0
        case WLOG_DEBUG:
125
0
        case WLOG_INFO:
126
0
          fp = stdout;
127
0
          break;
128
0
        default:
129
0
          fp = stderr;
130
0
          break;
131
0
      }
132
0
      break;
133
0
  }
134
135
0
  if (message->Level != WLOG_OFF)
136
0
    (void)fprintf(fp, "%s%s\n", message->PrefixString, message->TextString);
137
0
#endif
138
0
  return TRUE;
139
0
}
140
141
static int g_DataId = 0;
142
143
static BOOL WLog_ConsoleAppender_WriteDataMessage(WINPR_ATTR_UNUSED wLog* log,
144
                                                  WINPR_ATTR_UNUSED wLogAppender* appender,
145
                                                  wLogMessage* message)
146
0
{
147
#if defined(ANDROID)
148
  return FALSE;
149
#else
150
0
  int DataId = 0;
151
0
  char* FullFileName = NULL;
152
153
0
  DataId = g_DataId++;
154
0
  FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
155
156
0
  WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
157
158
0
  free(FullFileName);
159
160
0
  return TRUE;
161
0
#endif
162
0
}
163
164
static int g_ImageId = 0;
165
166
static BOOL WLog_ConsoleAppender_WriteImageMessage(WINPR_ATTR_UNUSED wLog* log,
167
                                                   WINPR_ATTR_UNUSED wLogAppender* appender,
168
                                                   wLogMessage* message)
169
0
{
170
#if defined(ANDROID)
171
  return FALSE;
172
#else
173
0
  int ImageId = 0;
174
0
  char* FullFileName = NULL;
175
176
0
  ImageId = g_ImageId++;
177
0
  FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
178
179
0
  WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
180
0
                          message->ImageHeight, message->ImageBpp);
181
182
0
  free(FullFileName);
183
184
0
  return TRUE;
185
0
#endif
186
0
}
187
188
static int g_PacketId = 0;
189
190
static BOOL WLog_ConsoleAppender_WritePacketMessage(WINPR_ATTR_UNUSED wLog* log,
191
                                                    wLogAppender* appender, wLogMessage* message)
192
0
{
193
#if defined(ANDROID)
194
  return FALSE;
195
#else
196
0
  char* FullFileName = NULL;
197
198
0
  g_PacketId++;
199
200
0
  if (!appender->PacketMessageContext)
201
0
  {
202
0
    FullFileName = WLog_Message_GetOutputFileName(-1, "pcap");
203
0
    appender->PacketMessageContext = (void*)Pcap_Open(FullFileName, TRUE);
204
0
    free(FullFileName);
205
0
  }
206
207
0
  if (appender->PacketMessageContext)
208
0
    return WLog_PacketMessage_Write((wPcap*)appender->PacketMessageContext, message->PacketData,
209
0
                                    message->PacketLength, message->PacketFlags);
210
211
0
  return TRUE;
212
0
#endif
213
0
}
214
static BOOL WLog_ConsoleAppender_Set(wLogAppender* appender, const char* setting, void* value)
215
0
{
216
0
  wLogConsoleAppender* consoleAppender = (wLogConsoleAppender*)appender;
217
218
  /* Just check the value string is not empty */
219
0
  if (!value || (strnlen(value, 2) == 0))
220
0
    return FALSE;
221
222
0
  if (strcmp("outputstream", setting) != 0)
223
0
    return FALSE;
224
225
0
  if (!strcmp("stdout", value))
226
0
    consoleAppender->outputStream = WLOG_CONSOLE_STDOUT;
227
0
  else if (!strcmp("stderr", value))
228
0
    consoleAppender->outputStream = WLOG_CONSOLE_STDERR;
229
0
  else if (!strcmp("default", value))
230
0
    consoleAppender->outputStream = WLOG_CONSOLE_DEFAULT;
231
0
  else if (!strcmp("debug", value))
232
0
    consoleAppender->outputStream = WLOG_CONSOLE_DEBUG;
233
0
  else
234
0
    return FALSE;
235
236
0
  return TRUE;
237
0
}
238
239
static void WLog_ConsoleAppender_Free(wLogAppender* appender)
240
0
{
241
0
  if (appender)
242
0
  {
243
0
    if (appender->PacketMessageContext)
244
0
    {
245
0
      Pcap_Close((wPcap*)appender->PacketMessageContext);
246
0
    }
247
248
0
    free(appender);
249
0
  }
250
0
}
251
252
wLogAppender* WLog_ConsoleAppender_New(WINPR_ATTR_UNUSED wLog* log)
253
0
{
254
0
  wLogConsoleAppender* ConsoleAppender = NULL;
255
256
0
  ConsoleAppender = (wLogConsoleAppender*)calloc(1, sizeof(wLogConsoleAppender));
257
258
0
  if (!ConsoleAppender)
259
0
    return NULL;
260
261
0
  ConsoleAppender->Type = WLOG_APPENDER_CONSOLE;
262
263
0
  ConsoleAppender->Open = WLog_ConsoleAppender_Open;
264
0
  ConsoleAppender->Close = WLog_ConsoleAppender_Close;
265
0
  ConsoleAppender->WriteMessage = WLog_ConsoleAppender_WriteMessage;
266
0
  ConsoleAppender->WriteDataMessage = WLog_ConsoleAppender_WriteDataMessage;
267
0
  ConsoleAppender->WriteImageMessage = WLog_ConsoleAppender_WriteImageMessage;
268
0
  ConsoleAppender->WritePacketMessage = WLog_ConsoleAppender_WritePacketMessage;
269
0
  ConsoleAppender->Set = WLog_ConsoleAppender_Set;
270
0
  ConsoleAppender->Free = WLog_ConsoleAppender_Free;
271
272
0
  ConsoleAppender->outputStream = WLOG_CONSOLE_DEFAULT;
273
274
#ifdef _WIN32
275
  if (IsDebuggerPresent())
276
    ConsoleAppender->outputStream = WLOG_CONSOLE_DEBUG;
277
#endif
278
279
0
  return (wLogAppender*)ConsoleAppender;
280
0
}