FreeRDP
Loading...
Searching...
No Matches
JournaldAppender.c
1
21#include <winpr/config.h>
22
23#include "JournaldAppender.h"
24
25#include <unistd.h>
26#include <syslog.h>
27#include <systemd/sd-journal.h>
28
29#include <winpr/crt.h>
30#include <winpr/environment.h>
31
32typedef struct
33{
34 WLOG_APPENDER_COMMON();
35 char* identifier;
36 FILE* stream;
37} wLogJournaldAppender;
38
39static BOOL WLog_JournaldAppender_Open(wLog* log, wLogAppender* appender)
40{
41 int fd = 0;
42 wLogJournaldAppender* journaldAppender = NULL;
43
44 if (!log || !appender)
45 return FALSE;
46
47 journaldAppender = (wLogJournaldAppender*)appender;
48 if (journaldAppender->stream)
49 return TRUE;
50
51 fd = sd_journal_stream_fd(journaldAppender->identifier, LOG_INFO, 1);
52 if (fd < 0)
53 return FALSE;
54
55 journaldAppender->stream = fdopen(fd, "w");
56 if (!journaldAppender->stream)
57 {
58 close(fd);
59 return FALSE;
60 }
61
62 setbuffer(journaldAppender->stream, NULL, 0);
63 return TRUE;
64}
65
66static BOOL WLog_JournaldAppender_Close(wLog* log, wLogAppender* appender)
67{
68 if (!log || !appender)
69 return FALSE;
70
71 return TRUE;
72}
73
74static BOOL WLog_JournaldAppender_WriteMessage(wLog* log, wLogAppender* appender,
75 wLogMessage* message)
76{
77 char* formatStr = NULL;
78 wLogJournaldAppender* journaldAppender = NULL;
79 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
80
81 if (!log || !appender || !message)
82 return FALSE;
83
84 journaldAppender = (wLogJournaldAppender*)appender;
85
86 switch (message->Level)
87 {
88 case WLOG_TRACE:
89 case WLOG_DEBUG:
90 formatStr = "<7>%s%s\n";
91 break;
92 case WLOG_INFO:
93 formatStr = "<6>%s%s\n";
94 break;
95 case WLOG_WARN:
96 formatStr = "<4>%s%s\n";
97 break;
98 case WLOG_ERROR:
99 formatStr = "<3>%s%s\n";
100 break;
101 case WLOG_FATAL:
102 formatStr = "<2>%s%s\n";
103 break;
104 case WLOG_OFF:
105 return TRUE;
106 default:
107 (void)fprintf(stderr, "%s: unknown level %" PRIu32 "\n", __func__, message->Level);
108 return FALSE;
109 }
110
111 message->PrefixString = prefix;
112 WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
113
114 if (message->Level != WLOG_OFF)
115 {
116 WINPR_PRAGMA_DIAG_PUSH
117 WINPR_PRAGMA_DIAG_IGNORED_FORMAT_NONLITERAL(void)
118 fprintf(journaldAppender->stream, formatStr, message->PrefixString, message->TextString);
119 WINPR_PRAGMA_DIAG_POP
120 }
121 return TRUE;
122}
123
124static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
125 wLogMessage* message)
126{
127 if (!log || !appender || !message)
128 return FALSE;
129
130 return TRUE;
131}
132
133static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
134 wLogMessage* message)
135{
136 if (!log || !appender || !message)
137 return FALSE;
138
139 return TRUE;
140}
141
142static BOOL WLog_JournaldAppender_Set(wLogAppender* appender, const char* setting, void* value)
143{
144 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
145
146 /* Just check the value string is not empty */
147 if (!value || (strnlen(value, 2) == 0))
148 return FALSE;
149
150 if (strcmp("identifier", setting) != 0)
151 return FALSE;
152
153 /* If the stream is already open the identifier can't be changed */
154 if (journaldAppender->stream)
155 return FALSE;
156
157 if (journaldAppender->identifier)
158 free(journaldAppender->identifier);
159
160 return ((journaldAppender->identifier = _strdup((const char*)value)) != NULL);
161}
162
163static void WLog_JournaldAppender_Free(wLogAppender* appender)
164{
165 wLogJournaldAppender* journaldAppender = NULL;
166 if (appender)
167 {
168 journaldAppender = (wLogJournaldAppender*)appender;
169 if (journaldAppender->stream)
170 (void)fclose(journaldAppender->stream);
171 free(journaldAppender->identifier);
172 free(journaldAppender);
173 }
174}
175
176wLogAppender* WLog_JournaldAppender_New(wLog* log)
177{
178 wLogJournaldAppender* appender = NULL;
179 DWORD nSize = 0;
180 LPCSTR name = "WLOG_JOURNALD_ID";
181
182 appender = (wLogJournaldAppender*)calloc(1, sizeof(wLogJournaldAppender));
183 if (!appender)
184 return NULL;
185
186 appender->Type = WLOG_APPENDER_JOURNALD;
187 appender->Open = WLog_JournaldAppender_Open;
188 appender->Close = WLog_JournaldAppender_Close;
189 appender->WriteMessage = WLog_JournaldAppender_WriteMessage;
190 appender->WriteDataMessage = WLog_JournaldAppender_WriteDataMessage;
191 appender->WriteImageMessage = WLog_JournaldAppender_WriteImageMessage;
192 appender->Set = WLog_JournaldAppender_Set;
193 appender->Free = WLog_JournaldAppender_Free;
194
195 nSize = GetEnvironmentVariableA(name, NULL, 0);
196 if (nSize)
197 {
198 appender->identifier = (LPSTR)malloc(nSize);
199 if (!appender->identifier)
200 goto error_open;
201
202 if (GetEnvironmentVariableA(name, appender->identifier, nSize) != nSize - 1)
203 goto error_open;
204
205 if (!WLog_JournaldAppender_Open(log, (wLogAppender*)appender))
206 goto error_open;
207 }
208
209 return (wLogAppender*)appender;
210
211error_open:
212 free(appender->identifier);
213 free(appender);
214 return NULL;
215}