ReactOS 0.4.15-dev-8236-g99f0937
syslog.c
Go to the documentation of this file.
1/*
2 * syslog-client.c - syslog client implementation for windows
3 *
4 * Created by Alexander Yaworsky
5 *
6 * THIS SOFTWARE IS NOT COPYRIGHTED
7 *
8 * This source code is offered for use in the public domain. You may
9 * use, modify or distribute it freely.
10 *
11 * This code is distributed in the hope that it will be useful but
12 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
13 * DISCLAIMED. This includes but is not limited to warranties of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 *
16 */
17
18/* define SYSLOG_CONF_DIR where syslog.host should be
19 */
20
21#ifndef SYSLOG_CONF_DIR
22static const char *syslog_conf_dir = ".";
23#else
24static const char *syslog_conf_dir = SYSLOG_CONF_DIR;
25#endif
26
27#include <stdio.h>
28#include <string.h>
29#include <winsock2.h>
30#include <ws2tcpip.h>
31#include "syslog.h"
32
33#ifdef TEST
34# define SYSLOG_DGRAM_SIZE 80
35#else
36# define SYSLOG_DGRAM_SIZE 1024
37#endif
38
40static int log_mask = 0xFF;
41static char *syslog_ident;
42static int syslog_facility;
43static char str_pid[ 40 ];
45static SOCKET sock;
48static int datagramm_size;
49
50/******************************************************************************
51 * set_syslog_conf_dir
52 *
53 * maybe this function will be useful...
54 */
55const char* set_syslog_conf_dir( const char* dir )
56{
57 const char *ret = syslog_conf_dir;
59 return ret;
60}
61
62/******************************************************************************
63 * init_logger_addr
64 *
65 * Read configuration file syslog.host. This file should contain host address
66 * and, optionally, port. Initialize sa_logger. If the configuration file does
67 * not exist, use localhost:514.
68 * Returns: 0 - ok, -1 - error.
69 */
70static void init_logger_addr()
71{
72 char pathname[ FILENAME_MAX ];
73 char *p;
74 FILE *fd;
75 char host[256];
76 struct hostent * phe;
77
78 memset( &sa_logger, 0, sizeof(SOCKADDR_IN) );
80
81 if( '\\' == syslog_conf_dir[0] || '/' == syslog_conf_dir[0] || ':' == syslog_conf_dir[1] )
82 {
83 /* absolute path */
85 }
86 else
87 {
88 /* relative path */
89 char *q;
90
91 strcpy( pathname, __argv[0] );
92 p = strrchr( pathname, '\\' ) + 1;
93 q = strrchr( pathname, '/' ) + 1;
94 if( p < q )
95 *q = 0;
96 else if( p > q )
97 *p = 0;
98 else
99 pathname[0] = 0;
101 }
102 p = &pathname[ strlen( pathname ) - 1 ];
103 if( '\\' != *p && '/' != *p )
104 {
105 p++; *p = '/';
106 }
107 strcpy( ++p, "syslog.host" );
108
109 /* read destination host name */
110 fd = fopen( pathname, "r" );
111 if( !fd )
112 goto use_default;
113
114 if( NULL == fgets( host, sizeof(host), fd ) )
115 host[0] = 0;
116 else
117 {
118 p = strchr( host, '\n' );
119 if( p )
120 *p = 0;
121 p = strchr( host, '\r' );
122 if( p )
123 *p = 0;
124 }
125 fclose( fd );
126
127 p = strchr( host, ':' );
128 if( p )
129 *p++ = 0;
130
131 phe = gethostbyname( host );
132 if( !phe )
133 goto use_default;
134
135 memcpy( &sa_logger.sin_addr.s_addr, phe->h_addr, phe->h_length );
136
137 if( p )
138 sa_logger.sin_port = htons( (unsigned short) strtoul( p, NULL, 0 ) );
139 else
141 return;
142
143use_default:
144 sa_logger.sin_addr.S_un.S_addr = htonl( 0x7F000001 );
146}
147
148/******************************************************************************
149 * closelog
150 *
151 * Close descriptor used to write to system logger.
152 */
154{
155 if( !initialized )
156 return;
157 closesocket( sock );
158 WSACleanup();
160}
161
162/******************************************************************************
163 * openlog
164 *
165 * Open connection to system logger.
166 */
167void openlog( char* ident, int option, int facility )
168{
169 BOOL failed = TRUE, wsa_initialized = FALSE;
170 WSADATA wsd;
171 SOCKADDR_IN sa_local;
172 DWORD n;
173 int size;
174
175 if( initialized )
176 return;
177
178 syslog_facility = facility? facility : LOG_USER;
179
180 /* FIXME: should we reset logmask? */
181
182 if( option & LOG_PID )
183 snprintf( str_pid, sizeof(str_pid), "[%lu]", GetCurrentProcessId() );
184 else
185 str_pid[0] = 0;
186
187 /* FIXME: handle other options */
188
189 n = sizeof(local_hostname);
191 goto done;
192
194 if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) )
195 goto done;
196 wsa_initialized = TRUE;
197
199
200 for( n = 0;; n++ )
201 {
202 sock = socket( AF_INET, SOCK_DGRAM, 0 );
203 if( INVALID_SOCKET == sock )
204 goto done;
205
206 memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
207 sa_local.sin_family = AF_INET;
208 if( bind( sock, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
209 break;
210 closesocket( sock );
212 if( n == 100 )
213 goto done;
214 Sleep(0);
215 }
216
217 /* get size of datagramm */
218 size = sizeof(datagramm_size);
220 goto done;
221 if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 )
222 goto done;
223 if( datagramm_size > sizeof(datagramm) )
224 datagramm_size = sizeof(datagramm);
225
226 if( atexit( closelog ) )
227 goto done;
228
230 syslog_facility = facility;
231 failed = FALSE;
232
233done:
234 if( failed )
235 {
237 if( wsa_initialized ) WSACleanup();
238 }
239 initialized = !failed;
240}
241
242/******************************************************************************
243 * setlogmask
244 *
245 * Set the log mask level.
246 */
247int setlogmask( int mask )
248{
249 int ret = log_mask;
250
251 if( mask )
252 log_mask = mask;
253 return ret;
254}
255
256/******************************************************************************
257 * syslog
258 *
259 * Generate a log message using FMT string and option arguments.
260 */
261void syslog( int pri, char* fmt, ... )
262{
263 va_list ap;
264
265 va_start( ap, fmt );
266 vsyslog( pri, fmt, ap );
267 va_end( ap );
268}
269
270/******************************************************************************
271 * vsyslog
272 *
273 * Generate a log message using FMT and using arguments pointed to by AP.
274 */
275void vsyslog( int pri, char* fmt, va_list ap )
276{
277 static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
278 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
279 SYSTEMTIME stm;
280 int len;
281 char *p;
282
283 if( !(LOG_MASK( LOG_PRI( pri )) & log_mask) )
284 return;
285
286 openlog( NULL, 0, pri & LOG_FACMASK );
287 if( !initialized )
288 return;
289
290 if( !(pri & LOG_FACMASK) )
291 pri |= syslog_facility;
292
293 GetLocalTime( &stm );
294 len = sprintf( datagramm, "<%d>%s %2d %02d:%02d:%02d %s %s%s: ",
295 pri,
296 month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond,
299 p = strchr( datagramm, '\n' );
300 if( p )
301 *p = 0;
302 p = strchr( datagramm, '\r' );
303 if( p )
304 *p = 0;
305
307}
308
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
unsigned int dir
Definition: maze.c:112
static WSADATA wsd
Definition: adapter.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
static const WCHAR month[12][4]
Definition: session.c:2150
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum GLint GLuint mask
Definition: glext.h:6028
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define FILENAME_MAX
Definition: stdio.h:64
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_CRTIMP char ** __argv
Definition: getargs.c:18
int __cdecl atexit(void(__cdecl *)(void))
Definition: atonexit.c:97
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define htonl(x)
Definition: module.h:214
char pathname[512]
Definition: util.h:13
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define closesocket
Definition: ncftp.h:477
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static int fd
Definition: io.c:51
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
WORD wMonth
Definition: winbase.h:906
WORD wHour
Definition: winbase.h:909
WORD wSecond
Definition: winbase.h:911
WORD wMinute
Definition: winbase.h:910
WORD wDay
Definition: winbase.h:908
Definition: dsound.c:943
short h_length
Definition: winsock.h:137
Definition: getopt.h:109
Definition: tcpcore.h:1455
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
void closelog()
Definition: syslog.c:153
static const char * syslog_conf_dir
Definition: syslog.c:22
#define SYSLOG_DGRAM_SIZE
Definition: syslog.c:36
const char * set_syslog_conf_dir(const char *dir)
Definition: syslog.c:55
static int syslog_facility
Definition: syslog.c:42
static char str_pid[40]
Definition: syslog.c:43
static char local_hostname[MAX_COMPUTERNAME_LENGTH+1]
Definition: syslog.c:46
void syslog(int pri, char *fmt,...)
Definition: syslog.c:261
static SOCKET sock
Definition: syslog.c:45
void openlog(char *ident, int option, int facility)
Definition: syslog.c:167
static SOCKADDR_IN sa_logger
Definition: syslog.c:44
static void init_logger_addr()
Definition: syslog.c:70
int setlogmask(int mask)
Definition: syslog.c:247
static char datagramm[SYSLOG_DGRAM_SIZE]
Definition: syslog.c:47
static BOOL initialized
Definition: syslog.c:39
static int log_mask
Definition: syslog.c:40
static char * syslog_ident
Definition: syslog.c:41
void vsyslog(int pri, char *fmt, va_list ap)
Definition: syslog.c:275
static int datagramm_size
Definition: syslog.c:48
#define LOG_FACMASK
Definition: syslog.h:111
#define LOG_MASK(pri)
Definition: syslog.h:147
#define LOG_PID
Definition: syslog.h:156
#define SYSLOG_PORT
Definition: syslog.h:163
#define LOG_PRI(p)
Definition: syslog.h:56
#define LOG_USER
Definition: syslog.h:88
#define vsnprintf
Definition: tif_win32.c:406
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int ret
char * host
Definition: whois.c:55
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:243
#define GetComputerName
Definition: winbase.h:3800
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:332
#define SOCK_DGRAM
Definition: winsock.h:336
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOL_SOCKET
Definition: winsock.h:398
#define snprintf
Definition: wintirpc.h:48
#define SO_MAX_MSG_SIZE
Definition: ws2def.h:119