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/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 \todo Add interactivity detection using timeout
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 \implementation We do \e not provide an \c instance() member so we can easily later extend
67 the server to allow registering more than one instance, e.g. with each instance on a
68 differently firewalled port and with different security restrictions.
70 \ingroup console_access
75 SENF_LOG_CLASS_AREA();
76 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
78 ///////////////////////////////////////////////////////////////////////////
81 typedef detail::ServerHandle ServerHandle;
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
89 Server & name(std::string const & name); ///< Set server name
90 /**< This information is used in the prompt string. */
92 void stop(); ///< Stop the server
93 /**< All clients will be closed */
98 Server(ServerHandle handle);
100 static Server & start(ServerHandle handle);
101 static boost::scoped_ptr<Server> & instancePtr();
103 void newClient(Scheduler::EventId event);
104 void removeClient(Client & client);
106 ServerHandle handle_;
108 typedef std::set< boost::intrusive_ptr<Client> > Clients;
115 /** \brief Server client instance
117 Whenever a new client connects, a new instance of this class is created. This class shows a
118 command prompt, receives the commands, parses them and then passes (using a CommandParser)
119 and passes the commands to an Executor instance.
121 \ingroup console_access
124 : public senf::intrusive_refcount,
125 private boost::base_from_member< detail::NonblockingSocketOStream >,
126 public senf::log::IOStreamTarget
128 typedef boost::base_from_member< detail::NonblockingSocketOStream > out_t;
130 SENF_LOG_CLASS_AREA();
131 SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
134 typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
138 void stop(); ///< Stop the client
139 /**< This will close the client socket. */
141 std::string const & name() const;
142 ClientHandle handle() const;
143 std::ostream & stream();
144 std::string promptString() const;
146 static Client & get(std::ostream & os);
151 Client(Server & server, ClientHandle handle, std::string const & name);
153 void translate(std::string & data);
154 void handleInput(std::string input);
155 virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
156 std::string const & area, unsigned level,
157 std::string const & message);
160 ClientHandle handle_;
161 CommandParser parser_;
164 std::string lastCommand_;
165 boost::scoped_ptr<detail::ClientReader> reader_;
168 friend class detail::ClientReader;
169 friend class detail::NonblockingSocketSink;
172 /** \brief Output Console Client instance as it's string representation
175 std::ostream & operator<<(std::ostream & os, Client const & client);
177 /** \brief Output Console Client instance as it's string representation
180 std::ostream & operator<<(std::ostream & os, Client * client);
184 ///////////////////////////////hh.e////////////////////////////////////////
185 #include "Server.cci"
186 //#include "Server.ct"
187 //#include "Server.cti"
194 // comment-column: 40
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // compile-command: "scons -u test"