- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gprotocolmessageforward.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 // gprotocolmessageforward.cpp
19 //
20
21 #include "gdef.h"
22 #include "gsmtp.h"
23 #include "gprotocolmessageforward.h"
24 #include "gprotocolmessagestore.h"
25 #include "gnullprocessor.h"
26 #include "gexecutableprocessor.h"
27 #include "gmessagestore.h"
28 #include "gmemory.h"
29 #include "gstr.h"
30 #include "gassert.h"
31 #include "glog.h"
32
33 GSmtp::ProtocolMessageForward::ProtocolMessageForward( MessageStore & store ,
34 std::auto_ptr<ProtocolMessage> pm ,
35 const GSmtp::Client::Config & client_config ,
36 const GAuth::Secrets & client_secrets , const std::string & server ,
37 unsigned int connection_timeout ) :
38 m_store(store) ,
39 m_client_resolver_info(server) ,
40 m_client_config(client_config) ,
41 m_client_secrets(client_secrets) ,
42 m_pm(pm) ,
43 m_client(NULL,true) ,
44 m_id(0) ,
45 m_connection_timeout(connection_timeout) ,
46 m_done_signal(true) // one-shot, but reset()able
47 {
48 // signal plumbing to receive 'done' events
49 m_pm->doneSignal().connect( G::slot(*this,&ProtocolMessageForward::processDone) ) ;
50 m_client.doneSignal().connect( G::slot(*this,&ProtocolMessageForward::clientDone) ) ;
51 }
52
53 GSmtp::ProtocolMessageForward::~ProtocolMessageForward()
54 {
55 m_pm->doneSignal().disconnect() ;
56 m_client.doneSignal().disconnect() ;
57 if( m_client.get() != NULL )
58 m_client->messageDoneSignal().disconnect() ;
59 }
60
61 G::Signal3<bool,unsigned long,std::string> & GSmtp::ProtocolMessageForward::storageDoneSignal()
62 {
63 return m_pm->doneSignal() ;
64 }
65
66 G::Signal3<bool,unsigned long,std::string> & GSmtp::ProtocolMessageForward::doneSignal()
67 {
68 return m_done_signal ;
69 }
70
71 void GSmtp::ProtocolMessageForward::reset()
72 {
73 m_pm->reset() ;
74 m_client.reset() ;
75 }
76
77 void GSmtp::ProtocolMessageForward::clear()
78 {
79 m_pm->clear() ;
80 }
81
82 bool GSmtp::ProtocolMessageForward::setFrom( const std::string & from )
83 {
84 return m_pm->setFrom( from ) ;
85 }
86
87 bool GSmtp::ProtocolMessageForward::addTo( const std::string & to , VerifierStatus to_status )
88 {
89 return m_pm->addTo( to , to_status ) ;
90 }
91
92 void GSmtp::ProtocolMessageForward::addReceived( const std::string & line )
93 {
94 m_pm->addReceived( line ) ;
95 }
96
97 bool GSmtp::ProtocolMessageForward::addText( const std::string & line )
98 {
99 return m_pm->addText( line ) ;
100 }
101
102 std::string GSmtp::ProtocolMessageForward::from() const
103 {
104 return m_pm->from() ;
105 }
106
107 void GSmtp::ProtocolMessageForward::process( const std::string & auth_id , const std::string & peer_socket_address ,
108 const std::string & peer_socket_name , const std::string & peer_certificate )
109 {
110 m_done_signal.reset() ; // one-shot reset
111 m_pm->process( auth_id , peer_socket_address , peer_socket_name , peer_certificate ) ;
112 }
113
114 void GSmtp::ProtocolMessageForward::processDone( bool success , unsigned long id , std::string reason )
115 {
116 G_DEBUG( "ProtocolMessageForward::processDone: " << (success?1:0) << ", " << id << ", \"" << reason << "\"" ) ;
117 if( success && id != 0UL )
118 {
119 m_id = id ;
120
121 // the message is now stored -- start the forwarding using the Client object
122 bool nothing_to_do = false ;
123 success = forward( id , nothing_to_do , &reason ) ;
124 if( !success || nothing_to_do )
125 {
126 // immediate failure or no recipients
127 m_done_signal.emit( success , id , reason ) ;
128 }
129 }
130 else
131 {
132 // message storage failed or cancelled
133 m_done_signal.emit( success , id , reason ) ;
134 }
135 }
136
137 bool GSmtp::ProtocolMessageForward::forward( unsigned long id , bool & nothing_to_do , std::string * reason_p )
138 {
139 try
140 {
141 nothing_to_do = false ;
142 *reason_p = std::string() ;
143 G_DEBUG( "GSmtp::ProtocolMessageForward::forward: forwarding message " << id ) ;
144
145 std::auto_ptr<StoredMessage> message = m_store.get( id ) ;
146
147 if( message->remoteRecipientCount() == 0U )
148 {
149 // use our local delivery mechanism, not the downstream server's
150 nothing_to_do = true ;
151 message->destroy() ; // (already copied to "*.local")
152 }
153 else
154 {
155 if( m_client.get() == NULL )
156 {
157 m_client.reset( new Client(m_client_resolver_info,m_client_secrets,m_client_config) ) ;
158 m_client->messageDoneSignal().connect( G::slot(*this,&GSmtp::ProtocolMessageForward::messageDone) ) ;
159 }
160 m_client->sendMessage( message ) ;
161 }
162 return true ;
163 }
164 catch( std::exception & e ) // send forwarding errors back to the remote client via the server protocol
165 {
166 if( reason_p != NULL )
167 {
168 G_DEBUG( "GSmtp::ProtocolMessageForward::forward: exception" ) ;
169 *reason_p = e.what() ;
170 }
171 return false ;
172 }
173 }
174
175 void GSmtp::ProtocolMessageForward::messageDone( std::string reason )
176 {
177 G_DEBUG( "GSmtp::ProtocolMessageForward::clientDone: \"" << reason << "\"" ) ;
178 const bool ok = reason.empty() ;
179 m_done_signal.emit( ok , m_id , reason ) ; // one-shot
180 }
181
182 void GSmtp::ProtocolMessageForward::clientDone( std::string reason , bool )
183 {
184 G_DEBUG( "GSmtp::ProtocolMessageForward::clientDone: \"" << reason << "\"" ) ;
185 const bool ok = reason.empty() ;
186 m_done_signal.emit( ok , m_id , reason ) ; // one-shot
187 }
188
gprotocolmessagestore.h
GSmtp::ProtocolMessageForward::storageDoneSignal
G::Signal3< bool, unsigned long, std::string > & storageDoneSignal()
Returns the signal which is used to signal that the storage is complete.
Definition: gprotocolmessageforward.cpp:61
GSmtp::ProtocolMessageForward::addText
virtual bool addText(const std::string &)
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:97
GSmtp::ProtocolMessageForward::processDone
void processDone(bool, unsigned long, std::string)
Called by derived classes that have intercepted the storageDoneSignal() when their own post-storage p...
Definition: gprotocolmessageforward.cpp:114
GSmtp::ProtocolMessageForward::clear
virtual void clear()
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:77
glog.h
GSmtp::ProtocolMessageForward::addReceived
virtual void addReceived(const std::string &)
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:92
G::slot
Slot0 slot(T &object, void(T::*fn)())
Part of the slot/signal system.
Definition: gslot.h:156
GSmtp::ProtocolMessageForward::setFrom
virtual bool setFrom(const std::string &from_user)
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:82
gexecutableprocessor.h
gstr.h
gassert.h
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
gmessagestore.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
GSmtp::ProtocolMessageForward::ProtocolMessageForward
ProtocolMessageForward(MessageStore &store, std::auto_ptr< ProtocolMessage > pm, const GSmtp::Client::Config &client_config, const GAuth::Secrets &client_secrets, const std::string &server_address, unsigned int connection_timeout)
Constructor.
Definition: gprotocolmessageforward.cpp:33
G_DEBUG
#define G_DEBUG(expr)
Definition: glog.h:95
GSmtp::Client::Config
A structure containing GSmtp::Client configuration parameters.
Definition: gsmtpclient.h:61
G::Signal3< bool, unsigned long, std::string >
GSmtp::VerifierStatus
A structure returned by GSmtp::Verifier to describe the status of a rcpt-to recipient.
Definition: gverifierstatus.h:51
GSmtp::ProtocolMessageForward::doneSignal
virtual G::Signal3< bool, unsigned long, std::string > & doneSignal()
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:66
gsmtp.h
gprotocolmessageforward.h
gnullprocessor.h
GSmtp::ProtocolMessageForward::process
virtual void process(const std::string &auth_id, const std::string &peer_socket_address, const std::string &peer_socket_name, const std::string &peer_certificate)
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:107
G::Signal2::connect
void connect(Slot2< P1, P2 > slot)
Definition: gslot.h:295
GSmtp::ProtocolMessageForward::from
virtual std::string from() const
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:102
gmemory.h
GSmtp::ProtocolMessageForward::addTo
virtual bool addTo(const std::string &to_user, VerifierStatus to_status)
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:87
GSmtp::ProtocolMessageForward::reset
virtual void reset()
Final override from GSmtp::ProtocolMessage.
Definition: gprotocolmessageforward.cpp:71
GSmtp::ProtocolMessageForward::~ProtocolMessageForward
virtual ~ProtocolMessageForward()
Destructor.
Definition: gprotocolmessageforward.cpp:53