summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclaiff <claiff@mail.ru>2022-09-19 19:25:16 +0300
committerclaiff <claiff@mail.ru>2022-09-20 12:44:34 +0300
commit7485f26f35c9cfc1489a2e425fee57a2b51059a9 (patch)
treea29ccecb6fba0b0b0f4ad3a1f6e12b429434fb77
parent7fd7a6488625acc45b48ca21d55ed13783cae27f (diff)
downloadobmc-sila-smtp-7485f26f35c9cfc1489a2e425fee57a2b51059a9.tar.xz
add logger journal and phosphor
-rw-r--r--CMakeLists.txt59
-rw-r--r--src/file/mail.cpp102
-rw-r--r--src/file/settings.cpp114
-rw-r--r--src/logger/journal.cpp11
-rw-r--r--src/logger/journal.hpp17
-rw-r--r--src/logger/logger_set.cpp44
-rw-r--r--src/logger/logger_set.hpp25
-rw-r--r--src/logger/phosphor.cpp11
-rw-r--r--src/logger/phosphor.hpp16
-rw-r--r--src/logger/types/ilogger.hpp15
-rw-r--r--src/managment/logger.cpp12
-rw-r--r--src/managment/logger.hpp13
-rw-r--r--src/message/sender.cpp246
13 files changed, 414 insertions, 271 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 95eb853..e3e2153 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,18 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Os -flto")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
+option (
+ ADD_JOURNAL_LOGGING
+ "All logging write to journalctl"
+ ON
+)
+
+option (
+ ADD_PHOSPHOR_LOGGING
+ "All logging write to webui"
+ ON
+)
+
if(NOT ${YOCTO_DEPENDENCIES})
include(ExternalProject)
@@ -73,10 +85,8 @@ else()
link_directories(${Boost_LIBRARY_DIRS})
find_package (PkgConfig REQUIRED)
- find_package (PkgConfig REQUIRED)
pkg_check_modules (LOGGING phosphor-logging REQUIRED)
- include_directories (SYSTEM ${LOGGING_INCLUDE_DIRS})
- link_directories (${LOGGING_LIBRARY_DIRS})
+
endif()
include_directories(src)
@@ -84,11 +94,12 @@ include_directories(src)
set(SRC_DIR src)
set(MESSAGE_DIR src/message)
set(SERVICE_DIR src/service)
-set(MANAGMENT_DIR src/managment)
+set(MANAGEMENT_DIR src/managment)
set(FILE_DIR src/file)
set(PARSER_DIR src/file/parser)
set(MANAGER_BUILDER_DIR src/managment/builder)
set(CONVERTER_DIR src/converter)
+set(LOGGER_DIR src/logger)
set(SRC_FILES
${SRC_DIR}/main.cpp
@@ -114,13 +125,11 @@ set(SRC_FILES
${MESSAGE_DIR}/builder/types/imessage_builder.hpp
${MESSAGE_DIR}/builder/types/idecorator.hpp
- ${MANAGMENT_DIR}/mail.hpp
- ${MANAGMENT_DIR}/mail.cpp
- ${MANAGMENT_DIR}/settings.hpp
- ${MANAGMENT_DIR}/settings.cpp
- ${MANAGMENT_DIR}/logger.hpp
- ${MANAGMENT_DIR}/logger.cpp
- ${MANAGMENT_DIR}/general.hpp
+ ${MANAGEMENT_DIR}/mail.hpp
+ ${MANAGEMENT_DIR}/mail.cpp
+ ${MANAGEMENT_DIR}/settings.hpp
+ ${MANAGEMENT_DIR}/settings.cpp
+ ${MANAGEMENT_DIR}/general.hpp
${FILE_DIR}/mail.hpp
${FILE_DIR}/mail.cpp
@@ -143,20 +152,38 @@ set(SRC_FILES
${MANAGER_BUILDER_DIR}/settings.cpp
${MANAGER_BUILDER_DIR}/mail.hpp
${MANAGER_BUILDER_DIR}/mail.cpp
- )
-add_executable(${PROJECT_NAME} ${SRC_FILES})
+ ${LOGGER_DIR}/types/ilogger.hpp
+ ${LOGGER_DIR}/journal.cpp
+ ${LOGGER_DIR}/journal.hpp
+ ${LOGGER_DIR}/logger_set.cpp
+ ${LOGGER_DIR}/logger_set.hpp
+)
+
+if( ${ADD_PHOSPHOR_LOGGING} )
+ set(PHOSPHOR_LOGGING_FILES
+ src/logger/phosphor.cpp
+ src/logger/phosphor.hpp
+ )
+endif()
+
+add_executable(${PROJECT_NAME} ${SRC_FILES} ${PHOSPHOR_LOGGING_FILES})
+
+target_compile_definitions (
+ ${PROJECT_NAME} PRIVATE $<$<BOOL:${ADD_JOURNAL_LOGGING}>: -DADD_JOURNAL_LOGGING>
+)
+
if(NOT ${YOCTO_DEPENDENCIES})
add_dependencies(${PROJECT_NAME} sdbusplus-project)
+elseif(${ADD_PHOSPHOR_LOGGING})
+ target_link_libraries (${PROJECT_NAME} phosphor_logging)
endif()
+
target_link_libraries(${PROJECT_NAME} boost_context)
target_link_libraries(${PROJECT_NAME} sdbusplus)
target_link_libraries(${PROJECT_NAME} systemd)
target_link_libraries(${PROJECT_NAME} curl)
-#target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES})
-target_link_libraries (${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES}
- phosphor_logging)
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
install(FILES ${PROJECT_SOURCE_DIR}/xyz.openbmc_project.SMTP.service
DESTINATION /lib/systemd/system/)
diff --git a/src/file/mail.cpp b/src/file/mail.cpp
index 5452136..1453535 100644
--- a/src/file/mail.cpp
+++ b/src/file/mail.cpp
@@ -1,63 +1,63 @@
#include <fstream>
#include "mail.hpp"
-#include "managment/logger.hpp"
+#include "logger/logger_set.hpp"
namespace smtp::file
{
- Mail::Mail( std::string const& path_file )
- : mPathFile( path_file )
- {
- }
+ Mail::Mail( std::string const& path_file )
+ : mPathFile( path_file )
+ {
+ }
- manage::MailsSet Mail::Read() const
- {
- std::ifstream mail_file{ mPathFile, std::fstream::in };
- if ( !mail_file.is_open() )
- {
- manage::Logger::LogError( "Unable to open file to read " + mPathFile );
- return {};
- }
- std::string line{};
- manage::MailsSet result;
+ manage::MailsSet Mail::Read() const
+ {
+ std::ifstream mail_file{mPathFile, std::fstream::in};
+ if( !mail_file.is_open())
+ {
+ logger::LoggerSet::GetInstance()->LogError( "Unable to open file to read " + mPathFile );
+ return {};
+ }
+ std::string line{};
+ manage::MailsSet result;
- while ( std::getline( mail_file, line ) )
- {
- auto parsed_data = GetMailFromLine( line );
- if( parsed_data )
- {
- result.push_back( *parsed_data );
- }
- }
- mail_file.close();
- return result;
- }
+ while( std::getline( mail_file, line ))
+ {
+ auto parsed_data = GetMailFromLine( line );
+ if( parsed_data )
+ {
+ result.push_back( *parsed_data );
+ }
+ }
+ mail_file.close();
+ return result;
+ }
- bool Mail::Write( manage::MailsSet const& data ) const
- {
- std::ofstream mail_file{ mPathFile, std::fstream::out | std::fstream::trunc };
- if ( !mail_file.is_open() )
- {
- manage::Logger::LogError( "Unable to open file to write " + mPathFile );
- return false;
- }
- for( const auto& pair : data )
- {
- mail_file << pair << "\n";
- }
- mail_file.close();
- return true;
- }
+ bool Mail::Write( manage::MailsSet const& data ) const
+ {
+ std::ofstream mail_file{mPathFile, std::fstream::out | std::fstream::trunc};
+ if( !mail_file.is_open())
+ {
+ logger::LoggerSet::GetInstance()->LogError( "Unable to open file to write " + mPathFile );
+ return false;
+ }
+ for( const auto& pair: data )
+ {
+ mail_file << pair << "\n";
+ }
+ mail_file.close();
+ return true;
+ }
- std::optional<std::string> Mail::GetMailFromLine( std::string const& line ) const
- {
- //TODO registrator if checking parsing
- auto pos = line.find('@');
- if(pos == std::string::npos)
- {
- return {};
- }
- return line;
- }
+ std::optional < std::string > Mail::GetMailFromLine( std::string const& line ) const
+ {
+ //TODO registrator if checking parsing
+ auto pos = line.find( '@' );
+ if( pos == std::string::npos )
+ {
+ return {};
+ }
+ return line;
+ }
}
diff --git a/src/file/settings.cpp b/src/file/settings.cpp
index 83c1037..445cb5e 100644
--- a/src/file/settings.cpp
+++ b/src/file/settings.cpp
@@ -1,71 +1,71 @@
#include <fstream>
#include "settings.hpp"
-#include "managment/logger.hpp"
+#include "logger/logger_set.hpp"
namespace smtp::file
{
- Settings::Settings( std::string const& path_file)
- : mPathFile( path_file )
- {
+ Settings::Settings( std::string const& path_file )
+ : mPathFile( path_file )
+ {
- }
+ }
- manage::SettingsFields Settings::Read() const
- {
- auto parsed_store = GetParsedStore();
- return converter::Full{}.Convert( parsed_store );
- }
+ manage::SettingsFields Settings::Read() const
+ {
+ auto parsed_store = GetParsedStore();
+ return converter::Full{}.Convert( parsed_store );
+ }
- bool Settings::Write( manage::SettingsFields const& settings_fields ) const
- {
- auto parsed_data = converter::Full{}.Convert( settings_fields );
- return SetParsedData( parsed_data );
- }
+ bool Settings::Write( manage::SettingsFields const& settings_fields ) const
+ {
+ auto parsed_data = converter::Full{}.Convert( settings_fields );
+ return SetParsedData( parsed_data );
+ }
- ParsedStoreType Settings::GetParsedStore() const
- {
- std::ifstream settings_file{ mPathFile, std::fstream::in };
- if ( !settings_file.is_open() )
- {
- manage::Logger::LogError( "Unable to open file to read " + mPathFile );
- return {};
- }
- std::string line{};
- ParsedStoreType result;
+ ParsedStoreType Settings::GetParsedStore() const
+ {
+ std::ifstream settings_file{mPathFile, std::fstream::in};
+ if( !settings_file.is_open())
+ {
+ logger::LoggerSet::GetInstance()->LogError( "Unable to open file to read " + mPathFile );
+ return {};
+ }
+ std::string line{};
+ ParsedStoreType result;
- while ( std::getline( settings_file, line ) )
- {
- auto parsed_data = parser::Settings{}.Parse(line);
- result.insert( parsed_data );
- }
- settings_file.close();
- return result;
- }
+ while( std::getline( settings_file, line ))
+ {
+ auto parsed_data = parser::Settings{}.Parse( line );
+ result.insert( parsed_data );
+ }
+ settings_file.close();
+ return result;
+ }
- bool Settings::SetParsedData( ParsedStoreType const& parsed_data ) const
- {
- std::ofstream settings_file{ mPathFile, std::fstream::out | std::fstream::trunc };
- if ( !settings_file.is_open() )
- {
- manage::Logger::LogError( "Unable to open file to write " + mPathFile );
- return false;
- }
- for( const auto& data : parsed_data )
- {
- auto line = BuildParam( data );
- settings_file << line << "\n";
- }
- settings_file.close();
- return true;
- }
+ bool Settings::SetParsedData( ParsedStoreType const& parsed_data ) const
+ {
+ std::ofstream settings_file{mPathFile, std::fstream::out | std::fstream::trunc};
+ if( !settings_file.is_open())
+ {
+ logger::LoggerSet::GetInstance()->LogError( "Unable to open file to write " + mPathFile );
+ return false;
+ }
+ for( const auto& data: parsed_data )
+ {
+ auto line = BuildParam( data );
+ settings_file << line << "\n";
+ }
+ settings_file.close();
+ return true;
+ }
- std::string Settings::BuildParam( std::pair<std::string, std::string> const& data) const
- {
- std::string result;
- result += data.first;
- result += '=';
- result += data.second;
- return result;
- }
+ std::string Settings::BuildParam( std::pair < std::string, std::string > const& data ) const
+ {
+ std::string result;
+ result += data.first;
+ result += '=';
+ result += data.second;
+ return result;
+ }
}
diff --git a/src/logger/journal.cpp b/src/logger/journal.cpp
new file mode 100644
index 0000000..001e87d
--- /dev/null
+++ b/src/logger/journal.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+
+#include "journal.hpp"
+
+namespace smtp::logger
+{
+ void Journal::LogError( std::string const& message ) const
+ {
+ std::cout << message << std::endl;
+ }
+} \ No newline at end of file
diff --git a/src/logger/journal.hpp b/src/logger/journal.hpp
new file mode 100644
index 0000000..1b06b8c
--- /dev/null
+++ b/src/logger/journal.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "types/ilogger.hpp"
+
+namespace smtp::logger
+{
+ class Journal
+ : public types::ILogger
+ {
+ public:
+ Journal() = default;
+ ~Journal() override = default;
+
+ void LogError( std::string const& message ) const override;
+ };
+}
+
diff --git a/src/logger/logger_set.cpp b/src/logger/logger_set.cpp
new file mode 100644
index 0000000..8a061ed
--- /dev/null
+++ b/src/logger/logger_set.cpp
@@ -0,0 +1,44 @@
+#include "logger_set.hpp"
+#include "journal.hpp"
+
+namespace smtp::logger
+{
+ std::shared_ptr < LoggerSet > LoggerSet::mInstance = nullptr;
+
+ LoggerSet::LoggerSet( std::list < types::ILoggerPtr > const& logger )
+ : mLogger( logger )
+ {
+
+ }
+
+ std::shared_ptr < LoggerSet > LoggerSet::GetInstance()
+ {
+ if( !mInstance )
+ {
+ BuildLogger();
+ }
+ return mInstance;
+ }
+
+ void LoggerSet::BuildLogger()
+ {
+ std::list < types::ILoggerPtr > loggers;
+#ifdef ADD_JOURNAL_LOGGING
+ loggers.push_back( std::make_shared < Journal >());
+#endif
+#ifdef ADD_PHOSPHOR_LOGGING
+ loggers.push_back( std::make_shared < Journal >());
+#endif
+ mInstance.reset( new LoggerSet( loggers ));
+ }
+
+ void LoggerSet::LogError( std::string const& message )
+ {
+ for( const auto& logger: mLogger )
+ {
+ logger->LogError( message );
+ }
+ }
+
+
+}
diff --git a/src/logger/logger_set.hpp b/src/logger/logger_set.hpp
new file mode 100644
index 0000000..fb74e56
--- /dev/null
+++ b/src/logger/logger_set.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <string>
+#include <list>
+
+#include "types/ilogger.hpp"
+
+namespace smtp::logger
+{
+ class LoggerSet
+ {
+ private:
+ explicit LoggerSet( std::list < types::ILoggerPtr > const& logger );
+ static void BuildLogger();
+
+ static std::shared_ptr < LoggerSet > mInstance;
+ std::list < types::ILoggerPtr > mLogger;
+ public:
+ LoggerSet( const LoggerSet& ) = delete;
+ LoggerSet& operator=( LoggerSet& ) = delete;
+
+ void LogError( std::string const& message );
+ static std::shared_ptr < LoggerSet > GetInstance();
+ };
+}
diff --git a/src/logger/phosphor.cpp b/src/logger/phosphor.cpp
new file mode 100644
index 0000000..48bb49e
--- /dev/null
+++ b/src/logger/phosphor.cpp
@@ -0,0 +1,11 @@
+#include <phosphor-logging/elog-errors.hpp>
+
+#include "phosphor.hpp"
+
+namespace smtp::logger
+{
+ void Phosphor::LogError( std::string const& message ) const
+ {
+ phosphor::logging::log < phosphor::logging::level::ERR >( message.c_str());
+ }
+} \ No newline at end of file
diff --git a/src/logger/phosphor.hpp b/src/logger/phosphor.hpp
new file mode 100644
index 0000000..dd536b5
--- /dev/null
+++ b/src/logger/phosphor.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "types/ilogger.hpp"
+
+namespace smtp::logger
+{
+ class Phosphor
+ : public types::ILogger
+ {
+ public:
+ Phosphor() = default;
+ ~Phosphor() override = default;
+
+ void LogError( std::string const& message ) const override;
+ };
+}
diff --git a/src/logger/types/ilogger.hpp b/src/logger/types/ilogger.hpp
new file mode 100644
index 0000000..9f88668
--- /dev/null
+++ b/src/logger/types/ilogger.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <memory>
+
+namespace smtp::logger::types
+{
+ class ILogger
+ {
+ public:
+ virtual ~ILogger() = default;
+
+ virtual void LogError( std::string const& message ) const = 0;
+ };
+ using ILoggerPtr = std::shared_ptr<ILogger>;
+} \ No newline at end of file
diff --git a/src/managment/logger.cpp b/src/managment/logger.cpp
deleted file mode 100644
index 0c55394..0000000
--- a/src/managment/logger.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <iostream>
-
-#include "logger.hpp"
-
-namespace smtp::manage
-{
- void Logger::LogError( std::string const& message )
- {
- std::cout << message << std::endl;
- }
-
-}
diff --git a/src/managment/logger.hpp b/src/managment/logger.hpp
deleted file mode 100644
index 315e17e..0000000
--- a/src/managment/logger.hpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include <string>
-
-namespace smtp::manage
-{
- class Logger
- {
- public:
- Logger() = default;
- static void LogError( std::string const& message );
- };
-}
diff --git a/src/message/sender.cpp b/src/message/sender.cpp
index 5b3a421..5845628 100644
--- a/src/message/sender.cpp
+++ b/src/message/sender.cpp
@@ -1,4 +1,4 @@
-#include <string.h>
+#include <cstring>
#include "sender.hpp"
#include "builder/date.hpp"
@@ -7,128 +7,130 @@
#include "builder/subject.hpp"
#include "builder/text.hpp"
#include "builder/from.hpp"
-#include "managment/logger.hpp"
+#include "logger/logger_set.hpp"
namespace smtp::message
{
- static std::string mText = "";
-
- //
- // Constructors/Destructors
- //
- Sender::Sender( manage::Settings& settings_storage, manage::Mail const& mail_to )
- : mSettingsStorage( settings_storage ),
- mMailTo( mail_to )
- {
-
- }
-
- //
- //Public methods
- //
-
- bool Sender::Send( std::string const& mail_from, std::string const& subject, std::string const& text )
- {
- CURLcode result = CURLE_OK;
- curl_slist *recipients = NULL;
- WriteThis upload_ctx{};
- auto curl = curl_easy_init();
-
- //TODO сделать инициализацию через регистратор инициализаторов
- mSettingsStorage.ReloadSettings();
- if( !InitCurl( curl, upload_ctx, mail_from ) )
- {
- manage::Logger::LogError("Error to initializate curl");
- return false;
- }
- //TODO раздать mail_to другим методам
- auto mail_to = mMailTo.GetMailToSend();
- if( mail_to.empty() )
- {
- manage::Logger::LogError("We haven't any mail to");
- return false;
- }
- FillRecipients( curl, recipients );
- UpdateMailText( mail_from, subject, text);
-
- result = curl_easy_perform(curl);
-
- if ( result != CURLE_OK )
- {
- std::string message = "Error to send messge: " + std::string( curl_easy_strerror( result ));
- manage::Logger::LogError(message);
- return false;
- }
- //TODO сделать деинициализацию через регистратор деинициализаторов
- curl_slist_free_all( recipients );
- curl_easy_cleanup( curl );
- return true;
- }
-
- //
- //Private methods
- //
- bool smtp::message::Sender::InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from )
- {
- if( !curl )
- {
- return false;
- }
- curl_easy_setopt(curl, CURLOPT_USERNAME, mSettingsStorage.GetUserName().c_str());
- curl_easy_setopt(curl, CURLOPT_PASSWORD, mSettingsStorage.GetPassword().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);
- return true;
- }
-
- void Sender::UpdateMailText( std::string const& mail_from, std::string const& subject, std::string const& text ) const
- {
- auto mail_to = mMailTo.GetMailToSend();
- auto text_decorator = std::make_shared<builder::Text>( text );
- text_decorator->Apply( std::make_shared<builder::Subject>( subject ) )
- .Apply( std::make_shared<builder::Cc>( mail_to ) )
- .Apply( std::make_shared<builder::From>( mail_from ) )
- .Apply( std::make_shared<builder::MailTo>( mail_to ) )
- .Apply( std::make_shared<builder::Date>() );
- mText = text_decorator->Get();
- }
-
- void Sender::FillRecipients( CURL* curl, curl_slist* recipients )
- {
- auto mail_to = mMailTo.GetMailToSend();
- for( const auto& recipient : mail_to )
- {
- recipients = curl_slist_append( recipients, recipient.c_str() );
- }
-
- curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients );
- }
-
- std::string Sender::GetHostPortData() const
- {
- auto result = "smtp://" + mSettingsStorage.GetHost();
- if( !mSettingsStorage.GetPort().empty() )
- {
- result += ":" + mSettingsStorage.GetPort();
- }
- return result;
- }
- //TODO Надо убрать этот ужас. Без статики!!!
- size_t Sender::ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp )
- {
- struct WriteThis *pooh = reinterpret_cast<WriteThis*>( userp );
- if( size * nmemb < 1 || pooh->counter++ > 0 )
- {
- return 0;
- }
- memcpy( ptr, mText.c_str(), mText.size() );
- return mText.size();
- }
+ static std::string mText;
+
+ //
+ // Constructors/Destructors
+ //
+ Sender::Sender( manage::Settings& settings_storage, manage::Mail const& mail_to )
+ : mSettingsStorage( settings_storage )
+ , mMailTo( mail_to )
+ {
+
+ }
+
+ //
+ //Public methods
+ //
+
+ bool Sender::Send( std::string const& mail_from, std::string const& subject, std::string const& text )
+ {
+ CURLcode result = CURLE_OK;
+ curl_slist* recipients = nullptr;
+ WriteThis upload_ctx{};
+ auto curl = curl_easy_init();
+
+ //TODO сделать инициализацию через регистратор инициализаторов
+ mSettingsStorage.ReloadSettings();
+ if( !InitCurl( curl, upload_ctx, mail_from ))
+ {
+ logger::LoggerSet::GetInstance()->LogError( "Error to initializate curl" );
+ return false;
+ }
+ //TODO раздать mail_to другим методам
+ auto mail_to = mMailTo.GetMailToSend();
+ if( mail_to.empty())
+ {
+ logger::LoggerSet::GetInstance()->LogError( "We haven't any mail to" );
+ return false;
+ }
+ FillRecipients( curl, recipients );
+ UpdateMailText( mail_from, subject, text );
+
+ result = curl_easy_perform( curl );
+
+ if( result != CURLE_OK )
+ {
+ std::string message = "Error to send messge: " + std::string( curl_easy_strerror( result ));
+ logger::LoggerSet::GetInstance()->LogError( message );
+ return false;
+ }
+ //TODO сделать деинициализацию через регистратор деинициализаторов
+ curl_slist_free_all( recipients );
+ curl_easy_cleanup( curl );
+ return true;
+ }
+
+ //
+ //Private methods
+ //
+ bool smtp::message::Sender::InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from )
+ {
+ if( !curl )
+ {
+ return false;
+ }
+ curl_easy_setopt( curl, CURLOPT_USERNAME, mSettingsStorage.GetUserName().c_str());
+ curl_easy_setopt( curl, CURLOPT_PASSWORD, mSettingsStorage.GetPassword().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 );
+ return true;
+ }
+
+ void
+ Sender::UpdateMailText( std::string const& mail_from, std::string const& subject, std::string const& text ) const
+ {
+ auto mail_to = mMailTo.GetMailToSend();
+ auto text_decorator = std::make_shared < builder::Text >( text );
+ text_decorator->Apply( std::make_shared < builder::Subject >( subject ))
+ .Apply( std::make_shared < builder::Cc >( mail_to ))
+ .Apply( std::make_shared < builder::From >( mail_from ))
+ .Apply( std::make_shared < builder::MailTo >( mail_to ))
+ .Apply( std::make_shared < builder::Date >());
+ mText = text_decorator->Get();
+ }
+
+ void Sender::FillRecipients( CURL* curl, curl_slist* recipients )
+ {
+ auto mail_to = mMailTo.GetMailToSend();
+ for( const auto& recipient: mail_to )
+ {
+ recipients = curl_slist_append( recipients, recipient.c_str());
+ }
+
+ curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients );
+ }
+
+ std::string Sender::GetHostPortData() const
+ {
+ auto result = "smtp://" + mSettingsStorage.GetHost();
+ if( !mSettingsStorage.GetPort().empty())
+ {
+ result += ":" + mSettingsStorage.GetPort();
+ }
+ return result;
+ }
+
+ //TODO Надо убрать этот ужас. Без статики!!!
+ size_t Sender::ReadCallBack( void* ptr, size_t size, size_t nmemb, void* userp )
+ {
+ auto pooh = reinterpret_cast<WriteThis*>( userp );
+ if( size * nmemb < 1 || pooh->counter++ > 0 )
+ {
+ return 0;
+ }
+ memcpy( ptr, mText.c_str(), mText.size());
+ return mText.size();
+ }
}