21#include <winpr/config.h>
23#include "JournaldAppender.h"
27#include <systemd/sd-journal.h>
30#include <winpr/environment.h>
37} wLogJournaldAppender;
39static BOOL WLog_JournaldAppender_Open(wLog* log, wLogAppender* appender)
42 wLogJournaldAppender* journaldAppender =
nullptr;
44 if (!log || !appender)
47 journaldAppender = (wLogJournaldAppender*)appender;
48 if (journaldAppender->stream)
51 fd = sd_journal_stream_fd(journaldAppender->identifier, LOG_INFO, 1);
55 journaldAppender->stream = fdopen(fd,
"w");
56 if (!journaldAppender->stream)
62 setbuffer(journaldAppender->stream,
nullptr, 0);
66static BOOL WLog_JournaldAppender_Close(wLog* log, wLogAppender* appender)
68 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
69 if (!log || !appender)
72 if (journaldAppender->stream)
73 (void)fclose(journaldAppender->stream);
75 free(journaldAppender->identifier);
77 journaldAppender->stream =
nullptr;
78 journaldAppender->identifier =
nullptr;
82static BOOL WLog_JournaldAppender_WriteMessage(wLog* log, wLogAppender* appender,
85 if (!log || !appender || !cmessage)
88 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
90 const char* formatStr =
nullptr;
91 switch (cmessage->Level)
95 formatStr =
"<7>%s%s\n";
98 formatStr =
"<6>%s%s\n";
101 formatStr =
"<4>%s%s\n";
104 formatStr =
"<3>%s%s\n";
107 formatStr =
"<2>%s%s\n";
112 (void)fprintf(stderr,
"%s: unknown level %" PRIu32
"\n", __func__, cmessage->Level);
116 char prefix[WLOG_MAX_PREFIX_SIZE] = WINPR_C_ARRAY_INIT;
117 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix,
sizeof(prefix));
119 if (cmessage->Level != WLOG_OFF)
121 WINPR_PRAGMA_DIAG_PUSH
122 WINPR_PRAGMA_DIAG_IGNORED_FORMAT_NONLITERAL(
void)
123 fprintf(journaldAppender->stream, formatStr, prefix, cmessage->TextString);
124 WINPR_PRAGMA_DIAG_POP
129static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
132 if (!log || !appender || !message)
135 (void)fprintf(stderr,
"[TODO: %s] data messages not implemented! Ignoring.\n", __func__);
139static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
142 if (!log || !appender || !message)
145 (void)fprintf(stderr,
"[TODO: %s] image messages not implemented! Ignoring.\n", __func__);
149static BOOL WLog_JournaldAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
151 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
154 if (!value || (strnlen(value, 2) == 0))
157 if (strcmp(
"identifier", setting) != 0)
161 if (journaldAppender->stream)
164 if (journaldAppender->identifier)
165 free(journaldAppender->identifier);
167 return ((journaldAppender->identifier = _strdup((
const char*)value)) !=
nullptr);
170static void WLog_JournaldAppender_Free(wLogAppender* appender)
172 wLogJournaldAppender* journaldAppender =
nullptr;
175 journaldAppender = (wLogJournaldAppender*)appender;
176 if (journaldAppender->stream)
177 (void)fclose(journaldAppender->stream);
178 free(journaldAppender->identifier);
179 free(journaldAppender);
183wLogAppender* WLog_JournaldAppender_New(wLog* log)
185 LPCSTR name =
"WLOG_JOURNALD_ID";
187 wLogJournaldAppender* appender = (wLogJournaldAppender*)calloc(1,
sizeof(wLogJournaldAppender));
191 appender->common.Type = WLOG_APPENDER_JOURNALD;
192 appender->common.Open = WLog_JournaldAppender_Open;
193 appender->common.Close = WLog_JournaldAppender_Close;
194 appender->common.WriteMessage = WLog_JournaldAppender_WriteMessage;
195 appender->common.WriteDataMessage = WLog_JournaldAppender_WriteDataMessage;
196 appender->common.WriteImageMessage = WLog_JournaldAppender_WriteImageMessage;
197 appender->common.Set = WLog_JournaldAppender_Set;
198 appender->common.Free = WLog_JournaldAppender_Free;
200 const DWORD nSize = GetEnvironmentVariableA(name,
nullptr, 0);
203 appender->identifier = (LPSTR)malloc(nSize);
204 if (!appender->identifier)
207 if (GetEnvironmentVariableA(name, appender->identifier, nSize) != nSize - 1)
210 if (!WLog_JournaldAppender_Open(log, (wLogAppender*)appender))
214 return (wLogAppender*)appender;
217 free(appender->identifier);