summaryrefslogtreecommitdiff
path: root/src/liblogger
diff options
context:
space:
mode:
authorAndreas Baumann <abaumann@yahoo.com>2012-09-10 10:33:38 +0200
committerAndreas Baumann <abaumann@yahoo.com>2012-09-10 10:33:38 +0200
commita3cc8b970a24e1970275f0e8032bf6b221d3e235 (patch)
tree8f69aa22ef6abf18457db3d923fbb1feaf2c5a48 /src/liblogger
parentdcc75cfbc4e5069038f0ec9929d1000f1630e382 (diff)
downloadcrawler-a3cc8b970a24e1970275f0e8032bf6b221d3e235.tar.gz
crawler-a3cc8b970a24e1970275f0e8032bf6b221d3e235.tar.bz2
libutil move and liblogger rename on Windows
Diffstat (limited to 'src/liblogger')
-rwxr-xr-xsrc/liblogger/ConsoleLogSink.cpp17
-rw-r--r--src/liblogger/FileLogSink.cpp85
-rwxr-xr-xsrc/liblogger/GNUmakefile43
-rwxr-xr-xsrc/liblogger/Logger.cpp183
-rwxr-xr-xsrc/liblogger/Makefile.W3260
-rwxr-xr-xsrc/liblogger/SyslogLogSink.cpp91
-rwxr-xr-xsrc/liblogger/WinDbgLogSink.cpp22
-rw-r--r--src/liblogger/win32/syslog_win32.c261
-rw-r--r--src/liblogger/win32/syslog_win32.h171
9 files changed, 933 insertions, 0 deletions
diff --git a/src/liblogger/ConsoleLogSink.cpp b/src/liblogger/ConsoleLogSink.cpp
new file mode 100755
index 0000000..84a1ebd
--- /dev/null
+++ b/src/liblogger/ConsoleLogSink.cpp
@@ -0,0 +1,17 @@
+#include "ConsoleLogSink.hpp"
+
+#include <iostream>
+
+using namespace std;
+
+void ConsoleLogSink::log( const LogLevel level, const string &msg )
+{
+ if( level > reportingLevel( ) ) return;
+
+ cerr << Logger::toString( level )
+ << ": "
+ << msg
+ << endl;
+
+ cerr.flush( );
+}
diff --git a/src/liblogger/FileLogSink.cpp b/src/liblogger/FileLogSink.cpp
new file mode 100644
index 0000000..d812dbe
--- /dev/null
+++ b/src/liblogger/FileLogSink.cpp
@@ -0,0 +1,85 @@
+#include "FileLogSink.hpp"
+
+#include <iostream>
+#include <cstring>
+
+#ifndef _WIN32
+#include <sys/time.h>
+#else
+#define WIN32_MEAN_AND_LEAN
+#include <windows.h>
+#endif
+
+using namespace std;
+
+#ifndef _WIN32
+
+static string timestamp( )
+{
+ time_t t;
+ time( &t );
+
+ struct tm r;
+ memset( &r, 0, sizeof( r ) );
+ localtime_r( &t, &r );
+
+ char buf[30];
+ strftime( buf, sizeof( buf ), "%F - %X", &r );
+
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ char result[100];
+ snprintf( result, sizeof( result ), "%s.%03ld", buf, (long)tv.tv_usec / 1000 );
+
+ return result;
+}
+
+#else
+
+static string timestamp( )
+{
+ enum { LEN = 255 };
+ char buf[LEN];
+
+ if( GetTimeFormat( LOCALE_USER_DEFAULT, 0, 0, "HH':'mm':'ss", buf, LEN ) == 0 ) {
+ return "<timestamp error>";
+ }
+
+ static DWORD first = GetTickCount( );
+
+ char result[LEN] = { 0 };
+ _snprintf( result, LEN, "%s.%03ld", buf, (long)( GetTickCount( ) - first ) % 1000 );
+
+ return result;
+}
+
+#endif
+
+FileLogSink::FileLogSink( const LogLevel level, const string &filename )
+ : LogSink( level ), m_filename( filename )
+{
+ m_file.exceptions( m_file.badbit | m_file.failbit );
+
+ try {
+ m_file.open( m_filename.c_str( ), std::ios::app );
+ } catch( exception &e ) {
+ LOG( logCRITICAL ) << e.what( );
+ }
+}
+
+FileLogSink::~FileLogSink( )
+{
+ m_file.close( );
+}
+
+void FileLogSink::log( const LogLevel level, const string &msg )
+{
+ if( level > reportingLevel( ) ) return;
+
+ m_file << timestamp( )
+ << " "
+ << Logger::toString( level )
+ << ": "
+ << msg
+ << endl;
+}
diff --git a/src/liblogger/GNUmakefile b/src/liblogger/GNUmakefile
new file mode 100755
index 0000000..7993f7d
--- /dev/null
+++ b/src/liblogger/GNUmakefile
@@ -0,0 +1,43 @@
+TOPDIR = ../..
+
+SUBDIRS =
+
+-include $(TOPDIR)/makefiles/gmake/platform.mk
+
+INCLUDE_CPPFLAGS = \
+
+INCLUDE_LDFLAGS = \
+
+INCLUDE_DIRS = \
+ -I. \
+ -I$(TOPDIR)/include/logger \
+ -I$(TOPDIR)/include/util
+
+INCLUDE_LIBS = \
+
+STATIC_LIB = liblogger.a
+
+DYNAMIC_LIB = liblogger.so
+DYNAMIC_LIB_MAJOR = 0
+DYNAMIC_LIB_MINOR = 0
+DYNAMIC_LIB_PATCH = 0
+
+CPP_OBJS = \
+ Logger.o \
+ ConsoleLogSink.o \
+ FileLogSink.o \
+ SyslogLogSink.o
+
+-include $(TOPDIR)/makefiles/gmake/sub.mk
+
+local_all:
+
+local_clean:
+
+local_distclean:
+
+local_install:
+
+local_uninstall:
+
+local_test:
diff --git a/src/liblogger/Logger.cpp b/src/liblogger/Logger.cpp
new file mode 100755
index 0000000..c4d44d8
--- /dev/null
+++ b/src/liblogger/Logger.cpp
@@ -0,0 +1,183 @@
+#include "Logger.hpp"
+#include "LogSink.hpp"
+#include "ConsoleLogSink.hpp"
+#include "FileLogSink.hpp"
+#include "SyslogLogSink.hpp"
+#ifdef _WIN32
+#include "WinDbgLogSink.hpp"
+#endif
+
+#include <algorithm>
+#include <list>
+
+using namespace std;
+
+LogStream::LogStream( Logger &logger, const LogLevel level )
+ : m_logger( logger ), m_level( level )
+{
+}
+
+LogStream::~LogStream( )
+{
+ m_logger.log( m_level, str( ) );
+}
+
+ostream &LogStream::get( )
+{
+ // transform the ostringstream to ostream, so the operator
+ // << functions work a little bit more as expected (e.g.
+ // for strings/char *)
+ return static_cast<ostream &>( *this );
+}
+
+class LoggerImpl
+{
+ public:
+ void addSink( LogSink *sink );
+ void removeSink( LogSink *sink );
+ void log( const LogLevel level, const std::string &msg );
+
+ static std::string toString( const LogLevel level );
+ static LogLevel fromString( const std::string &s );
+
+ void openConsoleLog( const LogLevel level );
+ void openFileLog( const LogLevel level, const std::string &filename );
+ void openSyslog( const LogLevel level, const string &ident, const string &facility );
+ void openWinDbgLog( const LogLevel level );
+
+ public:
+ LoggerImpl( );
+ ~LoggerImpl( );
+
+ private:
+ typedef std::list< LogSink * > SinkList;
+ SinkList m_sinks;
+};
+
+LoggerImpl::LoggerImpl( )
+{
+}
+
+LoggerImpl::~LoggerImpl( )
+{
+ SinkList::const_iterator it, end = m_sinks.end( );
+
+ for( it = m_sinks.begin( ); it != end; it++ ) {
+ delete (*it);
+ }
+}
+
+void LoggerImpl::addSink( LogSink *sink )
+{
+ m_sinks.push_back( sink );
+}
+void LoggerImpl::removeSink( LogSink *sink )
+{
+ SinkList::iterator it = find( m_sinks.begin( ), m_sinks.end( ), sink );
+ if( it != m_sinks.end( ) ) {
+ m_sinks.erase( it );
+ }
+}
+
+void LoggerImpl::log( const LogLevel level, const string &msg )
+{
+ SinkList::const_iterator it, end = m_sinks.end( );
+
+ for( it = m_sinks.begin( ); it != end; it++ ) {
+ (*it)->log( level, msg );
+ }
+}
+
+void LoggerImpl::openConsoleLog( const LogLevel level )
+{
+ addSink( new ConsoleLogSink( level ) );
+}
+
+void LoggerImpl::openFileLog( const LogLevel level, const string &filename )
+{
+ addSink( new FileLogSink( level, filename ) );
+}
+
+void LoggerImpl::openSyslog( const LogLevel level, const string &ident, const string &facility )
+{
+ addSink( new SyslogLogSink( level, ident, facility ) );
+}
+
+void LoggerImpl::openWinDbgLog( const LogLevel level )
+{
+#ifdef _WIN32
+ addSink( new WinDbgLogSink( level ) );
+#else
+ (void)level;
+ LOG( logWARNING ) << "WinDbg logger is only available on Windows";
+#endif
+}
+
+string Logger::toString( const LogLevel level )
+{
+ static const char* const buf[] = { "NONE", "FATAL", "CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4" };
+ return buf[level];
+}
+
+LogLevel Logger::fromString( const string& level )
+{
+ if( level == "DEBUG4" ) return logDEBUG4;
+ if( level == "DEBUG3" ) return logDEBUG3;
+ if( level == "DEBUG2" ) return logDEBUG2;
+ if( level == "DEBUG1") return logDEBUG1;
+ if( level == "DEBUG") return logDEBUG;
+ if( level == "INFO") return logINFO;
+ if( level == "NOTICE" ) return logNOTICE;
+ if( level == "WARNING" ) return logWARNING;
+ if( level == "ERROR" ) return logERROR;
+ if( level == "CRITICAL" ) return logCRITICAL;
+ if( level == "FATAL" ) return logFATAL;
+ if( level == "NONE" ) return logNONE;
+
+ LOG( logWARNING ) << "Unknown log level '" << level << "'. Using INFO level as default.";
+ return logINFO;
+}
+
+Logger::Logger( )
+{
+ m_impl.reset( new LoggerImpl( ) );
+}
+
+Logger::~Logger( )
+{
+}
+
+void Logger::addSink( LogSink *sink )
+{
+ m_impl->addSink( sink );
+}
+
+void Logger::removeSink( LogSink *sink )
+{
+ m_impl->removeSink( sink );
+}
+
+void Logger::log( const LogLevel level, const string &msg )
+{
+ m_impl->log( level, msg );
+}
+
+void Logger::openConsoleLog( const LogLevel level )
+{
+ m_impl->openConsoleLog( level );
+}
+
+void Logger::openFileLog( const LogLevel level, const std::string &filename )
+{
+ m_impl->openFileLog( level, filename );
+}
+
+void Logger::openSyslog( const LogLevel level, const string &ident, const string &facility )
+{
+ m_impl->openSyslog( level, ident, facility );
+}
+
+void Logger::openWinDbgLog( const LogLevel level )
+{
+ m_impl->openWinDbgLog( level );
+}
diff --git a/src/liblogger/Makefile.W32 b/src/liblogger/Makefile.W32
new file mode 100755
index 0000000..10c99f6
--- /dev/null
+++ b/src/liblogger/Makefile.W32
@@ -0,0 +1,60 @@
+TOPDIR = ..\..
+
+SUBDIRS =
+
+!INCLUDE $(TOPDIR)\makefiles\nmake\platform.mk
+
+INCLUDE_CXXFLAGS = \
+ /D_WIN32_WINNT=0x504 \
+ /DBUILDING_LOGGER /DBUILDING_UTIL
+
+INCLUDE_DIRS = \
+ /I. \
+ /I$(TOPDIR)\include\logger \
+ /I$(TOPDIR)\include\util
+
+INCLUDE_LDFLAGS = \
+
+INCLUDE_LIBS = \
+ $(TOPDIR)\src\libutil\util.lib \
+ Ws2_32.lib
+
+CPP_OBJS = \
+ win32\syslog_win32.obj \
+ Logger.obj \
+ ConsoleLogSink.obj \
+ FileLogSink.obj \
+ SyslogLogSink.obj \
+ WinDbgLogSink.obj
+
+DYNAMIC_CPP_OBJS = \
+ win32\syslog_win32.dllobj \
+ Logger.dllobj \
+ ConsoleLogSink.dllobj \
+ FileLogSink.dllobj \
+ SyslogLogSink.dllobj \
+ WinDbgLogSink.dllobj
+
+DYNAMIC_LIB = \
+ logger.dll
+
+STATIC_LIB = \
+ loggerstatic.lib
+
+!INCLUDE $(TOPDIR)\makefiles\nmake\sub.mk
+
+$(DYNAMIC_LIB): $(DYNAMIC_CPP_OBJS)
+ $(LINK) /nologo /dll /out:$@ $(LDFLAGS) $(LIBS) $?
+
+$(STATIC_LIB): $(CPP_OBJS)
+ $(LINK) /nologo /dll /out:$@ $(STATIC_LDFLAGS) $(LIBS) $?
+
+local_all: $(DYNAMIC_LIB) $(STATIC_LIB)
+
+local_clean:
+ @-erase $(DYNAMIC_LIB) $(STATIC_LIB) 2>NUL
+ @-erase win32\*.obj 2>NUL
+
+local_distclean:
+
+local_test:
diff --git a/src/liblogger/SyslogLogSink.cpp b/src/liblogger/SyslogLogSink.cpp
new file mode 100755
index 0000000..c2716a9
--- /dev/null
+++ b/src/liblogger/SyslogLogSink.cpp
@@ -0,0 +1,91 @@
+#include "SyslogLogSink.hpp"
+
+#ifndef _WIN32
+#include <syslog.h>
+#else
+#include "win32/syslog_win32.h"
+#endif
+
+using namespace std;
+
+SyslogLogSink::SyslogLogSink( const LogLevel level, const string &ident, const string &facility )
+ : LogSink( level ), m_ident( ident ), m_facility( facility )
+{
+ openlog( m_ident.c_str( ), LOG_PID, facilityFromString( m_facility ) );
+}
+
+SyslogLogSink::~SyslogLogSink( )
+{
+ closelog( );
+}
+
+void SyslogLogSink::log( const LogLevel level, const string &msg )
+{
+ if( level > reportingLevel( ) ) return;
+
+ syslog( levelToSyslogLevel( level ), "%s", msg.c_str( ) );
+}
+
+int SyslogLogSink::levelToSyslogLevel( const LogLevel level )
+{
+ switch( level ) {
+ case logFATAL: return LOG_ALERT;
+ case logCRITICAL: return LOG_CRIT;
+ case logERROR: return LOG_ERR;
+ case logWARNING: return LOG_WARNING;
+ case logNOTICE: return LOG_NOTICE;
+ case logINFO: return LOG_INFO;
+ case logDEBUG:
+ case logDEBUG1:
+ case logDEBUG2:
+ case logDEBUG3:
+ case logDEBUG4: return LOG_DEBUG;
+
+ case logNONE:
+ default:
+ LOG( logWARNING ) << "Unknown log level '" << level << "'. Using LOG)ERR level as syslog log level.";
+ return LOG_ERR;
+ }
+}
+
+int SyslogLogSink::facilityFromString( const std::string &facility )
+{
+ if( facility == "kern" ) return LOG_KERN;
+ else if( facility == "user" ) return LOG_USER;
+ else if( facility == "mail" ) return LOG_MAIL;
+ else if( facility == "daemon" ) return LOG_DAEMON;
+ else if( facility == "auth" ) return LOG_AUTH;
+ else if( facility == "syslog" ) return LOG_SYSLOG;
+ else if( facility == "lpr" ) return LOG_LPR;
+ else if( facility == "news" ) return LOG_NEWS;
+ else if( facility == "uucp" ) return LOG_UUCP;
+ else if( facility == "cron" ) return LOG_CRON;
+#ifdef LOG_AUTHPRIV
+ else if( facility == "authpriv" ) return LOG_AUTHPRIV;
+#endif
+#ifdef LOG_FTP
+ else if( facility == "ftp" ) return LOG_FTP;
+#endif
+#ifdef LOG_NTP
+ else if( facility == "ntp" ) return LOG_NTP;
+#endif
+#ifdef LOG_SECURITY
+ else if( facility == "security" ) return LOG_SECURITY;
+#endif
+#ifdef LOG_CONSOLE
+ else if( facility == "console" ) return LOG_CONSOLE;
+#endif
+#ifdef LOG_AUDIT
+ else if( facility == "audit" ) return LOG_AUDIT;
+#endif
+ else if( facility == "local0" ) return LOG_LOCAL0;
+ else if( facility == "local1" ) return LOG_LOCAL1;
+ else if( facility == "local2" ) return LOG_LOCAL2;
+ else if( facility == "local3" ) return LOG_LOCAL3;
+ else if( facility == "local4" ) return LOG_LOCAL4;
+ else if( facility == "local5" ) return LOG_LOCAL5;
+ else if( facility == "local6" ) return LOG_LOCAL6;
+ else if( facility == "local7" ) return LOG_LOCAL7;
+ else return LOG_USER;
+}
+
diff --git a/src/liblogger/WinDbgLogSink.cpp b/src/liblogger/WinDbgLogSink.cpp
new file mode 100755
index 0000000..f5a830c
--- /dev/null
+++ b/src/liblogger/WinDbgLogSink.cpp
@@ -0,0 +1,22 @@
+#include "WinDbgLogSink.hpp"
+
+#include <sstream>
+
+#define WIN32_MEAN_AND_LEAN
+#include <windows.h>
+
+using namespace std;
+
+void WinDbgLogSink::log( const LogLevel level, const string &msg )
+{
+ if( level > reportingLevel( ) ) return;
+
+ ostringstream ss;
+
+ ss << Logger::toString( level )
+ << ": "
+ << msg
+ << "\r\n";
+
+ OutputDebugString( ss.str( ).c_str( ) );
+}
diff --git a/src/liblogger/win32/syslog_win32.c b/src/liblogger/win32/syslog_win32.c
new file mode 100644
index 0000000..e94bb9e
--- /dev/null
+++ b/src/liblogger/win32/syslog_win32.c
@@ -0,0 +1,261 @@
+/************************************************************************
+
+ Copyright (C) 2011, 2012 Project Wolframe.
+ All rights reserved.
+
+ This file is part of Project Wolframe.
+
+ Commercial Usage
+ Licensees holding valid Project Wolframe Commercial licenses may
+ use this file in accordance with the Project Wolframe
+ Commercial License Agreement provided with the Software or,
+ alternatively, in accordance with the terms contained
+ in a written agreement between the licensee and Project Wolframe.
+
+ GNU General Public License Usage
+ Alternatively, you can redistribute this file and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Wolframe is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Wolframe. If not, see <http://www.gnu.org/licenses/>.
+
+ If you have questions regarding the use of this file, please contact
+ Project Wolframe.
+
+************************************************************************/
+
+/*
+ * syslog-client.c - syslog client implementation for windows
+ *
+ * Created by Alexander Yaworsky
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/**
+ * \file syslog_win32.c
+ * \brief implementation of a syslog client on Windows
+ *
+ * It is roughly based on the one of http://syslog-win32.sourceforge.net,
+ * changed in the way it's configured (we can't have a /etc/syslog.conf
+ * on Windows, host and port must be injectable through a function from
+ * the Wolframe configuration), in the way the messages are composed using
+ * newer string functions, using WSock2 funtions like getaddrinfo and
+ * some small other things like added documentation.
+*/
+
+/* TODOS:
+ * - reset logmask in openlog?
+ * - handle more options
+ */
+
+#include "syslog_win32.h"
+
+#include <Winsock2.h>
+#include <ws2tcpip.h>
+#include <string.h>
+#include <stdio.h>
+
+static BOOL initialized = FALSE;
+static BOOL wsa_initialized = FALSE;
+
+static int log_mask = 0xFF;
+static const char *syslog_ident = NULL;
+static int syslog_facility = 0;
+static char str_pid[40];
+static char local_hostname[MAX_COMPUTERNAME_LENGTH+4];
+
+static char syslog_hostname[256] = "localhost";
+static char syslog_service[256] = "514";
+
+/* UDP socket and data to use for sending messages */
+static SOCKADDR_STORAGE sa_logger;
+static SOCKET sock = INVALID_SOCKET;
+#define SYSLOG_DGRAM_SIZE 1024
+static char datagram[SYSLOG_DGRAM_SIZE];
+static int datagram_size = SYSLOG_DGRAM_SIZE;
+
+void openlog( const char* ident, int option, int facility )
+{
+ BOOL failed = TRUE;
+ WSADATA wsd;
+ struct addrinfo hints;
+ struct addrinfo *result = NULL;
+ SOCKADDR_IN sa_local;
+ int size;
+ DWORD n;
+
+ /* allow idempotent calls, first options are taken, use closelog
+ * before openlog if you want to reconfigure the syslog interface
+ */
+ if( initialized ) return;
+
+ /* Initialize Windows Socket DLL */
+ if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) != 0 ) goto DONE;
+ wsa_initialized = TRUE;
+
+ /* tell getaddrinfo what we want */
+ memset( &hints, 0, sizeof( struct addrinfo ) );
+ hints.ai_flags = 0;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+
+ /* resolve the domain name into a list of addresses */
+ if( getaddrinfo( syslog_hostname, syslog_service, &hints, &result ) != 0 ) goto DONE;
+
+ /* Compose the socket address and port of the logging destination */
+ memset( &sa_logger, 0, sizeof( SOCKADDR_IN ) );
+ memcpy( &sa_logger, result->ai_addr, result->ai_addrlen );
+
+ /* Create a UDP socket */
+ sock = socket( result->ai_family, result->ai_socktype, result->ai_protocol );
+ if( sock == INVALID_SOCKET ) goto DONE;
+
+ /* from RFC 3164: The client should connect from a constant port, if possible
+ * also port 514.
+ *
+ * But if we are on the same machine with loopback the port is taken?
+ * Should we try 514 and if it is taken take a fixed different one?
+ */
+
+ /* bind to the socket */
+ memset( &sa_local, 0, sizeof( SOCKADDR_IN ) );
+ sa_local.sin_family = AF_INET;
+ if( bind( sock, (SOCKADDR *)&sa_local, sizeof( SOCKADDR_IN ) ) != 0 ) goto DONE;
+
+ /* determine the maximal size of a datagram packet we can send */
+ size = sizeof( datagram_size );
+ if( getsockopt( sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&datagram_size, &size ) != 0 ) goto DONE;
+ if( datagram_size > sizeof( datagram ) ) datagram_size = sizeof( datagram );
+
+ /* set global facility and ident */
+ syslog_facility = facility ? facility : LOG_USER;
+ syslog_ident = ident;
+
+ /* by RFC 3164 we should put here the name of the local machine */
+ n = sizeof( local_hostname );
+ if( !GetComputerName( local_hostname, &n ) ) goto DONE;
+
+ /* interpret options, currently we use only LOG_PID */
+ if( option & LOG_PID )
+ _snprintf_s( str_pid, sizeof( str_pid ), _TRUNCATE, "[%lu]", GetCurrentProcessId( ) );
+ else
+ str_pid[0] = '\0';
+
+ /* install C cleanup function */
+ if( atexit( closelog ) ) goto DONE;
+
+ /* if we get here, everything's peachy */
+ failed = FALSE;
+
+DONE:
+ if( failed ) {
+ if( sock != INVALID_SOCKET ) {
+ closesocket( sock );
+ sock = INVALID_SOCKET;
+ }
+ if( wsa_initialized ) {
+ wsa_initialized = FALSE;
+ WSACleanup( );
+ }
+ }
+
+ initialized = !failed;
+}
+
+extern int setlogmask( int mask )
+{
+ /* set log mask, return old one */
+ int old_mask = log_mask;
+
+ if( mask ) log_mask = mask;
+
+ return old_mask;
+}
+
+void syslog( int pri, char* fmt, ... )
+{
+ va_list ap;
+ va_start( ap, fmt );
+ vsyslog( pri, fmt, ap );
+ va_end( ap );
+}
+
+void vsyslog( int pri, char* fmt, va_list ap )
+{
+ /* from RFC 3164: Mmm is the English language abbreviation for the month of the
+ * year with the first character in uppercase and the other two
+ * characters in lowercase. The following are the only acceptable
+ * values:
+ *
+ * Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
+ */
+ static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+ int len;
+ SYSTEMTIME t;
+
+ /* do not log if we are not inside the logging mask */
+ if( !( LOG_MASK( LOG_PRI( pri ) ) & log_mask ) ) return;
+
+ /* open default logger, will return immediatelly if already
+ * registered before */
+ openlog( NULL, 0, pri & LOG_FACMASK );
+
+ /* do not log if not initialized after opening a default log */
+ if( !initialized ) return;
+
+ if( !( pri & LOG_FACMASK ) ) pri |= syslog_facility;
+
+ /* from RFC 3164: .. hh:mm:ss is the local time. .. */
+ GetLocalTime( &t );
+
+ /* the PRI and the HEADER with TIMESTAMP and HOSTNAME as
+ * well as the TAG field of the MSG part
+ */
+ len = _snprintf_s( datagram, datagram_size, _TRUNCATE, "<%d>%s %2d %02d:%02d:%02d %s %s%s: ",
+ pri, month[t.wMonth-1], t.wDay, t.wHour, t.wMinute, t.wSecond,
+ local_hostname, syslog_ident ? syslog_ident : "", str_pid );
+
+ /* append now the formatted user message */
+ (void)_vsnprintf_s( datagram + len, datagram_size - len, _TRUNCATE, fmt, ap );
+
+ /* send as datagram, we are not really interested in errors here */
+ (void)sendto( sock, datagram, strlen( datagram ), 0, (SOCKADDR *)&sa_logger, sizeof( SOCKADDR_IN ) );
+}
+
+void closelog( )
+{
+ if( !initialized ) return;
+
+ if( sock != INVALID_SOCKET ) (void)closesocket( sock );
+ if( wsa_initialized ) WSACleanup( );
+
+ sock = INVALID_SOCKET;
+ wsa_initialized = FALSE;
+ initialized = FALSE;
+}
+
+void set_syslogd_destination( const char *hostname, const char *service )
+{
+ strncpy_s( syslog_hostname, 255, hostname, _TRUNCATE );
+ strncpy_s( syslog_service, 255, service, _TRUNCATE );
+}
diff --git a/src/liblogger/win32/syslog_win32.h b/src/liblogger/win32/syslog_win32.h
new file mode 100644
index 0000000..94157a1
--- /dev/null
+++ b/src/liblogger/win32/syslog_win32.h
@@ -0,0 +1,171 @@
+/************************************************************************
+
+ Copyright (C) 2011, 2012 Project Wolframe.
+ All rights reserved.
+
+ This file is part of Project Wolframe.
+
+ Commercial Usage
+ Licensees holding valid Project Wolframe Commercial licenses may
+ use this file in accordance with the Project Wolframe
+ Commercial License Agreement provided with the Software or,
+ alternatively, in accordance with the terms contained
+ in a written agreement between the licensee and Project Wolframe.
+
+ GNU General Public License Usage
+ Alternatively, you can redistribute this file and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Wolframe is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Wolframe. If not, see <http://www.gnu.org/licenses/>.
+
+ If you have questions regarding the use of this file, please contact
+ Project Wolframe.
+
+************************************************************************/
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)syslog.h 8.1 (Berkeley) 6/2/93
+ */
+
+///
+/// \file syslog_win32.h
+/// \brief syslog header file on Windows
+///
+
+#ifndef _SYSLOG_WIN32_HPP_INCLUDED
+#define _SYSLOG_WIN32_HPP_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+
+/*
+ * priorities/facilities are encoded into a single 32-bit quantity, where the
+ * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+ * (0-big number). Both the priorities and the facilities map roughly
+ * one-to-one to strings in the syslogd(8) source code. This mapping is
+ * included in this file.
+ *
+ * priorities (these are ordered)
+ */
+#define LOG_EMERG 0 /* system is unusable */
+#define LOG_ALERT 1 /* action must be taken immediately */
+#define LOG_CRIT 2 /* critical conditions */
+#define LOG_ERR 3 /* error conditions */
+#define LOG_WARNING 4 /* warning conditions */
+#define LOG_NOTICE 5 /* normal but significant condition */
+#define LOG_INFO 6 /* informational */
+#define LOG_DEBUG 7 /* debug-level messages */
+
+#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */
+ /* extract priority */
+#define LOG_PRI(p) ((p) & LOG_PRIMASK)
+#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
+
+/* facility codes */
+#define LOG_KERN (0<<3) /* kernel messages */
+#define LOG_USER (1<<3) /* random user-level messages */
+#define LOG_MAIL (2<<3) /* mail system */
+#define LOG_DAEMON (3<<3) /* system daemons */
+#define LOG_AUTH (4<<3) /* security/authorization messages */
+#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
+#define LOG_LPR (6<<3) /* line printer subsystem */
+#define LOG_NEWS (7<<3) /* network news subsystem */
+#define LOG_UUCP (8<<3) /* UUCP subsystem */
+#define LOG_CRON (9<<3) /* clock daemon */
+#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
+#define LOG_FTP (11<<3) /* ftp daemon */
+
+ /* other codes through 15 reserved for system use */
+#define LOG_LOCAL0 (16<<3) /* reserved for local use */
+#define LOG_LOCAL1 (17<<3) /* reserved for local use */
+#define LOG_LOCAL2 (18<<3) /* reserved for local use */
+#define LOG_LOCAL3 (19<<3) /* reserved for local use */
+#define LOG_LOCAL4 (20<<3) /* reserved for local use */
+#define LOG_LOCAL5 (21<<3) /* reserved for local use */
+#define LOG_LOCAL6 (22<<3) /* reserved for local use */
+#define LOG_LOCAL7 (23<<3) /* reserved for local use */
+
+#define LOG_NFACILITIES 24 /* current number of facilities */
+#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
+ /* facility of pri */
+#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
+
+/*
+ * arguments to setlogmask.
+ */
+#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
+
+/*
+ * Option flags for openlog.
+ */
+#define LOG_PID 0x01 /* log the pid with each message */
+
+/* Close descriptor used to write to system logger.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern void closelog (void);
+
+/* Open connection to system logger.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern void openlog (const char *__ident, int __option, int __facility);
+
+/* Set the log mask level. */
+extern int setlogmask( int __mask );
+
+/* Generate a log message using FMT string and option arguments. */
+extern void syslog (int __pri, char *__fmt, ...);
+
+/* Generate a log message using FMT and using arguments pointed to by AP. */
+void vsyslog( int __pri, char* __fmt, va_list __ap );
+
+/* Wolframe specific function, set the hostname and port for logging through
+ * the configuration programatically */
+extern void set_syslogd_destination( const char *__hostname, const char *__service );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _SYSLOG_WIN32_HPP_INCLUDED