- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

run.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // run.cpp
19 //
20
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "gssl.h"
24 #include "gsmtp.h"
25 #include "run.h"
26 #include "admin.h"
27 #include "gsmtpserver.h"
28 #include "gsmtpclient.h"
29 #include "gsecrets.h"
30 #include "geventloop.h"
31 #include "garg.h"
32 #include "gdaemon.h"
33 #include "gpidfile.h"
34 #include "gfilestore.h"
35 #include "gnewfile.h"
36 #include "gmultiserver.h"
37 #include "gadminserver.h"
38 #include "gpopserver.h"
39 #include "gprocessorfactory.h"
40 #include "gverifierfactory.h"
41 #include "gslot.h"
42 #include "gmonitor.h"
43 #include "glocal.h"
44 #include "gfile.h"
45 #include "gpath.h"
46 #include "groot.h"
47 #include "gexception.h"
48 #include "gprocess.h"
49 #include "gmemory.h"
50 #include "gtest.h"
51 #include "glogoutput.h"
52 #include "gdebug.h"
53 #include "legal.h"
54 #include <iostream>
55 #include <exception>
56 #include <utility>
57
58 #ifndef G_CAPABILITIES
59 #define G_CAPABILITIES ""
60 #endif
61
62 std::string Main::Run::capabilities()
63 {
64 return G_CAPABILITIES ;
65 }
66
67 std::string Main::Run::versionNumber()
68 {
69 return "1.9" ;
70 }
71
72 Main::Run::Run( Main::Output & output , const G::Arg & arg , const std::string & switch_spec ) :
73 m_output(output) ,
74 m_switch_spec(switch_spec) ,
75 m_arg(arg) ,
76 m_client_resolver_info(std::string(),std::string()) ,
77 m_prepare_error(false)
78 {
79 m_client.doneSignal().connect( G::slot(*this,&Run::pollingClientDone) ) ;
80 m_client.eventSignal().connect( G::slot(*this,&Run::clientEvent) ) ;
81 }
82
83 Main::Run::~Run()
84 {
85 try
86 {
87 if( m_store.get() ) m_store->signal().disconnect() ;
88 if( m_smtp_server.get() ) m_smtp_server->eventSignal().disconnect() ;
89 m_client.doneSignal().disconnect() ;
90 m_client.eventSignal().disconnect() ;
91
92 // there are no EventLoop or TimerList instances when this
93 // destuctor runs so delete the client with ..ForExit()
94 m_client.cleanupForExit() ;
95
96 // call some more destructors early (in the correct order)
97 // within the scope of the catch
98 m_forwarding_timer <<= 0 ;
99 m_poll_timer <<= 0 ;
100 m_smtp_server <<= 0 ;
101 m_admin_server <<= 0 ;
102 m_pop_secrets <<= 0 ;
103 m_client_secrets <<= 0 ;
104 m_store <<= 0 ;
105 m_cfg <<= 0 ;
106 m_cl <<= 0 ;
107 m_log_output <<= 0 ;
108 }
109 catch(...)
110 {
111 }
112 }
113
114 bool Main::Run::prepareError() const
115 {
116 return m_prepare_error ;
117 }
118
119 const Main::Configuration & Main::Run::config() const
120 {
121 cl() ;
122 return *m_cfg.get() ;
123 }
124
125 std::string Main::Run::smtpIdent() const
126 {
127 return std::string("E-MailRelay V") + versionNumber() ;
128 }
129
130 void Main::Run::closeFiles()
131 {
132 if( config().daemon() )
133 {
134 const bool keep_stderr = true ;
135 G::Process::closeFiles( keep_stderr ) ;
136 }
137 }
138
139 void Main::Run::closeMoreFiles()
140 {
141 if( config().closeStderr() )
142 G::Process::closeStderr() ;
143 }
144
145 bool Main::Run::hidden() const
146 {
147 return cl().contains("hidden") ;
148 }
149
150 bool Main::Run::prepare()
151 {
152 #ifndef USE_SMALL_CONFIG
153 if( cl().contains("help") )
154 {
155 cl().showHelp( false ) ;
156 m_prepare_error = false ;
157 return false ;
158 }
159 else if( cl().hasUsageErrors() )
160 {
161 cl().showUsageErrors( true ) ;
162 m_prepare_error = true ;
163 return false ;
164 }
165 else if( cl().contains("version") )
166 {
167 cl().showVersion( false ) ;
168 m_prepare_error = false ;
169 return false ;
170 }
171 else if( cl().argc() > 1U )
172 {
173 cl().showArgcError( true ) ;
174 m_prepare_error = true ;
175 return false ;
176 }
177 else if( cl().hasSemanticError() )
178 {
179 cl().showSemanticError( true ) ;
180 m_prepare_error = true ;
181 return false ;
182 }
183 #endif
184
185 // early singletons...
186 //
187 const Configuration & cfg = config() ;
188 m_log_output <<= new G::LogOutput( m_arg.prefix() ,
189 cfg.log() , // output
190 cfg.log() , // with-logging
191 cfg.verbose() , // with-verbose-logging
192 cfg.debug() , // with-debug
193 true , // with-level
194 cfg.logTimestamp() , // with-timestamp
195 !cfg.debug() , // strip-context
196 cfg.useSyslog() , // use-syslog
197 cfg.logFile() , // stderr-replacement
198 G::LogOutput::Mail // facility
199 ) ;
200
201 #ifndef USE_SMALL_CONFIG
202 // emit warnings for dodgy switch combinations
203 cl().logSemanticWarnings() ;
204 #endif
205
206 return true ;
207 }
208
209 #ifndef USE_SMALL_CONFIG
210 void Main::Run::checkPort( bool check , const std::string & interface_ , unsigned int port )
211 {
212 if( check )
213 {
214 GNet::Address address =
215 interface_.length() ?
216 GNet::Address(interface_,port) :
217 GNet::Address(port) ;
218 GNet::Server::canBind( address , true ) ;
219 }
220 }
221 #endif
222
223 void Main::Run::checkPorts() const
224 {
225 #ifndef USE_SMALL_CONFIG
226 const Configuration & cfg = config() ;
227 if( cfg.doServing() )
228 {
229 G::Strings smtp_interfaces = cfg.listeningInterfaces("smtp") ;
230 checkPort( cfg.doSmtp() && smtp_interfaces.empty() , std::string() , cfg.port() ) ;
231 for( G::Strings::iterator p1 = smtp_interfaces.begin() ; p1 != smtp_interfaces.end() ; ++p1 )
232 checkPort( cfg.doSmtp() , *p1 , cfg.port() ) ;
233
234 G::Strings pop_interfaces = cfg.listeningInterfaces("pop") ;
235 checkPort( cfg.doPop() && pop_interfaces.empty() , std::string() , cfg.popPort() ) ;
236 for( G::Strings::iterator p2 = pop_interfaces.begin() ; p2 != pop_interfaces.end() ; ++p2 )
237 checkPort( cfg.doPop() , *p2 , cfg.popPort() ) ;
238
239 G::Strings admin_interfaces = cfg.listeningInterfaces("admin") ;
240 checkPort( cfg.doAdmin() && admin_interfaces.empty() , std::string() , cfg.adminPort() ) ;
241 for( G::Strings::iterator p3 = admin_interfaces.begin() ; p3 != admin_interfaces.end() ; ++p3 )
242 checkPort( cfg.doAdmin() , *p3 , cfg.adminPort() ) ;
243 }
244 #endif
245 }
246
247 void Main::Run::run()
248 {
249 try
250 {
251 runCore() ;
252 G_LOG( "Main::Run::run: done" ) ;
253 }
254 catch( std::exception & e )
255 {
256 G_ERROR( "Main::Run::run: " << e.what() ) ;
257 throw ;
258 }
259 catch(...)
260 {
261 G_ERROR( "Main::Run::run: unknown exception" ) ;
262 throw ;
263 }
264 }
265
266 void Main::Run::runCore()
267 {
268 const Configuration & cfg = config() ;
269
270 // fqdn override option
271 //
272 std::string nul( 1U , '\0' ) ;
273 if( cfg.fqdn(nul) != nul )
274 GNet::Local::fqdn( cfg.fqdn() ) ;
275
276 // tighten the umask
277 //
278 G::Process::Umask::set( G::Process::Umask::Tightest ) ;
279
280 // close inherited file descriptors to avoid locking file
281 // systems when running as a daemon -- this has to be done
282 // early, before opening any sockets or message-store streams
283 //
284 if( cfg.daemon() )
285 {
286 closeFiles() ;
287 }
288
289 // release root privileges and extra group memberships
290 //
291 G::Root::init( cfg.nobody() ) ;
292
293 // event loop singletons
294 //
295 GNet::TimerList timer_list ;
296 std::auto_ptr<GNet::EventLoop> event_loop(GNet::EventLoop::create()) ;
297 if( ! event_loop->init() )
298 throw G::Exception( "cannot initialise network layer" ) ;
299
300 // early check on socket bindability
301 //
302 checkPorts() ;
303
304 #ifndef USE_NO_EXEC
305 // early check on script executablity
306 //
307 checkScripts() ;
308 #endif
309
310 // ssl library singleton
311 //
312 bool ssl_active = cfg.clientTls() || cfg.clientOverTls() || !cfg.serverTlsFile().empty() ;
313 GSsl::Library ssl( ssl_active , cfg.serverTlsFile() , cfg.tlsConfig() ) ;
314 if( ssl_active && !ssl.enabled() )
315 throw G::Exception( "cannot do tls/ssl: openssl not built in: remove tls options from the command-line or rebuild the emailrelay executable with openssl" ) ;
316
317 // network monitor singleton
318 //
319 GNet::Monitor monitor ;
320 monitor.signal().connect( G::slot(*this,&Run::raiseNetworkEvent) ) ;
321
322 // message store singletons
323 //
324 m_store <<= new GSmtp::FileStore( cfg.spoolDir() , false , cfg.maxSize() ) ;
325 m_store->signal().connect( G::slot(*this,&Run::raiseStoreEvent) ) ;
326 GPop::Store pop_store( cfg.spoolDir() , cfg.popByName() , ! cfg.popNoDelete() ) ;
327
328 // authentication secrets
329 //
330 m_client_secrets <<= new GAuth::Secrets( cfg.clientSecretsFile() , "client" ) ;
331 GAuth::Secrets server_secrets( cfg.serverSecretsFile() , "server" ) ;
332 if( cfg.doPop() )
333 m_pop_secrets <<= new GPop::Secrets( cfg.popSecretsFile() ) ;
334
335 // daemonise
336 //
337 G::PidFile pid_file ;
338 if( cfg.usePidFile() ) pid_file.init( G::Path(cfg.pidFile()) ) ;
339 if( cfg.daemon() ) G::Daemon::detach( pid_file ) ;
340
341 // run as forwarding agent
342 //
343 if( cfg.doForwardingOnStartup() )
344 {
345 if( m_store->empty() )
346 cl().showNoop( true ) ;
347 else
348 doForwardingOnStartup( *m_store.get() , *m_client_secrets.get() , *event_loop.get() ) ;
349 }
350
351 // run as storage daemon
352 //
353 if( cfg.doServing() )
354 {
355 doServing( *m_client_secrets.get() , *m_store.get() , server_secrets ,
356 pop_store , *m_pop_secrets.get() , pid_file , *event_loop.get() ) ;
357 }
358 }
359
360 void Main::Run::doServing( const GAuth::Secrets & client_secrets ,
361 GSmtp::MessageStore & store , const GAuth::Secrets & server_secrets ,
362 GPop::Store & pop_store , const GPop::Secrets & pop_secrets ,
363 G::PidFile & pid_file , GNet::EventLoop & event_loop )
364 {
365 const Configuration & cfg = config() ;
366 if( cfg.doSmtp() )
367 {
368 if( cfg.immediate() )
369 G_WARNING( "Run::doServing: using --immediate can result in client timeout errors: try --poll=0 instead" ) ;
370
371 m_smtp_server <<= new GSmtp::Server(
372 store ,
373 client_secrets ,
374 server_secrets ,
375 serverConfig() ,
376 cfg.immediate() ? cfg.serverAddress() : std::string() ,
377 cfg.connectionTimeout() ,
378 clientConfig() ) ;
379
380 m_smtp_server->eventSignal().connect( G::slot(*this,&Run::serverEvent) ) ;
381 }
382
383 #ifndef USE_NO_POP
384 std::auto_ptr<GPop::Server> pop_server ;
385 if( cfg.doPop() )
386 {
387 pop_server <<= new GPop::Server( pop_store , pop_secrets , popConfig() ) ;
388 }
389 #endif
390
391 #ifndef USE_NO_ADMIN
392 if( cfg.doAdmin() )
393 {
394 std::auto_ptr<GSmtp::AdminServer> admin_server = Admin::newServer( cfg , store , clientConfig() ,
395 client_secrets , versionNumber() ) ;
396 m_admin_server <<= admin_server.release() ;
397 }
398 #endif
399
400 if( cfg.doPolling() )
401 {
402 m_poll_timer <<= new GNet::Timer<Run>(*this,&Run::onPollTimeout,*this) ;
403 m_poll_timer->startTimer( cfg.pollingTimeout() ) ;
404 }
405
406 if( cfg.forwardingOnStore() || cfg.forwardingOnDisconnect() )
407 {
408 m_forwarding_timer <<= new GNet::Timer<Run>(*this,&Run::onForwardingTimeout,*this) ;
409 }
410
411 {
412 // dont change the effective group id here -- create the pid file with the
413 // unprivileged group ownership so that it can be deleted more easily
414 G::Root claim_root(false) ;
415 pid_file.commit() ;
416 }
417
418 closeMoreFiles() ;
419 if( m_smtp_server.get() ) m_smtp_server->report() ;
420 if( m_admin_server.get() ) Admin::report( *m_admin_server.get() ) ;
421 #ifndef USE_NO_POP
422 if( pop_server.get() ) pop_server->report() ;
423 #endif
424
425 event_loop.run() ;
426
427 if( m_smtp_server.get() ) m_smtp_server->eventSignal().disconnect() ;
428 m_smtp_server <<= 0 ;
429 m_admin_server <<= 0 ;
430 }
431
432 void Main::Run::doForwardingOnStartup( GSmtp::MessageStore & store , const GAuth::Secrets & secrets ,
433 GNet::EventLoop & event_loop )
434 {
435 const Configuration & cfg = config() ;
436
437 GNet::ClientPtr<GSmtp::Client> client_ptr( new GSmtp::Client(
438 GNet::ResolverInfo(cfg.serverAddress()) , secrets , clientConfig() ) ) ;
439
440 client_ptr->sendMessagesFrom( store ) ; // once connected
441
442 // quit() the event loop when all done so that run() returns
443 client_ptr.doneSignal().connect( G::slot(*this,&Run::forwardingClientDone) ) ;
444
445 // emit progress events
446 client_ptr.eventSignal().connect( G::slot(*this,&Run::clientEvent) ) ;
447
448 closeMoreFiles() ;
449 std::string quit_reason = event_loop.run() ;
450 if( !quit_reason.empty() )
451 cl().showError( quit_reason ) ;
452 }
453
454 GSmtp::Server::Config Main::Run::serverConfig() const
455 {
456 const Configuration & cfg = config() ;
457 return
458 GSmtp::Server::Config(
459 cfg.allowRemoteClients() ,
460 cfg.port() ,
461 GNet::MultiServer::addressList( cfg.listeningInterfaces("smtp") , cfg.port() ) ,
462 smtpIdent() ,
463 cfg.anonymous() ,
464 cfg.filter() ,
465 cfg.filterTimeout() ,
466 cfg.verifier() ,
467 cfg.filterTimeout() , // verifier timeout - re-use filter timeout value
468 cfg.peerLookup() ) ; // use connection table to get username of local peers
469 }
470
471 #ifndef USE_NO_POP
472 GPop::Server::Config Main::Run::popConfig() const
473 {
474 const Configuration & cfg = config() ;
475 return GPop::Server::Config( cfg.allowRemoteClients() , cfg.popPort() , cfg.listeningInterfaces("pop") ) ;
476 }
477 #endif
478
479 GSmtp::Client::Config Main::Run::clientConfig() const
480 {
481 const Configuration & cfg = config() ;
482
483 return
484 GSmtp::Client::Config(
485 cfg.clientFilter() ,
486 cfg.filterTimeout() ,
487 clientBindAddress(cfg.clientInterface()) ,
488 GSmtp::ClientProtocol::Config(
489 GNet::Local::fqdn() ,
490 cfg.responseTimeout() ,
491 cfg.promptTimeout() , // waiting for "service ready"
492 cfg.filterTimeout() ,
493 true , // (must-authenticate)
494 true , // (must-accept-all-recipients)
495 false ) , // (eight-bit-strict)
496 cfg.connectionTimeout() ,
497 cfg.secureConnectionTimeout() ,
498 cfg.clientOverTls() ) ;
499 }
500
501 GNet::Address Main::Run::clientBindAddress( const std::string & s )
502 {
503 return s.empty() ?
504 GNet::Address(0U) : (
505 GNet::Address::validString( s ) ?
506 GNet::Address( s ) :
507 GNet::Address( s , 0U ) ) ;
508 }
509
510 void Main::Run::onException( std::exception & e )
511 {
512 // gets here if onTimeout() throws
513 G_ERROR( "Main::Run::onException: exception while forwarding: " << e.what() ) ;
514 }
515
516 void Main::Run::onPollTimeout()
517 {
518 G_DEBUG( "Main::Run::onPollTimeout" ) ;
519 m_poll_timer->startTimer( config().pollingTimeout() ) ;
520 doForwarding( "poll" ) ;
521 }
522
523 void Main::Run::onForwardingTimeout()
524 {
525 G_DEBUG( "Main::Run::onForwardingTimeout" ) ;
526 doForwarding( "forward" ) ;
527 }
528
529 void Main::Run::doForwarding( const std::string & event_key )
530 {
531 if( m_client.busy() )
532 {
533 G_LOG( "Main::Run::doForwarding: " << event_key << ": still busy from last time" ) ;
534 emit( event_key , "busy" , "" ) ;
535 }
536 else
537 {
538 emit( event_key , "start" , "" ) ;
539 std::string error = doForwardingCore() ;
540 emit( event_key , "end" , error ) ;
541 }
542 }
543
544 std::string Main::Run::doForwardingCore()
545 {
546 try
547 {
548 const Configuration & cfg = config() ;
549
550 G_DEBUG( "Main::Run::doForwarding: polling" ) ;
551 if( cfg.pollingLog() )
552 G_LOG( "Main::Run::doForwarding: polling" ) ;
553
554 if( ! m_store->empty() )
555 {
556 m_client.reset( new GSmtp::Client( GNet::ResolverInfo(cfg.serverAddress()) ,
557 *m_client_secrets.get() , clientConfig() ) ) ;
558
559 m_client->sendMessagesFrom( *m_store.get() ) ; // once connected
560 }
561 return std::string() ;
562 }
563 catch( std::exception & e )
564 {
565 G_ERROR( "Main::Run::doForwarding: polling: " << e.what() ) ;
566 return e.what() ;
567 }
568 }
569
570 const Main::CommandLine & Main::Run::cl() const
571 {
572 // lazy evaluation so that the constructor doesnt throw
573 if( m_cl.get() == NULL )
574 {
575 const_cast<Run*>(this)->m_cl <<= new CommandLine( m_output , m_arg , m_switch_spec , versionNumber() , capabilities() ) ;
576 const_cast<Run*>(this)->m_cfg <<= new Configuration( cl().cfg() ) ;
577 }
578 return *m_cl.get() ;
579 }
580
581 void Main::Run::forwardingClientDone( std::string reason , bool )
582 {
583 G_DEBUG( "Main::Run::forwardingClientDone: \"" << reason << "\"" ) ;
584 GNet::EventLoop::instance().quit( reason ) ;
585 }
586
587 void Main::Run::pollingClientDone( std::string reason , bool )
588 {
589 G_DEBUG( "Main::Run::pollingClientDone: \"" << reason << "\"" ) ;
590 if( ! reason.empty() )
591 {
592 G_ERROR( "Main::Run::pollingClientDone: polling: " << reason ) ;
593 }
594 }
595
596 void Main::Run::clientEvent( std::string s1 , std::string s2 )
597 {
598 emit( "client" , s1 , s2 ) ;
599 }
600
601 void Main::Run::serverEvent( std::string s1 , std::string )
602 {
603 if( s1 == "done" && config().forwardingOnDisconnect() )
604 {
605 G_ASSERT( m_forwarding_timer.get() != NULL ) ;
606 m_forwarding_timer->cancelTimer() ;
607 m_forwarding_timer->startTimer( 0U ) ;
608 }
609 }
610
611 void Main::Run::raiseStoreEvent( bool repoll )
612 {
613 emit( "store" , "update" , repoll ? std::string("poll") : std::string() ) ;
614
615 const bool expiry_forced_by_filter = repoll ;
616 if( config().doPolling() && expiry_forced_by_filter )
617 {
618 G_ASSERT( m_poll_timer.get() != NULL ) ;
619 m_poll_timer->cancelTimer() ;
620 m_poll_timer->startTimer( 0U ) ;
621 }
622
623 if( config().forwardingOnStore() )
624 {
625 G_ASSERT( m_forwarding_timer.get() != NULL ) ;
626 m_forwarding_timer->cancelTimer() ;
627 m_forwarding_timer->startTimer( 0U ) ;
628 }
629 }
630
631 void Main::Run::raiseNetworkEvent( std::string s1 , std::string s2 )
632 {
633 emit( "network" , s1 , s2 ) ;
634 }
635
636 void Main::Run::emit( const std::string & s0 , const std::string & s1 , const std::string & s2 )
637 {
638 #ifndef USE_NO_ADMIN
639 try
640 {
641 m_signal.emit( s0 , s1 , s2 ) ;
642 if( m_admin_server.get() != NULL )
643 {
644 Admin::notify( *m_admin_server.get() , s0 , s1 , s2 ) ;
645 }
646 }
647 catch( std::exception & e )
648 {
649 G_WARNING( "Main::Run::emit: " << e.what() ) ;
650 }
651 #endif
652 }
653
654 G::Signal3<std::string,std::string,std::string> & Main::Run::signal()
655 {
656 return m_signal ;
657 }
658
659 #ifndef USE_NO_EXEC
660 void Main::Run::checkScripts() const
661 {
662 const Configuration & cfg = config() ;
663 checkProcessorScript( cfg.filter() ) ;
664 checkProcessorScript( cfg.clientFilter() ) ;
665 checkVerifierScript( cfg.verifier() ) ;
666 }
667 void Main::Run::checkVerifierScript( const std::string & s ) const
668 {
669 std::string reason = GSmtp::VerifierFactory::check( s ) ;
670 if( !reason.empty() )
671 {
672 G_WARNING( "Main::Run::checkScript: invalid verifier \"" << s << "\": " << reason ) ;
673 }
674 }
675 void Main::Run::checkProcessorScript( const std::string & s ) const
676 {
677 std::string reason = GSmtp::ProcessorFactory::check( s ) ;
678 if( !reason.empty() )
679 {
680 G_WARNING( "Main::Run::checkScript: invalid preprocessor \"" << s << "\": " << reason ) ;
681 }
682 }
683 #endif
684
G::PidFile::init
void init(const Path &pid_file_path)
Used after default construction.
Definition: gpidfile.cpp:46
GNet::MultiServer::addressList
static AddressList addressList(const Address &)
A trivial convenience fuction that returns the given addresses as a single-element list...
Definition: gmultiserver.cpp:41
G::Process::Umask::Tightest
Definition: gprocess.h:66
Main::Run::prepare
bool prepare()
Prepares to run() typically by parsing the commandline.
Definition: run.cpp:150
gssl.h
Main::Configuration::clientOverTls
bool clientOverTls() const
Returns true if using the SMTP over TLS (vs.
Definition: configuration.cpp:294
G::Signal1::connect
void connect(Slot1< P > slot)
Definition: gslot.h:221
Main::Configuration::verifier
std::string verifier() const
Returns the path of an external address verifier program.
Definition: configuration.cpp:344
GNet::Server::canBind
static bool canBind(const Address &listening_address, bool do_throw)
Checks that the specified address can be bound.
Definition: gserver.cpp:172
GPop::Secrets
A simple interface to a store of secrets as used in authentication.
Definition: gpopsecrets.h:44
Main::Run::run
void run()
Runs the application.
Definition: run.cpp:247
gadminserver.h
gsmtpserver.h
Main::Configuration::filter
std::string filter() const
Returns the path to a server-side pre-processor.
Definition: configuration.cpp:264
GNet
Network classes.
GSmtp::FileStore::signal
virtual G::Signal1< bool > & signal()
Final override from GSmtp::MessageStore.
Definition: gfilestore.cpp:269
Main::Configuration::doServing
bool doServing() const
Returns true if running as a server (SMTP, POP, admin or COM).
Definition: configuration.cpp:160
Main::Configuration::daemon
bool daemon() const
Returns true if running as a daemon.
Definition: configuration.cpp:133
G::Strings
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
Main::Run::Run
Run(Output &output, const G::Arg &arg, const std::string &switch_spec)
Constructor. Tries not to throw.
Definition: run.cpp:72
G::LogOutput::Mail
Definition: glogoutput.h:44
Main::Configuration::popNoDelete
bool popNoDelete() const
Returns true if pop deletion is to be disabled.
Definition: configuration.cpp:229
Main::Run::config
const Configuration & config() const
Returns a configuration object.
Definition: run.cpp:119
G::Process::closeStderr
static void closeStderr()
Closes stderr.
Definition: gprocess_unix.cpp:63
GNet::EventLoop
An abstract base class for a singleton that keeps track of open sockets and their associated handlers...
Definition: geventloop.h:51
GNet::Address
The Address class encapsulates an IP transport address.
Definition: gaddress.h:48
Main::Run::hidden
bool hidden() const
Returns true if the program should run in hidden mode.
Definition: run.cpp:145
GNet::Local::fqdn
static std::string fqdn()
Returns the fully-qualified-domain-name.
Definition: glocal.cpp:67
GNet::ClientPtr::eventSignal
G::Signal2< std::string, std::string > & eventSignal()
Returns a signal which indicates something interesting.
Definition: gclientptr.h:223
G::Root
A class which acquires the process's special privileges on construction and releases them on destruct...
Definition: groot.h:49
G::slot
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
Definition: gslot.h:156
GNet::ResolverInfo
A class that holds a host/service name pair and optionally the results of a name-to-address lookup...
Definition: gresolverinfo.h:48
G_CAPABILITIES
#define G_CAPABILITIES
Definition: run.cpp:59
GNet::Monitor::signal
G::Signal2< std::string, std::string > & signal()
Provides a callback signal which can be connect()ed to a slot.
Definition: gmonitor.cpp:110
GSmtp::ClientProtocol::Config
A structure containing GSmtp::ClientProtocol configuration parameters.
Definition: gclientprotocol.h:193
Main::Configuration::spoolDir
G::Path spoolDir() const
Returns the spool directory.
Definition: configuration.cpp:138
GNet::TimerList
A singleton which maintains a list of all Timer objects, and interfaces to the event loop on their be...
Definition: gtimerlist.h:42
gslot.h
groot.h
geventloop.h
gtest.h
GPop::Server::Config
A structure containing GPop::Server configuration parameters.
Definition: gpopserver.h:101
Main::Configuration::useSyslog
bool useSyslog() const
Returns true if generating syslog events.
Definition: configuration.cpp:55
glogoutput.h
gmultiserver.h
GPop::Store
A message store.
Definition: gpopstore.h:46
Main::Output
An abstract interface for generating output on a command-line or a GUI.
Definition: output.h:38
garg.h
GSmtp::Server::eventSignal
G::Signal2< std::string, std::string > & eventSignal()
Returns a signal that indicates that something has happened.
Definition: gsmtpserver.cpp:162
Main::Configuration::verbose
bool verbose() const
Returns true if doing verbose logging.
Definition: configuration.cpp:45
Main::Configuration::serverTlsFile
std::string serverTlsFile() const
Returns the tls certificate file if the server should support tls.
Definition: configuration.cpp:304
GPop::Server
A POP server class.
Definition: gpopserver.h:96
GSmtp::Server::Config
A structure containing GSmtp::Server configuration parameters.
Definition: gsmtpserver.h:99
gpidfile.h
Main::Configuration::debug
bool debug() const
Returns true if doing debug-level logging.
Definition: configuration.cpp:50
G_ASSERT
#define G_ASSERT(test)
Definition: gassert.h:30
Main::Run::~Run
virtual ~Run()
Destructor.
Definition: run.cpp:83
gsecrets.h
gfilestore.h
GNet::EventLoop::run
virtual std::string run()=0
Runs the main event loop.
GSmtp::MessageStore
A class which allows SMTP messages (envelope+content) to be stored and retrieved. ...
Definition: gmessagestore.h:45
GAuth::Secrets
A simple interface to a store of secrets as used in authentication.
Definition: gsecrets.h:44
Main::Configuration::serverSecretsFile
std::string serverSecretsFile() const
Returns the server-side autentication secrets (password) file.
Definition: configuration.cpp:314
run.h
admin.h
GNet::Address::length
socklen_t length() const
Returns the size of the sockaddr address.
Definition: gaddress_ipv4.cpp:606
GNet::Monitor
A singleton for monitoring SimpleClient and ServerPeer connections.
Definition: gmonitor.h:43
Main::Admin::newServer
static std::auto_ptr< GSmtp::AdminServer > newServer(const Configuration &, GSmtp::MessageStore &store, const GSmtp::Client::Config &, const GAuth::Secrets &client_secrets, const std::string &version_number)
A factory function for creating a new GSmtp::AdminServer instance on the heap.
Definition: admin_enabled.cpp:32
GSmtp::VerifierFactory::check
static std::string check(const std::string &address)
Checks an address.
Definition: gverifierfactory_exec_enabled.cpp:30
G_ERROR
#define G_ERROR(expr)
Definition: glog.h:108
Main::Run::prepareError
bool prepareError() const
Returns true if prepare() failed.
Definition: run.cpp:114
G_LOG
#define G_LOG(expr)
Definition: glog.h:98
Main::Configuration::nobody
std::string nobody() const
Returns the name of an unprivileged user.
Definition: configuration.cpp:339
Main::CommandLine
A class which deals with the command-line interface to the process, both input and output...
Definition: commandline.h:44
Main::Configuration::log
bool log() const
Returns true if doing logging.
Definition: configuration.cpp:36
GSmtp::Server
An SMTP server class.
Definition: gsmtpserver.h:92
gfile.h
G::PidFile::commit
void commit()
Creates the file.
Definition: gpidfile.cpp:98
legal.h
gprocess.h
GNet::ClientPtr::doneSignal
G::Signal2< std::string, bool > & doneSignal()
Returns a signal which indicates that client processing is complete and the client instance has delet...
Definition: gclientptr.h:217
Main::Configuration::fqdn
std::string fqdn(std::string default_=std::string()) const
Returns the fully-qualified-domain-name override.
Definition: configuration.cpp:334
G_DEBUG
#define G_DEBUG(expr)
Definition: glog.h:95
Main::Configuration::logFile
std::string logFile() const
Returns the path of a stderr replacement for logging.
Definition: configuration.cpp:67
GSmtp::Client::Config
A structure containing GSmtp::Client configuration parameters.
Definition: gsmtpclient.h:61
Main::Configuration::maxSize
unsigned int maxSize() const
Returns the maximum size of submitted messages, or zero.
Definition: configuration.cpp:354
Main::Configuration::clientFilter
std::string clientFilter() const
Returns the path to a client-side pre-processor.
Definition: configuration.cpp:269
gmonitor.h
Main::Configuration::pidFile
std::string pidFile() const
Returns the pid file's path.
Definition: configuration.cpp:254
GSmtp::Client
A class which acts as an SMTP client, extracting messages from a message store and forwarding them to...
Definition: gsmtpclient.h:55
Main::Run::onException
virtual void onException(std::exception &)
Final override from GNet::EventHandler.
Definition: run.cpp:510
gexception.h
G::Signal3< std::string, std::string, std::string >
G::LogOutput
Controls and implements low-level logging output, as used by the Log interface.
Definition: glogoutput.h:41
gprocessorfactory.h
Main::Run::versionNumber
static std::string versionNumber()
Returns the application version number string.
Definition: run.cpp:67
gdaemon.h
Main::Configuration::logTimestamp
bool logTimestamp() const
Returns true if logging output should be timestamped.
Definition: configuration.cpp:62
G::Exception
A general-purpose exception class derived from std::exception and containing a std::string.
Definition: gexception.h:44
gpath.h
Main::Configuration::popByName
bool popByName() const
Returns true if the pop spool directory is modified according to the client name. ...
Definition: configuration.cpp:224
GSmtp::FileStore
A concrete implementation of the MessageStore interface dealing in paired flat files and with an opti...
Definition: gfilestore.h:62
Main::Admin::report
static void report(const GSmtp::AdminServer &server)
Calls report() on the given server.
Definition: admin_enabled.cpp:71
glocal.h
GNet::ClientPtr< GSmtp::Client >
GSsl::Library
A RAII class for initialising the underlying ssl library.
Definition: gssl.h:147
G::Daemon::detach
static void detach()
Detaches from the parent environment.
Definition: gdaemon_unix.cpp:32
Main::Configuration::doForwardingOnStartup
bool doForwardingOnStartup() const
Returns true if running as a client.
Definition: configuration.cpp:155
GSmtp::ProcessorFactory::check
static std::string check(const std::string &address)
Checks an address.
Definition: gprocessorfactory_exec_enabled.cpp:32
gverifierfactory.h
G::Arg
A class which holds a represention of the argc/argv command line array, and supports simple command-l...
Definition: garg.h:46
GNet::EventLoop::create
static EventLoop * create()
A factory method which creates an instance of a derived class on the heap.
Definition: geventloop_unix.cpp:204
gsmtp.h
gsmtpclient.h
G::Process::closeFiles
static void closeFiles(bool keep_stderr=false)
Closes all open file descriptors.
Definition: gprocess_unix.cpp:70
Main::Configuration::tlsConfig
unsigned int tlsConfig() const
Returns TLS configuration flags.
Definition: configuration.cpp:299
gnewfile.h
gpopserver.h
Main::Configuration::clientSecretsFile
std::string clientSecretsFile() const
Returns the client-side autentication secrets (password) file.
Definition: configuration.cpp:284
G::PidFile
A class for creating pid files.
Definition: gpidfile.h:56
G::Signal2::connect
void connect(Slot2< P1, P2 > slot)
Definition: gslot.h:295
Main::Run::signal
G::Signal3< std::string, std::string, std::string > & signal()
Provides a signal which is activated when something changes.
Definition: run.cpp:654
gmemory.h
Main::Configuration::usePidFile
bool usePidFile() const
Returns true if writing a pid file.
Definition: configuration.cpp:249
G::Root::init
static void init(const std::string &nobody)
Initialises this class on process start-up by releasing root or suid privileges.
Definition: groot.cpp:74
G::Path
A Path object represents a file system path.
Definition: gpath.h:44
Main::Configuration
An interface for returning application configuration information.
Definition: configuration.h:45
GNet::EventLoop::instance
static EventLoop & instance()
Returns a reference to an instance of the class, if any.
Definition: geventloop.cpp:43
GNet::EventLoop::quit
virtual void quit(std::string reason)=0
Causes run() to return (once the call stack has unwound).
Main::Configuration::doPop
bool doPop() const
Returns true if listening for pop connections.
Definition: configuration.cpp:219
G_WARNING
#define G_WARNING(expr)
Definition: glog.h:107
gdebug.h
Main::Admin::notify
static void notify(GSmtp::AdminServer &server, const std::string &, const std::string &, const std::string &)
Calls notify() on the given server.
Definition: admin_enabled.cpp:65
G::Process::Umask::set
static void set(Mode)
Definition: gprocess_unix.cpp:282
Main::Configuration::clientTls
bool clientTls() const
Returns true if the client protocol should take account of the server's tls capability.
Definition: configuration.cpp:289
Main::Configuration::popSecretsFile
std::string popSecretsFile() const
Returns the pop-server autentication secrets (password) file.
Definition: configuration.cpp:309