ReactOS  0.4.12-dev-36-g472787f
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
22 static const char *syslog_conf_dir = ".";
23 #else
24 static 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 
40 static int log_mask = 0xFF;
41 static char *syslog_ident;
42 static int syslog_facility;
43 static char str_pid[ 40 ];
45 static SOCKET sock;
48 static int datagramm_size;
49 
50 /******************************************************************************
51  * set_syslog_conf_dir
52  *
53  * maybe this function will be useful...
54  */
55 const 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  */
70 static 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) );
79  sa_logger.sin_family = AF_INET;
80 
81  if( '\\' == syslog_conf_dir[0] || '/' == syslog_conf_dir[0] || ':' == syslog_conf_dir[1] )
82  {
83  /* absolute path */
84  strcpy( pathname, syslog_conf_dir );
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;
100  strcat( pathname, syslog_conf_dir );
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
140  sa_logger.sin_port = htons( SYSLOG_PORT );
141  return;
142 
143 use_default:
144  sa_logger.sin_addr.S_un.S_addr = htonl( 0x7F000001 );
145  sa_logger.sin_port = htons( SYSLOG_PORT );
146 }
147 
148 /******************************************************************************
149  * closelog
150  *
151  * Close descriptor used to write to system logger.
152  */
153 void closelog()
154 {
155  if( !initialized )
156  return;
157  closesocket( sock );
158  WSACleanup();
159  initialized = FALSE;
160 }
161 
162 /******************************************************************************
163  * openlog
164  *
165  * Open connection to system logger.
166  */
167 void 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);
190  if( !GetComputerName( local_hostname, &n ) )
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);
219  if( getsockopt( sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &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 
233 done:
234  if( failed )
235  {
236  if( sock != INVALID_SOCKET ) closesocket( sock );
237  if( wsa_initialized ) WSACleanup();
238  }
239  initialized = !failed;
240 }
241 
242 /******************************************************************************
243  * setlogmask
244  *
245  * Set the log mask level.
246  */
247 int 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  */
261 void 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  */
275 void 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,
298  vsnprintf( datagramm + len, datagramm_size - len, fmt, ap );
299  p = strchr( datagramm, '\n' );
300  if( p )
301  *p = 0;
302  p = strchr( datagramm, '\r' );
303  if( p )
304  *p = 0;
305 
306  sendto( sock, datagramm, strlen(datagramm), 0, (SOCKADDR*) &sa_logger, sizeof(SOCKADDR_IN) );
307 }
308 
#define vsnprintf
Definition: tif_win32.c:408
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
_CRTIMP char ** __argv
Definition: getargs.c:18
#define TRUE
Definition: types.h:120
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
static SOCKET sock
Definition: syslog.c:45
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define htonl(x)
Definition: module.h:212
WORD wMonth
Definition: winbase.h:871
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
char pathname[512]
Definition: util.h:13
char * host
Definition: whois.c:55
#define GetComputerName
Definition: winbase.h:3614
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
void vsyslog(int pri, char *fmt, va_list ap)
Definition: syslog.c:275
#define snprintf
Definition: wintirpc.h:48
static int fd
Definition: io.c:51
static SOCKADDR_IN sa_logger
Definition: syslog.c:44
void syslog(int pri, char *fmt,...)
Definition: syslog.c:261
static int log_mask
Definition: syslog.c:40
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define SOL_SOCKET
Definition: winsock.h:398
GLuint const GLubyte mask[]
Definition: s_context.h:57
int __cdecl atexit(void(__cdecl *)(void))
Definition: atonexit.c:56
static char * syslog_ident
Definition: syslog.c:41
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define SYSLOG_DGRAM_SIZE
Definition: syslog.c:36
GLuint n
Definition: s_context.h:57
GLenum GLint GLuint mask
Definition: glext.h:6028
#define va_end(ap)
Definition: acmsvcex.h:90
#define closesocket
Definition: main.c:39
short h_length
Definition: winsock.h:137
WORD wMinute
Definition: winbase.h:875
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
Definition: getopt.h:108
char * va_list
Definition: acmsvcex.h:78
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
unsigned int dir
Definition: maze.c:112
#define SO_MAX_MSG_SIZE
Definition: ws2def.h:119
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
#define LOG_PID
Definition: syslog.h:156
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define INVALID_SOCKET
Definition: winsock.h:332
static int syslog_facility
Definition: syslog.c:42
void openlog(char *ident, int option, int facility)
Definition: syslog.c:167
static BOOL initialized
Definition: syslog.c:39
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
static void init_logger_addr()
Definition: syslog.c:70
WORD wSecond
Definition: winbase.h:876
int ret
#define SYSLOG_PORT
Definition: syslog.h:163
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
const char * set_syslog_conf_dir(const char *dir)
Definition: syslog.c:55
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
struct in_addr sin_addr
Definition: winsock.h:512
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
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:240
WORD wDay
Definition: winbase.h:873
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
void closelog()
Definition: syslog.c:153
#define LOG_USER
Definition: syslog.h:88
#define LOG_MASK(pri)
Definition: syslog.h:147
WORD wHour
Definition: winbase.h:874
#define va_start(ap, A)
Definition: acmsvcex.h:91
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
static int datagramm_size
Definition: syslog.c:48
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: tcpcore.h:1455
#define FILENAME_MAX
Definition: stdio.h:64
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
static char str_pid[40]
Definition: syslog.c:43
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static const char * syslog_conf_dir
Definition: syslog.c:22
#define AF_INET
Definition: tcpip.h:117
UINT_PTR SOCKET
Definition: winsock.h:47
int month[12]
Definition: systime.c:13
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
#define SOCK_DGRAM
Definition: winsock.h:336
#define memset(x, y, z)
Definition: compat.h:39
static WSADATA wsd
Definition: adapter.c:5
#define LOG_FACMASK
Definition: syslog.h:111
static char local_hostname[MAX_COMPUTERNAME_LENGTH+1]
Definition: syslog.c:46
Definition: dsound.c:943
short sin_family
Definition: winsock.h:510
static char datagramm[SYSLOG_DGRAM_SIZE]
Definition: syslog.c:47
DWORD WINAPI GetCurrentProcessId(VOID)
Definition: proc.c:1188
#define LOG_PRI(p)
Definition: syslog.h:56
int setlogmask(int mask)
Definition: syslog.c:247