42 #include "../core/uuid.hpp"
44 #include <boost/exception/diagnostic_information.hpp>
45 #include <boost/lexical_cast.hpp>
53 curl::payload_message_t
curl::payload_text_strs_{};
56 ::curl_slist_free_all(recipients_);
61 addrs_.push_back(addr);
62 recipients_=::curl_slist_append(recipients_, addrs_.rbegin()->c_str());
65 __attribute__((pure))
bool
67 return addrs_.empty();
70 curl::
curl(
std::string
const &smtp_url,
unsigned short port,
std::string
const &username,
std::string
const &password,
bool enable_logging,
bool enable_ssl_verification)
noexcept(
false)
71 : handle_(::curl_easy_init()), smtp_url_(smtp_url+
":"+
boost::lexical_cast<
std::string>(port)), username_(username), password_(password) {
73 throw std::runtime_error(
"Failed to initialise curl library. Try running the program again, or rebooting...");
75 ::curl_easy_setopt(handle_, CURLOPT_USERNAME, username_.c_str());
76 ::curl_easy_setopt(handle_, CURLOPT_PASSWORD, password_.c_str());
77 ::curl_easy_setopt(handle_, CURLOPT_URL, smtp_url_.c_str());
84 ::curl_easy_setopt(handle_, CURLOPT_USE_SSL,
static_cast<
long>(CURLUSESSL_ALL));
88 if (!enable_ssl_verification) {
89 ignore_ssl_verification();
94 ::curl_easy_cleanup(handle_);
98 curl::ignore_ssl_verification()
noexcept(
true) {
99 ::curl_easy_setopt(handle_, CURLOPT_SSL_VERIFYPEER, 0L);
100 ::curl_easy_setopt(handle_, CURLOPT_SSL_VERIFYHOST, 0L);
104 curl::set_logging()
noexcept(
true) {
105 ::curl_easy_setopt(handle_, CURLOPT_VERBOSE, 1L);
111 ::curl_easy_setopt(handle_, CURLOPT_MAIL_FROM, from_.c_str());
115 curl::payload_source(
void *ptr, size_t size, size_t nmemb,
void *userp) {
116 upload_status *upload_ctx =
reinterpret_cast<upload_status *>(userp);
119 if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
122 if (upload_ctx->lines_read<payload_text_strs_.size()) {
123 payload_message_t::value_type
const &data=payload_text_strs_[upload_ctx->lines_read];
125 std::memcpy(ptr, data.data(), data.size());
126 ++upload_ctx->lines_read;
136 for (
auto const &recipient : recipients) {
138 create_message(recipient, subject, body);
139 upload_ctx_.lines_read=0;
140 email_recipients a_recipient;
141 a_recipient.push_back(recipient);
142 assert(a_recipient.recipients_);
143 ::curl_easy_setopt(handle_, CURLOPT_MAIL_RCPT, a_recipient.recipients_);
144 CURLcode res=::curl_easy_perform(handle_);
146 ::curl_easy_setopt(handle_, CURLOPT_READFUNCTION, payload_source);
147 ::curl_easy_setopt(handle_, CURLOPT_READDATA, &upload_ctx_);
148 ::curl_easy_setopt(handle_, CURLOPT_UPLOAD, 1L);
149 res=::curl_easy_perform(handle_);
151 failures.emplace_back(std::make_tuple(recipient, ::curl_easy_strerror(res)));
154 failures.emplace_back(std::make_tuple(recipient, ::curl_easy_strerror(res)));
156 }
catch (std::exception
const &ex) {
157 failures.emplace_back(std::make_tuple(recipient, boost::diagnostic_information(ex)));
159 failures.emplace_back(std::make_tuple(recipient,
"Unknown error."));
166 curl::current_time_for_email()
noexcept(
false) {
167 std::stringstream buffer;
168 std::time_t t=
std::time(
nullptr);
169 std::tm tm=*
std::localtime(&t);
170 buffer<<
std::put_time(&tm,
"%a %d %b %Y %H:%M:%S %Y %z");
175 curl::create_message(
std::string
const &to,
std::string
const &subject,
std::string
const &body)
const noexcept(
false) {
176 const char newline[]=
"\r\n";
177 payload_text_strs_.clear();
178 payload_text_strs_.emplace_back(
"Date: "+current_time_for_email()+newline);
179 payload_text_strs_.emplace_back(
"To: "+to+newline);
180 payload_text_strs_.emplace_back(
"From: "+from_+newline);
181 payload_text_strs_.emplace_back(
"Message-ID: "+get_uuid_as_string()+from_+newline);
182 payload_text_strs_.emplace_back(
"Subject: "+subject+newline);
183 payload_text_strs_.emplace_back(newline);
184 payload_text_strs_.emplace_back(body+newline);