54 if( m_ok )
return std::string() ;
55 const std::string default_ =
"pre-processing failed" ;
56 return m_text.empty() ? default_ : m_text ;
59 bool GSmtp::ExecutableProcessor::process(
const std::string & path )
61 int exit_code = preprocessCore(
G::Path(path) ) ;
64 bool is_zero = exit_code == 0 ;
65 bool is_special = exit_code >= 100 && exit_code <= 107 ;
66 bool is_failure = !is_zero && !is_special ;
69 G_WARNING(
"GSmtp::ExecutableProcessor::preprocess: pre-processing failed: exit code " << exit_code ) ;
73 m_repoll = is_special && ((exit_code-100)&2) != 0 ;
74 m_cancelled = is_special && ((exit_code-100)&1) == 0 ;
77 m_ok = is_zero || ( is_special && !m_cancelled ) ;
81 int GSmtp::ExecutableProcessor::preprocessCore(
const G::Path & path )
83 G_LOG(
"GSmtp::ExecutableProcessor::preprocess: running \"" << m_exe.displayString() <<
" " << path <<
"\"" ) ;
87 args.push_back( path.
str() ) ;
90 std::string raw_output ;
92 &raw_output , 127 , execErrorHandler ) ;
95 m_text = parseOutput( raw_output ) ;
96 G_LOG(
"GSmtp::ExecutableProcessor::preprocess: exit status " << exit_code <<
" (\"" << m_text <<
"\")" ) ;
101 std::string GSmtp::ExecutableProcessor::execErrorHandler(
int error )
104 std::ostringstream ss ;
109 std::string GSmtp::ExecutableProcessor::parseOutput( std::string s )
const
113 const std::string start_1(
"<<") ;
114 const std::string end_1(
">>") ;
115 const std::string start_2(
"[[") ;
116 const std::string end_2(
"]]") ;
123 for( G::Strings::iterator p = lines.begin() ; p != lines.end() ; ++p )
125 std::string line = *p ;
126 size_t pos_start = line.find(start_1) ;
127 size_t pos_end = line.find(end_1) ;
128 if( pos_start != 0U )
130 pos_start = line.find(start_2) ;
131 pos_end = line.find(end_2) ;
133 if( pos_start == 0U && pos_end != std::string::npos )
145 return m_done_signal ;
156 bool ok = process( message_file ) ;
157 m_done_signal.emit( ok ) ;
ExecutableProcessor(const G::Executable &)
Constructor.
static int spawn(Identity nobody, const Path &exe, const Strings &args, std::string *pipe_result_p=NULL, int error_return=127, std::string(*error_decode_fn)(int)=0)
Runs a command in an unprivileged child process.
std::string str() const
Returns the path string.
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
virtual void start(const std::string &path)
Final override from from GSmtp::Processor.
static Identity nobody()
Returns the 'nobody' identity.
std::list< std::string > Strings
A std::list of std::strings.
static void splitIntoFields(const std::string &in, Strings &out, const std::string &seperators, char escape= '\0', bool discard_bogus_escapes=true)
Splits the string into fields.
A structure representing an external program, holding a path and a set of arguments.
virtual std::string text() const
Final override from from GSmtp::Processor.
static std::string lower(const std::string &s)
Returns a copy of 's' in which all uppercase characters have been replaced by lowercase characters...
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 void abort()
Final override from from GSmtp::Processor.
virtual ~ExecutableProcessor()
Destructor.
virtual bool cancelled() const
Final override from from GSmtp::Processor.
virtual G::Signal1< bool > & doneSignal()
Final override from from GSmtp::Processor.
virtual bool repoll() const
Final override from from GSmtp::Processor.
A Path object represents a file system path.
static std::string strerror(int errno_)
Translates an 'errno' value into a meaningful diagnostic string.