Coverage Report

Created: 2025-11-24 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/utils/wlog/ConsoleAppender.c
Line
Count
Source
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
1
#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
  wLogAppender 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
1
{
44
1
  return TRUE;
45
1
}
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
                                              const wLogMessage* cmessage)
55
996
{
56
996
  if (!appender)
57
0
    return FALSE;
58
59
996
  wLogConsoleAppender* consoleAppender = (wLogConsoleAppender*)appender;
60
61
996
  char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
62
996
  WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix, sizeof(prefix));
63
64
#ifdef _WIN32
65
  if (consoleAppender->outputStream == WLOG_CONSOLE_DEBUG)
66
  {
67
    OutputDebugStringA(prefix);
68
    OutputDebugStringA(cmessage->TextString);
69
    OutputDebugStringA("\n");
70
71
    return TRUE;
72
  }
73
#endif
74
#ifdef ANDROID
75
  android_LogPriority level;
76
  switch (cmessage->Level)
77
  {
78
    case WLOG_TRACE:
79
      level = ANDROID_LOG_VERBOSE;
80
      break;
81
    case WLOG_DEBUG:
82
      level = ANDROID_LOG_DEBUG;
83
      break;
84
    case WLOG_INFO:
85
      level = ANDROID_LOG_INFO;
86
      break;
87
    case WLOG_WARN:
88
      level = ANDROID_LOG_WARN;
89
      break;
90
    case WLOG_ERROR:
91
      level = ANDROID_LOG_ERROR;
92
      break;
93
    case WLOG_FATAL:
94
      level = ANDROID_LOG_FATAL;
95
      break;
96
    case WLOG_OFF:
97
      level = ANDROID_LOG_SILENT;
98
      break;
99
    default:
100
      level = ANDROID_LOG_FATAL;
101
      break;
102
  }
103
104
  if (level != ANDROID_LOG_SILENT)
105
    __android_log_print(level, log->Name, "%s%s", prefix, cmessage->TextString);
106
107
#else
108
996
  FILE* fp = NULL;
109
996
  switch (consoleAppender->outputStream)
110
996
  {
111
0
    case WLOG_CONSOLE_STDOUT:
112
0
      fp = stdout;
113
0
      break;
114
0
    case WLOG_CONSOLE_STDERR:
115
0
      fp = stderr;
116
0
      break;
117
996
    default:
118
996
      switch (cmessage->Level)
119
996
      {
120
0
        case WLOG_TRACE:
121
0
        case WLOG_DEBUG:
122
0
        case WLOG_INFO:
123
0
          fp = stdout;
124
0
          break;
125
996
        default:
126
996
          fp = stderr;
127
996
          break;
128
996
      }
129
996
      break;
130
996
  }
131
132
996
  if (cmessage->Level != WLOG_OFF)
133
996
    (void)fprintf(fp, "%s%s\n", prefix, cmessage->TextString);
134
996
#endif
135
996
  return TRUE;
136
996
}
137
138
static int g_DataId = 0;
139
140
static BOOL WLog_ConsoleAppender_WriteDataMessage(WINPR_ATTR_UNUSED wLog* log,
141
                                                  WINPR_ATTR_UNUSED wLogAppender* appender,
142
                                                  const wLogMessage* message)
143
0
{
144
#if defined(ANDROID)
145
  return FALSE;
146
#else
147
0
  int DataId = 0;
148
0
  char* FullFileName = NULL;
149
150
0
  DataId = g_DataId++;
151
0
  FullFileName = WLog_Message_GetOutputFileName(DataId, "dat");
152
153
0
  WLog_DataMessage_Write(FullFileName, message->Data, message->Length);
154
155
0
  free(FullFileName);
156
157
0
  return TRUE;
158
0
#endif
159
0
}
160
161
static int g_ImageId = 0;
162
163
static BOOL WLog_ConsoleAppender_WriteImageMessage(WINPR_ATTR_UNUSED wLog* log,
164
                                                   WINPR_ATTR_UNUSED wLogAppender* appender,
165
                                                   const wLogMessage* message)
