diff --git a/Utils/Console/Executor.hh b/Utils/Console/Executor.hh index 540472d02ba5d3221313558f6c4e5daf2875c989..6a950f0b2dacacbec58c8728460d645d0aca6164 100644 --- a/Utils/Console/Executor.hh +++ b/Utils/Console/Executor.hh @@ -108,16 +108,17 @@ namespace console { /**< if autocomplete is enabled, path components which can be uniquely completed will be completed automatically. Disabled by default (but enabled - automatically by the interactive console) void - autocomplete(bool v). */ + automatically by the interactive console). */ Executor & autocomplete(bool v); ///< Set autocomplete status /**< \see autocomplete() */ + DirectoryNode & chroot() const; ///< Get root node /**< The root node defaults to senf::console::root(). If changed, all path references are relative to this node and objects outside that tree cannot be accessed. */ + Executor & chroot(DirectoryNode & node); ///< chroot into given directory /**< After this call, all path's are interpreted relative to \a node and only nodes in the tree rooted at \a node diff --git a/Utils/Console/Parse.cc b/Utils/Console/Parse.cc index dece5df2982ed8052ec857f38b453f357cc26000..65dcaf3058598e9484fd6bff80169779b382b5dd 100644 --- a/Utils/Console/Parse.cc +++ b/Utils/Console/Parse.cc @@ -393,7 +393,35 @@ senf::console::CommandParser::parseIncremental(std::string const & commands, Cal parseLoop(commands.begin(), commands.end(), "<unknown>", cb) ); } -///////////////////////////////cc.e//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// Character sets + +prefix_ bool senf::console::CommandParser::isSpecialChar(char ch) +{ + return Impl::Grammar::special_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isPunctuationChar(char ch) +{ + return Impl::Grammar::punctuation_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isSpaceChar(char ch) +{ + return Impl::Grammar::space_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isInvalidChar(char ch) +{ + return Impl::Grammar::invalid_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isWordChar(char ch) +{ + return Impl::Grammar::word_p.test(ch); +} + +/////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Parse.mpp" diff --git a/Utils/Console/Parse.hh b/Utils/Console/Parse.hh index 5e8b0ac84d0c09154254dd841bae52cb503f36a2..7afbaa1d2cb1b601066ba32defbf5da0edf848e4 100644 --- a/Utils/Console/Parse.hh +++ b/Utils/Console/Parse.hh @@ -615,6 +615,12 @@ namespace console { to be terminated explicitly. This means, that the last ';' is \e not optional in this case. */ + static bool isSpecialChar(char ch); ///< Check, if \a ch is a special character + static bool isPunctuationChar(char ch); ///< Check, if \a ch is a punctuation character + static bool isSpaceChar(char ch); ///< Check, if \a ch is a space character + static bool isInvalidChar(char ch); ///< Check, if \a ch is an invalid character + static bool isWordChar(char ch); ///< Check, if \a ch is a word character + /** \brief Exception thrown when the parser detects an error */ struct ParserErrorException : public SyntaxErrorException { explicit ParserErrorException(std::string const & msg) : SyntaxErrorException(msg) {} }; diff --git a/Utils/Console/Parse.ih b/Utils/Console/Parse.ih index 38b9fc924edc073385e53fbff55e2514b2e4eb44..4f0569f59ec01dfc453ea39e97eae3e0b8cec0ce 100644 --- a/Utils/Console/Parse.ih +++ b/Utils/Console/Parse.ih @@ -78,6 +78,16 @@ namespace detail { ParseDispatcher & dispatcher; + ////////////////////////////////////////////////////////////////////////// + // charachter sets + + static boost::spirit::chset<> special_p; + static boost::spirit::chset<> punctuation_p; + static boost::spirit::chset<> space_p; + static boost::spirit::chset<> invalid_p; + static boost::spirit::chset<> word_p; + static boost::spirit::distinct_parser<> keyword_p; + /////////////////////////////////////////////////////////////////////////// // Errors @@ -104,33 +114,8 @@ namespace detail { punctuation, hexbyte, balanced_tokens, simple_argument, complex_argument, builtin, skip, statement, relpath, abspath, arguments, group_start, group_close, statement_end, opt_path; - boost::spirit::chset<> special_p, punctuation_p, space_p, invalid_p, word_p; - boost::spirit::distinct_parser<> keyword_p; - - definition(CommandGrammar const & self) : - - // Characters with a special meaning within the parser - special_p ("/(){};\""), - - // Additional characters which are returned as punctuation tokens - // (only allowed within '()'). - punctuation_p (",="), - - // Whitespace characters - space_p (" \t\n\r"), - - // Invalid characters: All chars below \x20 (space) which are not space_p - // (don't put a \0 in the chset<> argument *string* ...) - invalid_p ( (boost::spirit::chset<>('\0') - | boost::spirit::chset<>("\x01-\x20")) - space_p ), - - // Valid word characters - word_p ( - boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p), - - // Keywords must not be followed by a word char or '/' - keyword_p ( word_p | boost::spirit::ch_p('/') ) + definition(CommandGrammar const & self) { using namespace boost::spirit; using namespace ::phoenix; @@ -203,14 +188,14 @@ namespace detail { ; builtin - = keyword_p("cd") + = self.keyword_p("cd") >> path_expected(path) >> eps_p [ bind(&PD::builtin_cd)(d_, path_) ] - | keyword_p("ls") + | self.keyword_p("ls") >> ! path >> eps_p [ bind(&PD::builtin_ls)(d_, path_) ] - | keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] - | keyword_p("help") + | self.keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] + | self.keyword_p("help") >> ! path >> eps_p [ bind(&PD::builtin_help)(d_, path_) ] ; @@ -316,7 +301,7 @@ namespace detail { | ch_p(';') [ token_ = construct_<Token>( Token::CommandTerminator, ";") ] - | punctuation_p [ token_ = construct_<Token>( + | self.punctuation_p [ token_ = construct_<Token>( Token::OtherPunctuation, construct_<std::string>(1u, arg1)) ] ; @@ -324,7 +309,7 @@ namespace detail { word // Returns value in context.token = lexeme_d [ - (+ word_p) [ str_ = construct_<std::string>(arg1, arg2) ] + (+ self.word_p) [ str_ = construct_<std::string>(arg1, arg2) ] ] >> eps_p [ token_ = construct_<Token>( Token::Word, @@ -347,7 +332,7 @@ namespace detail { ; skip - = space_p | comment_p('#') + = self.space_p | comment_p('#') ; /////////////////////////////////////////////////////////////////// @@ -381,6 +366,19 @@ namespace detail { }; }; + template <class PD> boost::spirit::chset<> CommandGrammar<PD>::special_p ( + "/(){};\""); + template <class PD> boost::spirit::chset<> CommandGrammar<PD>::punctuation_p ( + ",="); + template <class PD> boost::spirit::chset<> CommandGrammar<PD>::space_p ( + " \t\n\r"); + template <class PD> boost::spirit::chset<> CommandGrammar<PD>::invalid_p ( + (boost::spirit::chset<>('\0') | boost::spirit::chset<>("\x01-\x20")) - space_p ); + template <class PD> boost::spirit::chset<> CommandGrammar<PD>::word_p ( + boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p); + template <class PD> boost::spirit::distinct_parser<> CommandGrammar<PD>::keyword_p ( + word_p | boost::spirit::ch_p('/')); + #endif }}} diff --git a/Utils/Logger/FileTarget.cc b/Utils/Logger/FileTarget.cc index 52ebaf82670003f024e0ea75c727ddbe5ca57e9a..e15b3e8818541afe044cad79580964f3e2d06152 100644 --- a/Utils/Logger/FileTarget.cc +++ b/Utils/Logger/FileTarget.cc @@ -33,8 +33,21 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +namespace { + + std::string quoteFilename(std::string filename) + { + for (std::string::iterator i (filename.begin()); i != filename.end(); ++i) + if (! senf::console::CommandParser::isWordChar(*i)) + *i = '_'; + return filename; + } + +} + prefix_ senf::log::FileTarget::FileTarget(std::string const & file) - : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member), + : ofstream_t(file.c_str(), std::ofstream::app), + IOStreamTarget(quoteFilename(file), ofstream_t::member), file_(file) { consoleDir().add( "reopen", senf::membind( diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 7c85321000a711d5cab288ea7cc798804cf5999a..40cdd5867709bc5d3d6d60c8f2b87913f1c43b03 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -68,10 +68,13 @@ prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole() .doc("Create new syslog target."); } -prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) +prefix_ boost::shared_ptr<senf::console::DirectoryNode> +senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr<Target>(new SyslogTarget(facility))); + std::auto_ptr<Target> tp (new SyslogTarget(facility)); + Target & target (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return target.consoleDir().node().thisptr(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index 0049f59fd46661a79b7f2ebb6a3ce398e41dadfb..eeebbb93da9d9b7dc8072c414b49d45d1ae127d8 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -28,12 +28,16 @@ // Custom includes #include <syslog.h> +#include <boost/shared_ptr.hpp> #include "Target.hh" //#include "SyslogTarget.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { + + namespace console { class DirectoryNode; } + namespace log { /** \brief Log target writing to the syslog @@ -118,7 +122,8 @@ namespace log { private: struct RegisterConsole { RegisterConsole(); - static void create(LogFacility facility); + static boost::shared_ptr<senf::console::DirectoryNode> create( + LogFacility facility); static RegisterConsole instance; }; }; diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc index af8da40c9abb74da8049f2e37b9b730f7659493e..e420ec57b9d03c8c91a7a17c252f714fe9b452a7 100644 --- a/Utils/Logger/SyslogUDPTarget.cc +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -84,62 +84,74 @@ prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole() namespace kw = senf::console::kw; detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast<void (*)(INet4SocketAddress const &, LogFacility)>( + "udp-target", + static_cast<senf::console::DirectoryNode::ptr (*)(INet4SocketAddress const &, LogFacility)>( &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", + " 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<void (*)(INet4Address const &, LogFacility)>( + "udp-target", + static_cast<senf::console::DirectoryNode::ptr (*)(INet4Address const &, LogFacility)>( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast<void (*)(INet6SocketAddress const &, LogFacility)>( + "udp-target", + static_cast<senf::console::DirectoryNode::ptr (*)(INet6SocketAddress const &, LogFacility)>( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast<void (*)(INet6Address const &, LogFacility)>( + "udp-target", + static_cast<senf::console::DirectoryNode::ptr (*)(INet6Address const &, LogFacility)>( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); } -prefix_ void +prefix_ boost::shared_ptr<senf::console::DirectoryNode> senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); + std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr<senf::console::DirectoryNode> senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); + std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr<senf::console::DirectoryNode> senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); + std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr<senf::console::DirectoryNode> senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); + std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh index e6f35ffc1f381afa71781c4ff46745c788237e27..b9401535c4ff29cd5f96e5514617ebaaf2f6f85c 100644 --- a/Utils/Logger/SyslogUDPTarget.hh +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -154,14 +154,14 @@ namespace log { 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 boost::shared_ptr<senf::console::DirectoryNode> create( + senf::INet4SocketAddress const & target, LogFacility facility = USER); + static boost::shared_ptr<senf::console::DirectoryNode> create( + senf::INet4Address const & target, LogFacility facility = USER); + static boost::shared_ptr<senf::console::DirectoryNode> create( + senf::INet6SocketAddress const & target, LogFacility facility = USER); + static boost::shared_ptr<senf::console::DirectoryNode> create( + senf::INet6Address const & target, LogFacility facility = USER); static RegisterConsole instance; }; };