diff options
Diffstat (limited to 'winpr/libwinpr/utils/wlog/JournaldAppender.c')
-rw-r--r-- | winpr/libwinpr/utils/wlog/JournaldAppender.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/winpr/libwinpr/utils/wlog/JournaldAppender.c b/winpr/libwinpr/utils/wlog/JournaldAppender.c new file mode 100644 index 0000000..504108b --- /dev/null +++ b/winpr/libwinpr/utils/wlog/JournaldAppender.c @@ -0,0 +1,210 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright © 2015 Thincast Technologies GmbH + * Copyright © 2015 David FORT <contact@hardening-consulting.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <winpr/config.h> + +#include "JournaldAppender.h" + +#include <unistd.h> +#include <syslog.h> +#include <systemd/sd-journal.h> + +#include <winpr/crt.h> +#include <winpr/environment.h> + +typedef struct +{ + WLOG_APPENDER_COMMON(); + char* identifier; + FILE* stream; +} wLogJournaldAppender; + +static BOOL WLog_JournaldAppender_Open(wLog* log, wLogAppender* appender) +{ + int fd = 0; + wLogJournaldAppender* journaldAppender = NULL; + + if (!log || !appender) + return FALSE; + + journaldAppender = (wLogJournaldAppender*)appender; + if (journaldAppender->stream) + return TRUE; + + fd = sd_journal_stream_fd(journaldAppender->identifier, LOG_INFO, 1); + if (fd < 0) + return FALSE; + + journaldAppender->stream = fdopen(fd, "w"); + if (!journaldAppender->stream) + { + close(fd); + return FALSE; + } + + setbuffer(journaldAppender->stream, NULL, 0); + return TRUE; +} + +static BOOL WLog_JournaldAppender_Close(wLog* log, wLogAppender* appender) +{ + if (!log || !appender) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) +{ + char* formatStr = NULL; + wLogJournaldAppender* journaldAppender = NULL; + char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 }; + + if (!log || !appender || !message) + return FALSE; + + journaldAppender = (wLogJournaldAppender*)appender; + + switch (message->Level) + { + case WLOG_TRACE: + case WLOG_DEBUG: + formatStr = "<7>%s%s\n"; + break; + case WLOG_INFO: + formatStr = "<6>%s%s\n"; + break; + case WLOG_WARN: + formatStr = "<4>%s%s\n"; + break; + case WLOG_ERROR: + formatStr = "<3>%s%s\n"; + break; + case WLOG_FATAL: + formatStr = "<2>%s%s\n"; + break; + case WLOG_OFF: + return TRUE; + default: + fprintf(stderr, "%s: unknown level %" PRIu32 "\n", __func__, message->Level); + return FALSE; + } + + message->PrefixString = prefix; + WLog_Layout_GetMessagePrefix(log, appender->Layout, message); + + if (message->Level != WLOG_OFF) + fprintf(journaldAppender->stream, formatStr, message->PrefixString, message->TextString); + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteDataMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_WriteImageMessage(wLog* log, wLogAppender* appender, + wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + return TRUE; +} + +static BOOL WLog_JournaldAppender_Set(wLogAppender* appender, const char* setting, void* value) +{ + wLogJournaldAppender* journaldAppender = (wLogJournaldAppender*)appender; + + /* Just check the value string is not empty */ + if (!value || (strnlen(value, 2) == 0)) + return FALSE; + + if (strcmp("identifier", setting)) + return FALSE; + + /* If the stream is already open the identifier can't be changed */ + if (journaldAppender->stream) + return FALSE; + + if (journaldAppender->identifier) + free(journaldAppender->identifier); + + return ((journaldAppender->identifier = _strdup((const char*)value)) != NULL); +} + +static void WLog_JournaldAppender_Free(wLogAppender* appender) +{ + wLogJournaldAppender* journaldAppender = NULL; + if (appender) + { + journaldAppender = (wLogJournaldAppender*)appender; + if (journaldAppender->stream) + fclose(journaldAppender->stream); + free(journaldAppender->identifier); + free(journaldAppender); + } +} + +wLogAppender* WLog_JournaldAppender_New(wLog* log) +{ + wLogJournaldAppender* appender = NULL; + DWORD nSize = 0; + LPCSTR name = "WLOG_JOURNALD_ID"; + + appender = (wLogJournaldAppender*)calloc(1, sizeof(wLogJournaldAppender)); + if (!appender) + return NULL; + + appender->Type = WLOG_APPENDER_JOURNALD; + appender->Open = WLog_JournaldAppender_Open; + appender->Close = WLog_JournaldAppender_Close; + appender->WriteMessage = WLog_JournaldAppender_WriteMessage; + appender->WriteDataMessage = WLog_JournaldAppender_WriteDataMessage; + appender->WriteImageMessage = WLog_JournaldAppender_WriteImageMessage; + appender->Set = WLog_JournaldAppender_Set; + appender->Free = WLog_JournaldAppender_Free; + + nSize = GetEnvironmentVariableA(name, NULL, 0); + if (nSize) + { + appender->identifier = (LPSTR)malloc(nSize); + if (!appender->identifier) + goto error_open; + + if (GetEnvironmentVariableA(name, appender->identifier, nSize) != nSize - 1) + goto error_open; + + if (!WLog_JournaldAppender_Open(log, (wLogAppender*)appender)) + goto error_open; + } + + return (wLogAppender*)appender; + +error_open: + free(appender->identifier); + free(appender); + return NULL; +} |