diff options
Diffstat (limited to '')
-rw-r--r-- | src/net/imap/IMAPConnection.cpp | 103 |
1 files changed, 81 insertions, 22 deletions
diff --git a/src/net/imap/IMAPConnection.cpp b/src/net/imap/IMAPConnection.cpp index 935de8cf..c5ff58a7 100644 --- a/src/net/imap/IMAPConnection.cpp +++ b/src/net/imap/IMAPConnection.cpp @@ -35,6 +35,8 @@ #include "vmime/exception.hpp" #include "vmime/platform.hpp" +#include "vmime/utility/stringUtils.hpp" + #include "vmime/net/defaultConnectionInfos.hpp" #if VMIME_HAVE_SASL_SUPPORT @@ -66,7 +68,7 @@ namespace imap { IMAPConnection::IMAPConnection(ref <IMAPStore> store, ref <security::authenticator> auth) : m_store(store), m_auth(auth), m_socket(NULL), m_parser(NULL), m_tag(NULL), m_hierarchySeparator('\0'), m_state(STATE_NONE), m_timeoutHandler(NULL), - m_secured(false), m_firstTag(true), m_capabilitiesFetched(false) + m_secured(false), m_firstTag(true), m_capabilitiesFetched(false), m_noModSeq(false) { } @@ -155,6 +157,12 @@ void IMAPConnection::connect() needAuth = true; } + if (greet->resp_cond_auth()->resp_text()->resp_text_code() && + greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data()) + { + processCapabilityResponseData(greet->resp_cond_auth()->resp_text()->resp_text_code()->capability_data()); + } + #if VMIME_HAVE_TLS_SUPPORT // Setup secured connection, if requested const bool tls = HAS_PROPERTY(PROPERTY_CONNECTION_TLS) @@ -266,6 +274,10 @@ void IMAPConnection::authenticate() internalDisconnect(); throw exceptions::authentication_error(m_parser->lastLine()); } + + // Server capabilities may change when logged in + if (!processCapabilityResponseData(resp)) + invalidateCapabilities(); } @@ -397,6 +409,9 @@ void IMAPConnection::authenticateSASL() // Send response send(false, saslContext->encodeB64(resp, respLen), true); + + // Server capabilities may change when logged in + invalidateCapabilities(); } catch (exceptions::sasl_exception& e) { @@ -506,6 +521,23 @@ const std::vector <string> IMAPConnection::getCapabilities() } +bool IMAPConnection::hasCapability(const string& capa) +{ + if (!m_capabilitiesFetched) + fetchCapabilities(); + + const string normCapa = utility::stringUtils::toUpper(capa); + + for (unsigned int i = 0, n = m_capabilities.size() ; i < n ; ++i) + { + if (m_capabilities[i] == normCapa) + return true; + } + + return false; +} + + void IMAPConnection::invalidateCapabilities() { m_capabilities.clear(); @@ -519,35 +551,50 @@ void IMAPConnection::fetchCapabilities() utility::auto_ptr <IMAPParser::response> resp(m_parser->readResponse()); - std::vector <string> res; - if (resp->response_done()->response_tagged()-> resp_cond_state()->status() == IMAPParser::resp_cond_state::OK) { - const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = - resp->continue_req_or_response_data(); + processCapabilityResponseData(resp); + } +} - for (unsigned int i = 0 ; i < respDataList.size() ; ++i) - { - if (respDataList[i]->response_data() == NULL) - continue; - const IMAPParser::capability_data* capaData = - respDataList[i]->response_data()->capability_data(); +bool IMAPConnection::processCapabilityResponseData(const IMAPParser::response* resp) +{ + const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = + resp->continue_req_or_response_data(); + + for (unsigned int i = 0 ; i < respDataList.size() ; ++i) + { + if (respDataList[i]->response_data() == NULL) + continue; - if (capaData == NULL) - continue; + const IMAPParser::capability_data* capaData = + respDataList[i]->response_data()->capability_data(); - std::vector <IMAPParser::capability*> caps = capaData->capabilities(); + if (capaData == NULL) + continue; - for (unsigned int j = 0 ; j < caps.size() ; ++j) - { - if (caps[j]->auth_type()) - res.push_back("AUTH=" + caps[j]->auth_type()->name()); - else - res.push_back(caps[j]->atom()->value()); - } - } + processCapabilityResponseData(capaData); + return true; + } + + return false; +} + + +void IMAPConnection::processCapabilityResponseData(const IMAPParser::capability_data* capaData) +{ + std::vector <string> res; + + std::vector <IMAPParser::capability*> caps = capaData->capabilities(); + + for (unsigned int j = 0 ; j < caps.size() ; ++j) + { + if (caps[j]->auth_type()) + res.push_back("AUTH=" + caps[j]->auth_type()->name()); + else + res.push_back(utility::stringUtils::toUpper(caps[j]->atom()->value())); } m_capabilities = res; @@ -756,6 +803,18 @@ ref <const socket> IMAPConnection::getSocket() const } +bool IMAPConnection::isMODSEQDisabled() const +{ + return m_noModSeq; +} + + +void IMAPConnection::disableMODSEQ() +{ + m_noModSeq = true; +} + + } // imap } // net } // vmime |