#include #include "message_sender.hpp" #include "message_builder/date.hpp" #include "message_builder/mail_to.hpp" #include "message_builder/cc.hpp" #include "message_builder/subject.hpp" #include "message_builder/text.hpp" #include "message_builder/from.hpp" namespace smtp { static std::string mText = ""; // // Constructors/Destructors // MessageSender::MessageSender( SettingsStorage const& settings_storage ) : mSettingsStorage( settings_storage ) { } // //Public methods // bool MessageSender::Send( std::string const& mail_from, std::string const& mail_to, std::list const& cc, std::string const& subject, std::string const& text ) { CURLcode result = CURLE_OK; struct curl_slist *recipients = NULL; struct WriteThis upload_ctx; upload_ctx.counter = 0; auto curl = curl_easy_init(); if( !curl ) { //Error return false; } mText = GetText( mail_from, mail_to, cc, subject, text); FillRecipients( curl, mail_to, cc, recipients ); curl_easy_setopt(curl, CURLOPT_USERNAME, mSettingsStorage.username.c_str()); curl_easy_setopt(curl, CURLOPT_PASSWORD, mSettingsStorage.password.c_str()); curl_easy_setopt(curl, CURLOPT_URL, GetHostPortData().c_str()); curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); curl_easy_setopt(curl, CURLOPT_MAIL_FROM, mail_from.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallBack); curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); result = curl_easy_perform(curl); if (result != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(result)); return false; } curl_slist_free_all(recipients); curl_easy_cleanup(curl); return true; } // //Private methods // std::string MessageSender::GetText( std::string const& mail_from, std::string const& mail_to, std::list const& cc, std::string const& subject, std::string const& text ) const { auto text_decorator = std::make_shared( text ); text_decorator->Apply( std::make_shared( subject ) ) .Apply( std::make_shared( cc ) ) .Apply( std::make_shared( mail_from ) ) .Apply( std::make_shared( mail_to ) ) .Apply( std::make_shared() ); return text_decorator->Get(); } void MessageSender::FillRecipients( CURL* curl, std::string const& mail_to, std::list const& cc, curl_slist* recipients ) { recipients = curl_slist_append( recipients, mail_to.c_str() ); for( const auto& recipient : cc ) { recipients = curl_slist_append( recipients, recipient.c_str() ); } curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients ); } std::string MessageSender::GetHostPortData() const { auto result = "smtp://" + mSettingsStorage.host; if( !mSettingsStorage.port.empty() ) { result += ":" + mSettingsStorage.port; } return result; } size_t MessageSender::ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ) { struct WriteThis *pooh = reinterpret_cast( userp ); if( size * nmemb < 1 ) { return 0; } if( pooh->counter++ > 0 ) { return 0; } memcpy( ptr, mText.c_str(), mText.size() ); return mText.size(); } }