55 G_LOG(
"GSmtp::NewMessage: content file: " << m_content_path ) ;
56 std::auto_ptr<std::ostream> content_stream = m_store.
stream( m_content_path ) ;
57 m_content = content_stream ;
64 G_DEBUG(
"GSmtp::NewFile::dtor: " << m_content_path ) ;
73 void GSmtp::NewFile::cleanup()
84 const std::string & peer_socket_name ,
const std::string & peer_certificate )
92 m_envelope_path_0 = m_store.envelopeWorkingPath( m_seq ) ;
93 m_envelope_path_1 = m_store.envelopePath( m_seq ) ;
94 if( ! saveEnvelope( auth_id , peer_socket_address , peer_socket_name , peer_certificate ) )
95 throw GSmtp::MessageStore::StorageError( std::string() +
"cannot write " + m_envelope_path_0.str() ) ;
99 if( m_to_local.size() != 0U )
101 deliver( m_to_local , m_content_path , m_envelope_path_0 , m_envelope_path_1 ) ;
104 return m_content_path.str() ;
109 bool ok = commitEnvelope() ;
112 throw GSmtp::MessageStore::StorageError( std::string() +
"cannot rename to " + m_envelope_path_1.str() ) ;
118 m_to_local.push_back( to ) ;
120 m_to_remote.push_back( to ) ;
125 m_size += ( line.size() + 2U ) ;
127 m_eight_bit = isEightBit( line ) ;
129 *(m_content.get()) << line << crlf() ;
130 return m_max_size == 0UL || m_size < m_max_size ;
133 void GSmtp::NewFile::flushContent()
135 G_ASSERT( m_content.get() != NULL ) ;
137 if( ! m_content->good() )
138 throw GSmtp::MessageStore::WriteError( m_content_path.str() ) ;
142 void GSmtp::NewFile::discardContent()
147 void GSmtp::NewFile::deleteContent()
149 FileWriter claim_writer ;
153 void GSmtp::NewFile::deleteEnvelope()
155 if( ! m_envelope_path_0.str().empty() )
157 FileWriter claim_writer ;
164 struct EightBit : std::unary_function<char,bool>
166 bool operator()(
char c ) {
return !! (
static_cast<unsigned char>(c) & 0x80U ) ; }
170 bool GSmtp::NewFile::isEightBit(
const std::string & line )
172 return std::find_if( line.begin() , line.end() , EightBit() ) != line.end() ;
175 bool GSmtp::NewFile::saveEnvelope(
const std::string & auth_id ,
const std::string & peer_socket_address ,
176 const std::string & peer_socket_name ,
const std::string & peer_certificate )
const
178 std::auto_ptr<std::ostream> envelope_stream = m_store.stream( m_envelope_path_0 ) ;
179 writeEnvelope( *(envelope_stream.get()) , m_envelope_path_0.str() ,
180 auth_id , peer_socket_address , peer_socket_name , peer_certificate ) ;
181 bool ok = envelope_stream->good() ;
185 bool GSmtp::NewFile::commitEnvelope()
187 FileWriter claim_writer ;
192 void GSmtp::NewFile::deliver(
const G::Strings & ,
193 const G::Path & content_path ,
const G::Path & envelope_path_now ,
194 const G::Path & envelope_path_later )
199 G_LOG_S(
"GSmtp::NewMessage: copying message for local recipient(s): "
200 << content_path.
basename() <<
".local" ) ;
202 FileWriter claim_writer ;
207 void GSmtp::NewFile::writeEnvelope( std::ostream & stream ,
const std::string & where ,
208 const std::string & auth_id ,
const std::string & peer_socket_address ,
209 const std::string & peer_socket_name ,
const std::string & peer_certificate_in )
const
211 G_LOG(
"GSmtp::NewMessage: envelope file: " << where ) ;
213 std::string peer_certificate = peer_certificate_in ;
216 const std::string x( m_store.x() ) ;
218 stream << x <<
"Format: " << m_store.format() << crlf() ;
219 stream << x <<
"Content: " << (m_eight_bit?
"8":
"7") <<
"bit" << crlf() ;
220 stream << x <<
"From: " << m_from << crlf() ;
221 stream << x <<
"ToCount: " << (m_to_local.size()+m_to_remote.size()) << crlf() ;
223 G::Strings::const_iterator to_p = m_to_local.begin() ;
224 for( ; to_p != m_to_local.end() ; ++to_p )
225 stream << x <<
"To-Local: " << *to_p << crlf() ;
228 G::Strings::const_iterator to_p = m_to_remote.begin() ;
229 for( ; to_p != m_to_remote.end() ; ++to_p )
230 stream << x <<
"To-Remote: " << *to_p << crlf() ;
233 stream << x <<
"Client: " << peer_socket_address << crlf() ;
234 stream << x <<
"ClientName: " <<
G::Xtext::encode(peer_socket_name) << crlf() ;
235 stream << x <<
"ClientCertificate: " << peer_certificate << crlf() ;
236 stream << x <<
"End: 1" << crlf() ;
240 const std::string & GSmtp::NewFile::crlf()
const
242 static const std::string s(
"\015\012" ) ;
253 return m_content_path ;
std::string str() const
Returns the path string.
G::Path contentPath(unsigned long seq) const
Returns the path for a content file.
G::Path contentPath() const
Returns the path of the content file.
static bool copy(const Path &from, const Path &to, const NoThrow &)
Copies a file. Returns false on error.
std::string basename() const
Returns the path, excluding drive/directory parts.
std::list< std::string > Strings
A std::list of std::strings.
static std::string encode(const std::string &)
Encodes the given string.
virtual void addTo(const std::string &to, bool local)
Final override from GSmtp::NewMessage.
std::auto_ptr< std::ostream > stream(const G::Path &path)
Returns a stream to the given content.
static bool rename(const Path &from, const Path &to, const NoThrow &)
Renames the file. Returns false on error.
virtual ~NewFile()
Destructor.
NewFile(const std::string &from, FileStore &store, unsigned long max_size=0UL)
Constructor. The FileStore reference is kept.
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'...
virtual std::string prepare(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::NewMessage.
virtual void commit()
Final override from GSmtp::NewMessage.
static bool remove(const Path &path, const NoThrow &)
Deletes the file or directory. Returns false on error.
An overload discriminator class for File methods.
virtual unsigned long id() const
Final override from GSmtp::NewMessage.
A concrete implementation of the MessageStore interface dealing in paired flat files and with an opti...
unsigned long newSeq()
Hands out a new non-zero sequence number.
virtual bool addText(const std::string &line)
Final override from GSmtp::NewMessage.
A Path object represents a file system path.