From 2ceb0b0797ec75801fcc59e58f6564af573276bd Mon Sep 17 00:00:00 2001 From: g0dil <g0dil@wiback.org> Date: Wed, 10 Dec 2008 19:34:10 +0000 Subject: [PATCH] Utils/Logger: Implement direct syslog-via-UDP target --- Packets/DefaultBundle/RTPPacket.hh | 7 +- Socket/Protocols/BSDSocketAddress.cc | 2 +- Socket/Protocols/UN/UNSocketProtocol.cc | 2 +- Socket/SocketProtocol.cci | 1 - Utils/Logger/IOStreamTarget.cc | 5 +- Utils/Logger/IOStreamTarget.hh | 1 - Utils/Logger/Levels.hh | 3 + Utils/Logger/SConscript | 4 +- Utils/Logger/SyslogTarget.cc | 6 +- Utils/Logger/SyslogTarget.hh | 4 +- Utils/Logger/SyslogUDPTarget.cc | 102 ++++++++++++++++++ Utils/Logger/SyslogUDPTarget.hh | 133 ++++++++++++++++++++++++ Utils/Logger/SyslogUDPTarget.test.cc | 74 +++++++++++++ 13 files changed, 326 insertions(+), 18 deletions(-) create mode 100644 Utils/Logger/SyslogUDPTarget.cc create mode 100644 Utils/Logger/SyslogUDPTarget.hh create mode 100644 Utils/Logger/SyslogUDPTarget.test.cc diff --git a/Packets/DefaultBundle/RTPPacket.hh b/Packets/DefaultBundle/RTPPacket.hh index 5a2785d0c..62a1f48c2 100644 --- a/Packets/DefaultBundle/RTPPacket.hh +++ b/Packets/DefaultBundle/RTPPacket.hh @@ -29,13 +29,14 @@ #include "../../Packets/Packets.hh" #include "../../Socket/Protocols/INet/INet6Address.hh" #include "../../Socket/Protocols/INet.hh" +#include "../../Utils/Logger/SenfLog.hh" namespace senf { struct RTPPacketParser : public senf::PacketParserBase { - SENF_LOG_CLASS_AREA(); - # include SENF_PARSER() + SENF_LOG_CLASS_AREA(); +# include SENF_PARSER() SENF_PARSER_BITFIELD ( version, 2, unsigned ); //Version (RFC 3550) SENF_PARSER_BITFIELD ( padding, 1, bool ); //1 if padding behind payload SENF_PARSER_BITFIELD ( extension, 1, bool ); @@ -55,7 +56,7 @@ namespace senf { : public senf::PacketTypeBase, public senf::PacketTypeMixin<RTPPacketType> { - SENF_LOG_CLASS_AREA(); + SENF_LOG_CLASS_AREA(); typedef senf::PacketTypeMixin<RTPPacketType> mixin; typedef senf::ConcretePacket<RTPPacketType> packet; typedef RTPPacketParser parser; diff --git a/Socket/Protocols/BSDSocketAddress.cc b/Socket/Protocols/BSDSocketAddress.cc index b3a3635c6..1f3e9b319 100644 --- a/Socket/Protocols/BSDSocketAddress.cc +++ b/Socket/Protocols/BSDSocketAddress.cc @@ -23,7 +23,7 @@ /** \file \brief BSDSocketAddress non-inline non-template implementation */ -//#include "BSDSocketAddress.hh" +#include "BSDSocketAddress.hh" //#include "BSDSocketAddress.ih" // Custom includes diff --git a/Socket/Protocols/UN/UNSocketProtocol.cc b/Socket/Protocols/UN/UNSocketProtocol.cc index c9db37763..85266bdcd 100644 --- a/Socket/Protocols/UN/UNSocketProtocol.cc +++ b/Socket/Protocols/UN/UNSocketProtocol.cc @@ -31,7 +31,7 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <linux/sockios.h> // for SIOCINQ / SIOCOUTQ -#include <senf/Utils/Logger.hh> +#include "../../../Utils/Logger/SenfLog.hh" #include "../../../Utils/Exception.hh" //#include "UNSocketProtocol.mpp" diff --git a/Socket/SocketProtocol.cci b/Socket/SocketProtocol.cci index 47f7a685c..372ef3ecc 100644 --- a/Socket/SocketProtocol.cci +++ b/Socket/SocketProtocol.cci @@ -28,7 +28,6 @@ // Custom includes #include "../Utils/senfassert.hh" -#include "../Utils/Logger/SenfLog.hh" #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// diff --git a/Utils/Logger/IOStreamTarget.cc b/Utils/Logger/IOStreamTarget.cc index ca2695805..25880596d 100644 --- a/Utils/Logger/IOStreamTarget.cc +++ b/Utils/Logger/IOStreamTarget.cc @@ -39,9 +39,6 @@ /////////////////////////////////////////////////////////////////////////// // senf::log::IOStreamTarget -char const * const senf::log::IOStreamTarget::LEVELNAMES_[8] = { - "NONE", "VERBOSE", "NOTICE", "MESSAGE", "IMPORTANT", "CRITICAL", "FATAL", "DISABLED" }; - prefix_ senf::log::IOStreamTarget::IOStreamTarget(std::ostream & os) : stream_ (os), noformat_ (false), showTime_ (true), showStream_ (false), showLevel_ (true), showArea_ (true) @@ -94,7 +91,7 @@ prefix_ void senf::log::IOStreamTarget::v_write(time_type timestamp, if (showStream_) datestream_ << '[' << stream << "] "; if (showLevel_) - datestream_ << '[' << LEVELNAMES_[level] << "] "; + datestream_ << '[' << LEVELNAMES[level] << "] "; if (showArea_ && area != "senf::log::DefaultArea") datestream_ << '[' << area << "] "; diff --git a/Utils/Logger/IOStreamTarget.hh b/Utils/Logger/IOStreamTarget.hh index 11935beae..aee7e3f3c 100644 --- a/Utils/Logger/IOStreamTarget.hh +++ b/Utils/Logger/IOStreamTarget.hh @@ -95,7 +95,6 @@ namespace log { bool showLevel_; bool showArea_; - static char const * const LEVELNAMES_[8]; }; }} diff --git a/Utils/Logger/Levels.hh b/Utils/Logger/Levels.hh index e53af866a..e390f4464 100644 --- a/Utils/Logger/Levels.hh +++ b/Utils/Logger/Levels.hh @@ -108,6 +108,9 @@ namespace log { struct NONE : public detail::LevelBase { static unsigned const value = 0; }; ///\} + + static char const * const LEVELNAMES[8] = { + "NONE", "VERBOSE", "NOTICE", "MESSAGE", "IMPORTANT", "CRITICAL", "FATAL", "DISABLED" }; }} diff --git a/Utils/Logger/SConscript b/Utils/Logger/SConscript index 6b3c30fd9..672c29beb 100644 --- a/Utils/Logger/SConscript +++ b/Utils/Logger/SConscript @@ -11,9 +11,7 @@ SENFSCons.AllIncludesHH(env, [ f for f in glob.glob("*.hh") if ( f not in ('all_includes.hh','Logger.hh','SenfLog.hh') and not f.endswith('.test.hh') ) ]) sources = SENFSCons.GlobSources() -objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Utils' ] ) - -SENFSCons.InstallIncludeFiles(env, [ 'SenfLog.hh' ]) +objects = SENFSCons.Objects( env, sources = sources, LIBS = [ 'Utils', 'Socket' ] ) SENFSCons.Doxygen(env) diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 61212adca..6b175c65f 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -32,7 +32,7 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -int const senf::log::SyslogTarget::LEVELMAP_[8] = { +int const senf::log::SyslogTarget::LEVELMAP[8] = { 0, LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_CRIT, LOG_EMERG, 0 }; prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string const & stream, @@ -40,9 +40,9 @@ prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string c std::string const & message) { if (area != "senf::log::DefaultArea") - syslog(facility_ | LEVELMAP_[level], "[%s] %s", area.c_str(), message.c_str()); + syslog(facility_ | LEVELMAP[level], "[%s] %s", area.c_str(), message.c_str()); else - syslog(facility_ | LEVELMAP_[level], "%s", message.c_str()); + syslog(facility_ | LEVELMAP[level], "%s", message.c_str()); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index 786b58cf1..d11e448a8 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -89,7 +89,9 @@ namespace log { std::string const & message); int facility_; - static int const LEVELMAP_[8]; + + public: + static int const LEVELMAP[8]; }; }} diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc new file mode 100644 index 000000000..331485b70 --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -0,0 +1,102 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget non-inline non-template implementation */ + +#include "SyslogUDPTarget.hh" +//#include "SyslogUDPTarget.ih" + +// Custom includes +#include <sstream> +#include "../../Socket/Protocols/INet/ConnectedUDPSocketHandle.hh" +#include <boost/algorithm/string/trim.hpp> +#include <boost/tokenizer.hpp> + +//#include "SyslogUDPTarget.mpp" +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4Address const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv4ClientSocketHandle(senf::INet4SocketAddress(target, 514u)) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet4SocketAddress const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv4ClientSocketHandle(target) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6Address const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv6ClientSocketHandle(senf::INet6SocketAddress(target, 514u)) ) +{} + +prefix_ senf::log::SyslogUDPTarget::SyslogUDPTarget(senf::INet6SocketAddress const & target, + int facility) + : facility_ (facility), + handle_ ( senf::ConnectedUDPv6ClientSocketHandle(target) ) +{} + +prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::string const & stream, + std::string const & area, unsigned level, + std::string const & message) +{ + std::stringstream prefix; + prefix << '<' << (facility_ | senf::log::SyslogTarget::LEVELMAP[level]) << "> "; + if (area != "senf::log::DefaultArea") + prefix << '[' << area << "] "; + std::string m (boost::trim_right_copy(message)); + + typedef boost::char_separator<char> Separator; + typedef boost::tokenizer<Separator> Tokenizer; + Separator separator ("\n"); + Tokenizer tokenizer (m, separator); + Tokenizer::iterator i (tokenizer.begin()); + Tokenizer::iterator const i_end (tokenizer.end()); + + std::stringstream line; + for (; i != i_end; ++i) + for (unsigned j (0); j < i->size(); j += 896) { + line << prefix.str() << std::string(*i, j, 896); + handle_.write(line.str()); + line.str(""); + } +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ +//#include "SyslogUDPTarget.mpp" + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh new file mode 100644 index 000000000..a025c3ebb --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -0,0 +1,133 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget public header */ + +#ifndef HH_SENF_Utils_Logger_SyslogUDPTarget_ +#define HH_SENF_Utils_Logger_SyslogUDPTarget_ 1 + +// Custom includes +#include "SyslogTarget.hh" +#include "../../Socket/Protocols/INet/INetAddressing.hh" +#include "../../Socket/ClientSocketHandle.hh" +#include "../../Socket/FramingPolicy.hh" +#include "../../Socket/ReadWritePolicy.hh" +#include "../../Socket/CommunicationPolicy.hh" + +//#include "SyslogUDPTarget.mpp" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace log { + + /** \brief Log target writing UDP syslog packets + + The SyslogUDPTarget will send all log messages directly via UDP to a target host. This host + should have a syslog daemon or relay running. The protocol is defined in <a + href="ttp://tools.ietf.org/html/rfc3164">RFC-3164</a>. + + This log target has some important benefits: + + \li It will never block. It may however lose log messages. + \li It does \e not add timestamp information locally. + + These are \e advantages since this makes SyslogUDPTarget a very reliable high-performance + logging target. + + Valid facility values are from <tt>man 3 syslog</tt>: + + \par "" + <tt>LOG_AUTHPRIV</tt>, <tt>LOG_CRON</tt>, <tt>LOG_DAEMON</tt>, <tt>LOG_FTP</tt>, + <tt>LOG_KERN</tt>, <tt>LOG_LOCAL0</tt>, <tt>LOG_LOCAL1</tt>, <tt>LOG_LOCAL2</tt>, + <tt>LOG_LOCAL3</tt>, <tt>LOG_LOCAL4</tt>, <tt>LOG_LOCAL5</tt>, <tt>LOG_LOCAL6</tt>, + <tt>LOG_LOCAL7</tt>, <tt>LOG_LPR</tt>, <tt>LOG_MAIL</tt>, <tt>LOG_NEWS</tt>, + <tt>LOG_SYSLOG</tt>, <tt>LOG_USER</tt>, <tt>LOG_UUCP</tt> + + the default facility is <tt>LOG_USER</tt> + + The SENF log levels are mapped to syslog levels in the following way: + + <table class="senf fixedcolumn"> + <tr><td>senf::log::VERBOSE</td> <td>\c LOG_DEBUG</td></tr> + <tr><td>senf::log::NOTICE</td> <td>\c LOG_INFO</td></tr> + <tr><td>senf::log::MESSAGE</td> <td>\c LOG_NOTICE</td></tr> + <tr><td>senf::log::IMPORTANT</td> <td>\c LOG_WARNING</td></tr> + <tr><td>senf::log::CRITICAL</td> <td>\c LOG_CRIT</td></tr> + <tr><td>senf::log::FATAL</td> <td>\c LOG_EMERG</td></tr> + </table> + + \note Since the UDP syslog packets are limited to 1024 characters and there must be some + space left so a relay may optionally add a timestamp and hostname section, the log + messages are split after 896 characters. Additionally the log messages are split at each + newline char since non-printable characters are not allowed. + */ + class SyslogUDPTarget + : public Target + { + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + /////////////////////////////////////////////////////////////////////////// + ///\name Structors and default members + ///@{ + + explicit SyslogUDPTarget(senf::INet4Address const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet4SocketAddress const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet6Address const & target, int facility = LOG_USER); + explicit SyslogUDPTarget(senf::INet6SocketAddress const & target, int facility = LOG_USER); + + ///@} + /////////////////////////////////////////////////////////////////////////// + + private: + void v_write(time_type timestamp, std::string const & stream, + std::string const & area, unsigned level, + std::string const & message); + + int facility_; + typedef senf::ClientSocketHandle< senf::MakeSocketPolicy< + senf::DatagramFramingPolicy, + senf::ConnectedCommunicationPolicy, + senf::WriteablePolicy>::policy > Handle; + Handle handle_; + }; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "SyslogUDPTarget.cci" +//#include "SyslogUDPTarget.ct" +//#include "SyslogUDPTarget.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Logger/SyslogUDPTarget.test.cc b/Utils/Logger/SyslogUDPTarget.test.cc new file mode 100644 index 000000000..0968f0843 --- /dev/null +++ b/Utils/Logger/SyslogUDPTarget.test.cc @@ -0,0 +1,74 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund <g0dil@berlios.de> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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 this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/** \file + \brief SyslogUDPTarget.test unit tests */ + +//#include "SyslogUDPTarget.test.hh" +//#include "SyslogUDPTarget.test.ih" + +// Custom includes +#include "SyslogUDPTarget.hh" +#include "../../Socket/Protocols/INet/UDPSocketHandle.hh" +#include "Logger.hh" + +#include "../../Utils/auto_unit_test.hh" +#include <boost/test/test_tools.hpp> + +#define prefix_ +///////////////////////////////cc.p//////////////////////////////////////// + +BOOST_AUTO_UNIT_TEST(syslogUDPTarget) +{ + senf::log::SyslogUDPTarget udplog ( + senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u)); + senf::UDPv4ClientSocketHandle server ( + senf::INet4SocketAddress(senf::INet4Address::Loopback, 23444u)); + + udplog.route(); + + SENF_LOG(("Test message")); + BOOST_CHECK_EQUAL( server.read(), "<13> Test message" ); + + SENF_LOG(("Test message\nLine 2")); + BOOST_CHECK_EQUAL( server.read(), "<13> Test message" ); + BOOST_CHECK_EQUAL( server.read(), "<13> Line 2" ); + + SENF_LOG(("Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); + + BOOST_CHECK_EQUAL( server.read(), "<13> Very long message: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); + BOOST_CHECK_EQUAL( server.read(), "<13> xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: -- GitLab