42bool GStore::FileDelivery::deliver(
const MessageId & message_id ,
bool is_new )
44 bool deleted = false ;
45 FileStore::State store_state = is_new ? FileStore::State::New : FileStore::State::Locked ;
46 G::Path envelope_path = epath( message_id , store_state ) ;
48 if( !envelope.to_local.empty() )
50 if( m_store.directory() != m_store.deliveryDir() )
52 G_LOG(
"GStore::FileDelivery::deliver: delivery: delivering " << message_id.
str() <<
" to "
53 "[" << m_store.deliveryDir() <<
"/<mbox>]" ) ;
56 deleted = deliverToMailboxes( m_store.deliveryDir() , envelope , envelope_path , cpath(message_id) ) ;
61bool GStore::FileDelivery::deliverToMailboxes(
const G::Path & delivery_dir ,
const Envelope & envelope ,
64 G_ASSERT( !envelope.to_local.empty() ) ;
70 for(
const auto & mailbox : mailbox_list )
73 G::Path mbox_dir = delivery_dir + mailbox ;
74 if( !FileOp::isdir(mbox_dir) )
76 G_LOG(
"GStore::FileDelivery::deliverToMailboxes: delivery: creating mailbox [" << mailbox <<
"]" ) ;
77 if( !FileOp::mkdir( mbox_dir ) )
82 deliverTo( m_store ,
"deliver" , mbox_dir , envelope_path , content_path , m_config.hardlink ) ;
86 if( envelope.to_remote.empty() && !m_config.no_delete )
88 FileOp::remove( content_path ) ;
89 FileOp::remove( envelope_path ) ;
100 bool hardlink ,
bool pop_by_name )
102 if( FileOp::isdir( dst_dir+
"tmp" , dst_dir+
"cur" , dst_dir+
"new" ) )
106 std::ostringstream ss ;
108 G::Path tmp_content_path = dst_dir +
"tmp" + ss.
str() ;
109 G::Path new_content_path = dst_dir +
"new" + ss.
str() ;
110 if( !FileOp::copy( content_path , tmp_content_path , hardlink ) )
112 if( !FileOp::rename( tmp_content_path , new_content_path ) )
114 G_DEBUG(
"GStore::FileDelivery::deliverTo: delivery: delivered " <<
id(envelope_path) <<
" as maildir " << ss.str() ) ;
116 else if( pop_by_name )
120 G::Path new_envelope_path = dst_dir + (new_filename+
".envelope") ;
121 if( !FileOp::copy( envelope_path , new_envelope_path ) )
127 G::Path new_content_path = dst_dir + (new_filename+
".content") ;
128 G::Path new_envelope_path = dst_dir + (new_filename+
".envelope") ;
129 G::ScopeExit clean_up_content( [new_content_path](){FileOp::remove(new_content_path);} ) ;
132 bool ok = FileOp::copy( content_path , new_content_path , hardlink ) ;
137 if( !FileOp::copy( envelope_path , new_envelope_path ) )
138 throw EnvelopeWriteError( prefix , new_envelope_path.str() ,
G::Process::strerror(FileOp::errno_()) ) ;
140 clean_up_content.release() ;
141 G_DEBUG(
"GStore::FileDelivery::deliver: " << prefix <<
": delivered " <<
id(envelope_path) <<
" to mailbox " << dst_dir.
basename() ) ;
147 G_ASSERT( !envelope.to_local.empty() ) ;
148 using namespace std::placeholders ;
150 std::transform( envelope.to_local.begin() , envelope.to_local.end() ,
151 std::back_inserter(list) , std::bind(&FileDelivery::mailbox,config,_1) ) ;
152 std::sort( list.begin() , list.end() ) ;
153 list.erase( std::unique( list.begin() , list.end() ) , list.end() ) ;
154 G_ASSERT( !list.empty() ) ;
158std::string GStore::FileDelivery::mailbox(
const Config & ,
const std::string & recipient )
164 const std::string & mailbox = recipient ;
166 G_LOG(
"GStore::FileDelivery::mailbox: delivery: recipient [" << recipient <<
"]: delivery to mailbox [" << mailbox <<
"]" ) ;
170std::string GStore::FileDelivery::id(
const G::Path & envelope_path )
175G::Path GStore::FileDelivery::epath(
const MessageId & message_id , FileStore::State store_state )
const
177 return m_store.envelopePath( message_id , store_state ) ;
180G::Path GStore::FileDelivery::cpath(
const MessageId & message_id )
const
182 return m_store.contentPath( message_id ) ;
A structure containing the contents of an envelope file, with support for file reading,...
FileDelivery(FileStore &, const Config &)
Constructor.
static void deliverTo(FileStore &, G::string_view prefix, const G::Path &dst_dir, const G::Path &envelope_path, const G::Path &content_path, bool hardlink=false, bool pop_by_name=false)
Low-level function to copy a single message into a mailbox sub-directory or a pop-by-name sub-directo...
A concrete implementation of the MessageStore interface dealing in paired flat files.
static Envelope readEnvelope(const G::Path &, std::ifstream *=nullptr)
Used by FileStore sibling classes to read an envelope file.
A somewhat opaque identifer for a GStore::MessageStore message id.
std::string str() const
Returns the id string.
A Path object represents a file system path.
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
Path withoutExtension() const
Returns a path without the basename extension, if any.
std::string str() const
Returns the path string.
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.
A class that calls an exit function at the end of its scope.
static SystemTime now()
Factory function for the current time.
A class like c++17's std::string_view.
std::vector< std::string > StringArray
A std::vector of std::strings.
std::string hostname()
Returns the hostname.
A configuration structure for GStore::FileDelivery.