51 std::unique_ptr<StoredMessage> next()
override ;
67GSmtp::FileIterator::FileIterator(
FileStore & store ,
const G::Path & dir ,
bool lock ,
bool failures ) :
72 m_iter.
readType( dir , std::string(failures?
".envelope.bad":
".envelope") ) ;
75GSmtp::FileIterator::~FileIterator()
78std::unique_ptr<GSmtp::StoredMessage> GSmtp::FileIterator::next()
80 while( m_iter.more() )
82 auto m = std::make_unique<StoredFile>( m_store , m_iter.filePath() ) ;
83 if( !m->id().valid() )
86 if( m_lock && !m->lock() )
88 G_WARNING(
"GSmtp::MessageStore: cannot lock file: \"" << m_iter.filePath() <<
"\"" ) ;
93 const bool check_recipients = m_lock ;
94 bool ok = m->readEnvelope(reason,check_recipients) && m->openContent(reason) ;
96 m->fail( reason , 0 ) ;
98 G_WARNING(
"GSmtp::MessageStore: ignoring \"" << m_iter.filePath() <<
"\": " << reason ) ;
100 return std::unique_ptr<StoredMessage>( m.release() ) ;
110 m_max_size(max_size) ,
111 m_test_for_eight_bit(test_for_eight_bit)
117 m_test_for_eight_bit = true ;
120 m_test_for_eight_bit = false ;
131 return "X-MailRelay-" ;
137 if( generation == -2 )
139 else if( generation == -1 )
148 format_in == format(0) ||
149 format_in == format(-1) ||
150 format_in == format(-2) ;
153void GSmtp::FileStore::checkPath(
const G::Path & directory_path )
163 error = dir_test.usable() ;
174 FileWriter claim_writer ;
175 ok = dir_test.writeable( tmp_filename ) ;
181 G_WARNING(
"GSmtp::MessageStore: " << format(
gettext(
"directory not writable: \"%1%\"")) % directory_path ) ;
187 return envelopePath(
id).str() ;
192 auto stream_ptr = std::make_unique<std::ofstream>() ;
207 G_ASSERT( modifier !=
nullptr ) ;
208 return m_dir +
id.str().append(
".envelope").append(modifier) ;
219 std::ostringstream ss ;
220 ss <<
"emailrelay." <<
G::Process::Id().str() <<
"." << timestamp <<
"." << m_seq ;
228 list.
readType( m_dir ,
".envelope" , 1U ) ;
229 const bool no_more = !list.
more() ;
235 return iteratorImp( lock ) ;
238std::shared_ptr<GSmtp::MessageStore::Iterator> GSmtp::FileStore::iteratorImp(
bool lock )
240 return std::make_shared<FileIterator>( *
this , m_dir , lock ,
false ) ;
245 return std::make_shared<FileIterator>( *
this , m_dir ,
false ,
true ) ;
250 G::Path path = envelopePath(
id ) ;
252 auto message = std::make_unique<StoredFile>( *
this , path ) ;
253 if( !message->lock() )
254 throw GetError( path.
str() +
": cannot lock the file" ) ;
257 const bool check_recipients = false ;
258 if( !message->readEnvelope(reason,check_recipients) )
259 throw GetError( path.
str() +
": cannot read the envelope: " + reason ) ;
261 if( !message->openContent(reason) )
262 throw GetError( path.
str() +
": cannot read the content: " + reason ) ;
264 return std::unique_ptr<StoredMessage>( message.release() ) ;
268 const std::string & from_auth_in ,
const std::string & from_auth_out )
270 return std::make_unique<NewFile>( *
this , from , from_auth_in , from_auth_out ,
271 m_max_size , m_test_for_eight_bit ) ;
276 G_DEBUG(
"GSmtp::FileStore::updated" ) ;
277 m_update_signal.emit() ;
282 return m_update_signal ;
287 return m_rescan_signal ;
290void GSmtp::FileStore::rescan()
292 messageStoreRescanSignal().emit() ;
295void GSmtp::FileStore::unfailAll()
300void GSmtp::FileStore::unfailAllImp()
302 std::shared_ptr<MessageStore::Iterator> iter( failures() ) ;
305 std::unique_ptr<StoredMessage> message = iter->next() ;
306 if( message ==
nullptr )
308 G_DEBUG(
"GSmtp::FileStore::unfailAllImp: " << message->location() ) ;
313void GSmtp::FileStore::clearAll()
316 std::shared_ptr<MessageStore::Iterator> iter( iteratorImp(
true) ) ;
319 std::unique_ptr<StoredMessage> message = iter->next() ;
347 G::Process::Umask(
G::Process::Umask::Mode::Tighter)
Used by GSmtp::FileStore, GSmtp::NewFile and GSmtp::StoredFile to claim read permissions for reading ...
~DirectoryReader()
Destructor. Switches identity back.
DirectoryReader()
Default constructor.
A GSmtp::MessageStore::Iterator for GSmtp::FileStore.
FileReader()
Default constructor.
~FileReader()
Destructor. Switches identity back.
A concrete implementation of the MessageStore interface dealing in paired flat files.
G::Slot::Signal & messageStoreRescanSignal() override
Override from GSmtp::MessageStore.
FileStore(const G::Path &dir, unsigned long max_size, bool test_for_eight_bit)
Constructor.
std::unique_ptr< StoredMessage > get(const MessageId &) override
Override from GSmtp::MessageStore.
std::shared_ptr< MessageStore::Iterator > failures() override
Override from GSmtp::MessageStore.
static bool knownFormat(const std::string &format)
Returns true if the storage format string is recognised and supported for reading.
void updated() override
Override from GSmtp::MessageStore.
std::unique_ptr< std::ofstream > stream(const G::Path &path)
Returns a stream to the given content.
G::Path contentPath(const MessageId &) const
Returns the path for a content file.
std::shared_ptr< MessageStore::Iterator > iterator(bool lock) override
Override from GSmtp::MessageStore.
std::unique_ptr< NewMessage > newMessage(const std::string &from, const std::string &from_auth_in, const std::string &from_auth_out) override
Override from GSmtp::MessageStore.
static std::string x()
Returns the prefix for envelope header lines.
G::Path envelopePath(const MessageId &, const char *modifier="") const
Returns the path for an envelope file.
static std::string format(int generation=0)
Returns an identifier for the storage format implemented by this class, or some older generation of i...
bool empty() const override
Override from GSmtp::MessageStore.
std::string location(const MessageId &) const override
Override from GSmtp::MessageStore.
G::Slot::Signal & messageStoreUpdateSignal() override
Override from GSmtp::MessageStore.
MessageId newId()
Hands out a new message id.
Used by GSmtp::FileStore, GSmtp::NewFile and GSmtp::StoredFile to claim write permissions.
~FileWriter()
Destructor. Switches identity back.
FileWriter()
Default constructor.
A somewhat opaque identifer for a MessageStore message.
A iterator similar to G::DirectoryIterator but doing all file i/o in one go.
void readType(const Path &dir, const std::string &suffix, unsigned int limit=0U)
An initialiser that is to be used after default construction.
bool more()
Returns true if more and advances by one.
An encapsulation of a file system directory that works with G::DirectoryIterator.
static std::string tmp()
A convenience function for constructing a filename for writeable().
static void open(std::ofstream &, const Path &)
Calls open() on the given output file stream.
A Path object represents a file system path.
Path withExtension(const std::string &ext) const
Returns the path with the new basename extension.
std::string str() const
Returns the path string.
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.
static SystemTime now()
Factory function for the current time.
std::time_t s() const noexcept
Returns the number of seconds since the start of the epoch.
static bool enabled() noexcept
Returns true if test features are enabled.
SMTP and message-store classes.
const char * gettext(const char *)
Returns the message translation in the current locale's codeset, eg.
A base class for GSmtp::MessageStore iterators.
A slot holder, with connect() and emit() methods.