aboutsummaryrefslogtreecommitdiff
path: root/butl/sendmail.ixx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-13 10:47:47 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-13 10:47:47 +0200
commitabbb859d9eefa62a5cc774bd08020bf30ad77c26 (patch)
treeac2b8648dc9d792154680bff38e5c3f1be73264d /butl/sendmail.ixx
parent714ce38164dbb4b19be8db286182dba3784d471f (diff)
Implement sendmail process
Diffstat (limited to 'butl/sendmail.ixx')
-rw-r--r--butl/sendmail.ixx65
1 files changed, 65 insertions, 0 deletions
diff --git a/butl/sendmail.ixx b/butl/sendmail.ixx
new file mode 100644
index 0000000..3f6597d
--- /dev/null
+++ b/butl/sendmail.ixx
@@ -0,0 +1,65 @@
+// file : butl/sendmail.ixx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <utility> // move(), forward()
+
+namespace butl
+{
+ template <typename E, typename... O>
+ inline sendmail::
+ sendmail (E&& err,
+ const std::string& from,
+ const std::string& subj,
+ const recipients_type& to,
+ const recipients_type& cc,
+ const recipients_type& bcc,
+ O&&... options)
+ : sendmail ([] (const char* [], std::size_t) {},
+ std::forward<E> (err),
+ from,
+ subj,
+ to,
+ cc,
+ bcc,
+ std::forward<O> (options)...)
+ {
+ }
+
+ template <typename C, typename E, typename... O>
+ inline sendmail::
+ sendmail (const C& cmdc,
+ E&& err,
+ const std::string& from,
+ const std::string& subj,
+ const recipients_type& to,
+ const recipients_type& cc,
+ const recipients_type& bcc,
+ O&&... options)
+ {
+ {
+ fdpipe pipe (fdopen_pipe ()); // Text mode seems appropriate.
+
+ process& p (*this);
+ p = process_start (cmdc,
+ pipe.in,
+ 2, // No output expected so redirect to stderr.
+ std::forward<E> (err),
+ dir_path (),
+ "sendmail",
+ "-i", // Don't treat '.' as the end of input.
+ "-t", // Read recipients from headers.
+ std::forward<O> (options)...);
+
+ out.open (std::move (pipe.out));
+ } // Close pipe.in.
+
+ // Write headers.
+ //
+ // Note that if this throws, then the ofdstream will be closed first
+ // (which should signal to the process we are done). Then the process's
+ // destructor will wait for its termination ignoring any errors.
+ //
+ headers (from, subj, to, cc, bcc);
+ }
+}