From: g0dil Date: Sat, 7 Feb 2009 19:00:49 +0000 (+0000) Subject: Socket/Protocols/INet: Implement address input streaming X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=6cfb0a8ca46d3cb0cc521a75118027ecc3fa4ef1;p=senf.git Socket/Protocols/INet: Implement address input streaming Utils/Logger: Implement dynmaic targets git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1106 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/Protocols/INet/INet4Address.cc b/Socket/Protocols/INet/INet4Address.cc index 0c100fb..d83c034 100644 --- a/Socket/Protocols/INet/INet4Address.cc +++ b/Socket/Protocols/INet/INet4Address.cc @@ -161,6 +161,20 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & return os; } +prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet4Address::from_string(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "INet4Address.mpp" diff --git a/Socket/Protocols/INet/INet4Address.hh b/Socket/Protocols/INet/INet4Address.hh index e11982d..e69c224 100644 --- a/Socket/Protocols/INet/INet4Address.hh +++ b/Socket/Protocols/INet/INet4Address.hh @@ -175,6 +175,7 @@ namespace senf { \related INet4Address */ std::ostream & operator<<(std::ostream & os, INet4Address const & addr); + std::istream & operator>>(std::istream & os, INet4Address & addr); /** \brief CHeck INet4Address against a fixed network prefix diff --git a/Socket/Protocols/INet/INet6Address.cc b/Socket/Protocols/INet/INet6Address.cc index 6c76f77..9aa5238 100644 --- a/Socket/Protocols/INet/INet6Address.cc +++ b/Socket/Protocols/INet/INet6Address.cc @@ -105,6 +105,19 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & return os; } +prefix_ std::istream & senf::operator>>(std::istream & is, INet6Address & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet6Address::from_string(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} senf::INet6Address const senf::INet6Address::None; senf::INet6Address const senf::INet6Address::Loopback (0u,0u,0u,0u,0u,0u,0u,1u); diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh index 98fb726..600ed57 100644 --- a/Socket/Protocols/INet/INet6Address.hh +++ b/Socket/Protocols/INet/INet6Address.hh @@ -283,6 +283,7 @@ namespace senf { \related INet6Address */ std::ostream & operator<<(std::ostream & os, INet6Address const & addr); + std::istream & operator>>(std::istream & is, INet6Address & addr); /** \brief Check INet6Address against a fixed network prefix diff --git a/Socket/Protocols/INet/INetAddressing.cc b/Socket/Protocols/INet/INetAddressing.cc index fdb4ee1..e224408 100644 --- a/Socket/Protocols/INet/INetAddressing.cc +++ b/Socket/Protocols/INet/INetAddressing.cc @@ -71,6 +71,26 @@ prefix_ senf::INet4SocketAddress::INet4SocketAddress(unsigned p) port(p); } +prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr) +{ + os << addr.address() << ":" << addr.port(); + return os; +} + +prefix_ std::istream & senf::operator>>(std::istream & is, INet4SocketAddress & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet4SocketAddress(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + /////////////////////////////////////////////////////////////////////////// // senf::INet6SocketAddress @@ -131,6 +151,30 @@ prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface) } } +prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr) +{ + os << '[' << addr.address(); + std::string iface (addr.iface()); + if (! iface.empty()) + os << '%' << iface; + os << "]:" << addr.port(); + return os; +} + +prefix_ std::istream & senf::operator>>(std::istream & is, INet6SocketAddress & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet6SocketAddress(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "INetAddressing.mpp" diff --git a/Socket/Protocols/INet/INetAddressing.cci b/Socket/Protocols/INet/INetAddressing.cci index dc6bd0c..5561938 100644 --- a/Socket/Protocols/INet/INetAddressing.cci +++ b/Socket/Protocols/INet/INetAddressing.cci @@ -70,12 +70,6 @@ prefix_ void senf::INet4SocketAddress::port(unsigned p) addr_.sin_port = htons(p); } -prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr) -{ - os << addr.address() << ":" << addr.port(); - return os; -} - /////////////////////////////////////////////////////////////////////////// // senf::INet6SocketAddress @@ -143,16 +137,6 @@ prefix_ void senf::INet6SocketAddress::iface(std::string const & iface) assignIface(iface); } -prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr) -{ - os << '[' << addr.address(); - std::string iface (addr.iface()); - if (! iface.empty()) - os << '%' << iface; - os << "]:" << addr.port(); - return os; -} - ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/Protocols/INet/INetAddressing.hh b/Socket/Protocols/INet/INetAddressing.hh index f9327b5..a54b95e 100644 --- a/Socket/Protocols/INet/INetAddressing.hh +++ b/Socket/Protocols/INet/INetAddressing.hh @@ -109,6 +109,7 @@ namespace senf { \related INet4SocketAddress */ std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr); + std::istream & operator>>(std::istream & is, INet4SocketAddress & addr); /** \brief IPv6 socket address @@ -202,6 +203,7 @@ namespace senf { \related INet6SocketAddress */ std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr); + std::istream & operator>>(std::istream & is, INet6SocketAddress & addr); /// \addtogroup policy_impl_group /// @{ diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index 04cb751..a228c33 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -67,6 +67,7 @@ prefix_ std::string senf::console::Executor::cwdPath() { if (skipping()) return ""; + (void) cwd(); // ensure, cwd is live. return "/" + senf::stringJoin( senf::make_transform_range( boost::make_iterator_range(boost::next(cwd_.begin()), cwd_.end()), diff --git a/Utils/Logger/FileTarget.cc b/Utils/Logger/FileTarget.cc index 2baff33..7cc2ad0 100644 --- a/Utils/Logger/FileTarget.cc +++ b/Utils/Logger/FileTarget.cc @@ -27,15 +27,26 @@ //#include "FileTarget.ih" // Custom includes +#include "../Console/Console.hh" //#include "FileTarget.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ senf::log::FileTarget::FileTarget(std::string file) +prefix_ senf::log::FileTarget::FileTarget(std::string const & file) : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member), file_(file) -{} +{ + consoleDir().add( "reopen", senf::membind( + static_cast(&FileTarget::reopen), + this)) + .doc("Reopen logfile"); + consoleDir().add("reopen", senf::membind( + static_cast(&FileTarget::reopen), + this)) + .arg("filename","new filename") + .overloadDoc("Reopen logfile under new name"); +} prefix_ void senf::log::FileTarget::reopen() { @@ -43,10 +54,27 @@ prefix_ void senf::log::FileTarget::reopen() ofstream_t::member.open(file_.c_str(), std::ofstream::app); } -prefix_ void senf::log::FileTarget::reopen(std::string file) +prefix_ void senf::log::FileTarget::reopen(std::string const & file) { file_ = file; reopen(); + // Rename console directory + console::DirectoryNode::ptr parent (consoleDir().node().parent()); + if (parent) + parent->add(file, consoleDir().node().unlink()); +} + +prefix_ senf::log::FileTarget::RegisterConsole::RegisterConsole() +{ + detail::TargetRegistry::instance().consoleDir().add("file-target",&RegisterConsole::create) + .arg("filename", "name of logfile") + .doc("Create new file target."); +} + +prefix_ void senf::log::FileTarget::RegisterConsole::create(std::string const & filename) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new FileTarget(filename))); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/FileTarget.hh b/Utils/Logger/FileTarget.hh index 5c4cc34..ccd78fc 100644 --- a/Utils/Logger/FileTarget.hh +++ b/Utils/Logger/FileTarget.hh @@ -65,16 +65,23 @@ namespace log { ///\name Structors and default members ///@{ - explicit FileTarget(std::string file); ///< Construct FileTarget writing to \a file + explicit FileTarget(std::string const & filename); + ///< Construct FileTarget writing to \a file ///@} /////////////////////////////////////////////////////////////////////////// void reopen(); ///< Reopen %log after log-file rotation - void reopen(std::string file); ///< Reopen %log under a new name + void reopen(std::string const & file); ///< Reopen %log under a new name private: std::string file_; + + struct RegisterConsole { + RegisterConsole(); + static void create(std::string const & filename); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 6b175c6..7c85321 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -27,6 +27,7 @@ //#include "SyslogTarget.ih" // Custom includes +#include "../Console/Console.hh" //#include "SyslogTarget.mpp" #define prefix_ @@ -45,6 +46,34 @@ prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string c syslog(facility_ | LEVELMAP[level], "%s", message.c_str()); } +namespace senf { +namespace log { + + SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogTarget, LogFacility, + (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG) + (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5) + (LOCAL6)(LOCAL7)); + +}} + +prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole() +{ + namespace kw = senf::console::kw; + + detail::TargetRegistry::instance().consoleDir().add("syslog-target",&RegisterConsole::create) + .arg("facility", "syslog facility to send messages to. One of\n" + " AUTHPRIV, CRON, DAEMON, FTP, KERN, LPR, MAIL, NEWS, SYSLOG, USER,\n" + " UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7", + kw::default_value = USER) + .doc("Create new syslog target."); +} + +prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new SyslogTarget(facility))); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "SyslogTarget.mpp" diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index d11e448..0049f59 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -92,6 +92,35 @@ namespace log { public: static int const LEVELMAP[8]; + + enum LogFacility { + AUTHPRIV = LOG_AUTHPRIV, + CRON = LOG_CRON, + DAEMON = LOG_DAEMON, + FTP = LOG_FTP, + KERN = LOG_KERN, + LOCAL0 = LOG_LOCAL0, + LOCAL1 = LOG_LOCAL1, + LOCAL2 = LOG_LOCAL2, + LOCAL3 = LOG_LOCAL3, + LOCAL4 = LOG_LOCAL4, + LOCAL5 = LOG_LOCAL5, + LOCAL6 = LOG_LOCAL6, + LOCAL7 = LOG_LOCAL7, + LPR = LOG_LPR, + MAIL = LOG_MAIL, + NEWS = LOG_NEWS, + SYSLOG = LOG_SYSLOG, + USER = LOG_USER, + UUCP = LOG_UUCP + }; + + private: + struct RegisterConsole { + RegisterConsole(); + static void create(LogFacility facility); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc index 03a055f..af8da40 100644 --- a/Utils/Logger/SyslogUDPTarget.cc +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -30,6 +30,7 @@ #include #include #include +#include "../Console/Console.hh" //#include "SyslogUDPTarget.mpp" #define prefix_ @@ -68,6 +69,79 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin } } +namespace senf { +namespace log { + + SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogUDPTarget, LogFacility, + (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG) + (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5) + (LOCAL6)(LOCAL7)); + +}} + +prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole() +{ + namespace kw = senf::console::kw; + + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast( + &RegisterConsole::create)) + .arg("address", "target address to send log messages to") + .arg("facility", "syslog facility to send messages to. One of\n" + " AUTHPRIV, CRON, DAEMON, FTP, KERN, LPR, MAIL, NEWS, SYSLOG, USER,\n" + " UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7", + kw::default_value = USER) + .doc("Create new udp target. The {address} can be an IPv4 or IPv6 address. If the port\n" + "number is omitted, it defaults to the default syslog port 514."); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr(new SyslogUDPTarget(target, facility))); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "SyslogUDPTarget.mpp" diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh index c3d8b15..e6f35ff 100644 --- a/Utils/Logger/SyslogUDPTarget.hh +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -86,6 +86,8 @@ namespace log { include the \c PRI part but skip the \c HEADER part (which includes the timestamp and hostname) for better performance. We add a space after the \c PRI to force the syslog daemon to skip the \c HEADER part. + + \ingroup targets */ class SyslogUDPTarget : public Target, private detail::LogFormat @@ -124,6 +126,44 @@ namespace log { senf::ConnectedCommunicationPolicy, senf::WriteablePolicy>::policy > Handle; Handle handle_; + + public: + enum LogFacility { + AUTHPRIV = LOG_AUTHPRIV, + CRON = LOG_CRON, + DAEMON = LOG_DAEMON, + FTP = LOG_FTP, + KERN = LOG_KERN, + LOCAL0 = LOG_LOCAL0, + LOCAL1 = LOG_LOCAL1, + LOCAL2 = LOG_LOCAL2, + LOCAL3 = LOG_LOCAL3, + LOCAL4 = LOG_LOCAL4, + LOCAL5 = LOG_LOCAL5, + LOCAL6 = LOG_LOCAL6, + LOCAL7 = LOG_LOCAL7, + LPR = LOG_LPR, + MAIL = LOG_MAIL, + NEWS = LOG_NEWS, + SYSLOG = LOG_SYSLOG, + USER = LOG_USER, + UUCP = LOG_UUCP + }; + + private: + + struct RegisterConsole { + RegisterConsole(); + static void create(senf::INet4SocketAddress const & target, + LogFacility facility = USER); + static void create(senf::INet4Address const & target, + LogFacility facility = USER); + static void create(senf::INet6SocketAddress const & target, + LogFacility facility = USER); + static void create(senf::INet6Address const & target, + LogFacility facility = USER); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index a35fca6..7218a24 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -241,12 +241,21 @@ prefix_ senf::log::detail::TargetRegistry::TargetRegistry() kw::default_value = "senf::log::Debug") .arg("area","area to write message to", kw::default_value = "senf::log::DefaultArea") - .arg("level", "log level", + .arg("level", "log level, one of:\n" + " VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL, FATAL", kw::default_value = MESSAGE) .arg("message", "message to write") .doc("Write log message"); } +prefix_ senf::log::detail::TargetRegistry::~TargetRegistry() +{ + Targets::iterator i (dynamicTargets_.begin()); + Targets::iterator const i_end (dynamicTargets_.end()); + for (; i != i_end; ++i) + delete *i; +} + prefix_ void senf::log::detail::TargetRegistry::consoleAreas(std::ostream & os) { AreaRegistry::iterator i (AreaRegistry::instance().begin()); @@ -404,6 +413,15 @@ prefix_ void senf::log::Target::consoleList(std::ostream & os) /////////////////////////////////////////////////////////////////////////// // senf::log::detail::TargetRegistry +prefix_ void senf::log::detail::TargetRegistry::dynamicTarget(std::auto_ptr target) +{ + target->consoleDir().add("remove", boost::function( + boost::bind( + &TargetRegistry::consoleRemoveTarget, this, target.get()))) + .doc("Remove target."); + dynamicTargets_.insert(target.release()); +} + prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target, std::string const & name) { @@ -423,6 +441,13 @@ prefix_ void senf::log::detail::TargetRegistry::write(StreamBase const & stream, else area.write( TimeSource::now(), stream, level, msg ); } + +prefix_ void senf::log::detail::TargetRegistry::consoleRemoveTarget(Target * target) +{ + dynamicTargets_.erase(target); + delete target; +} + /////////////////////////////////////////////////////////////////////////// // namespace members @@ -434,6 +459,13 @@ prefix_ std::ostream & senf::log::operator<<(std::ostream & os, senf::log::Targe return os; } +////////////////////////////////////////////////////////////////////////// +// I need to put this here, otherwise the file target will not be registered +// if it is not used ... :-( + +senf::log::FileTarget::RegisterConsole senf::log::FileTarget::RegisterConsole::instance; +senf::log::SyslogTarget::RegisterConsole senf::log::SyslogTarget::RegisterConsole::instance; +senf::log::SyslogUDPTarget::RegisterConsole senf::log::SyslogUDPTarget::RegisterConsole::instance; ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Utils/Logger/Target.cci b/Utils/Logger/Target.cci index 09c5706..7e02f91 100644 --- a/Utils/Logger/Target.cci +++ b/Utils/Logger/Target.cci @@ -134,6 +134,11 @@ prefix_ bool senf::log::detail::TargetRegistry::fallbackRouting() return fallbackRouting_; } +prefix_ senf::console::ScopedDirectory<> & senf::log::detail::TargetRegistry::consoleDir() +{ + return consoleDir_(); +} + //////////////////////////////////////// // private members diff --git a/Utils/Logger/Target.ih b/Utils/Logger/Target.ih index bc48061..f926f87 100644 --- a/Utils/Logger/Target.ih +++ b/Utils/Logger/Target.ih @@ -60,8 +60,13 @@ namespace detail { void routed(); bool fallbackRouting(); + senf::console::ScopedDirectory<> & consoleDir(); + + void dynamicTarget(std::auto_ptr target); + private: TargetRegistry(); + ~TargetRegistry(); void registerTarget(Target * target, std::string const & name); void unregisterTarget(Target * target); @@ -70,6 +75,7 @@ namespace detail { void consoleStreams(std::ostream & os); void consoleWrite(std::string const & stream, std::string const & area, Level level, std::string const & msg); + void consoleRemoveTarget(Target * target); typedef std::set Targets; Targets targets_; @@ -77,6 +83,8 @@ namespace detail { bool fallbackRouting_; console::LazyDirectory consoleDir_; + + Targets dynamicTargets_; friend class senf::log::Target; friend class senf::singleton; diff --git a/Utils/Termlib/Editor.cc b/Utils/Termlib/Editor.cc index f3a0c19..8f434a6 100644 --- a/Utils/Termlib/Editor.cc +++ b/Utils/Termlib/Editor.cc @@ -433,7 +433,6 @@ prefix_ void senf::term::LineEditor::insert(std::string const & text) prefix_ void senf::term::LineEditor::pushHistory(std::string const & text) { if (! text.empty() - && (historyPoint_ == history_.size() || history_[historyPoint_] != text) && (history_.empty() || history_.back() != text)) { history_.push_back(text); while (history_.size() > MAX_HISTORY_SIZE)