aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/imap/IMAPConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/net/imap/IMAPConnection.cpp103
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