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/ReadHelper.hh"
41 #include "Executor.hh"
42 #include "../Socket/Protocols/INet/INetAddressing.hh"
43 #include "../Utils/Logger.hh"
45 //#include "Server.mpp"
47 ///////////////////////////////hh.p////////////////////////////////////////
54 /** \brief Interactive console server
56 This class provides an interactive console TCP server.
58 \idea To support blocking commands, we could give the Client 'suspend()' and 'resume()'
59 members. suspend() would probably throw some kind of exception to transfer control back
60 to the Client instance. on resume(), the command would be called again, maybe setting
61 some flag or something. Example for use: Host name resolution: Here we can just built
62 our own little host-name cache. When the name is not found, we ask the resolver to
63 resolve it and call 'resume' when the name is found. Since it is in the cache now, the
64 command will now complete.
66 \ingroup console_access
69 : public senf::intrusive_refcount
71 SENF_LOG_CLASS_AREA();
72 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
74 ///////////////////////////////////////////////////////////////////////////
77 typedef detail::ServerHandle ServerHandle;
79 enum Mode { Automatic, Interactive, Noninteractive };
81 ///////////////////////////////////////////////////////////////////////////
85 static Server & start(senf::INet4SocketAddress const & address);
86 ///< Start server on given IPv4 address/port
87 static Server & start(senf::INet6SocketAddress const & address);
88 ///< Start server on given IPv6 address/port
90 std::string const & name() const; ///< Get server name
91 /**< This information is used in the prompt string. */
93 Server & name(std::string const & name); ///< Set server name
94 /**< This information is used in the prompt string. */
96 DirectoryNode & root() const; ///< Get root node
98 Server & root(DirectoryNode & root); ///< Set root node
99 /**< \a node will be the root node for all clients launched
102 Mode mode() const; ///< Get mode
103 /**< \see \ref mode(Mode) */
105 Server & mode(Mode mode); ///< Set mode
106 /**< There are two Server types:
107 \li An interactive server displays a command prompt and
108 optionally supports command-line editing.
109 \li A non-interactive server does not display any
110 prompt and does not allow any interactive
111 editing. This type of server is used for (remote)
114 The \a mode parameter selects between these modes. In
115 \c Automatic (the default), a client connection is
116 considered to be interactive if there is no data
117 traffic in the first 500ms after the connection is
120 void stop(); ///< Stop the server
121 /**< All clients will be closed
122 \warning The Server instance itself will be deleted */
127 Server(ServerHandle handle);
129 static Server & start(ServerHandle handle);
131 void newClient(int event);
132 void removeClient(Client & client);
134 ServerHandle handle_;
135 DirectoryNode::ptr root_;
138 typedef std::set< boost::intrusive_ptr<Client> > Clients;
145 /** \brief Server client instance
147 Whenever a new client connects, a new instance of this class is created. This class shows a
148 command prompt, receives the commands, parses them and then passes (using a CommandParser)
149 and passes the commands to an Executor instance.
151 \ingroup console_access
154 : public senf::intrusive_refcount,
155 private boost::base_from_member< detail::NonblockingSocketOStream >,
156 public senf::log::IOStreamTarget
158 typedef boost::base_from_member< detail::NonblockingSocketOStream > out_t;
160 SENF_LOG_CLASS_AREA();
161 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
163 static const unsigned INTERACTIVE_TIMEOUT = 500; // milliseconds;
166 typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
170 void stop(); ///< Stop the client
171 /**< This will close the client socket. */
173 std::string const & name() const;
174 ClientHandle handle() const;
175 std::ostream & stream();
176 std::string promptString() const;
177 DirectoryNode & root() const;
178 Server::Mode mode() const;
180 static Client & get(std::ostream & os);
185 Client(Server & server, ClientHandle handle);
187 void setInteractive();
188 void setNoninteractive();
190 void translate(std::string & data);
191 unsigned handleInput(std::string input, bool incremental = false);
192 virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
193 std::string const & area, unsigned level,
194 std::string const & message);
197 ClientHandle handle_;
198 SchedulerBinding binding_;
199 scheduler::TimerEvent timer_;
200 CommandParser parser_;
203 std::string lastCommand_;
204 boost::scoped_ptr<detail::ClientReader> reader_;
208 friend class detail::ClientReader;
209 friend class detail::NonblockingSocketSink;
212 /** \brief Output Console Client instance as it's string representation
215 std::ostream & operator<<(std::ostream & os, Client const & client);
217 /** \brief Output Console Client instance as it's string representation
220 std::ostream & operator<<(std::ostream & os, Client * client);
224 ///////////////////////////////hh.e////////////////////////////////////////
225 #include "Server.cci"
226 //#include "Server.ct"
227 //#include "Server.cti"
234 // comment-column: 40
235 // c-file-style: "senf"
236 // indent-tabs-mode: nil
237 // ispell-local-dictionary: "american"
238 // compile-command: "scons -u test"