aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/pop
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/pop')
-rw-r--r--src/core/pop/.DS_Storebin0 -> 6148 bytes
-rw-r--r--src/core/pop/MCPOP.h9
-rw-r--r--src/core/pop/MCPOPMessageInfo.cc76
-rw-r--r--src/core/pop/MCPOPMessageInfo.h38
-rw-r--r--src/core/pop/MCPOPProgressCallback.h15
-rw-r--r--src/core/pop/MCPOPSession.cc545
-rw-r--r--src/core/pop/MCPOPSession.h90
7 files changed, 773 insertions, 0 deletions
diff --git a/src/core/pop/.DS_Store b/src/core/pop/.DS_Store
new file mode 100644
index 00000000..5008ddfc
--- /dev/null
+++ b/src/core/pop/.DS_Store
Binary files differ
diff --git a/src/core/pop/MCPOP.h b/src/core/pop/MCPOP.h
new file mode 100644
index 00000000..7651f9e6
--- /dev/null
+++ b/src/core/pop/MCPOP.h
@@ -0,0 +1,9 @@
+#ifndef __MAILCORE_MCPOP_H
+
+#define __MAILCORE_MCPOP_H
+
+#include <mailcore/MCPOPMessageInfo.h>
+#include <mailcore/MCPOPProgressCallback.h>
+#include <mailcore/MCPOPSession.h>
+
+#endif
diff --git a/src/core/pop/MCPOPMessageInfo.cc b/src/core/pop/MCPOPMessageInfo.cc
new file mode 100644
index 00000000..eafbda9f
--- /dev/null
+++ b/src/core/pop/MCPOPMessageInfo.cc
@@ -0,0 +1,76 @@
+#include "MCPOPMessageInfo.h"
+
+using namespace mailcore;
+
+void POPMessageInfo::init()
+{
+ mIndex = 0;
+ mSize = 0;
+ mUid = NULL;
+}
+
+POPMessageInfo::POPMessageInfo()
+{
+ init();
+}
+
+POPMessageInfo::POPMessageInfo(POPMessageInfo * other)
+{
+ init();
+ mIndex = other->mIndex;
+ mSize = other->mSize;
+ MC_SAFE_REPLACE_COPY(String, mUid, other->mUid);
+}
+
+POPMessageInfo::~POPMessageInfo()
+{
+ MC_SAFE_RELEASE(mUid);
+}
+
+#if 0
+String * POPMessageInfo::className()
+{
+ return MCSTR("POPMessageInfo");
+}
+#endif
+
+String * POPMessageInfo::description()
+{
+ return String::stringWithUTF8Format("<%s:%p %u %s %u>",
+ MCUTF8(className()), this, mIndex, MCUTF8(mUid), mSize);
+}
+
+Object * POPMessageInfo::copy()
+{
+ return new POPMessageInfo(this);
+}
+
+void POPMessageInfo::setIndex(unsigned int index)
+{
+ mIndex = index;
+}
+
+unsigned int POPMessageInfo::index()
+{
+ return mIndex;
+}
+
+void POPMessageInfo::setSize(unsigned int size)
+{
+ mSize = size;
+}
+
+unsigned int POPMessageInfo::size()
+{
+ return mSize;
+}
+
+void POPMessageInfo::setUid(String * uid)
+{
+ MC_SAFE_REPLACE_COPY(String, mUid, uid);
+}
+
+String * POPMessageInfo::uid()
+{
+ return mUid;
+}
diff --git a/src/core/pop/MCPOPMessageInfo.h b/src/core/pop/MCPOPMessageInfo.h
new file mode 100644
index 00000000..1e52b695
--- /dev/null
+++ b/src/core/pop/MCPOPMessageInfo.h
@@ -0,0 +1,38 @@
+#ifndef __MAILCORE_MCPOPMESSAGEINFO_H_
+
+#define __MAILCORE_MCPOPMESSAGEINFO_H_
+
+#include <mailcore/MCBaseTypes.h>
+
+namespace mailcore {
+
+ class POPMessageInfo : public Object {
+ private:
+ unsigned int mIndex;
+ unsigned int mSize;
+ String * mUid;
+
+ void init();
+
+ public:
+ POPMessageInfo();
+ POPMessageInfo(POPMessageInfo * other);
+ virtual ~POPMessageInfo();
+
+ //virtual String * className();
+ virtual String * description();
+ virtual Object * copy();
+
+ virtual void setIndex(unsigned int index);
+ virtual unsigned int index();
+
+ virtual void setSize(unsigned int size);
+ virtual unsigned int size();
+
+ virtual void setUid(String * uid);
+ virtual String * uid();
+ };
+
+}
+
+#endif
diff --git a/src/core/pop/MCPOPProgressCallback.h b/src/core/pop/MCPOPProgressCallback.h
new file mode 100644
index 00000000..2fc1b66b
--- /dev/null
+++ b/src/core/pop/MCPOPProgressCallback.h
@@ -0,0 +1,15 @@
+#ifndef __MAILCORE_MCPOPPROGRESSCALLBACK_H_
+
+#define __MAILCORE_MCPOPPROGRESSCALLBACK_H_
+
+namespace mailcore {
+
+ class POPSession;
+
+ class POPProgressCallback {
+ public:
+ virtual void bodyProgress(POPSession * session, unsigned int current, unsigned int maximum) {};
+ };
+}
+
+#endif
diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc
new file mode 100644
index 00000000..eea5af90
--- /dev/null
+++ b/src/core/pop/MCPOPSession.cc
@@ -0,0 +1,545 @@
+#include "MCPOPSession.h"
+
+#include <string.h>
+
+#include "MCPOPMessageInfo.h"
+#include "MCPOPProgressCallback.h"
+#include "MCMessageHeader.h"
+
+using namespace mailcore;
+
+enum {
+ STATE_DISCONNECTED,
+ STATE_CONNECTED,
+ STATE_LOGGEDIN,
+ STATE_LISTED,
+};
+
+void POPSession::init()
+{
+ mHostname = NULL;
+ mPort = 0;
+ mUsername = NULL;
+ mPassword = NULL;
+ mAuthType = AuthTypeSASLNone;
+ mConnectionType = ConnectionTypeClear;
+ mCheckCertificateEnabled = true;
+ mTimeout = 30;
+
+ mPop = NULL;
+ mCapabilities = POPCapabilityNone;
+ mProgressCallback = NULL;
+ mState = STATE_DISCONNECTED;
+}
+
+POPSession::POPSession()
+{
+ init();
+}
+
+POPSession::~POPSession()
+{
+ MC_SAFE_RELEASE(mHostname);
+ MC_SAFE_RELEASE(mUsername);
+ MC_SAFE_RELEASE(mPassword);
+}
+
+#if 0
+String * POPSession::className()
+{
+ return MCSTR("POPSession");
+}
+#endif
+
+void POPSession::setHostname(String * hostname)
+{
+ MC_SAFE_REPLACE_COPY(String, mHostname, hostname);
+}
+
+String * POPSession::hostname()
+{
+ return mHostname;
+}
+
+void POPSession::setPort(unsigned int port)
+{
+ mPort = port;
+}
+
+unsigned int POPSession::port()
+{
+ return mPort;
+}
+
+void POPSession::setUsername(String * username)
+{
+ MC_SAFE_REPLACE_COPY(String, mUsername, username);
+}
+
+String * POPSession::username()
+{
+ return mUsername;
+}
+
+void POPSession::setPassword(String * password)
+{
+ MC_SAFE_REPLACE_COPY(String, mPassword, password);
+}
+
+String * POPSession::password()
+{
+ return mPassword;
+}
+
+void POPSession::setAuthType(AuthType authType)
+{
+ mAuthType = authType;
+}
+
+AuthType POPSession::authType()
+{
+ return mAuthType;
+}
+
+void POPSession::setConnectionType(ConnectionType connectionType)
+{
+ mConnectionType = connectionType;
+}
+
+ConnectionType POPSession::connectionType()
+{
+ return mConnectionType;
+}
+
+void POPSession::setTimeout(time_t timeout)
+{
+ mTimeout = timeout;
+}
+
+time_t POPSession::timeout()
+{
+ return mTimeout;
+}
+
+void POPSession::setCheckCertificateEnabled(bool enabled)
+{
+ mCheckCertificateEnabled = enabled;
+}
+
+bool POPSession::isCheckCertificateEnabled()
+{
+ return mCheckCertificateEnabled;
+}
+
+bool POPSession::checkCertificate()
+{
+ // XXX
+ return true;
+}
+
+void POPSession::bodyProgress(unsigned int current, unsigned int maximum)
+{
+ if (mProgressCallback != NULL) {
+ mProgressCallback->bodyProgress(this, current, maximum);
+ }
+}
+
+void POPSession::body_progress(size_t current, size_t maximum, void * context)
+{
+ POPSession * session;
+
+ session = (POPSession *) context;
+ session->bodyProgress((unsigned int) current, (unsigned int) maximum);
+}
+
+void POPSession::setup()
+{
+ mPop = mailpop3_new(0, NULL);
+}
+
+void POPSession::unsetup()
+{
+ if (mPop != NULL) {
+ if (mPop->pop3_stream != NULL) {
+ mailstream_close(mPop->pop3_stream);
+ mPop->pop3_stream = NULL;
+ }
+ mailpop3_free(mPop);
+ mPop = NULL;
+ }
+}
+
+void POPSession::connectIfNeeded(ErrorCode * pError)
+{
+ if (mState == STATE_DISCONNECTED) {
+ connect(pError);
+ }
+ else {
+ * pError = ErrorNone;
+ }
+}
+
+void POPSession::connect(ErrorCode * pError)
+{
+ int r;
+
+ setup();
+
+ switch (mConnectionType) {
+ case ConnectionTypeStartTLS:
+ MCLog("connect %s %u", MCUTF8(hostname()), (unsigned int) port());
+ r = mailpop3_socket_connect(mPop, MCUTF8(hostname()), port());
+ if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorConnection;
+ return;
+ }
+
+ MCLog("start TLS");
+ r = mailpop3_socket_starttls(mPop);
+ if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorStartTLSNotAvailable;
+ return;
+ }
+ MCLog("done");
+ if (!checkCertificate()) {
+ * pError = ErrorCertificate;
+ return;
+ }
+ break;
+
+ case ConnectionTypeTLS:
+ MCLog("connect %s %u", MCUTF8(hostname()), (unsigned int) port());
+ r = mailpop3_ssl_connect(mPop, MCUTF8(hostname()), port());
+ if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorConnection;
+ return;
+ }
+ if (!checkCertificate()) {
+ * pError = ErrorCertificate;
+ return;
+ }
+ break;
+
+ default:
+ r = mailpop3_socket_connect(mPop, MCUTF8(hostname()), port());
+ if (r != MAILIMAP_NO_ERROR) {
+ * pError = ErrorConnection;
+ return;
+ }
+ break;
+ }
+
+ mailstream_low * low;
+ String * identifierString;
+ char * identifier;
+
+ low = mailstream_get_low(mPop->pop3_stream);
+ if (mUsername != NULL) {
+ identifierString = String::stringWithUTF8Format("%s@%s:%u", MCUTF8(mUsername), MCUTF8(mHostname), mPort);
+ }
+ else {
+ identifierString = String::stringWithUTF8Format("%s:%u", MCUTF8(mUsername), mPort);
+ }
+ identifier = strdup(identifierString->UTF8Characters());
+ mailstream_low_set_identifier(low, identifier);
+ mState = STATE_CONNECTED;
+ * pError = ErrorNone;
+}
+
+void POPSession::disconnect()
+{
+ if (mPop == NULL)
+ return;
+
+ mailpop3_quit(mPop);
+ mState = STATE_DISCONNECTED;
+ unsetup();
+}
+
+void POPSession::loginIfNeeded(ErrorCode * pError)
+{
+ connectIfNeeded(pError);
+ if (* pError != ErrorNone)
+ return;
+
+ if (mState == STATE_CONNECTED) {
+ login(pError);
+ }
+ else {
+ * pError = ErrorNone;
+ }
+}
+
+void POPSession::login(ErrorCode * pError)
+{
+ int r;
+ const char * utf8username;
+ const char * utf8password;
+
+ utf8username = MCUTF8(username());
+ utf8password = MCUTF8(password());
+ if (utf8username == NULL) {
+ utf8username = "";
+ }
+ if (utf8password == NULL) {
+ utf8password = "";
+ }
+
+ switch (authType()) {
+ case 0:
+ default:
+ r = mailpop3_user(mPop, utf8username);
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorAuthentication;
+ return;
+ }
+
+ r = mailpop3_pass(mPop, utf8password);
+ break;
+
+ case AuthTypeSASLCRAMMD5:
+ r = mailpop3_auth(mPop, "CRAM-MD5",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL);
+ break;
+
+ case AuthTypeSASLPlain:
+ r = mailpop3_auth(mPop, "PLAIN",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL);
+ break;
+
+ case AuthTypeSASLGSSAPI:
+ // needs to be tested
+ r = mailpop3_auth(mPop, "GSSAPI",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL /* realm */);
+ break;
+
+ case AuthTypeSASLDIGESTMD5:
+ r = mailpop3_auth(mPop, "DIGEST-MD5",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL);
+ break;
+
+ case AuthTypeSASLLogin:
+ r = mailpop3_auth(mPop, "LOGIN",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL);
+ break;
+
+ case AuthTypeSASLSRP:
+ r = mailpop3_auth(mPop, "SRP",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL);
+ break;
+
+ case AuthTypeSASLNTLM:
+ r = mailpop3_auth(mPop, "NTLM",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL /* realm */);
+ break;
+
+ case AuthTypeSASLKerberosV4:
+ r = mailpop3_auth(mPop, "KERBEROS_V4",
+ MCUTF8(hostname()),
+ NULL,
+ NULL,
+ utf8username, utf8username,
+ utf8password, NULL /* realm */);
+ break;
+ }
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorAuthentication;
+ return;
+ }
+
+ mState = STATE_LOGGEDIN;
+ * pError = ErrorNone;
+}
+
+Array * POPSession::fetchMessages(ErrorCode * pError)
+{
+ int r;
+ carray * msg_list;
+
+ loginIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return NULL;
+ }
+
+ r = mailpop3_list(mPop, &msg_list);
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return NULL;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorFetchMessageList;
+ return NULL;
+ }
+
+ Array * result = Array::array();
+ for(unsigned int i = 0 ; i < carray_count(msg_list) ; i ++) {
+ struct mailpop3_msg_info * msg_info;
+ String * uid;
+
+ msg_info = (struct mailpop3_msg_info *) carray_get(msg_list, i);
+ if (msg_info->msg_uidl == NULL)
+ continue;
+
+ uid = String::stringWithUTF8Characters(msg_info->msg_uidl);
+
+ POPMessageInfo * info = new POPMessageInfo();
+ info->setUid(uid);
+ info->setIndex(msg_info->msg_index);
+ result->addObject(info);
+ info->release();
+ }
+
+ * pError = ErrorNone;
+ mState = STATE_LISTED;
+
+ return result;
+}
+
+void POPSession::listIfNeeded(ErrorCode * pError)
+{
+ if (mState == STATE_LISTED) {
+ * pError = ErrorNone;
+ return;
+ }
+
+ fetchMessages(pError);
+}
+
+MessageHeader * POPSession::fetchHeader(unsigned int index, ErrorCode * pError)
+{
+ int r;
+ char * content;
+ size_t content_len;
+
+ listIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return NULL;
+ }
+
+ r = mailpop3_top(mPop, index, 0, &content, &content_len);
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return NULL;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorFetch;
+ return NULL;
+ }
+
+ Data * data;
+ data = new Data(content, (unsigned int) content_len);
+ MessageHeader * result = new MessageHeader();
+ result->importHeadersData(data);
+ result->autorelease();
+ data->release();
+
+ mailpop3_top_free(content);
+ * pError = ErrorNone;
+
+ return result;
+}
+
+MessageHeader * POPSession::fetchHeader(POPMessageInfo * msg, ErrorCode * pError)
+{
+ return fetchHeader(msg->index(), pError);
+}
+
+Data * POPSession::fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError)
+{
+ int r;
+ char * content;
+ size_t content_len;
+
+ listIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return NULL;
+ }
+
+ mProgressCallback = callback;
+
+ r = mailpop3_retr(mPop, index, &content, &content_len);
+ mProgressCallback = NULL;
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return NULL;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorFetch;
+ return NULL;
+ }
+
+ Data * result;
+ result = Data::dataWithBytes(content, (unsigned int) content_len);
+ mailpop3_retr_free(content);
+ * pError = ErrorNone;
+
+ return result;
+}
+
+Data * POPSession::fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError)
+{
+ return fetchMessage(msg->index(), callback, pError);
+}
+
+void POPSession::deleteMessage(unsigned int index, ErrorCode * pError)
+{
+ int r;
+
+ listIfNeeded(pError);
+ if (* pError != ErrorNone) {
+ return;
+ }
+
+ r = mailpop3_dele(mPop, index);
+ if (r == MAILPOP3_ERROR_STREAM) {
+ * pError = ErrorConnection;
+ return;
+ }
+ else if (r != MAILPOP3_NO_ERROR) {
+ * pError = ErrorDeleteMessage;
+ return;
+ }
+
+ * pError = ErrorNone;
+}
+
+void POPSession::deleteMessage(POPMessageInfo * msg, ErrorCode * pError)
+{
+ deleteMessage(msg->index(), pError);
+}
diff --git a/src/core/pop/MCPOPSession.h b/src/core/pop/MCPOPSession.h
new file mode 100644
index 00000000..ef6c132b
--- /dev/null
+++ b/src/core/pop/MCPOPSession.h
@@ -0,0 +1,90 @@
+#ifndef __MAILCORE_MCPOPSESSION_H_
+
+#define __MAILCORE_MCPOPSESSION_H_
+
+#include <mailcore/MCBaseTypes.h>
+#include <mailcore/MCMessageConstants.h>
+#include <libetpan/libetpan.h>
+
+namespace mailcore {
+
+ class POPMessageInfo;
+ class POPProgressCallback;
+ class MessageHeader;
+
+ class POPSession : public Object {
+ private:
+ String * mHostname;
+ unsigned int mPort;
+ String * mUsername;
+ String * mPassword;
+ AuthType mAuthType;
+ ConnectionType mConnectionType;
+ bool mCheckCertificateEnabled;
+ time_t mTimeout;
+
+ mailpop3 * mPop;
+ POPCapability mCapabilities;
+ POPProgressCallback * mProgressCallback;
+ int mState;
+
+ void init();
+ void bodyProgress(unsigned int current, unsigned int maximum);
+ bool checkCertificate();
+ static void body_progress(size_t current, size_t maximum, void * context);
+ void setup();
+ void unsetup();
+ void connectIfNeeded(ErrorCode * pError);
+ void loginIfNeeded(ErrorCode * pError);
+ void listIfNeeded(ErrorCode * pError);
+
+ public:
+ POPSession();
+ virtual ~POPSession();
+
+ //virtual String * className();
+
+ virtual void setHostname(String * hostname);
+ virtual String * hostname();
+
+ virtual void setPort(unsigned int port);
+ virtual unsigned int port();
+
+ virtual void setUsername(String * login);
+ virtual String * username();
+
+ virtual void setPassword(String * password);
+ virtual String * password();
+
+ virtual void setAuthType(AuthType authType);
+ virtual AuthType authType();
+
+ virtual void setConnectionType(ConnectionType connectionType);
+ virtual ConnectionType connectionType();
+
+ virtual void setTimeout(time_t timeout);
+ virtual time_t timeout();
+
+ virtual void setCheckCertificateEnabled(bool enabled);
+ virtual bool isCheckCertificateEnabled();
+
+ virtual void connect(ErrorCode * pError);
+ virtual void disconnect();
+
+ virtual void login(ErrorCode * pError);
+
+ Array * fetchMessages(ErrorCode * pError);
+
+ MessageHeader * fetchHeader(unsigned int index, ErrorCode * pError);
+ MessageHeader * fetchHeader(POPMessageInfo * msg, ErrorCode * pError);
+
+ Data * fetchMessage(unsigned int index, POPProgressCallback * callback, ErrorCode * pError);
+ Data * fetchMessage(POPMessageInfo * msg, POPProgressCallback * callback, ErrorCode * pError);
+
+ void deleteMessage(unsigned int index, ErrorCode * pError);
+ void deleteMessage(POPMessageInfo * msg, ErrorCode * pError);
+ };
+
+}
+
+#endif