4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief Server public header */
26 #ifndef HH_SENF_Scheduler_Console_Server_
27 #define HH_SENF_Scheduler_Console_Server_ 1
31 #include <boost/utility.hpp>
32 #include <boost/scoped_ptr.hpp>
33 #include <boost/shared_ptr.hpp>
34 #include "../../Utils/intrusive_refcount.hh"
35 #include "../../Socket/Protocols/INet/TCPSocketHandle.hh"
36 #include "../../Socket/ServerSocketHandle.hh"
37 #include "../../Scheduler/Scheduler.hh"
38 #include "../../Scheduler/ReadHelper.hh"
40 #include "Executor.hh"
41 #include "../../Socket/Protocols/INet/INetAddressing.hh"
42 #include "../../Utils/Logger.hh"
44 //#include "Server.mpp"
46 ///////////////////////////////hh.p////////////////////////////////////////
53 /** \brief Interactive console server
55 This class provides an interactive console TCP server.
57 \idea To support blocking commands, we could give the Client 'suspend()' and 'resume()'
58 members. suspend() would probably throw some kind of exception to transfer control back
59 to the Client instance. on resume(), the command would be called again, maybe setting
60 some flag or something. Example for use: Host name resolution: Here we can just built
61 our own little host-name cache. When the name is not found, we ask the resolver to
62 resolve it and call 'resume' when the name is found. Since it is in the cache now, the
63 command will now complete.
65 \ingroup console_access
68 : public senf::intrusive_refcount
70 SENF_LOG_CLASS_AREA();
71 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
73 ///////////////////////////////////////////////////////////////////////////
76 typedef detail::ServerHandle ServerHandle;
78 enum Mode { Automatic, Interactive, Noninteractive };
80 ///////////////////////////////////////////////////////////////////////////
82 static Server & start(senf::INet4SocketAddress const & address);
83 ///< Start server on given IPv4 address/port
84 static Server & start(senf::INet6SocketAddress const & address);
85 ///< Start server on given IPv6 address/port
87 std::string const & name() const; ///< Get server name
88 /**< This information is used in the prompt string. */
90 Server & name(std::string const & name); ///< Set server name
91 /**< This information is used in the prompt string. */
93 DirectoryNode & root() const; ///< Get root node
95 Server & root(DirectoryNode & root); ///< Set root node
96 /**< \a node will be the root node for all clients launched
99 Mode mode() const; ///< Get mode
100 /**< \see \ref mode(Mode) */
102 Server & mode(Mode mode); ///< Set mode
103 /**< There are two Server types:
104 \li An interactive server displays a command prompt and
105 optionally supports command-line editing.
106 \li A non-interactive server does not display any
107 prompt and does not allow any interactive
108 editing. This type of server is used for (remote)
111 The \a mode parameter selects between these modes. In
112 \c Automatic (the default), a client connection is
113 considered to be interactive if there is no data
114 traffic in the first 500ms after the connection is
117 void stop(); ///< Stop the server
118 /**< All clients will be closed
119 \warning The Server instance itself will be deleted */
124 Server(ServerHandle handle);
126 static Server & start(ServerHandle handle);
128 void newClient(int event);
129 void removeClient(Client & client);
131 ServerHandle handle_;
132 scheduler::FdEvent event_;
133 DirectoryNode::ptr root_;
136 typedef std::set< boost::intrusive_ptr<Client> > Clients;
143 /** \brief Server client instance
145 Whenever a new client connects, a new instance of this class is created. This class shows a
146 command prompt, receives the commands, parses them and then passes (using a CommandParser)
147 and passes the commands to an Executor instance.
149 \ingroup console_access
152 : public senf::intrusive_refcount,
153 private boost::base_from_member< detail::NonblockingSocketOStream >,
154 public senf::log::IOStreamTarget
156 typedef boost::base_from_member< detail::NonblockingSocketOStream > out_t;
158 SENF_LOG_CLASS_AREA();
159 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
161 static const unsigned INTERACTIVE_TIMEOUT = 500; // milliseconds;
164 typedef Server::ServerHandle::ClientHandle ClientHandle;
168 void stop(); ///< Stop the client
169 /**< This will close the client socket. */
171 std::string const & name() const;
172 ClientHandle handle() const;
173 std::ostream & stream();
174 std::string promptString() const;
175 DirectoryNode & root() const;
176 Server::Mode mode() const;
177 void write(std::string const & data) const;
179 static Client & get(std::ostream & os);
184 Client(Server & server, ClientHandle handle);
186 void setInteractive();
187 void setNoninteractive();
189 size_t handleInput(std::string input, bool incremental = false);
190 virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
191 std::string const & area, unsigned level,
192 std::string const & message);
195 ClientHandle handle_;
196 scheduler::FdEvent readevent_;
197 scheduler::TimerEvent timer_;
198 CommandParser parser_;
201 std::string lastCommand_;
202 boost::scoped_ptr<detail::ClientReader> reader_;
206 friend class detail::ClientReader;
207 friend class detail::NonblockingSocketSink;
210 /** \brief Output Console Client instance as it's string representation
213 std::ostream & operator<<(std::ostream & os, Client const & client);
215 /** \brief Output Console Client instance as it's string representation
218 std::ostream & operator<<(std::ostream & os, Client * client);
222 ///////////////////////////////hh.e////////////////////////////////////////
223 #include "Server.cci"
224 //#include "Server.ct"
225 //#include "Server.cti"
232 // comment-column: 40
233 // c-file-style: "senf"
234 // indent-tabs-mode: nil
235 // ispell-local-dictionary: "american"
236 // compile-command: "scons -u test"