summaryrefslogtreecommitdiffabout
path: root/SyslogSocket.cpp
Unidiff
Diffstat (limited to 'SyslogSocket.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--SyslogSocket.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/SyslogSocket.cpp b/SyslogSocket.cpp
new file mode 100644
index 0000000..641499f
--- a/dev/null
+++ b/SyslogSocket.cpp
@@ -0,0 +1,192 @@
1#include "stdafx.h"
2#include "SyslogSocket.h"
3
4LPCTSTR CSyslogSocket::m_Priorities[8] = {
5 "emerg", "alert", "crit", "err", "warn", "notice", "info", "debug"
6};
7LPCTSTR CSyslogSocket::m_Facilities[24] = {
8 "kernel", "user", "mail", "daemon", "auth", "syslog", "lpr","news","uucp","cron","authpriv","reserved0","reserved1","reserved2","reserved3","reserved4","local0","local1","local2","local3","local4","local5","local6","local7"
9};
10
11BOOL CSyslogSocket::CreateListen(UINT port)
12{
13 if(!Create(port?port:m_Port,SOCK_DGRAM))
14 return FALSE;
15 DoSelect();
16 return TRUE;
17}
18
19CSyslogSocket::CSyslogSocket()
20{
21 m_Port=514;
22 m_MaxLine=2048;
23 m_DefaultPriority=MakePriority(priNotice,facUser);
24 memset(&m_DefaultHost,0,sizeof(m_DefaultHost));
25 m_DefaultHost.sin_family=AF_INET;
26 m_DefaultHost.sin_addr.s_addr=inet_addr("127.0.0.1");
27 m_DefaultHost.sin_port=m_Port;
28}
29
30void CSyslogSocket::DoSelect()
31{
32 AsyncSelect(FD_CLOSE|FD_READ|(m_Queue.IsEmpty()?0:FD_WRITE));
33}
34
35void CSyslogSocket::OnReceive(int nErrorCode)
36{
37 if(nErrorCode){
38 TRACE0("Error on receiving socket\n");
39 return;
40 }
41SOCKADDR_IN sin;
42int sinLength = sizeof(sin);
43CString inputLine;
44LPTSTR buff = inputLine.GetBuffer(m_MaxLine+1);
45int bytes = ReceiveFrom(buff,m_MaxLine,(SOCKADDR*)&sin,&sinLength);
46 if(bytes==SOCKET_ERROR){
47 TRACE0("Failed to receive datagram\n");
48 return;
49 }
50 buff[bytes]=0;
51 inputLine.ReleaseBuffer();
52UINT pri = m_DefaultPriority;
53 if(!inputLine.IsEmpty()){
54 if(inputLine[0]=='<'){
55 inputLine=inputLine.Mid(1);
56 CString newPri = inputLine.SpanIncluding("0123456789");
57 inputLine=inputLine.Mid(newPri.GetLength());
58 if((!inputLine.IsEmpty()) && inputLine[0]=='>')
59 inputLine=inputLine.Mid(1);
60 pri = atoi((LPCTSTR)newPri);
61 }
62 }
63 ASSERT(sin.sin_family==AF_INET);
64 Log(Priority(pri),Facility(pri),inputLine,&sin);
65 DoSelect();
66}
67
68void CSyslogSocket::Log(UINT pri,UINT fac,LPCTSTR line,SOCKADDR_IN *sin)
69{
70 // Default implementation does nothing.
71}
72
73CString CSyslogSocket::Escape(LPCTSTR str)
74{
75CString rv;
76 while(*str){
77 int c = *(str++);
78 if(iscntrl(c)){
79 switch(c){
80 case '\n':
81 c=' ';
82 break;
83 case '\t':
84 c='\t';
85 break;
86 default:
87 rv+='^';
88 c|='@';
89 break;
90 }
91 }
92 rv+=(char)c;
93 }
94 return rv;
95}
96
97BOOL CSyslogSocket::LogTo(SOCKADDR_IN* sin,UINT pri,UINT fac,LPCTSTR str)
98{
99 ASSERT(sin);
100CString tmp;
101 tmp.Format("<%u>",MakePriority(pri,fac));
102 tmp+=str;
103 return LogTo(sin,tmp);
104}
105
106BOOL CSyslogSocket::LogTo(SOCKADDR_IN* sin,LPCTSTR str)
107{
108CSyslogOutgoingPacket *p = new CSyslogOutgoingPacket;
109 ASSERT(p);
110 memmove(&p->m_To,sin,sizeof(p->m_To));
111 p->m_What=str;
112 m_Queue.AddTail(p);
113 DoSelect();
114 return TRUE;
115}
116
117BOOL CSyslogSocket::LogTo(DWORD sinAddr,UINT sinPort,LPCTSTR str)
118{
119SOCKADDR_IN sin;
120 memset(&sin,0,sizeof(sin));
121 sin.sin_addr.s_addr=sinAddr;
122 sin.sin_port=sinPort;
123 sin.sin_family=AF_INET;
124 return LogTo(&sin,str);
125}
126
127BOOL CSyslogSocket::LogTo(DWORD sinAddr,UINT sinPort,UINT pri,UINT fac,LPCTSTR str)
128{
129SOCKADDR_IN sin;
130 memset(&sin,0,sizeof(sin));
131 sin.sin_addr.s_addr=sinAddr;
132 sin.sin_port=sinPort;
133 sin.sin_family=AF_INET;
134 return LogTo(&sin,pri,fac,str);
135}
136
137BOOL CSyslogSocket::LogTo(DWORD sinAddr,UINT pri,UINT fac,LPCTSTR str)
138{
139 return LogTo(sinAddr,m_Port,pri,fac,str);
140}
141
142BOOL CSyslogSocket::LogTo(DWORD sinAddr,LPCTSTR str)
143{
144 return LogTo(sinAddr,m_Port,str);
145}
146
147BOOL CSyslogSocket::LogTo(UINT pri,UINT fac,LPCTSTR str)
148{
149 return LogTo(&m_DefaultHost,pri,fac,str);
150}
151
152BOOL CSyslogSocket::LogTo(LPCTSTR str)
153{
154 return LogTo(&m_DefaultHost,str);
155}
156
157UINT CSyslogSocket::Facility(LPCTSTR str)
158{
159 ASSERT(str);
160 for(int tmp=0;tmp<(sizeof(m_Facilities)/sizeof(m_Facilities[0]));tmp++)
161 if(!strcmp(str,m_Facilities[tmp]))
162 return tmp;
163 return facNone;
164}
165
166UINT CSyslogSocket::Priority(LPCTSTR str)
167{
168 ASSERT(str);
169 for(int tmp=0;tmp<(sizeof(m_Priorities)/sizeof(m_Priorities[0]));tmp++)
170 if(!strcmp(str,m_Priorities[tmp]))
171 return tmp;
172 return priNone;
173}
174
175void CSyslogSocket::OnSend(int nErrorCode)
176{
177 if(nErrorCode){
178 TRACE0("Error on sending socket\n");
179 return;
180 }
181 if(!m_Queue.IsEmpty()){
182 CSyslogOutgoingPacket *p = m_Queue.GetHead();
183 ASSERT(p);
184 m_Queue.RemoveHead();
185 int rv = SendTo((LPCTSTR)p->m_What,p->m_What.GetLength(),(SOCKADDR*)&p->m_To,sizeof(SOCKADDR_IN));
186 if(rv!=p->m_What.GetLength()){
187 TRACE0("Failed to send on socket\n");
188 }
189 delete p;
190 }
191 DoSelect();
192}