166
0
{
167
#if defined(ANDROID)
168
  return FALSE;
169
#else
170
0
  int ImageId = 0;
171
0
  char* FullFileName = NULL;
172
173
0
  ImageId = g_ImageId++;
174
0
  FullFileName = WLog_Message_GetOutputFileName(ImageId, "bmp");
175
176
0
  WLog_ImageMessage_Write(FullFileName, message->ImageData, message->ImageWidth,
177
0
                          message->ImageHeight, message->ImageBpp);
178
179
0
  free(FullFileName);
180
181
0
  return TRUE;
182
0
#endif
183
0
}
184
185
static int g_PacketId = 0;
186
187
static BOOL WLog_ConsoleAppender_WritePacketMessage(WINPR_ATTR_UNUSED wLog* log,
188
                                                    wLogAppender* appender,
189
                                                    const wLogMessage* message)
190
0
{
191
#if defined(ANDROID)
192
  return FALSE;
193
#else
194
0
  char* FullFileName = NULL;
195
196
0
  g_PacketId++;
197
198
0
  if (!appender->PacketMessageContext)
199
0
  {
200
0
    FullFileName = WLog_Message_GetOutputFileName(-1, "pcap");
201
0
    appender->PacketMessageContext = (void*)Pcap_Open(FullFileName, TRUE);
202
0
    free(FullFileName);
203
0
  }
204
205
0
  if (appender->PacketMessageContext)
206
0
    return WLog_PacketMessage_Write((wPcap*)appender->PacketMessageContext, message->PacketData,
207
0
                                    message->PacketLength, message->PacketFlags);
208
209
0
  return TRUE;
210
0
#endif
211
0
}
212
static BOOL WLog_ConsoleAppender_Set(wLogAppender* appender, const char* setting, void* value)
213
0
{
214
0
  wLogConsoleAppender* consoleAppender = (wLogConsoleAppender*)appender;
215
216
  /* Just check the value string is not empty */
217
0
  if (!value || (strnlen(value, 2) == 0))
218
0
    return FALSE;
219
220
0
  if (strcmp("outputstream", setting) != 0)
221
0
    return FALSE;
222
223
0
  if (!strcmp("stdout", value))
224
0
    consoleAppender->outputStream = WLOG_CONSOLE_STDOUT;
225
0
  else if (!strcmp("stderr", value))
226
0
    consoleAppender->outputStream = WLOG_CONSOLE_STDERR;
227
0
  else if (!strcmp("default", value))
228
0
    consoleAppender->outputStream = WLOG_CONSOLE_DEFAULT;
229
0
  else if (!strcmp("debug", value))
230
0
    consoleAppender->outputStream = WLOG_CONSOLE_DEBUG;
231
0
  else
232
0
    return FALSE;
233
234
0
  return TRUE;
235
0
}
236
237
static void WLog_ConsoleAppender_Free(wLogAppender* appender)
238
1
{
239
1
  if (appender)
240
1
  {
241
1
    if (appender->PacketMessageContext)
242
0
    {
243
0
      Pcap_Close((wPcap*)appender->PacketMessageContext);
244
0
    }
245
246
1
    free(appender);
247
1
  }
248
1
}
249
250
wLogAppender* WLog_ConsoleAppender_New(WINPR_ATTR_UNUSED wLog* log)
251
1
{
252
1
  wLogConsoleAppender* ConsoleAppender =
253
1
      (wLogConsoleAppender*)calloc(1, sizeof(wLogConsoleAppender));
254
255
1
  if (!ConsoleAppender)
256
0
    return NULL;
257
258
1
  ConsoleAppender->common.Type = WLOG_APPENDER_CONSOLE;
259
1
  ConsoleAppender->common.Open = WLog_ConsoleAppender_Open;
260
1
  ConsoleAppender->common.Close = WLog_ConsoleAppender_Close;
261
1
  ConsoleAppender->common.WriteMessage = WLog_ConsoleAppender_WriteMessage;
262
1
  ConsoleAppender->common.WriteDataMessage = WLog_ConsoleAppender_WriteDataMessage;
263
1
  ConsoleAppender->common.WriteImageMessage = WLog_ConsoleAppender_WriteImageMessage;
264
1
  ConsoleAppender->common.WritePacketMessage = WLog_ConsoleAppender_WritePacketMessage;
265
1
  ConsoleAppender->common.Set = WLog_ConsoleAppender_Set;
266
1
  ConsoleAppender->common.Free = WLog_ConsoleAppender_Free;
267
268
1
  ConsoleAppender->outputStream = WLOG_CONSOLE_DEFAULT;
269
270
#ifdef _WIN32
271
  if (IsDebuggerPresent())
272
    ConsoleAppender->outputStream = WLOG_CONSOLE_DEBUG;
273
#endif
274
275
1
  return &ConsoleAppender->common;
276
1
}