aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2016-03-03 22:45:19 -0800
committerGravatar Hoa V. DINH <dinh.viet.hoa@gmail.com>2016-03-03 22:45:19 -0800
commita55c8f370bd663ea1d31fed230987711aa1cf176 (patch)
tree567a995e2f0565d24aebff0fab959d3c95045670
parent886aae2ab94c74a4d4c644c446f67d37a333c1f9 (diff)
Thread safety on logger
-rw-r--r--src/async/nntp/MCNNTPAsyncSession.cpp4
-rw-r--r--src/async/pop/MCPOPAsyncSession.cpp4
-rw-r--r--src/async/smtp/MCSMTPAsyncSession.cpp4
-rwxr-xr-xsrc/core/imap/MCIMAPSession.cpp11
-rwxr-xr-xsrc/core/imap/MCIMAPSession.h1
-rw-r--r--src/core/nntp/MCNNTPSession.cpp436
-rw-r--r--src/core/nntp/MCNNTPSession.h8
-rw-r--r--src/core/pop/MCPOPSession.cpp37
-rw-r--r--src/core/pop/MCPOPSession.h8
-rw-r--r--src/core/provider/MCAccountValidator.cpp43
-rw-r--r--src/core/provider/MCAccountValidator.h13
-rw-r--r--src/core/smtp/MCSMTPSession.cpp36
-rw-r--r--src/core/smtp/MCSMTPSession.h8
-rw-r--r--src/objc/provider/MCOAccountValidator.h3
-rw-r--r--src/objc/provider/MCOAccountValidator.mm47
15 files changed, 432 insertions, 231 deletions
diff --git a/src/async/nntp/MCNNTPAsyncSession.cpp b/src/async/nntp/MCNNTPAsyncSession.cpp
index eeed1244..fdf1165c 100644
--- a/src/async/nntp/MCNNTPAsyncSession.cpp
+++ b/src/async/nntp/MCNNTPAsyncSession.cpp
@@ -285,13 +285,13 @@ void NNTPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
{
pthread_mutex_lock(&mConnectionLoggerLock);
mConnectionLogger = logger;
- if (mConnectionLogger != NULL) {
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+ if (logger != NULL) {
mSession->setConnectionLogger(mInternalLogger);
}
else {
mSession->setConnectionLogger(NULL);
}
- pthread_mutex_unlock(&mConnectionLoggerLock);
}
ConnectionLogger * NNTPAsyncSession::connectionLogger()
diff --git a/src/async/pop/MCPOPAsyncSession.cpp b/src/async/pop/MCPOPAsyncSession.cpp
index dead660f..f1897b84 100644
--- a/src/async/pop/MCPOPAsyncSession.cpp
+++ b/src/async/pop/MCPOPAsyncSession.cpp
@@ -240,13 +240,13 @@ void POPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
{
pthread_mutex_lock(&mConnectionLoggerLock);
mConnectionLogger = logger;
- if (mConnectionLogger != NULL) {
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+ if (logger != NULL) {
mSession->setConnectionLogger(mInternalLogger);
}
else {
mSession->setConnectionLogger(NULL);
}
- pthread_mutex_unlock(&mConnectionLoggerLock);
}
ConnectionLogger * POPAsyncSession::connectionLogger()
diff --git a/src/async/smtp/MCSMTPAsyncSession.cpp b/src/async/smtp/MCSMTPAsyncSession.cpp
index 46b25184..8ec8e2d4 100644
--- a/src/async/smtp/MCSMTPAsyncSession.cpp
+++ b/src/async/smtp/MCSMTPAsyncSession.cpp
@@ -277,13 +277,13 @@ void SMTPAsyncSession::setConnectionLogger(ConnectionLogger * logger)
{
pthread_mutex_lock(&mConnectionLoggerLock);
mConnectionLogger = logger;
- if (mConnectionLogger != NULL) {
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+ if (logger != NULL) {
mSession->setConnectionLogger(mInternalLogger);
}
else {
mSession->setConnectionLogger(NULL);
}
- pthread_mutex_unlock(&mConnectionLoggerLock);
}
ConnectionLogger * SMTPAsyncSession::connectionLogger()
diff --git a/src/core/imap/MCIMAPSession.cpp b/src/core/imap/MCIMAPSession.cpp
index 96c618a7..8b8565d9 100755
--- a/src/core/imap/MCIMAPSession.cpp
+++ b/src/core/imap/MCIMAPSession.cpp
@@ -514,7 +514,7 @@ static void logger(mailimap * imap, int log_type, const char * buffer, size_t si
IMAPSession * session = (IMAPSession *) context;
session->lockConnectionLogger();
- if (session->connectionLogger() == NULL) {
+ if (session->connectionLoggerNoLock() == NULL) {
session->unlockConnectionLogger();
return;
}
@@ -530,11 +530,11 @@ static void logger(mailimap * imap, int log_type, const char * buffer, size_t si
if (isBuffer) {
AutoreleasePool * pool = new AutoreleasePool();
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->log(session, type, data);
+ session->connectionLoggerNoLock()->log(session, type, data);
pool->release();
}
else {
- session->connectionLogger()->log(session, type, NULL);
+ session->connectionLoggerNoLock()->log(session, type, NULL);
}
session->unlockConnectionLogger();
}
@@ -4015,6 +4015,11 @@ void IMAPSession::unlockConnectionLogger()
pthread_mutex_unlock(&mConnectionLoggerLock);
}
+ConnectionLogger * IMAPSession::connectionLoggerNoLock()
+{
+ return mConnectionLogger;
+}
+
String * IMAPSession::htmlRendering(IMAPMessage * message, String * folder, ErrorCode * pError)
{
HTMLRendererIMAPDataCallback * dataCallback = new HTMLRendererIMAPDataCallback(this, message->uid());
diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h
index 5f516ff5..9c6ba95b 100755
--- a/src/core/imap/MCIMAPSession.h
+++ b/src/core/imap/MCIMAPSession.h
@@ -219,6 +219,7 @@ namespace mailcore {
virtual IndexSet * storedCapabilities();
virtual void lockConnectionLogger();
virtual void unlockConnectionLogger();
+ virtual ConnectionLogger * connectionLoggerNoLock();
private:
String * mHostname;
diff --git a/src/core/nntp/MCNNTPSession.cpp b/src/core/nntp/MCNNTPSession.cpp
index e5004432..f3e485d0 100644
--- a/src/core/nntp/MCNNTPSession.cpp
+++ b/src/core/nntp/MCNNTPSession.cpp
@@ -49,6 +49,7 @@ void NNTPSession::init()
mProgressCallback = NULL;
mState = STATE_DISCONNECTED;
mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
}
NNTPSession::NNTPSession()
@@ -58,6 +59,7 @@ NNTPSession::NNTPSession()
NNTPSession::~NNTPSession()
{
+ pthread_mutex_destroy(&mConnectionLoggerLock);
MC_SAFE_RELEASE(mHostname);
MC_SAFE_RELEASE(mUsername);
MC_SAFE_RELEASE(mPassword);
@@ -158,20 +160,24 @@ void NNTPSession::bodyProgress(unsigned int current, unsigned int maximum)
static void logger(newsnntp * nntp, int log_type, const char * buffer, size_t size, void * context)
{
NNTPSession * session = (NNTPSession *) context;
+ session->lockConnectionLogger();
- if (session->connectionLogger() == NULL)
+ if (session->connectionLoggerNoLock() == NULL) {
+ session->unlockConnectionLogger();
return;
+ }
ConnectionLogType type = getConnectionType(log_type);
bool isBuffer = isBufferFromLogType(log_type);
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->log(session, type, data);
+ session->connectionLoggerNoLock()->log(session, type, data);
}
else {
- session->connectionLogger()->log(session, type, NULL);
+ session->connectionLoggerNoLock()->log(session, type, NULL);
}
+ session->unlockConnectionLogger();
}
@@ -622,169 +628,6 @@ Array * NNTPSession::fetchOverArticlesInRange(Range range, String * groupName, E
return result;
}
-void NNTPSession::postMessage(Data * messageData, NNTPProgressCallback * callback, ErrorCode * pError)
-{
- int r;
-
- messageData = dataWithFilteredBcc(messageData);
-
- mProgressCallback = callback;
- bodyProgress(0, messageData->length());
-
- MCLog("setup");
-
- MCLog("connect");
- loginIfNeeded(pError);
- if (* pError != ErrorNone) {
- goto err;
- }
-
- MCLog("send");
- r = newsnntp_post(mNNTP, messageData->bytes(), messageData->length());
-
- String * response;
-
- response = NULL;
- if (mNNTP->nntp_response != NULL) {
- response = String::stringWithUTF8Characters(mNNTP->nntp_response);
- }
-
- if (r == NEWSNNTP_ERROR_STREAM) {
- * pError = ErrorConnection;
- goto err;
- }
- else if (r != NEWSNNTP_NO_ERROR) {
- * pError = ErrorSendMessage;
- goto err;
- }
-
- bodyProgress(messageData->length(), messageData->length());
- * pError = ErrorNone;
-
-err:
- mProgressCallback = NULL;
-}
-
-void NNTPSession::postMessage(String * messagePath, NNTPProgressCallback * callback, ErrorCode * pError)
-{
- Data * messageData = Data::dataWithContentsOfFile(messagePath);
- if (!messageData) {
- * pError = ErrorFile;
- return;
- }
-
- return postMessage(messageData, callback, pError);
-}
-
-static void mmapStringDeallocator(char * bytes, unsigned int length) {
- mmap_string_unref(bytes);
-}
-
-Data * NNTPSession::dataWithFilteredBcc(Data * data)
-{
- int r;
- size_t idx;
- struct mailimf_message * msg;
-
- idx = 0;
- r = mailimf_message_parse(data->bytes(), data->length(), &idx, &msg);
- if (r != MAILIMF_NO_ERROR) {
- return Data::data();
- }
-
- struct mailimf_fields * fields = msg->msg_fields;
- int col = 0;
-
- int hasRecipient = 0;
- bool bccWasActuallyRemoved = false;
- for(clistiter * cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) {
- struct mailimf_field * field = (struct mailimf_field *) clist_content(cur);
- if (field->fld_type == MAILIMF_FIELD_BCC) {
- mailimf_field_free(field);
- clist_delete(fields->fld_list, cur);
- bccWasActuallyRemoved = true;
- break;
- }
- else if ((field->fld_type == MAILIMF_FIELD_TO) || (field->fld_type == MAILIMF_FIELD_CC)) {
- hasRecipient = 1;
- }
- }
- if (!hasRecipient) {
- struct mailimf_address_list * imfTo;
- imfTo = mailimf_address_list_new_empty();
- mailimf_address_list_add_parse(imfTo, (char *) "Undisclosed recipients:;");
- struct mailimf_to * toField = mailimf_to_new(imfTo);
- struct mailimf_field * field = mailimf_field_new(MAILIMF_FIELD_TO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, toField, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- mailimf_fields_add(fields, field);
- }
-
- Data * result;
- if (!hasRecipient || bccWasActuallyRemoved) {
- MMAPString * str = mmap_string_new("");
- mailimf_fields_write_mem(str, &col, fields);
- mmap_string_append(str, "\n");
- mmap_string_append_len(str, msg->msg_body->bd_text, msg->msg_body->bd_size);
-
- mmap_string_ref(str);
-
- result = Data::data();
- result->takeBytesOwnership(str->str, (unsigned int) str->len, mmapStringDeallocator);
- }
- else {
- // filter Bcc and modify To: only if necessary.
- result = data;
- }
-
- mailimf_message_free(msg);
-
- return result;
-}
-
-void NNTPSession::selectGroup(String * folder, ErrorCode * pError)
-{
- int r;
- struct newsnntp_group_info * info;
-
- loginIfNeeded(pError);
- if (* pError != ErrorNone) {
- return;
- }
-
- readerIfNeeded(pError);
- if (* pError != ErrorNone) {
- return;
- }
-
- r = newsnntp_group(mNNTP, folder->UTF8Characters(), &info);
- if (r == NEWSNNTP_ERROR_STREAM) {
- * pError = ErrorConnection;
- MCLog("select error : %s %i", MCUTF8DESC(this), * pError);
- return;
- }
- else if (r == NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP) {
- * pError = ErrorNonExistantFolder;
- return;
- }
- else if (r == MAILIMAP_ERROR_PARSE) {
- * pError = ErrorParse;
- return;
- }
-
- mState = STATE_SELECTED;
- * pError = ErrorNone;
- MCLog("select ok");
-}
-
-void NNTPSession::setConnectionLogger(ConnectionLogger * logger)
-{
- mConnectionLogger = logger;
-}
-
-ConnectionLogger * NNTPSession::connectionLogger()
-{
- return mConnectionLogger;
-}
-
// Taken from nntp/nntpdriver.c
static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct mailimf_fields ** result)
{
@@ -792,31 +635,31 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
clist * list;
struct mailimf_fields * fields;
int r;
-
+
list = clist_new();
if (list == NULL) {
r = MAIL_ERROR_MEMORY;
goto err;
}
-
+
if (item->ovr_subject != NULL) {
char * subject_str;
struct mailimf_subject * subject;
struct mailimf_field * field;
-
+
subject_str = strdup(item->ovr_subject);
if (subject_str == NULL) {
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
subject = mailimf_subject_new(subject_str);
if (subject == NULL) {
free(subject_str);
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
field = mailimf_field_new(MAILIMF_FIELD_SUBJECT,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
@@ -827,7 +670,7 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
r = clist_append(list, field);
if (r < 0) {
mailimf_field_free(field);
@@ -835,12 +678,12 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
goto free_list;
}
}
-
+
if (item->ovr_author != NULL) {
struct mailimf_mailbox_list * mb_list;
struct mailimf_from * from;
struct mailimf_field * field;
-
+
cur_token = 0;
r = mailimf_mailbox_list_parse(item->ovr_author, strlen(item->ovr_author),
&cur_token, &mb_list);
@@ -852,7 +695,7 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
field = mailimf_field_new(MAILIMF_FIELD_FROM,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, from,
@@ -863,7 +706,7 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
r = clist_append(list, field);
if (r < 0) {
mailimf_field_free(field);
@@ -871,20 +714,20 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
goto free_list;
}
break;
-
+
case MAILIMF_ERROR_PARSE:
break;
-
+
default:
goto free_list;
}
}
-
+
if (item->ovr_date != NULL) {
struct mailimf_date_time * date_time;
struct mailimf_orig_date * orig_date;
struct mailimf_field * field;
-
+
cur_token = 0;
r = mailimf_date_time_parse(item->ovr_date, strlen(item->ovr_date),
&cur_token, &date_time);
@@ -896,7 +739,7 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
field = mailimf_field_new(MAILIMF_FIELD_ORIG_DATE,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, orig_date, NULL,
@@ -907,7 +750,7 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
r = clist_append(list, field);
if (r < 0) {
mailimf_field_free(field);
@@ -915,24 +758,24 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
goto free_list;
}
break;
-
+
case MAILIMF_ERROR_PARSE:
break;
-
+
default:
goto free_list;
}
}
-
+
if (item->ovr_message_id != NULL) {
char * msgid_str;
struct mailimf_message_id * msgid;
struct mailimf_field * field;
-
+
cur_token = 0;
r = mailimf_msg_id_parse(item->ovr_message_id, strlen(item->ovr_message_id),
&cur_token, &msgid_str);
-
+
switch (r) {
case MAILIMF_NO_ERROR:
msgid = mailimf_message_id_new(msgid_str);
@@ -941,13 +784,13 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
field = mailimf_field_new(MAILIMF_FIELD_MESSAGE_ID,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, msgid, NULL,
NULL, NULL, NULL, NULL, NULL);
-
+
r = clist_append(list, field);
if (r < 0) {
mailimf_field_free(field);
@@ -955,25 +798,25 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
goto free_list;
}
break;
-
+
case MAILIMF_ERROR_PARSE:
break;
-
+
default:
goto free_list;
}
}
-
+
if (item->ovr_references != NULL) {
clist * msgid_list;
struct mailimf_references * references;
struct mailimf_field * field;
-
+
cur_token = 0;
-
+
r = mailimf_msg_id_list_parse(item->ovr_references, strlen(item->ovr_references),
&cur_token, &msgid_list);
-
+
switch (r) {
case MAILIMF_NO_ERROR:
references = mailimf_references_new(msgid_list);
@@ -984,41 +827,228 @@ static int xover_resp_to_fields(struct newsnntp_xover_resp_item * item, struct m
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
field = mailimf_field_new(MAILIMF_FIELD_REFERENCES,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
references, NULL, NULL, NULL, NULL);
-
+
r = clist_append(list, field);
if (r < 0) {
mailimf_field_free(field);
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
case MAILIMF_ERROR_PARSE:
break;
-
+
default:
goto free_list;
}
}
-
+
fields = mailimf_fields_new(list);
if (fields == NULL) {
r = MAIL_ERROR_MEMORY;
goto free_list;
}
-
+
* result = fields;
-
+
return MAIL_NO_ERROR;
-
+
free_list:
clist_foreach(list, (clist_func) mailimf_field_free, NULL);
clist_free(list);
err:
return r;
}
+
+void NNTPSession::postMessage(Data * messageData, NNTPProgressCallback * callback, ErrorCode * pError)
+{
+ int r;
+
+ messageData = dataWithFilteredBcc(messageData);
+
+ mProgressCallback = callback;
+ bodyProgress(0, messageData->length());
+
+ MCLog("setup");
+
+ MCLog("connect");
+ loginIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ goto err;
+ }
+
+ MCLog("send");
+ r = newsnntp_post(mNNTP, messageData->bytes(), messageData->length());
+
+ String * response;
+
+ response = NULL;
+ if (mNNTP->nntp_response != NULL) {
+ response = String::stringWithUTF8Characters(mNNTP->nntp_response);
+ }
+
+ if (r == NEWSNNTP_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ goto err;
+ }
+ else if (r != NEWSNNTP_NO_ERROR) {
+ * pError = ErrorSendMessage;
+ goto err;
+ }
+
+ bodyProgress(messageData->length(), messageData->length());
+ * pError = ErrorNone;
+
+err:
+ mProgressCallback = NULL;
+}
+
+void NNTPSession::postMessage(String * messagePath, NNTPProgressCallback * callback, ErrorCode * pError)
+{
+ Data * messageData = Data::dataWithContentsOfFile(messagePath);
+ if (!messageData) {
+ * pError = ErrorFile;
+ return;
+ }
+
+ return postMessage(messageData, callback, pError);
+}
+
+static void mmapStringDeallocator(char * bytes, unsigned int length) {
+ mmap_string_unref(bytes);
+}
+
+Data * NNTPSession::dataWithFilteredBcc(Data * data)
+{
+ int r;
+ size_t idx;
+ struct mailimf_message * msg;
+
+ idx = 0;
+ r = mailimf_message_parse(data->bytes(), data->length(), &idx, &msg);
+ if (r != MAILIMF_NO_ERROR) {
+ return Data::data();
+ }
+
+ struct mailimf_fields * fields = msg->msg_fields;
+ int col = 0;
+
+ int hasRecipient = 0;
+ bool bccWasActuallyRemoved = false;
+ for(clistiter * cur = clist_begin(fields->fld_list) ; cur != NULL ; cur = clist_next(cur)) {
+ struct mailimf_field * field = (struct mailimf_field *) clist_content(cur);
+ if (field->fld_type == MAILIMF_FIELD_BCC) {
+ mailimf_field_free(field);
+ clist_delete(fields->fld_list, cur);
+ bccWasActuallyRemoved = true;
+ break;
+ }
+ else if ((field->fld_type == MAILIMF_FIELD_TO) || (field->fld_type == MAILIMF_FIELD_CC)) {
+ hasRecipient = 1;
+ }
+ }
+ if (!hasRecipient) {
+ struct mailimf_address_list * imfTo;
+ imfTo = mailimf_address_list_new_empty();
+ mailimf_address_list_add_parse(imfTo, (char *) "Undisclosed recipients:;");
+ struct mailimf_to * toField = mailimf_to_new(imfTo);
+ struct mailimf_field * field = mailimf_field_new(MAILIMF_FIELD_TO, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, toField, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ mailimf_fields_add(fields, field);
+ }
+
+ Data * result;
+ if (!hasRecipient || bccWasActuallyRemoved) {
+ MMAPString * str = mmap_string_new("");
+ mailimf_fields_write_mem(str, &col, fields);
+ mmap_string_append(str, "\n");
+ mmap_string_append_len(str, msg->msg_body->bd_text, msg->msg_body->bd_size);
+
+ mmap_string_ref(str);
+
+ result = Data::data();
+ result->takeBytesOwnership(str->str, (unsigned int) str->len, mmapStringDeallocator);
+ }
+ else {
+ // filter Bcc and modify To: only if necessary.
+ result = data;
+ }
+
+ mailimf_message_free(msg);
+
+ return result;
+}
+
+void NNTPSession::selectGroup(String * folder, ErrorCode * pError)
+{
+ int r;
+ struct newsnntp_group_info * info;
+
+ loginIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return;
+ }
+
+ readerIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return;
+ }
+
+ r = newsnntp_group(mNNTP, folder->UTF8Characters(), &info);
+ if (r == NEWSNNTP_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ MCLog("select error : %s %i", MCUTF8DESC(this), * pError);
+ return;
+ }
+ else if (r == NEWSNNTP_ERROR_NO_SUCH_NEWS_GROUP) {
+ * pError = ErrorNonExistantFolder;
+ return;
+ }
+ else if (r == MAILIMAP_ERROR_PARSE) {
+ * pError = ErrorParse;
+ return;
+ }
+
+ mState = STATE_SELECTED;
+ * pError = ErrorNone;
+ MCLog("select ok");
+}
+
+void NNTPSession::lockConnectionLogger()
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+}
+
+void NNTPSession::unlockConnectionLogger()
+{
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
+void NNTPSession::setConnectionLogger(ConnectionLogger * logger)
+{
+ lockConnectionLogger();
+ mConnectionLogger = logger;
+ unlockConnectionLogger();
+}
+
+ConnectionLogger * NNTPSession::connectionLogger()
+{
+ ConnectionLogger * result;
+
+ lockConnectionLogger();
+ result = connectionLoggerNoLock();
+ unlockConnectionLogger();
+
+ return result;
+}
+
+ConnectionLogger * NNTPSession::connectionLoggerNoLock()
+{
+ return mConnectionLogger;
+}
+
diff --git a/src/core/nntp/MCNNTPSession.h b/src/core/nntp/MCNNTPSession.h
index 22734f2d..5e371eea 100644
--- a/src/core/nntp/MCNNTPSession.h
+++ b/src/core/nntp/MCNNTPSession.h
@@ -63,6 +63,11 @@ namespace mailcore {
virtual void setConnectionLogger(ConnectionLogger * logger);
virtual ConnectionLogger * connectionLogger();
+ public: // private
+ virtual void lockConnectionLogger();
+ virtual void unlockConnectionLogger();
+ virtual ConnectionLogger * connectionLoggerNoLock();
+
private:
String * mHostname;
unsigned int mPort;
@@ -77,7 +82,8 @@ namespace mailcore {
int mState;
ConnectionLogger * mConnectionLogger;
-
+ pthread_mutex_t mConnectionLoggerLock;
+
void init();
Data * dataWithFilteredBcc(Data * data);
static void body_progress(size_t current, size_t maximum, void * context);
diff --git a/src/core/pop/MCPOPSession.cpp b/src/core/pop/MCPOPSession.cpp
index ab8975a6..77452515 100644
--- a/src/core/pop/MCPOPSession.cpp
+++ b/src/core/pop/MCPOPSession.cpp
@@ -36,6 +36,7 @@ void POPSession::init()
mProgressCallback = NULL;
mState = STATE_DISCONNECTED;
mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
}
POPSession::POPSession()
@@ -45,6 +46,7 @@ POPSession::POPSession()
POPSession::~POPSession()
{
+ pthread_mutex_destroy(&mConnectionLoggerLock);
MC_SAFE_RELEASE(mHostname);
MC_SAFE_RELEASE(mUsername);
MC_SAFE_RELEASE(mPassword);
@@ -155,20 +157,24 @@ void POPSession::body_progress(size_t current, size_t maximum, void * context)
static void logger(mailpop3 * pop3, int log_type, const char * buffer, size_t size, void * context)
{
POPSession * session = (POPSession *) context;
-
- if (session->connectionLogger() == NULL)
+ session->lockConnectionLogger();
+
+ if (session->connectionLoggerNoLock() == NULL) {
+ session->unlockConnectionLogger();
return;
+ }
ConnectionLogType type = getConnectionType(log_type);
bool isBuffer = isBufferFromLogType(log_type);
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->log(session, type, data);
+ session->connectionLoggerNoLock()->log(session, type, data);
}
else {
- session->connectionLogger()->log(session, type, NULL);
+ session->connectionLoggerNoLock()->log(session, type, NULL);
}
+ session->unlockConnectionLogger();
}
void POPSession::setup()
@@ -592,12 +598,35 @@ void POPSession::noop(ErrorCode * pError)
}
}
+void POPSession::lockConnectionLogger()
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+}
+
+void POPSession::unlockConnectionLogger()
+{
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
void POPSession::setConnectionLogger(ConnectionLogger * logger)
{
+ lockConnectionLogger();
mConnectionLogger = logger;
+ unlockConnectionLogger();
}
ConnectionLogger * POPSession::connectionLogger()
{
+ ConnectionLogger * result;
+
+ lockConnectionLogger();
+ result = connectionLoggerNoLock();
+ unlockConnectionLogger();
+
+ return result;
+}
+
+ConnectionLogger * POPSession::connectionLoggerNoLock()
+{
return mConnectionLogger;
}
diff --git a/src/core/pop/MCPOPSession.h b/src/core/pop/MCPOPSession.h
index eda323c0..f32f9b18 100644
--- a/src/core/pop/MCPOPSession.h
+++ b/src/core/pop/MCPOPSession.h
@@ -64,7 +64,12 @@ namespace mailcore {
virtual void setConnectionLogger(ConnectionLogger * logger);
virtual ConnectionLogger * connectionLogger();
-
+
+ public: // private
+ virtual void lockConnectionLogger();
+ virtual void unlockConnectionLogger();
+ virtual ConnectionLogger * connectionLoggerNoLock();
+
private:
String * mHostname;
unsigned int mPort;
@@ -81,6 +86,7 @@ namespace mailcore {
int mState;
ConnectionLogger * mConnectionLogger;
+ pthread_mutex_t mConnectionLoggerLock;
void init();
void bodyProgress(unsigned int current, unsigned int maximum);
diff --git a/src/core/provider/MCAccountValidator.cpp b/src/core/provider/MCAccountValidator.cpp
index 59538c72..1e6ebdd9 100644
--- a/src/core/provider/MCAccountValidator.cpp
+++ b/src/core/provider/MCAccountValidator.cpp
@@ -64,6 +64,9 @@ void AccountValidator::init()
mImapEnabled = false;
mPopEnabled = false;
mSmtpEnabled = false;
+
+ mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
}
AccountValidator::AccountValidator()
@@ -73,6 +76,7 @@ AccountValidator::AccountValidator()
AccountValidator::~AccountValidator()
{
+ pthread_mutex_destroy(&mConnectionLoggerLock);
MC_SAFE_RELEASE(mEmail);
MC_SAFE_RELEASE(mUsername);
MC_SAFE_RELEASE(mPassword);
@@ -250,6 +254,7 @@ void AccountValidator::checkNextHost()
mImapSession->setHostname(mImapServer->hostname());
mImapSession->setPort(mImapServer->port());
mImapSession->setConnectionType(mImapServer->connectionType());
+ mImapSession->setConnectionLogger(this);
mOperation = (IMAPOperation *)mImapSession->checkAccountOperation();
mOperation->retain();
@@ -271,12 +276,13 @@ void AccountValidator::checkNextHost()
mPopSession = new POPAsyncSession();
mPopSession->setUsername(mUsername);
mPopSession->setPassword(mPassword);
-
+
mPopServer = (NetService *) mPopServices->objectAtIndex(mCurrentServiceIndex);
mPopSession->setHostname(mPopServer->hostname());
mPopSession->setPort(mPopServer->port());
mPopSession->setConnectionType(mPopServer->connectionType());
-
+ mPopSession->setConnectionLogger(this);
+
mOperation = mPopSession->checkAccountOperation();
mOperation->retain();
mOperation->setCallback(this);
@@ -306,7 +312,8 @@ void AccountValidator::checkNextHost()
mSmtpSession->setHostname(mSmtpServer->hostname());
mSmtpSession->setPort(mSmtpServer->port());
mSmtpSession->setConnectionType(mSmtpServer->connectionType());
-
+ mSmtpSession->setConnectionLogger(this);
+
mOperation = mSmtpSession->checkAccountOperation(Address::addressWithMailbox(mEmail));
mOperation->retain();
mOperation->setCallback(this);
@@ -334,16 +341,19 @@ void AccountValidator::checkNextHostDone()
if (mCurrentServiceTested == SERVICE_IMAP) {
mImapError = ((IMAPOperation *)mOperation)->error();
error = mImapError;
+ mImapSession->setConnectionLogger(NULL);
MC_SAFE_RELEASE(mImapSession);
}
else if (mCurrentServiceTested == SERVICE_POP) {
mPopError = ((POPOperation *)mOperation)->error();
error = mPopError;
+ mPopSession->setConnectionLogger(NULL);
MC_SAFE_RELEASE(mPopSession);
}
else if (mCurrentServiceTested == SERVICE_SMTP) {
mSmtpError = ((SMTPOperation *)mOperation)->error();
error = mSmtpError;
+ mSmtpSession->setConnectionLogger(NULL);
MC_SAFE_RELEASE(mSmtpSession);
}
@@ -495,3 +505,30 @@ ErrorCode AccountValidator::smtpError()
{
return mSmtpError;
}
+
+void AccountValidator::setConnectionLogger(ConnectionLogger * logger)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ mConnectionLogger = logger;
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
+ConnectionLogger * AccountValidator::connectionLogger()
+{
+ ConnectionLogger * result;
+
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ result = mConnectionLogger;
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+
+ return result;
+}
+
+void AccountValidator::log(void * sender, ConnectionLogType logType, Data * buffer)
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+ if (mConnectionLogger != NULL) {
+ mConnectionLogger->log(this, logType, buffer);
+ }
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
diff --git a/src/core/provider/MCAccountValidator.h b/src/core/provider/MCAccountValidator.h
index 436317cf..788458b6 100644
--- a/src/core/provider/MCAccountValidator.h
+++ b/src/core/provider/MCAccountValidator.h
@@ -23,7 +23,7 @@ namespace mailcore {
class POPAsyncSession;
class SMTPAsyncSession;
- class MAILCORE_EXPORT AccountValidator : public Operation, public OperationCallback {
+ class MAILCORE_EXPORT AccountValidator : public Operation, public OperationCallback, public ConnectionLogger {
public:
AccountValidator();
virtual ~AccountValidator();
@@ -53,6 +53,9 @@ namespace mailcore {
virtual void setPopServices(Array * popServices);
virtual Array * /* NetService */ popServices();
+ virtual void setConnectionLogger(ConnectionLogger * logger);
+ virtual ConnectionLogger * connectionLogger();
+
// result
virtual String * identifier();
virtual NetService * imapServer();
@@ -64,7 +67,10 @@ namespace mailcore {
virtual void start();
virtual void cancel();
-
+
+ public: // ConnectionLogger
+ virtual void log(void * sender, ConnectionLogType logType, Data * buffer);
+
private:
String * mEmail; /* for SMTP */
String * mUsername;
@@ -104,6 +110,9 @@ namespace mailcore {
bool mPopEnabled;
bool mSmtpEnabled;
+ pthread_mutex_t mConnectionLoggerLock;
+ ConnectionLogger * mConnectionLogger;
+
void init();
void setupServices();
void resolveMX();
diff --git a/src/core/smtp/MCSMTPSession.cpp b/src/core/smtp/MCSMTPSession.cpp
index 8bcaefff..ebf94f43 100644
--- a/src/core/smtp/MCSMTPSession.cpp
+++ b/src/core/smtp/MCSMTPSession.cpp
@@ -42,6 +42,7 @@ void SMTPSession::init()
mLastLibetpanError = 0;
mLastSMTPResponseCode = 0;
mConnectionLogger = NULL;
+ pthread_mutex_init(&mConnectionLoggerLock, NULL);
}
SMTPSession::SMTPSession()
@@ -51,6 +52,7 @@ SMTPSession::SMTPSession()
SMTPSession::~SMTPSession()
{
+ pthread_mutex_destroy(&mConnectionLoggerLock);
MC_SAFE_RELEASE(mLastSMTPResponse);
MC_SAFE_RELEASE(mHostname);
MC_SAFE_RELEASE(mUsername);
@@ -184,24 +186,29 @@ void SMTPSession::bodyProgress(unsigned int current, unsigned int maximum)
static void logger(mailsmtp * smtp, int log_type, const char * buffer, size_t size, void * context)
{
SMTPSession * session = (SMTPSession *) context;
+ session->lockConnectionLogger();
- if (session->connectionLogger() == NULL)
+ if (session->connectionLoggerNoLock() == NULL) {
+ session->unlockConnectionLogger();
return;
+ }
ConnectionLogType type = getConnectionType(log_type);
if ((int) type == -1) {
// in case of MAILSTREAM_LOG_TYPE_INFO_RECEIVED or MAILSTREAM_LOG_TYPE_INFO_SENT.
+ session->unlockConnectionLogger();
return;
}
bool isBuffer = isBufferFromLogType(log_type);
if (isBuffer) {
Data * data = Data::dataWithBytes(buffer, (unsigned int) size);
- session->connectionLogger()->log(session, type, data);
+ session->connectionLoggerNoLock()->log(session, type, data);
}
else {
- session->connectionLogger()->log(session, type, NULL);
+ session->connectionLoggerNoLock()->log(session, type, NULL);
}
+ session->unlockConnectionLogger();
}
@@ -862,12 +869,35 @@ bool SMTPSession::isDisconnected()
return mState == STATE_DISCONNECTED;
}
+void SMTPSession::lockConnectionLogger()
+{
+ pthread_mutex_lock(&mConnectionLoggerLock);
+}
+
+void SMTPSession::unlockConnectionLogger()
+{
+ pthread_mutex_unlock(&mConnectionLoggerLock);
+}
+
void SMTPSession::setConnectionLogger(ConnectionLogger * logger)
{
+ lockConnectionLogger();
mConnectionLogger = logger;
+ unlockConnectionLogger();
}
ConnectionLogger * SMTPSession::connectionLogger()
{
+ ConnectionLogger * result;
+
+ lockConnectionLogger();
+ result = connectionLoggerNoLock();
+ unlockConnectionLogger();
+
+ return result;
+}
+
+ConnectionLogger * SMTPSession::connectionLoggerNoLock()
+{
return mConnectionLogger;
}
diff --git a/src/core/smtp/MCSMTPSession.h b/src/core/smtp/MCSMTPSession.h
index 64ff30d0..7e899881 100644
--- a/src/core/smtp/MCSMTPSession.h
+++ b/src/core/smtp/MCSMTPSession.h
@@ -68,6 +68,11 @@ namespace mailcore {
virtual void noop(ErrorCode * pError);
+ public: // private
+ virtual void lockConnectionLogger();
+ virtual void unlockConnectionLogger();
+ virtual ConnectionLogger * connectionLoggerNoLock();
+
private:
String * mHostname;
unsigned int mPort;
@@ -89,7 +94,8 @@ namespace mailcore {
int mLastSMTPResponseCode;
ConnectionLogger * mConnectionLogger;
-
+ pthread_mutex_t mConnectionLoggerLock;
+
void init();
Data * dataWithFilteredBcc(Data * data);
static void body_progress(size_t current, size_t maximum, void * context);
diff --git a/src/objc/provider/MCOAccountValidator.h b/src/objc/provider/MCOAccountValidator.h
index b5f09bc2..8d6676b1 100644
--- a/src/objc/provider/MCOAccountValidator.h
+++ b/src/objc/provider/MCOAccountValidator.h
@@ -8,6 +8,7 @@
#import <Foundation/Foundation.h>
#import <MailCore/MCOOperation.h>
+#import <MailCore/MCOConstants.h>
/**
This class is used to validate an email provider and it's associated
@@ -34,6 +35,8 @@
@property (nonatomic, assign, getter=isPopEnabled) BOOL popEnabled;
@property (nonatomic, assign, getter=isSmtpEnabled) BOOL smtpEnabled;
+@property (nonatomic, copy) MCOConnectionLogger connectionLogger;
+
// result
@property (nonatomic, retain, readonly) NSString * identifier;
@property (nonatomic, retain, readonly) MCONetService * imapServer;
diff --git a/src/objc/provider/MCOAccountValidator.mm b/src/objc/provider/MCOAccountValidator.mm
index 0aa9a393..ab240bf5 100644
--- a/src/objc/provider/MCOAccountValidator.mm
+++ b/src/objc/provider/MCOAccountValidator.mm
@@ -20,10 +20,11 @@ typedef void (^CompletionType)(void);
@interface MCOAccountValidator ()
- (void) _operationCompleted;
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data;
@end
-class MCOValidatorOperationCallback: public mailcore::Object, public mailcore::OperationCallback {
+class MCOValidatorOperationCallback: public mailcore::Object, public mailcore::OperationCallback, public mailcore::ConnectionLogger {
public:
MCOValidatorOperationCallback(MCOAccountValidator * op)
{
@@ -35,6 +36,11 @@ public:
[mOperation _operationCompleted];
}
+ virtual void log(void * sender, mailcore::ConnectionLogType logType, mailcore::Data * data)
+ {
+ [mOperation _logWithSender:sender connectionType:(MCOConnectionLogType)logType data:MCO_TO_OBJC(data)];
+ }
+
private:
MCOAccountValidator * mOperation;
};
@@ -42,7 +48,8 @@ private:
@implementation MCOAccountValidator{
CompletionType _completionBlock;
mailcore::AccountValidator * _validator;
- MCOValidatorOperationCallback * _imapCallback;
+ MCOValidatorOperationCallback * _callback;
+ MCOConnectionLogger _connectionLogger;
}
#define nativeType mailcore::AccountValidator
@@ -84,13 +91,22 @@ MCO_OBJC_SYNTHESIZE_BOOL(setSmtpEnabled, isSmtpEnabled)
self = [super initWithMCOperation:validator];
_validator = validator;
- _imapCallback = new MCOValidatorOperationCallback(self);
- _validator->setCallback(_imapCallback);
+ _callback = new MCOValidatorOperationCallback(self);
+ _validator->setCallback(_callback);
_validator->retain();
return self;
}
+- (void) dealloc
+{
+ [_completionBlock release];
+ MC_SAFE_RELEASE(_validator);
+ MC_SAFE_RELEASE(_callback);
+ [_connectionLogger release];
+ [super dealloc];
+}
+
- (void) start:(void (^)(void))completionBlock
{
_completionBlock = [completionBlock copy];
@@ -150,4 +166,27 @@ MCO_OBJC_SYNTHESIZE_BOOL(setSmtpEnabled, isSmtpEnabled)
return [NSError mco_errorWithErrorCode:_validator->smtpError()];
}
+- (void) setConnectionLogger:(MCOConnectionLogger)connectionLogger
+{
+ [_connectionLogger release];
+ _connectionLogger = [connectionLogger copy];
+
+ if (_connectionLogger != nil) {
+ _validator->setConnectionLogger(_callback);
+ }
+ else {
+ _validator->setConnectionLogger(NULL);
+ }
+}
+
+- (MCOConnectionLogger) connectionLogger
+{
+ return _connectionLogger;
+}
+
+- (void) _logWithSender:(void *)sender connectionType:(MCOConnectionLogType)logType data:(NSData *)data
+{
+ _connectionLogger(sender, logType, data);
+}
+
@end