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 */
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/Binding.hh"
39 #include "../Scheduler/Timer.hh"
40 #include "../Scheduler/ReadHelper.hh"
42 #include "Executor.hh"
43 #include "../Socket/Protocols/INet/INetAddressing.hh"
44 #include "../Utils/Logger.hh"
46 //#include "Server.mpp"
48 ///////////////////////////////hh.p////////////////////////////////////////
55 /** \brief Interactive console server
57 This class provides an interactive console TCP server.
59 \idea To support blocking commands, we could give the Client 'suspend()' and 'resume()'
60 members. suspend() would probably throw some kind of exception to transfer control back
61 to the Client instance. on resume(), the command would be called again, maybe setting
62 some flag or something. Example for use: Host name resolution: Here we can just built
63 our own little host-name cache. When the name is not found, we ask the resolver to
64 resolve it and call 'resume' when the name is found. Since it is in the cache now, the
65 command will now complete.
67 \ingroup console_access
70 : public senf::intrusive_refcount
72 SENF_LOG_CLASS_AREA();
73 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
75 ///////////////////////////////////////////////////////////////////////////
78 typedef detail::ServerHandle ServerHandle;
80 enum Mode { Automatic, Interactive, Noninteractive };
82 ///////////////////////////////////////////////////////////////////////////
86 static Server & start(senf::INet4SocketAddress const & address);
87 ///< Start server on given IPv4 address/port
88 static Server & start(senf::INet6SocketAddress const & address);
89 ///< Start server on given IPv6 address/port
91 std::string const & name() const; ///< Get server name
92 /**< This information is used in the prompt string. */
94 Server & name(std::string const & name); ///< Set server name
95 /**< This information is used in the prompt string. */
97 DirectoryNode & root() const; ///< Get root node
99 Server & root(DirectoryNode & root); ///< Set root node
100 /**< \a node will be the root node for all clients launched
103 Mode mode() const; ///< Get mode
104 /**< \see \ref mode(Mode) */
106 Server & mode(Mode mode); ///< Set mode
107 /**< There are two Server types:
108 \li An interactive server displays a command prompt and
109 optionally supports command-line editing.
110 \li A non-interactive server does not display any
111 prompt and does not allow any interactive
112 editing. This type of server is used for (remote)
115 The \a mode parameter selects between these modes. In
116 \c Automatic (the default), a client connection is
117 considered to be interactive if there is no data
118 traffic in the first 500ms after the connection is
121 void stop(); ///< Stop the server
122 /**< All clients will be closed
123 \warning The Server instance itself will be deleted */
128 Server(ServerHandle handle);
130 static Server & start(ServerHandle handle);
132 void newClient(int event);
133 void removeClient(Client & client);
135 ServerHandle handle_;
136 DirectoryNode::ptr root_;
139 typedef std::set< boost::intrusive_ptr<Client> > Clients;
146 /** \brief Server client instance
148 Whenever a new client connects, a new instance of this class is created. This class shows a
149 command prompt, receives the commands, parses them and then passes (using a CommandParser)
150 and passes the commands to an Executor instance.
152 \ingroup console_access
155 : public senf::intrusive_refcount,
156 private boost::base_from_member< detail::NonblockingSocketOStream >,
157 public senf::log::IOStreamTarget
159 typedef boost::base_from_member< detail::NonblockingSocketOStream > out_t;
161 SENF_LOG_CLASS_AREA();
162 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
164 static const unsigned INTERACTIVE_TIMEOUT = 500; // milliseconds;
167 typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
171 void stop(); ///< Stop the client
172 /**< This will close the client socket. */
174 std::string const & name() const;
175 ClientHandle handle() const;
176 std::ostream & stream();
177 std::string promptString() const;
178 DirectoryNode & root() const;
179 Server::Mode mode() const;
181 static Client & get(std::ostream & os);
186 Client(Server & server, ClientHandle handle);
188 void setInteractive();
189 void setNoninteractive();
191 void translate(std::string & data);
192 unsigned handleInput(std::string input, bool incremental = false);
193 virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
194 std::string const & area, unsigned level,
195 std::string const & message);
198 ClientHandle handle_;
199 SchedulerBinding binding_;
200 SchedulerTimer timer_;
201 CommandParser parser_;
204 std::string lastCommand_;
205 boost::scoped_ptr<detail::ClientReader> reader_;
209 friend class detail::ClientReader;
210 friend class detail::NonblockingSocketSink;
213 /** \brief Output Console Client instance as it's string representation
216 std::ostream & operator<<(std::ostream & os, Client const & client);
218 /** \brief Output Console Client instance as it's string representation
221 std::ostream & operator<<(std::ostream & os, Client * client);
225 ///////////////////////////////hh.e////////////////////////////////////////
226 #include "Server.cci"
227 //#include "Server.ct"
228 //#include "Server.cti"
235 // comment-column: 40
236 // c-file-style: "senf"
237 // indent-tabs-mode: nil
238 // ispell-local-dictionary: "american"
239 // compile-command: "scons -u test"