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 = NULL;
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, NULL, 0);
66static BOOL WLog_JournaldAppender_Close(wLog* log, wLogAppender* appender)
68 if (!log || !appender)
74static BOOL WLog_JournaldAppender_WriteMessage(wLog* log, wLogAppender* appender,
77 if (!log || !appender || !cmessage)
80 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
82 const char* formatStr = NULL;
83 switch (cmessage->Level)
87 formatStr =
"<7>%s%s\n";
90 formatStr =
"<6>%s%s\n";
93 formatStr =
"<4>%s%s\n";
96 formatStr =
"<3>%s%s\n";
99 formatStr =
"<2>%s%s\n";
104 (void)fprintf(stderr,
"%s: unknown level %" PRIu32
"\n", __func__, cmessage->Level);
108 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
109 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix,
sizeof(prefix));
111 if (cmessage->Level != WLOG_OFF)
113 WINPR_PRAGMA_DIAG_PUSH
114 WINPR_PRAGMA_DIAG_IGNORED_FORMAT_NONLITERAL(
void)
115 fprintf(journaldAppender->stream, formatStr, prefix, cmessage->TextString);
116 WINPR_PRAGMA_DIAG_POP
121static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
124 if (!log || !appender || !message)
130static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
133 if (!log || !appender || !message)
139static BOOL WLog_JournaldAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
141 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
144 if (!value || (strnlen(value, 2) == 0))
147 if (strcmp(
"identifier", setting) != 0)
151 if (journaldAppender->stream)
154 if (journaldAppender->identifier)
155 free(journaldAppender->identifier);
157 return ((journaldAppender->identifier = _strdup((
const char*)value)) != NULL);
160static void WLog_JournaldAppender_Free(wLogAppender* appender)
162 wLogJournaldAppender* journaldAppender = NULL;
165 journaldAppender = (wLogJournaldAppender*)appender;
166 if (journaldAppender->stream)
167 (void)fclose(journaldAppender->stream);
168 free(journaldAppender->identifier);
169 free(journaldAppender);
173wLogAppender* WLog_JournaldAppender_New(wLog* log)
175 LPCSTR name =
"WLOG_JOURNALD_ID";
177 wLogJournaldAppender* appender = (wLogJournaldAppender*)calloc(1,
sizeof(wLogJournaldAppender));
181 appender->common.Type = WLOG_APPENDER_JOURNALD;
182 appender->common.Open = WLog_JournaldAppender_Open;
183 appender->common.Close = WLog_JournaldAppender_Close;
184 appender->common.WriteMessage = WLog_JournaldAppender_WriteMessage;
185 appender->common.WriteDataMessage = WLog_JournaldAppender_WriteDataMessage;
186 appender->common.WriteImageMessage = WLog_JournaldAppender_WriteImageMessage;
187 appender->common.Set = WLog_JournaldAppender_Set;
188 appender->common.Free = WLog_JournaldAppender_Free;
190 const DWORD nSize = GetEnvironmentVariableA(name, NULL, 0);
193 appender->identifier = (LPSTR)malloc(nSize);
194 if (!appender->identifier)
197 if (GetEnvironmentVariableA(name, appender->identifier, nSize) != nSize - 1)
200 if (!WLog_JournaldAppender_Open(log, (wLogAppender*)appender))
204 return (wLogAppender*)appender;
207 free(appender->identifier);