mirror of
https://github.com/deltachat/deltachat-core.git
synced 2025-10-06 03:50:08 +02:00
Prepare thread for message fetching.
This commit is contained in:
parent
9c4e1000ef
commit
6d5b5983e7
7 changed files with 178 additions and 76 deletions
11
src/main.cpp
11
src/main.cpp
|
@ -87,6 +87,7 @@ int main(int argc, char ** argv)
|
|||
printf("get <key> show configuration value\n");
|
||||
printf("connect connect to mailbox server\n");
|
||||
printf("disconnect disconnect from mailbox server\n");
|
||||
printf("fetch fetch messages\n");
|
||||
printf("info show database information\n");
|
||||
printf("exit exit program\n");
|
||||
}
|
||||
|
@ -117,12 +118,20 @@ int main(int argc, char ** argv)
|
|||
}
|
||||
else if( strcmp(cmd, "connect")==0 )
|
||||
{
|
||||
mailbox->Connect();
|
||||
if( !mailbox->Connect() ) {
|
||||
print_error();
|
||||
}
|
||||
}
|
||||
else if( strcmp(cmd, "disconnect")==0 )
|
||||
{
|
||||
mailbox->Disconnect();
|
||||
}
|
||||
else if( strcmp(cmd, "fetch")==0 )
|
||||
{
|
||||
if( !mailbox->Fetch() ) {
|
||||
print_error();
|
||||
}
|
||||
}
|
||||
else if( strncmp(cmd, "set", 3)==0 )
|
||||
{
|
||||
char* arg1 = (char*)strstr(cmd, " ");
|
||||
|
|
132
src/mrimap.cpp
132
src/mrimap.cpp
|
@ -23,6 +23,11 @@
|
|||
* Authors: Björn Petersen
|
||||
* Purpose: Reading from IMAP servers, see header for details.
|
||||
*
|
||||
*******************************************************************************
|
||||
*
|
||||
* TODO: On Android, I think, the thread must be marked using
|
||||
* AttachCurrentThread(), see MailCore2 code
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
@ -47,6 +52,7 @@ static bool is_error(int r, const char* msg)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
static char * get_msg_att_msg_content(struct mailimap_msg_att * msg_att, size_t * p_msg_size)
|
||||
{
|
||||
clistiter * cur;
|
||||
|
@ -182,6 +188,11 @@ static void fetch_messages(struct mailimap * imap)
|
|||
clistiter * cur;
|
||||
int r;
|
||||
|
||||
r = mailimap_select(imap, "INBOX");
|
||||
if( is_error(r, "could not select INBOX") ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* as improvement UIDVALIDITY should be read and the message cache should be cleaned
|
||||
if the UIDVALIDITY is not the same */
|
||||
|
||||
|
@ -211,52 +222,127 @@ static void fetch_messages(struct mailimap * imap)
|
|||
mailimap_fetch_list_free(fetch_result);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* The working thread
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
void MrImap::WorkingThread()
|
||||
{
|
||||
// connect to server
|
||||
struct mailimap* imap;
|
||||
|
||||
int r;
|
||||
imap = mailimap_new(0, NULL);
|
||||
r = mailimap_ssl_connect(imap, m_loginParam->m_mail_server, m_loginParam->m_mail_port);
|
||||
if( is_error(r, "could not connect to server") ) {
|
||||
goto WorkingThread_Exit;
|
||||
}
|
||||
|
||||
r = mailimap_login(imap, m_loginParam->m_mail_user, m_loginParam->m_mail_pw);
|
||||
if( is_error(r, "could not login") ) {
|
||||
goto WorkingThread_Exit;
|
||||
}
|
||||
|
||||
// endless look
|
||||
while( 1 )
|
||||
{
|
||||
// wait for condition
|
||||
pthread_mutex_lock(&m_condmutex);
|
||||
pthread_cond_wait(&m_cond, &m_condmutex); // wait unlocks the mutex and waits for signal, if it returns, the mutex is locked again
|
||||
int dowhat = m_dowhat;
|
||||
pthread_mutex_unlock(&m_condmutex);
|
||||
|
||||
switch( dowhat )
|
||||
{
|
||||
case DO_FETCH:
|
||||
fetch_messages(imap);
|
||||
break;
|
||||
|
||||
case DO_EXIT:
|
||||
goto WorkingThread_Exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WorkingThread_Exit:
|
||||
if( imap ) {
|
||||
mailimap_logout(imap);
|
||||
mailimap_free(imap);
|
||||
imap = NULL;
|
||||
}
|
||||
m_threadRunning = false;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Connect/disconnect by start/stop the working thread
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
MrImap::MrImap(MrMailbox* mailbox)
|
||||
{
|
||||
m_mailbox = mailbox;
|
||||
m_threadRunning = false;
|
||||
m_loginParam = NULL;
|
||||
|
||||
pthread_mutex_init(&m_condmutex, NULL);
|
||||
pthread_cond_init(&m_cond, NULL);
|
||||
}
|
||||
|
||||
|
||||
MrImap::~MrImap()
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
pthread_cond_destroy(&m_cond);
|
||||
pthread_mutex_destroy(&m_condmutex);
|
||||
}
|
||||
|
||||
|
||||
bool MrImap::Connect(const MrLoginParam* param)
|
||||
{
|
||||
struct mailimap * imap;
|
||||
int r;
|
||||
|
||||
if( param->m_mail_server == NULL || param->m_mail_user == NULL || param->m_mail_pw == NULL ) {
|
||||
return false;
|
||||
if( param==NULL || param->m_mail_server==NULL || param->m_mail_user==NULL || param->m_mail_pw==NULL ) {
|
||||
return false; // error, bad parameters
|
||||
}
|
||||
|
||||
imap = mailimap_new(0, NULL);
|
||||
r = mailimap_ssl_connect(imap, param->m_mail_server, param->m_mail_port);
|
||||
if( is_error(r, "could not connect to server") ) {
|
||||
return false;
|
||||
if( m_threadRunning ) {
|
||||
return true; // already trying to connect
|
||||
}
|
||||
|
||||
r = mailimap_login(imap, param->m_mail_user, param->m_mail_pw);
|
||||
if( is_error(r, "could not login") ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
r = mailimap_select(imap, "INBOX");
|
||||
if( is_error(r, "could not select INBOX") ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fetch_messages(imap);
|
||||
|
||||
mailimap_logout(imap);
|
||||
mailimap_free(imap);
|
||||
m_loginParam = param;
|
||||
m_threadRunning = true;
|
||||
pthread_create(&m_thread, NULL, (void * (*)(void *)) MrImap::StartupHelper, this);
|
||||
|
||||
// success, so far, the real connection takes place in the working thread
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MrImap::Disconnect()
|
||||
{
|
||||
if( !m_threadRunning ) {
|
||||
return; // already disconnected
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&m_condmutex);
|
||||
m_dowhat = DO_EXIT;
|
||||
pthread_mutex_unlock(&m_condmutex);
|
||||
pthread_cond_signal(&m_cond);
|
||||
}
|
||||
|
||||
|
||||
bool MrImap::Fetch()
|
||||
{
|
||||
if( !m_threadRunning ) {
|
||||
return false; // not connected
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&m_condmutex);
|
||||
m_dowhat = DO_FETCH;
|
||||
pthread_mutex_unlock(&m_condmutex);
|
||||
pthread_cond_signal(&m_cond);
|
||||
|
||||
// success, so far
|
||||
return true;
|
||||
}
|
||||
|
|
16
src/mrimap.h
16
src/mrimap.h
|
@ -39,11 +39,27 @@ class MrImap
|
|||
public:
|
||||
MrImap (MrMailbox* mailbox);
|
||||
~MrImap ();
|
||||
|
||||
bool IsConnected () { return m_threadRunning; }
|
||||
bool Connect (const MrLoginParam*);
|
||||
void Disconnect ();
|
||||
bool Fetch ();
|
||||
|
||||
private:
|
||||
MrMailbox* m_mailbox;
|
||||
const MrLoginParam* m_loginParam;
|
||||
|
||||
pthread_t m_thread;
|
||||
bool m_threadRunning;
|
||||
pthread_cond_t m_cond;
|
||||
pthread_mutex_t m_condmutex;
|
||||
|
||||
#define DO_FETCH 1
|
||||
#define DO_EXIT 2
|
||||
int m_dowhat;
|
||||
|
||||
static void StartupHelper (MrImap* imap) { imap->WorkingThread(); }
|
||||
void WorkingThread ();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -32,10 +32,8 @@
|
|||
#include "mrloginparam.h"
|
||||
|
||||
|
||||
MrLoginParam::MrLoginParam(MrMailbox* mailbox)
|
||||
MrLoginParam::MrLoginParam()
|
||||
{
|
||||
m_mailbox = mailbox;
|
||||
|
||||
// init pointers (this cannot be done by Clear() as this function checks against NULL pointers)
|
||||
m_email = NULL;
|
||||
|
||||
|
@ -75,24 +73,6 @@ void MrLoginParam::Clear()
|
|||
}
|
||||
|
||||
|
||||
void MrLoginParam::ReadFromSql()
|
||||
{
|
||||
Clear();
|
||||
|
||||
m_email = m_mailbox->GetConfig ("email", NULL);
|
||||
|
||||
m_mail_server = m_mailbox->GetConfig ("mail_server", NULL);
|
||||
m_mail_port = m_mailbox->GetConfigInt("mail_port", 0);
|
||||
m_mail_user = m_mailbox->GetConfig ("mail_user", NULL);
|
||||
m_mail_pw = m_mailbox->GetConfig ("mail_pw", NULL);
|
||||
|
||||
m_send_server = m_mailbox->GetConfig ("send_server", NULL);
|
||||
m_send_port = m_mailbox->GetConfigInt("send_port", 0);
|
||||
m_send_user = m_mailbox->GetConfig ("send_user", NULL);
|
||||
m_send_pw = m_mailbox->GetConfig ("send_pw", NULL);
|
||||
}
|
||||
|
||||
|
||||
void MrLoginParam::Complete()
|
||||
{
|
||||
if( m_email == NULL ) {
|
||||
|
|
|
@ -36,15 +36,12 @@ class MrMailbox;
|
|||
class MrLoginParam
|
||||
{
|
||||
public:
|
||||
MrLoginParam (MrMailbox* mailbox);
|
||||
MrLoginParam ();
|
||||
~MrLoginParam ();
|
||||
|
||||
// clears all data and frees its memory. All pointers are NULL after this function is called.
|
||||
void Clear ();
|
||||
|
||||
// read all data from database, unset values are still NULL after calling ReadFromSql()
|
||||
void ReadFromSql ();
|
||||
|
||||
// tries to set missing parameters from at least m_email and m_mail_pw
|
||||
void Complete ();
|
||||
|
||||
|
@ -60,9 +57,6 @@ public:
|
|||
char* m_send_user;
|
||||
char* m_send_pw;
|
||||
uint16_t m_send_port;
|
||||
|
||||
private:
|
||||
MrMailbox* m_mailbox;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -63,18 +63,6 @@ bool MrMailbox::Open(const char* dbfile)
|
|||
}
|
||||
}
|
||||
|
||||
// test LibEtPan
|
||||
#if 0
|
||||
struct mailimf_mailbox * mb;
|
||||
char * display_name;
|
||||
char * address;
|
||||
|
||||
display_name = strdup("DINH =?iso-8859-1?Q?Vi=EAt_Ho=E0?=");
|
||||
address = strdup("dinh.viet.hoa@free.fr");
|
||||
mb = mailimf_mailbox_new(display_name, address); // mailimf_mailbox_new() takes ownership of the given strings!
|
||||
mailimf_mailbox_free(mb);
|
||||
#endif
|
||||
|
||||
// success
|
||||
return true;
|
||||
|
||||
|
@ -98,15 +86,36 @@ void MrMailbox::Close()
|
|||
******************************************************************************/
|
||||
|
||||
|
||||
void MrMailbox::Connect()
|
||||
bool MrMailbox::Connect()
|
||||
{
|
||||
MrLoginParam param(this);
|
||||
if( m_imap.IsConnected() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
param.ReadFromSql();
|
||||
// read parameter, unset parameters are still NULL afterwards
|
||||
{
|
||||
MrSqlite3Locker locker(m_sql);
|
||||
|
||||
param.Complete();
|
||||
m_loginParam.Clear();
|
||||
|
||||
m_imap.Connect(¶m);
|
||||
m_loginParam.m_email = m_sql.GetConfig ("email", NULL);
|
||||
|
||||
m_loginParam.m_mail_server = m_sql.GetConfig ("mail_server", NULL);
|
||||
m_loginParam.m_mail_port = m_sql.GetConfigInt("mail_port", 0);
|
||||
m_loginParam.m_mail_user = m_sql.GetConfig ("mail_user", NULL);
|
||||
m_loginParam.m_mail_pw = m_sql.GetConfig ("mail_pw", NULL);
|
||||
|
||||
m_loginParam.m_send_server = m_sql.GetConfig ("send_server", NULL);
|
||||
m_loginParam.m_send_port = m_sql.GetConfigInt("send_port", 0);
|
||||
m_loginParam.m_send_user = m_sql.GetConfig ("send_user", NULL);
|
||||
m_loginParam.m_send_pw = m_sql.GetConfig ("send_pw", NULL);
|
||||
}
|
||||
|
||||
// try to suggest unset parameters
|
||||
m_loginParam.Complete();
|
||||
|
||||
// connect
|
||||
return m_imap.Connect(&m_loginParam);
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,6 +125,12 @@ void MrMailbox::Disconnect()
|
|||
}
|
||||
|
||||
|
||||
bool MrMailbox::Fetch()
|
||||
{
|
||||
return m_imap.Fetch();
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Handle contacts
|
||||
******************************************************************************/
|
||||
|
|
|
@ -59,8 +59,9 @@ public:
|
|||
void Close ();
|
||||
|
||||
// connect to the mailbox: error are be received asynchronously.
|
||||
void Connect ();
|
||||
bool Connect ();
|
||||
void Disconnect ();
|
||||
bool Fetch ();
|
||||
|
||||
// iterate contacts
|
||||
size_t GetContactCnt () { MrSqlite3Locker l(m_sql); return m_sql.GetContactCnt(); }
|
||||
|
@ -82,6 +83,7 @@ public:
|
|||
private:
|
||||
// private stuff
|
||||
MrSqlite3 m_sql;
|
||||
MrLoginParam m_loginParam;
|
||||
MrImap m_imap;
|
||||
friend class MrImap;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue