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 )
77 G::Path mbox_dir = delivery_dir/mailbox ;
78 if( !FileOp::isdir(mbox_dir) )
80 G_LOG(
"GStore::FileDelivery::deliverToMailboxes: delivery: creating mailbox [" << mailbox <<
"]" ) ;
81 if( !FileOp::mkdir( mbox_dir ) )
86 deliverTo( m_store ,
"deliver" , mbox_dir , envelope_path , content_path , m_config.hardlink ) ;
90 if( envelope.to_remote.empty() && !m_config.no_delete )
92 FileOp::remove( content_path ) ;
93 FileOp::remove( envelope_path ) ;
104 bool hardlink ,
bool pop_by_name )
106 if( FileOp::isdir( dst_dir/
"tmp" , dst_dir/
"cur" , dst_dir/
"new" ) )
110 std::ostringstream ss ;
112 G::Path tmp_content_path = dst_dir/
"tmp"/ss.
str() ;
113 G::Path new_content_path = dst_dir/
"new"/ss.
str() ;
114 if( !FileOp::copy( content_path , tmp_content_path , hardlink ) )
116 if( !FileOp::rename( tmp_content_path , new_content_path ) )
118 G_DEBUG(
"GStore::FileDelivery::deliverTo: delivery: delivered " <<
id(envelope_path) <<
" as maildir " << ss.str() ) ;
120 else if( pop_by_name )
124 G::Path new_envelope_path = dst_dir / (new_filename+
".envelope") ;
125 if( !FileOp::copy( envelope_path , new_envelope_path ) )
131 G::Path new_content_path = dst_dir / (new_filename+
".content") ;
132 G::Path new_envelope_path = dst_dir / (new_filename+
".envelope") ;
133 G::ScopeExit clean_up_content( [new_content_path](){FileOp::remove(new_content_path);} ) ;
136 bool ok = FileOp::copy( content_path , new_content_path , hardlink ) ;
141 if( !FileOp::copy( envelope_path , new_envelope_path ) )
144 clean_up_content.release() ;
145 G_DEBUG(
"GStore::FileDelivery::deliver: " << prefix <<
": delivered " <<
id(envelope_path) <<
" to mailbox " << dst_dir.
basename() ) ;
151 G_ASSERT( !envelope.to_local.empty() ) ;
152 using namespace std::placeholders ;
154 std::transform( envelope.to_local.begin() , envelope.to_local.end() ,
155 std::back_inserter(list) , std::bind(&FileDelivery::mailbox,config,_1) ) ;
156 std::sort( list.begin() , list.end() ) ;
157 list.erase( std::unique( list.begin() , list.end() ) , list.end() ) ;
158 G_ASSERT( !list.empty() ) ;
162std::string GStore::FileDelivery::mailbox(
const Config & ,
const std::string & recipient )
168 const std::string & mailbox = recipient ;
170 G_LOG(
"GStore::FileDelivery::mailbox: delivery: recipient [" << recipient <<
"]: delivery to mailbox [" << mailbox <<
"]" ) ;
174std::string GStore::FileDelivery::id(
const G::Path & envelope_path )
179G::Path GStore::FileDelivery::epath(
const MessageId & message_id , FileStore::State store_state )
const
181 return m_store.envelopePath( message_id , store_state ) ;
184G::Path GStore::FileDelivery::cpath(
const MessageId & message_id )
const
186 return m_store.contentPath( message_id ) ;
189std::string GStore::FileDelivery::hostname()
192 if( name.empty() ) name =
"localhost" ;
A structure containing the contents of an envelope file, with support for file reading,...
static void deliverTo(FileStore &, std::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...
FileDelivery(FileStore &, const Config &)
Constructor.
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.
bool simple() const
Returns true if the path has a single component (ignoring "." parts), ie.
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 bool isPrintable(std::string_view s) noexcept
Returns true if every character is 0x20 or above but not 0x7f.
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
static bool replace(std::string &s, std::string_view from, std::string_view to, std::size_t *pos_p=nullptr)
A std::string_view overload.
static SystemTime now()
Factory function for the current time.
std::vector< std::string > StringArray
A std::vector of std::strings.
std::string hostname()
Returns the hostname.
A configuration structure for GStore::FileDelivery.