38 const std::string & from_auth_in ,
const std::string & from_auth_out ,
39 std::size_t max_size ,
bool test_for_eight_bit ) :
43 m_test_for_eight_bit(test_for_eight_bit) ,
49 m_env.m_from_auth_in = from_auth_in ;
50 m_env.m_from_auth_out = from_auth_out ;
53 G_LOG(
"GSmtp::NewMessage: content file: " << cpath() ) ;
54 m_content = m_store.
stream( cpath() ) ;
61 G_DEBUG(
"GSmtp::NewFile::dtor: " << cpath() ) ;
69void GSmtp::NewFile::cleanup()
79bool GSmtp::NewFile::prepare(
const std::string & session_auth_id ,
const std::string & peer_socket_address ,
80 const std::string & peer_certificate )
83 G_ASSERT( m_content !=
nullptr ) ;
85 if( m_content->fail() )
86 throw FileError(
"cannot write content file " + cpath().str() ) ;
90 m_env.m_authentication = session_auth_id ;
91 m_env.m_client_socket_address = peer_socket_address ;
92 m_env.m_client_certificate = peer_certificate ;
94 throw FileError(
"cannot write envelope file " + epath(State::New).str() ) ;
97 if( !m_env.m_to_local.empty() && m_env.m_to_remote.empty() )
99 moveToLocal( cpath() , epath(State::New) , epath(State::Normal) ) ;
103 else if( !m_env.m_to_local.empty() )
105 copyToLocal( cpath() , epath(State::New) , epath(State::Normal) ) ;
114void GSmtp::NewFile::commit(
bool throw_on_error )
117 bool ok = commitEnvelope() ;
118 if( !ok && throw_on_error )
119 throw FileError(
"cannot rename envelope file to " + epath(State::Normal).str() ) ;
124void GSmtp::NewFile::addTo(
const std::string & to ,
bool local )
127 m_env.m_to_local.push_back( to ) ;
129 m_env.m_to_remote.push_back( to ) ;
132bool GSmtp::NewFile::addText(
const char * line_data , std::size_t line_size )
134 m_size +=
static_cast<unsigned long>( line_size ) ;
144 if( m_test_for_eight_bit && m_env.m_eight_bit != 1 )
145 m_env.m_eight_bit = isEightBit(line_data,line_size) ? 1 : 0 ;
147 std::ostream & stream = *m_content ;
148 stream.write( line_data , line_size ) ;
150 return m_max_size == 0UL || m_size < m_max_size ;
153void GSmtp::NewFile::discardContent()
158void GSmtp::NewFile::deleteContent()
160 FileWriter claim_writer ;
164void GSmtp::NewFile::deleteEnvelope()
166 FileWriter claim_writer ;
170bool GSmtp::NewFile::isEightBit(
const char * line_data , std::size_t line_size )
175bool GSmtp::NewFile::saveEnvelope()
177 G_LOG(
"GSmtp::NewMessage: envelope file: " << epath(State::New).basename() ) ;
178 std::unique_ptr<std::ofstream> envelope_stream = m_store.stream( epath(State::New) ) ;
180 m_env.m_crlf = true ;
181 envelope_stream->close() ;
182 return !envelope_stream->fail() ;
185bool GSmtp::NewFile::commitEnvelope()
187 FileWriter claim_writer ;
188 m_saved =
G::File::rename( epath(State::New) , epath(State::Normal) , std::nothrow ) ;
192void GSmtp::NewFile::moveToLocal(
const G::Path & content_path ,
const G::Path & envelope_path_now ,
193 const G::Path & envelope_path_later )
195 G_LOG_S(
"GSmtp::NewMessage: message for local-mailbox recipient(s): " << content_path.
basename() <<
".local" ) ;
196 FileWriter claim_writer ;
201void GSmtp::NewFile::copyToLocal(
const G::Path & content_path ,
const G::Path & envelope_path_now ,
202 const G::Path & envelope_path_later )
204 G_LOG_S(
"GSmtp::NewMessage: message for local-mailbox recipient(s): " << content_path.
basename() <<
".local" ) ;
205 FileWriter claim_writer ;
215std::string GSmtp::NewFile::location()
const
217 return cpath().str() ;
220G::Path GSmtp::NewFile::cpath()
const
222 return m_store.contentPath( m_id ) ;
225G::Path GSmtp::NewFile::epath( State state )
const
227 return state == State::Normal ?
228 m_store.envelopePath(m_id) :
229 G::Path( m_store.envelopePath(m_id).str() +
".new" ) ;
static std::size_t write(std::ostream &, const Envelope &)
Writes an envelope to a stream.
A concrete implementation of the MessageStore interface dealing in paired flat files.
std::unique_ptr< std::ofstream > stream(const G::Path &path)
Returns a stream to the given content.
A somewhat opaque identifer for a MessageStore message.
~NewFile() override
Destructor.
NewFile(FileStore &store, const std::string &from, const std::string &from_auth_in, const std::string &from_auth_out, std::size_t max_size, bool test_for_eight_bit)
Constructor. The FileStore reference is kept.
static bool rename(const Path &from, const Path &to, std::nothrow_t) noexcept
Renames the file.
static bool remove(const Path &path, std::nothrow_t) noexcept
Deletes the file or directory. Returns false on error.
static bool copy(const Path &from, const Path &to, std::nothrow_t)
Copies a file. Returns false on error.
A Path object represents a file system path.
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
std::string str() const
Returns the path string.
bool eightbit(const unsigned char *p, std::size_t n)
Returns true if the given data buffer contains a byte greater than 127.