Fix documentation
[senf.git] / Console / Server.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief Server public header */
25
26 #ifndef HH_Server_
27 #define HH_Server_ 1
28
29 // Custom includes
30 #include <set>
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"
39 #include "Parse.hh"
40 #include "Executor.hh"
41 #include "../Socket/Protocols/INet/INetAddressing.hh"
42 #include "../Utils/Logger.hh"
43
44 //#include "Server.mpp"
45 #include "Server.ih"
46 ///////////////////////////////hh.p////////////////////////////////////////
47
48 namespace senf {
49 namespace console {
50
51     class Client;
52
53     /** \brief Interactive console server
54
55         This class provides an interactive console TCP server.
56
57         \todo Add readline support
58         \todo Add interactivity detection using timeout
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.
66       */
67     class Server
68         : boost::noncopyable
69     {
70         SENF_LOG_CLASS_AREA();
71         SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
72     public:
73         ///////////////////////////////////////////////////////////////////////////
74         // Types
75
76         typedef senf::ServerSocketHandle<
77             senf::MakeSocketPolicy< senf::TCPv4SocketProtocol::Policy, 
78                                     senf::UnspecifiedAddressingPolicy>::policy > ServerHandle;
79
80         ~Server();
81
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
86         static Server & instance();
87
88         void name(std::string const & name); ///< Set server name
89                                         /**< This information is used in the prompt string. */
90
91     protected:
92
93     private:
94         Server(ServerHandle handle);
95
96         static void start(ServerHandle handle);
97         static boost::scoped_ptr<Server> & instancePtr();
98
99         void newClient(Scheduler::EventId event);
100         void removeClient(Client & client);
101         
102         ServerHandle handle_;
103         
104         typedef std::set< boost::intrusive_ptr<Client> > Clients;
105         Clients clients_;
106         std::string name_;
107         
108         friend class Client;
109     };
110     
111     /** \brief Server client instance
112
113         Whenever a new client connects, a new instance of this class is created. This class shows a
114         command prompt, receives the commands, parses them and then passes (using a CommandParser)
115         and passes the commands to an Executor instance.
116
117         \fixme Fix Client::clientData implementation
118         \fixme Don't register a new ReadHelper every round
119      */
120     class Client
121         : public senf::intrusive_refcount, 
122           private boost::base_from_member< detail::NonblockingSocketOStream >,
123           public senf::log::IOStreamTarget
124     {
125         typedef boost::base_from_member< detail::NonblockingSocketOStream > out_t;
126
127         SENF_LOG_CLASS_AREA();
128         SENF_LOG_DEFAULT_LEVEL( senf::log::NOTICE );
129     public:
130         typedef Server::ServerHandle::ClientSocketHandle ClientHandle;
131
132         ~Client();
133
134         void stopClient();              ///< Stop the client
135                                         /**< This will close the client socket. */
136
137     protected:
138         
139     private:
140         Client(ClientHandle handle, std::string const & name);
141
142         void clientData(ReadHelper<ClientHandle>::ptr helper);
143         void showPrompt();
144
145         virtual void v_write(boost::posix_time::ptime timestamp, std::string const & stream, 
146                              std::string const & area, unsigned level, 
147                              std::string const & message);
148         
149         ClientHandle handle_;
150         std::string tail_;
151         CommandParser parser_;
152         Executor executor_;
153         std::string name_;
154         unsigned promptLen_;
155         std::string lastCommand_;
156
157         friend class Server;
158     };
159
160 }}
161
162 ///////////////////////////////hh.e////////////////////////////////////////
163 #include "Server.cci"
164 //#include "Server.ct"
165 //#include "Server.cti"
166 #endif
167
168 \f
169 // Local Variables:
170 // mode: c++
171 // fill-column: 100
172 // comment-column: 40
173 // c-file-style: "senf"
174 // indent-tabs-mode: nil
175 // ispell-local-dictionary: "american"
176 // compile-command: "scons -u test"
177 // End: