39 const GNet::Address & local_address ,
const std::string & remote_address ,
40 const G::StringMap & extra_commands ,
bool with_terminate ) :
41 BufferedServerPeer(peer_info,crlf()) ,
43 m_local_address(local_address) ,
44 m_remote_address(remote_address) ,
46 m_extra_commands(extra_commands) ,
47 m_with_terminate(with_terminate)
60 m_server.unregister(
this ) ;
61 m_client.doneSignal().disconnect() ;
64 void GSmtp::AdminServerPeer::clientDone( std::string s ,
bool )
70 sendLine( std::string(
"error: ") + s ) ;
81 G_LOG_S(
"GSmtp::AdminServerPeer: admin connection closed: " << reason << (reason.empty()?
"":
": ")
82 << peerAddress().second.displayString() ) ;
91 if( is(line,
"flush") )
96 else if( is(line,
"help") )
101 else if( is(line,
"info") )
106 else if( is(line,
"notify") )
111 else if( is(line,
"list") )
116 else if( is(line,
"failures") )
121 else if( is(line,
"unfail-all") )
126 else if( is(line,
"pid") )
131 else if( is(line,
"quit") )
136 else if( is(line,
"terminate") && m_with_terminate )
141 else if( find(line,m_extra_commands).first )
143 sendLine( find(line,m_extra_commands).second ) ;
146 else if( line.find_first_not_of(
" \r\n\t") != std::string::npos )
148 sendLine(
"error: unrecognised command" ) ;
158 const std::string & GSmtp::AdminServerPeer::crlf()
160 static const std::string s(
"\015\012" ) ;
164 bool GSmtp::AdminServerPeer::is(
const std::string & line_in ,
const std::string & key )
166 std::string line( line_in ) ;
169 return line.find(key) == 0U ;
172 std::pair<bool,std::string> GSmtp::AdminServerPeer::find(
const std::string & line ,
const G::StringMap & map )
174 for( G::StringMap::const_iterator p = map.begin() ; p != map.end() ; ++p )
176 if( is(line,(*p).first) )
177 return std::make_pair(
true,(*p).second) ;
179 return std::make_pair(
false,std::string()) ;
182 void GSmtp::AdminServerPeer::help()
185 commands.push_back(
"flush" ) ;
186 commands.push_back(
"help" ) ;
187 commands.push_back(
"info" ) ;
188 commands.push_back(
"list" ) ;
189 commands.push_back(
"failures" ) ;
190 commands.push_back(
"unfail-all" ) ;
191 commands.push_back(
"notify" ) ;
192 commands.push_back(
"pid" ) ;
193 commands.push_back(
"quit" ) ;
194 if( m_with_terminate ) commands.push_back(
"terminate" ) ;
196 commands.splice( commands.end() , extras ) ;
198 sendLine( std::string(
"commands: ") +
G::Str::join(commands,
", ") ) ;
201 bool GSmtp::AdminServerPeer::flush()
203 G_DEBUG(
"GSmtp::AdminServerPeer: flush: \"" << m_remote_address <<
"\"" ) ;
205 bool do_prompt = false ;
206 if( m_client.busy() )
208 sendLine(
"error: still working" ) ;
210 else if( m_remote_address.empty() )
212 sendLine(
"error: no remote server configured: use --forward-to" ) ;
215 else if( m_server.store().empty() )
217 sendLine(
"error: no messages to send" ) ;
222 m_client.reset(
new Client(
GNet::ResolverInfo(m_remote_address),m_server.secrets(),m_server.clientConfig()) ) ;
223 m_client->sendMessagesFrom( m_server.store() ) ;
228 void GSmtp::AdminServerPeer::prompt()
230 send(
"E-MailRelay> " ) ;
233 void GSmtp::AdminServerPeer::sendLine( std::string line )
235 line.append(
"\n" ) ;
243 sendLine( std::string(1U,
'\n') +
"EVENT: " + s0 +
": " + s1 +
": " + s2 ) ;
246 void GSmtp::AdminServerPeer::info()
248 std::ostringstream ss ;
256 sendLine(
"no info" ) ;
260 void GSmtp::AdminServerPeer::pid()
267 return m_server.store().iterator(
false) ;
272 return m_server.store().failures() ;
275 void GSmtp::AdminServerPeer::list( MessageStore::Iterator iter )
277 std::ostringstream ss ;
280 std::auto_ptr<StoredMessage> message( iter.next() ) ;
281 if( message.get() == NULL )
break ;
282 ss << message->name() <<
"\n" ;
285 std::string result = ss.str() ;
286 if( result.size() == 0U )
287 sendLine(
"<none>" ) ;
292 void GSmtp::AdminServerPeer::unfailAll()
294 return m_server.store().unfailAll() ;
301 bool allow_remote ,
const GNet::Address & local_address ,
const std::string & remote_address ,
302 unsigned int connection_timeout ,
const G::StringMap & extra_commands ,
bool with_terminate ) :
303 GNet::MultiServer( listening_addresses , false ) ,
305 m_client_config(client_config) ,
307 m_local_address(local_address) ,
308 m_allow_remote(allow_remote) ,
309 m_remote_address(remote_address) ,
310 m_connection_timeout(connection_timeout) ,
311 m_extra_commands(extra_commands) ,
312 m_with_terminate(with_terminate)
329 G_WARNING(
"GSmtp::Server: configured to reject non-local admin connection: " << reason ) ;
334 m_extra_commands , m_with_terminate ) ;
335 m_peers.push_back( peer ) ;
338 catch( std::exception & e )
340 G_WARNING(
"GSmtp::AdminServer: exception from new connection: " << e.what() ) ;
347 serverReport(
"admin" ) ;
352 for( PeerList::iterator p = m_peers.begin() ; p != m_peers.end() ; ++p )
354 G_DEBUG(
"GSmtp::AdminServer::notify: " << (*p) <<
": " << s0 <<
": " << s1 ) ;
355 (*p)->notify( s0 , s1 , s2 ) ;
361 G_DEBUG(
"GSmtp::AdminServer::unregister: server=" <<
this <<
": peer=" << peer ) ;
362 PeerList::iterator p = std::find( m_peers.begin() , m_peers.end() , peer ) ;
363 if( p != m_peers.end() )
379 return m_connection_timeout ;
384 return m_client_config ;
An abstract base class for the GNet::Server's connection to a remote client.
A server class which implements the emailrelay administration interface.
virtual void onDelete(const std::string &)
Final override from GNet::ServerPeer.
void notify(const std::string &s0, const std::string &s1, const std::string &s2)
Called when something happens which the admin user might be interested in.
void unregister(AdminServerPeer *)
Called from the AdminServerPeer destructor.
std::list< std::string > Strings
A std::list of std::strings.
The Address class encapsulates an IP transport address.
void report(std::ostream &stream, const std::string &line_prefix=std::string(), const std::string &eol=std::string("\n")) const
Reports itself onto a stream.
static bool isLocal(const Address &)
Returns true if the given address appears to be local.
void report() const
Generates helpful diagnostics.
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
AdminServer(MessageStore &store, const GSmtp::Client::Config &client_config, const GAuth::Secrets &client_secrets, const GNet::MultiServer::AddressList &listening_addresses, bool allow_remote, const GNet::Address &local_address, const std::string &remote_address, unsigned int connection_timeout, const G::StringMap &extra_commands, bool with_terminate)
Constructor.
virtual bool onReceive(const std::string &)
Final override from GNet::BufferedServerPeer.
static void trim(std::string &s, const std::string &ws)
Trims both ends of s, taking off any of the 'ws' characters.
static void toLower(std::string &s)
Replaces all uppercase characters in string 's' by lowercase characters.
static Strings keys(const StringMap &string_map)
Extracts the keys from a map of strings.
std::string displayString(bool with_port=true, bool with_scope_id=false) const
Returns a string which represents the address for debugging and diagnostics purposes.
A class which allows SMTP messages (envelope+content) to be stored and retrieved. ...
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurences of sub-string 'from' with 'to'...
A simple interface to a store of secrets as used in authentication.
const GAuth::Secrets & secrets() const
Returns a reference to the secrets object, as passed in to the constructor.
static Monitor * instance()
Returns the singleton pointer. Returns null if none.
G::Signal2< std::string, bool > & doneSignal()
Returns a signal which indicates that client processing is complete and the client instance has delet...
MessageStore & store()
Returns a reference to the message store, as passed in to the constructor.
virtual ~AdminServerPeer()
Destructor.
void notify(const std::string &s0, const std::string &s1, const std::string &s2)
Called when something happens.
A structure containing GSmtp::Client configuration parameters.
A derivation of ServerPeer for the administration interface.
virtual GNet::ServerPeer * newPeer(GNet::Server::PeerInfo)
Final override from GNet::MultiServer.
virtual void onSendComplete()
Final override from GNet::BufferedServerPeer.
std::map< std::string, std::string > StringMap
A std::map of std::strings.
AdminServerPeer(GNet::Server::PeerInfo, AdminServer &, const GNet::Address &local, const std::string &remote, const G::StringMap &extra_commands, bool with_terminate)
Constructor.
std::list< Address > AddressList
virtual ~AdminServer()
Destructor.
static bool exists()
Returns true if an instance exists.
GSmtp::Client::Config clientConfig() const
Returns the client configuration.
void connect(Slot2< P1, P2 > slot)
A structure used in GNet::Server::newPeer().
unsigned int connectionTimeout() const
Returns the connection timeout, as passed in to the constructor.
static std::string join(const Strings &strings, const std::string &sep)
Concatenates a set of strings.
virtual void onSecure(const std::string &)
Final override from GNet::SocketProtocolSink.
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
virtual void quit(std::string reason)=0
Causes run() to return (once the call stack has unwound).
An iterator class for GSmtp::MessageStore.