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 wLogAppender 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 const wLogMessage* cmessage)
76{
77 if (!log || !appender || !cmessage)
78 return FALSE;
79
80 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
81
82 const char* formatStr = NULL;
83 switch (cmessage->Level)
84 {
85 case WLOG_TRACE:
86 case WLOG_DEBUG:
87 formatStr = "<7>%s%s\n";
88 break;
89 case WLOG_INFO:
90 formatStr = "<6>%s%s\n";
91 break;
92 case WLOG_WARN:
93 formatStr = "<4>%s%s\n";
94 break;
95 case WLOG_ERROR:
96 formatStr = "<3>%s%s\n";
97 break;
98 case WLOG_FATAL:
99 formatStr = "<2>%s%s\n";
100 break;
101 case WLOG_OFF:
102 return TRUE;
103 default:
104 (void)fprintf(stderr, "%s: unknown level %" PRIu32 "\n", __func__, cmessage->Level);
105 return FALSE;
106 }
107
108 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
109 WLog_Layout_GetMessagePrefix(log, appender->Layout, cmessage, prefix, sizeof(prefix));
110
111 if (cmessage->Level != WLOG_OFF)
112 {
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
117 }
118 return TRUE;
119}
120
121static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
122 const wLogMessage* message)
123{
124 if (!log || !appender || !message)
125 return FALSE;
126
127 return TRUE;
128}
129
130static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
131 const wLogMessage* message)
132{
133 if (!log || !appender || !message)
134 return FALSE;
135
136 return TRUE;
137}
138
139static BOOL WLog_JournaldAppender_Set(wLogAppender* appender, const char* setting, void* value)
140{
141 wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender;
142
143 /* Just check the value string is not empty */
144 if (!value || (strnlen(value, 2) == 0))
145 return FALSE;
146
147 if (strcmp("identifier", setting) != 0)
148 return FALSE;
149
150 /* If the stream is already open the identifier can't be changed */
151 if (journaldAppender->stream)
152 return FALSE;
153
154 if (journaldAppender->identifier)
155 free(journaldAppender->identifier);
156
157 return ((journaldAppender->identifier = _strdup((const char*)value)) != NULL);
158}
159
160static void WLog_JournaldAppender_Free(wLogAppender* appender)
161{
162 wLogJournaldAppender* journaldAppender = NULL;
163 if (appender)
164 {
165 journaldAppender = (wLogJournaldAppender*)appender;
166 if (journaldAppender->stream)
167 (void)fclose(journaldAppender->stream);
168 free(journaldAppender->identifier);
169 free(journaldAppender);
170 }
171}
172
173wLogAppender* WLog_JournaldAppender_New(wLog* log)
174{
175 LPCSTR name = "WLOG_JOURNALD_ID";
176
177 wLogJournaldAppender* appender = (wLogJournaldAppender*)calloc(1, sizeof(wLogJournaldAppender));
178 if (!appender)
179 return NULL;
180
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;
189
190 const DWORD nSize = GetEnvironmentVariableA(name, NULL, 0);
191 if (nSize)
192 {
193 appender->identifier = (LPSTR)malloc(nSize);
194 if (!appender->identifier)
195 goto error_open;
196
197 if (GetEnvironmentVariableA(name, appender->identifier, nSize) != nSize - 1)
198 goto error_open;
199
200 if (!WLog_JournaldAppender_Open(log, (wLogAppender*)appender))
201 goto error_open;
202 }
203
204 return (wLogAppender*)appender;
205
206error_open:
207 free(appender->identifier);
208 free(appender);
209 return NULL;
210}