21 #include <winpr/config.h>
23 #include <winpr/crt.h>
24 #include <winpr/environment.h>
25 #include <winpr/winsock.h>
31 WLOG_APPENDER_COMMON();
33 struct sockaddr targetAddr;
38 static BOOL WLog_UdpAppender_Open(wLog* log, wLogAppender* appender)
40 wLogUdpAppender* udpAppender = NULL;
41 char addressString[256] = { 0 };
42 struct addrinfo hints = { 0 };
43 struct addrinfo* result = { 0 };
45 char* colonPos = NULL;
50 udpAppender = (wLogUdpAppender*)appender;
52 if (udpAppender->targetAddrLen)
55 colonPos = strchr(udpAppender->host,
':');
60 const size_t addrLen = WINPR_ASSERTING_INT_CAST(
size_t, (colonPos - udpAppender->host));
61 memcpy(addressString, udpAppender->host, addrLen);
62 addressString[addrLen] =
'\0';
63 hints.ai_family = AF_INET;
64 hints.ai_socktype = SOCK_DGRAM;
65 status = getaddrinfo(addressString, colonPos + 1, &hints, &result);
70 if (result->ai_addrlen >
sizeof(udpAppender->targetAddr))
76 memcpy(&udpAppender->targetAddr, result->ai_addr, result->ai_addrlen);
77 udpAppender->targetAddrLen = (int)result->ai_addrlen;
82 static BOOL WLog_UdpAppender_Close(wLog* log, wLogAppender* appender)
84 if (!log || !appender)
90 static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogAppender* appender,
wLogMessage* message)
92 char prefix[WLOG_MAX_PREFIX_SIZE] = { 0 };
93 wLogUdpAppender* udpAppender = NULL;
95 if (!log || !appender || !message)
98 udpAppender = (wLogUdpAppender*)appender;
99 message->PrefixString = prefix;
100 WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
101 (void)_sendto(udpAppender->sock, message->PrefixString,
102 (
int)strnlen(message->PrefixString, INT_MAX), 0, &udpAppender->targetAddr,
103 udpAppender->targetAddrLen);
104 (void)_sendto(udpAppender->sock, message->TextString,
105 (
int)strnlen(message->TextString, INT_MAX), 0, &udpAppender->targetAddr,
106 udpAppender->targetAddrLen);
107 (void)_sendto(udpAppender->sock,
"\n", 1, 0, &udpAppender->targetAddr,
108 udpAppender->targetAddrLen);
112 static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogAppender* appender,
115 if (!log || !appender || !message)
121 static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogAppender* appender,
124 if (!log || !appender || !message)
130 static BOOL WLog_UdpAppender_Set(wLogAppender* appender,
const char* setting,
void* value)
132 const char target[] =
"target";
133 wLogUdpAppender* udpAppender = (wLogUdpAppender*)appender;
136 if (!value || (strnlen(value, 2) == 0))
139 if (strncmp(target, setting,
sizeof(target)) != 0)
142 udpAppender->targetAddrLen = 0;
144 if (udpAppender->host)
145 free(udpAppender->host);
147 udpAppender->host = _strdup((
const char*)value);
148 return (udpAppender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
151 static void WLog_UdpAppender_Free(wLogAppender* appender)
153 wLogUdpAppender* udpAppender = NULL;
157 udpAppender = (wLogUdpAppender*)appender;
159 if (udpAppender->sock != INVALID_SOCKET)
161 closesocket(udpAppender->sock);
162 udpAppender->sock = INVALID_SOCKET;
165 free(udpAppender->host);
170 wLogAppender* WLog_UdpAppender_New(wLog* log)
172 wLogUdpAppender* appender = NULL;
175 appender = (wLogUdpAppender*)calloc(1,
sizeof(wLogUdpAppender));
180 appender->Type = WLOG_APPENDER_UDP;
181 appender->Open = WLog_UdpAppender_Open;
182 appender->Close = WLog_UdpAppender_Close;
183 appender->WriteMessage = WLog_UdpAppender_WriteMessage;
184 appender->WriteDataMessage = WLog_UdpAppender_WriteDataMessage;
185 appender->WriteImageMessage = WLog_UdpAppender_WriteImageMessage;
186 appender->Free = WLog_UdpAppender_Free;
187 appender->Set = WLog_UdpAppender_Set;
188 appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
190 if (appender->sock == INVALID_SOCKET)
193 name =
"WLOG_UDP_TARGET";
194 nSize = GetEnvironmentVariableA(name, NULL, 0);
198 appender->host = (LPSTR)malloc(nSize);
203 if (GetEnvironmentVariableA(name, appender->host, nSize) != nSize - 1)
206 if (!WLog_UdpAppender_Open(log, (wLogAppender*)appender))
211 appender->host = _strdup(
"127.0.0.1:20000");
217 return (wLogAppender*)appender;
219 free(appender->host);
220 closesocket(appender->sock);