2007-06-20 22:46:45 -07:00
|
|
|
#include <e.h>
|
|
|
|
#include "e_mod_main.h"
|
|
|
|
#include "imap2.h"
|
|
|
|
|
2007-09-15 17:04:26 -07:00
|
|
|
#if 0
|
2008-01-04 00:31:21 -08:00
|
|
|
#define D(args...) printf(args)
|
2007-09-15 17:04:26 -07:00
|
|
|
#else
|
|
|
|
#define D(args...)
|
|
|
|
#endif
|
|
|
|
|
2007-06-22 07:28:06 -07:00
|
|
|
/*
|
|
|
|
* TODO:
|
2007-07-25 11:27:21 -07:00
|
|
|
* * Let the user select between Unseen, Recent and New mail
|
|
|
|
* * Don't fail on incomplete data from the server
|
2007-06-22 07:28:06 -07:00
|
|
|
*/
|
|
|
|
|
2007-06-20 22:46:45 -07:00
|
|
|
static ImapClient *_mail_imap_client_find (Ecore_Con_Server *server);
|
|
|
|
static ImapClient *_mail_imap_client_get (Config_Box *cb);
|
2010-07-06 10:52:01 -07:00
|
|
|
static Eina_Bool _mail_imap_server_add (void *data, int type, void *event);
|
|
|
|
static Eina_Bool _mail_imap_server_del (void *data, int type, void *event);
|
|
|
|
static Eina_Bool _mail_imap_server_data (void *data, int type, void *event);
|
2007-06-22 07:28:06 -07:00
|
|
|
static int _mail_imap_server_data_parse (ImapClient *ic, char *line);
|
2007-06-20 22:46:45 -07:00
|
|
|
static void _mail_imap_client_logout (ImapClient *ic);
|
2007-06-22 06:36:35 -07:00
|
|
|
static void _mail_imap_server_idle (ImapClient *ic);
|
|
|
|
static void _mail_imap_server_noop (ImapClient *ic);
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2010-07-06 10:52:01 -07:00
|
|
|
static int elements (char *p);
|
2007-07-25 11:27:21 -07:00
|
|
|
static char *find_rn (char *data, unsigned int size);
|
|
|
|
|
2008-10-22 06:53:03 -07:00
|
|
|
static Eina_List *iclients = NULL;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2008-01-04 00:31:21 -08:00
|
|
|
static Ecore_Event_Handler *add_handler = NULL;
|
|
|
|
static Ecore_Event_Handler *del_handler = NULL;
|
|
|
|
static Ecore_Event_Handler *data_handler = NULL;
|
|
|
|
|
2007-06-20 22:46:45 -07:00
|
|
|
void
|
|
|
|
_mail_imap_check_mail (void *data)
|
|
|
|
{
|
|
|
|
Ecore_Con_Type type;
|
2008-10-22 06:53:03 -07:00
|
|
|
Eina_List *l;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
|
|
|
for (l = iclients; l; l = l->next)
|
|
|
|
{
|
|
|
|
ImapClient *ic;
|
|
|
|
|
|
|
|
ic = l->data;
|
|
|
|
ic->data = data;
|
2008-01-04 00:31:21 -08:00
|
|
|
D ("Checking (%s@%d:%s): %p\n", ic->config->host, ic->config->port, ic->config->new_path, ic->server);
|
2007-06-20 22:46:45 -07:00
|
|
|
if (!ic->server)
|
|
|
|
{
|
|
|
|
if (ic->config->local)
|
|
|
|
type = ECORE_CON_LOCAL_SYSTEM;
|
|
|
|
else
|
|
|
|
type = ECORE_CON_REMOTE_SYSTEM;
|
|
|
|
|
|
|
|
if (ecore_con_ssl_available_get () && (ic->config->ssl))
|
2008-01-04 00:31:21 -08:00
|
|
|
{
|
|
|
|
D ("Use SSL for %s:%s\n", ic->config->host, ic->config->new_path);
|
2008-01-08 13:14:01 -08:00
|
|
|
switch (ic->config->ssl)
|
|
|
|
{
|
|
|
|
case 3:
|
|
|
|
type |= ECORE_CON_USE_SSL3;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
type |= ECORE_CON_USE_SSL;
|
|
|
|
break;
|
|
|
|
}
|
2008-01-04 00:31:21 -08:00
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
ic->state = IMAP_STATE_DISCONNECTED;
|
|
|
|
ic->server =
|
|
|
|
ecore_con_server_connect (type, ic->config->host,
|
|
|
|
ic->config->port, NULL);
|
|
|
|
ic->cmd = 1;
|
|
|
|
ic->idle = -1;
|
2007-07-20 05:50:31 -07:00
|
|
|
ic->idling = 0;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
2007-06-22 05:26:44 -07:00
|
|
|
else
|
|
|
|
{
|
2007-07-25 11:27:21 -07:00
|
|
|
if (ic->idling) _mail_imap_server_idle (ic);
|
2007-06-22 06:36:35 -07:00
|
|
|
else _mail_imap_server_noop (ic);
|
2007-06-22 05:26:44 -07:00
|
|
|
/* Need to set this to revert the state of the icon */
|
|
|
|
_mail_set_text (ic->data);
|
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_mail_imap_add_mailbox (void *data)
|
|
|
|
{
|
|
|
|
Config_Box *cb;
|
|
|
|
|
|
|
|
cb = data;
|
|
|
|
if (!cb)
|
|
|
|
return;
|
|
|
|
/* Client get will create the client if it does not exist */
|
|
|
|
_mail_imap_client_get (cb);
|
2008-01-04 00:31:21 -08:00
|
|
|
|
|
|
|
if (!add_handler)
|
|
|
|
add_handler = ecore_event_handler_add (ECORE_CON_EVENT_SERVER_ADD,
|
|
|
|
_mail_imap_server_add, NULL);
|
|
|
|
if (!del_handler)
|
|
|
|
del_handler = ecore_event_handler_add (ECORE_CON_EVENT_SERVER_DEL,
|
|
|
|
_mail_imap_server_del, NULL);
|
|
|
|
if (!data_handler)
|
|
|
|
data_handler = ecore_event_handler_add (ECORE_CON_EVENT_SERVER_DATA,
|
|
|
|
_mail_imap_server_data, NULL);
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_mail_imap_del_mailbox (void *data)
|
|
|
|
{
|
|
|
|
ImapClient *ic;
|
|
|
|
Config_Box *cb;
|
|
|
|
|
|
|
|
cb = data;
|
|
|
|
if (!cb)
|
|
|
|
return;
|
|
|
|
ic = _mail_imap_client_get (cb);
|
|
|
|
if (!ic)
|
|
|
|
return;
|
2008-10-22 06:53:03 -07:00
|
|
|
iclients = eina_list_remove (iclients, ic);
|
2008-01-08 13:14:01 -08:00
|
|
|
_mail_imap_client_logout (ic);
|
|
|
|
E_FREE (ic);
|
|
|
|
|
2008-01-04 00:31:21 -08:00
|
|
|
if (!iclients)
|
|
|
|
{
|
|
|
|
if (add_handler)
|
|
|
|
ecore_event_handler_del (add_handler);
|
|
|
|
add_handler = NULL;
|
|
|
|
if (del_handler)
|
|
|
|
ecore_event_handler_del (del_handler);
|
|
|
|
del_handler = NULL;
|
|
|
|
if (data_handler)
|
|
|
|
ecore_event_handler_del (data_handler);
|
|
|
|
data_handler = NULL;
|
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_mail_imap_shutdown ()
|
|
|
|
{
|
|
|
|
while (iclients)
|
|
|
|
{
|
|
|
|
ImapClient *ic;
|
|
|
|
|
|
|
|
ic = iclients->data;
|
2008-10-22 06:53:03 -07:00
|
|
|
iclients = eina_list_remove_list (iclients, iclients);
|
2007-06-20 22:46:45 -07:00
|
|
|
_mail_imap_client_logout (ic);
|
2007-07-25 11:28:17 -07:00
|
|
|
E_FREE (ic->prev.data);
|
2007-06-20 22:46:45 -07:00
|
|
|
E_FREE (ic);
|
|
|
|
}
|
2008-01-04 00:31:21 -08:00
|
|
|
|
|
|
|
if (add_handler)
|
|
|
|
ecore_event_handler_del (add_handler);
|
|
|
|
add_handler = NULL;
|
|
|
|
if (del_handler)
|
|
|
|
ecore_event_handler_del (del_handler);
|
|
|
|
del_handler = NULL;
|
|
|
|
if (data_handler)
|
|
|
|
ecore_event_handler_del (data_handler);
|
|
|
|
data_handler = NULL;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* PRIVATES */
|
|
|
|
static ImapClient *
|
|
|
|
_mail_imap_client_find (Ecore_Con_Server *server)
|
|
|
|
{
|
2008-10-22 06:53:03 -07:00
|
|
|
Eina_List *l;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
|
|
|
for (l = iclients; l; l = l->next)
|
|
|
|
{
|
|
|
|
ImapClient *ic;
|
|
|
|
|
|
|
|
ic = l->data;
|
|
|
|
if (ic->server == server)
|
|
|
|
return ic;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ImapClient *
|
|
|
|
_mail_imap_client_get (Config_Box *cb)
|
|
|
|
{
|
|
|
|
ImapClient *ic;
|
2008-10-22 06:53:03 -07:00
|
|
|
Eina_List *l;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
|
|
|
if (!cb)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (l = iclients; l; l = l->next)
|
|
|
|
{
|
|
|
|
ic = l->data;
|
|
|
|
if (ic->config == cb) return ic;
|
|
|
|
}
|
|
|
|
|
|
|
|
ic = E_NEW (ImapClient, 1);
|
|
|
|
ic->config = cb;
|
|
|
|
|
|
|
|
ic->cmd = 1;
|
|
|
|
ic->state = IMAP_STATE_DISCONNECTED;
|
|
|
|
|
|
|
|
ic->config->num_new = 0;
|
|
|
|
ic->config->num_total = 0;
|
|
|
|
|
2008-10-22 06:53:03 -07:00
|
|
|
iclients = eina_list_append (iclients, ic);
|
2007-06-20 22:46:45 -07:00
|
|
|
return ic;
|
|
|
|
}
|
|
|
|
|
2010-07-06 10:52:01 -07:00
|
|
|
static Eina_Bool
|
2007-06-20 22:46:45 -07:00
|
|
|
_mail_imap_server_add (void *data, int type, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Add *ev = event;
|
|
|
|
ImapClient *ic;
|
|
|
|
|
|
|
|
ic = _mail_imap_client_find (ev->server);
|
2010-07-06 10:52:01 -07:00
|
|
|
if (!ic) return EINA_TRUE;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2008-01-04 00:31:21 -08:00
|
|
|
D ("Connect to %s:%s\n", ic->config->host, ic->config->new_path);
|
2007-06-20 22:46:45 -07:00
|
|
|
ic->state = IMAP_STATE_CONNECTED;
|
|
|
|
ic->cmd = 1;
|
2010-07-06 10:52:01 -07:00
|
|
|
return EINA_FALSE;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
2010-07-06 10:52:01 -07:00
|
|
|
static Eina_Bool
|
2007-06-20 22:46:45 -07:00
|
|
|
_mail_imap_server_del (void *data, int type, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Del *ev = event;
|
|
|
|
ImapClient *ic;
|
|
|
|
|
|
|
|
ic = _mail_imap_client_find (ev->server);
|
2010-07-06 10:52:01 -07:00
|
|
|
if (!ic) return EINA_TRUE;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2008-01-04 00:31:21 -08:00
|
|
|
D ("Disconnect from %s:%s\n", ic->config->host, ic->config->new_path);
|
2007-06-22 05:26:44 -07:00
|
|
|
if (ic->state != IMAP_STATE_DISCONNECTED)
|
|
|
|
{
|
2007-06-22 06:36:35 -07:00
|
|
|
printf ("The connection was unexpectedly shut down, consider reducing the check time.\n");
|
2007-06-22 05:26:44 -07:00
|
|
|
ic->state = IMAP_STATE_DISCONNECTED;
|
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2007-07-25 11:28:17 -07:00
|
|
|
E_FREE (ic->prev.data);
|
2007-06-20 22:46:45 -07:00
|
|
|
ecore_con_server_del (ic->server);
|
|
|
|
ic->server = NULL;
|
|
|
|
|
|
|
|
_mail_set_text (ic->data);
|
2007-12-29 16:04:37 -08:00
|
|
|
|
|
|
|
if ((ic->config->num_new > 0)
|
|
|
|
&& (ic->config->use_exec) && (ic->config->exec))
|
|
|
|
_mail_start_exe (ic->config);
|
|
|
|
|
2010-07-06 10:52:01 -07:00
|
|
|
return EINA_FALSE;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
2010-07-06 10:52:01 -07:00
|
|
|
static Eina_Bool
|
2007-06-20 22:46:45 -07:00
|
|
|
_mail_imap_server_data (void *data, int type, void *event)
|
|
|
|
{
|
|
|
|
Ecore_Con_Event_Server_Data *ev = event;
|
|
|
|
ImapClient *ic;
|
|
|
|
char *reply, *p, *pp;
|
|
|
|
char out[1024];
|
2007-07-25 11:27:21 -07:00
|
|
|
unsigned int len, size;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
|
|
|
ic = _mail_imap_client_find (ev->server);
|
2010-07-06 10:52:01 -07:00
|
|
|
if (!ic) return EINA_TRUE;
|
|
|
|
if (ic->state == IMAP_STATE_DISCONNECTED) return EINA_TRUE;
|
2007-06-20 22:46:45 -07:00
|
|
|
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Data from %s:%s\n", ic->config->host, ic->config->new_path);
|
|
|
|
|
2007-07-25 11:27:21 -07:00
|
|
|
/* Hijack server data.
|
|
|
|
* We require minimum 2 characters, as the minimum server data is '\r\n' */
|
2007-07-25 11:28:17 -07:00
|
|
|
if ((ic->prev.data) || (ev->size < 2))
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
2007-07-25 11:27:21 -07:00
|
|
|
/* TODO: Check that we don't grow to big! */
|
2007-07-25 11:28:17 -07:00
|
|
|
ic->prev.data = realloc (ic->prev.data, ic->prev.size + ev->size);
|
|
|
|
memcpy (ic->prev.data + ic->prev.size, ev->data, ev->size);
|
|
|
|
ic->prev.size += ev->size;
|
2007-07-25 11:27:21 -07:00
|
|
|
E_FREE (ev->data);
|
2010-07-06 10:52:01 -07:00
|
|
|
if (ic->prev.size < 2) return EINA_FALSE;
|
2007-07-25 11:27:21 -07:00
|
|
|
|
2007-07-25 11:28:17 -07:00
|
|
|
reply = ic->prev.data;
|
|
|
|
size = ic->prev.size;
|
|
|
|
ic->prev.data = NULL;
|
|
|
|
ic->prev.size = 0;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
2007-07-25 11:27:21 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
reply = ev->data;
|
|
|
|
size = ev->size;
|
|
|
|
}
|
|
|
|
ev->data = NULL;
|
|
|
|
/* Check for correct EOD */
|
|
|
|
if ((*(reply + size - 2) != '\r') && (*(reply + size - 1) != '\n'))
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Wrong eod %s:%s\n", ic->config->host, ic->config->new_path);
|
2007-07-25 11:27:21 -07:00
|
|
|
/* We got incomplete data, search for last EOD */
|
|
|
|
unsigned int pos = 0;
|
|
|
|
char *data;
|
|
|
|
|
|
|
|
data = reply;
|
|
|
|
while (pos < (size - 1))
|
|
|
|
{
|
|
|
|
if ((*(reply + pos) == '\r') && (*(reply + pos + 1) == '\n'))
|
|
|
|
data = reply + pos + 2;
|
|
|
|
pos++;
|
|
|
|
}
|
2007-07-25 11:28:17 -07:00
|
|
|
ic->prev.size = size - (data - reply);
|
|
|
|
ic->prev.data = malloc (ic->prev.size);
|
|
|
|
memcpy (ic->prev.data, data, ic->prev.size);
|
2007-07-25 11:27:21 -07:00
|
|
|
|
|
|
|
/* Remove captured data from reply */
|
|
|
|
if (data == reply)
|
|
|
|
E_FREE (reply);
|
2007-06-20 22:46:45 -07:00
|
|
|
else
|
2007-11-07 10:31:27 -08:00
|
|
|
size -= ic->prev.size;
|
2007-07-25 11:27:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (reply)
|
|
|
|
{
|
|
|
|
p = reply;
|
|
|
|
pp = p;
|
|
|
|
while ((p) && ((p - reply) < size))
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
2007-07-25 11:27:21 -07:00
|
|
|
/* find EOL */
|
|
|
|
pp = find_rn (p, size - (pp - p));
|
|
|
|
if (!pp)
|
|
|
|
{
|
|
|
|
printf ("Imap Failure: Couldn't find EOL\n");
|
|
|
|
_mail_imap_client_logout (ic);
|
2010-07-06 10:52:01 -07:00
|
|
|
return EINA_FALSE;
|
2007-07-25 11:27:21 -07:00
|
|
|
}
|
|
|
|
*pp = '\0';
|
|
|
|
/* parse data */
|
|
|
|
if (!_mail_imap_server_data_parse (ic, p))
|
|
|
|
{
|
2008-01-08 13:14:01 -08:00
|
|
|
printf ("Imap Failure: Couldn't parse data\n");
|
2007-07-25 11:27:21 -07:00
|
|
|
_mail_imap_client_logout (ic);
|
2010-07-06 10:52:01 -07:00
|
|
|
return EINA_FALSE;
|
2007-07-25 11:27:21 -07:00
|
|
|
}
|
|
|
|
/* next */
|
|
|
|
p = pp + 2;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
2007-07-25 11:27:21 -07:00
|
|
|
free (reply);
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (ic->state)
|
|
|
|
{
|
|
|
|
case IMAP_STATE_DISCONNECTED:
|
|
|
|
/* ignore */
|
|
|
|
break;
|
|
|
|
case IMAP_STATE_CONNECTED:
|
|
|
|
if (ic->idle == -1)
|
|
|
|
{
|
|
|
|
/* Check whether this server supports idle */
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i CAPABILITY\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Log in */
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i LOGIN %s %s\r\n", ic->cmd++,
|
|
|
|
ic->config->user, ic->config->pass);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
2007-07-25 11:27:21 -07:00
|
|
|
ic->state = IMAP_STATE_AUTHENTICATED;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IMAP_STATE_AUTHENTICATED:
|
2007-06-22 06:49:36 -07:00
|
|
|
len = snprintf (out, sizeof (out), "A%04i EXAMINE %s\r\n", ic->cmd++,
|
2007-06-20 22:46:45 -07:00
|
|
|
ic->config->new_path);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
2007-07-25 11:27:21 -07:00
|
|
|
ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
2007-06-20 22:46:45 -07:00
|
|
|
break;
|
2007-07-25 11:27:21 -07:00
|
|
|
case IMAP_STATE_IDLING:
|
2007-06-22 06:36:35 -07:00
|
|
|
if ((ic->idle == 1) && (!ic->idling))
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Begin idle\n");
|
2007-06-22 06:36:35 -07:00
|
|
|
len = snprintf (out, sizeof (out), "A%04i IDLE\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
ic->idling = 1;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
break;
|
2007-07-25 11:27:21 -07:00
|
|
|
case IMAP_STATE_SEARCH_UNSEEN:
|
|
|
|
_mail_imap_server_idle (ic);
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i SEARCH UNSEEN UNDELETED\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
ic->state = IMAP_STATE_IDLING;
|
|
|
|
break;
|
|
|
|
case IMAP_STATE_SEARCH_RECENT:
|
|
|
|
_mail_imap_server_idle (ic);
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i SEARCH RECENT UNDELETED\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
ic->state = IMAP_STATE_IDLING;
|
|
|
|
break;
|
|
|
|
case IMAP_STATE_SEARCH_NEW:
|
|
|
|
_mail_imap_server_idle (ic);
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i SEARCH NEW UNDELETED\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
ic->state = IMAP_STATE_IDLING;
|
|
|
|
break;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
if (ic->cmd > 9999)
|
|
|
|
ic->cmd = 1;
|
2007-06-22 06:36:35 -07:00
|
|
|
_mail_set_text (ic->data);
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("\n");
|
2010-07-06 10:52:01 -07:00
|
|
|
return EINA_FALSE;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2007-06-22 07:28:06 -07:00
|
|
|
_mail_imap_server_data_parse (ImapClient *ic, char *line)
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
|
|
|
if (line[0] == 'A')
|
|
|
|
{
|
|
|
|
char *result, *value;
|
|
|
|
|
|
|
|
result = strchr (line, ' ');
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
printf ("Imap Failure: Missing result for tagged reply\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
result++;
|
|
|
|
value = strchr (result, ' ');
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
*value = '\0';
|
|
|
|
value++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
value = "";
|
|
|
|
/* This is a reply to one of our commands */
|
|
|
|
if (!strcmp (result, "NO"))
|
|
|
|
{
|
|
|
|
printf ("Imap Failure: %s\n", value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (!strcmp (result, "BAD"))
|
|
|
|
{
|
|
|
|
printf ("Imap Bad Command: %s\n", value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else if (!strcmp (result, "OK"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Reply ok: %s\n", value);
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf ("Unknown tagged reply: %s %s\n", line, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (line[0] == '*')
|
|
|
|
{
|
|
|
|
char *result, *value;
|
|
|
|
|
|
|
|
result = strchr (line, ' ');
|
|
|
|
if (!result)
|
|
|
|
{
|
|
|
|
printf ("Imap Failure: Missing result for tagged reply\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
result++;
|
|
|
|
value = strchr (result, ' ');
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
*value = '\0';
|
|
|
|
value++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
value = "";
|
|
|
|
|
|
|
|
if (!strcmp (result, "CAPABILITY"))
|
|
|
|
{
|
|
|
|
char *p, *pp;
|
|
|
|
|
|
|
|
p = value;
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
pp = strchr (p, ' ');
|
|
|
|
if (pp) *pp = '\0';
|
|
|
|
if (!strcmp (p, "IDLE"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Server supports idle\n");
|
2007-06-20 22:46:45 -07:00
|
|
|
ic->idle = 1;
|
|
|
|
}
|
|
|
|
if (pp)
|
|
|
|
{
|
|
|
|
*pp = ' ';
|
|
|
|
p = pp + 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
p = NULL;
|
|
|
|
}
|
|
|
|
if (ic->idle == -1) ic->idle = 0;
|
|
|
|
}
|
|
|
|
else if (!strcmp (result, "OK"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Result OK: %s\n", value);
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
2007-06-22 05:26:44 -07:00
|
|
|
else if (!strcmp (result, "FLAGS"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Flags: %s\n", value);
|
2007-06-22 05:26:44 -07:00
|
|
|
}
|
2007-07-25 11:27:21 -07:00
|
|
|
else if (!strcmp (result, "SEARCH"))
|
|
|
|
{
|
|
|
|
ic->config->num_new = elements (value);
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("New mail (%s:%s): %d\n", ic->config->host, ic->config->new_path, ic->config->num_new);
|
2007-07-25 11:27:21 -07:00
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
/* The result can be <n> <result> */
|
|
|
|
p = strchr (value, ' ');
|
|
|
|
if (p) *p = '\0';
|
|
|
|
if (!strcmp (value, "RECENT"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Recent mails: %d\n", atoi (result));
|
2007-07-25 11:27:21 -07:00
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
ic->state = IMAP_STATE_SEARCH_NEW;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
else if (!strcmp (value, "EXISTS"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Existing mails: %d\n", atoi (result));
|
2007-06-20 22:46:45 -07:00
|
|
|
ic->config->num_total = atoi (result);
|
|
|
|
}
|
2007-07-25 11:27:21 -07:00
|
|
|
else if (!strcmp (value, "FETCH"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Reading mail: %d\n", atoi (result));
|
2007-07-25 11:27:21 -07:00
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
ic->state = IMAP_STATE_SEARCH_NEW;
|
|
|
|
}
|
|
|
|
else if (!strcmp (value, "EXPUNGE"))
|
|
|
|
{
|
2007-09-15 17:04:26 -07:00
|
|
|
D ("Deleting mail: %d\n", atoi (result));
|
2007-07-25 11:27:21 -07:00
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
ic->state = IMAP_STATE_SEARCH_NEW;
|
|
|
|
}
|
2007-06-20 22:46:45 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
printf ("Unknown untagged reply: %s %s\n", line, value);
|
2007-07-25 11:27:21 -07:00
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_NEW;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (line[0] == '+')
|
|
|
|
{
|
|
|
|
/* Continuation mode */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf ("Unknown reply: %s\n", line);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_mail_imap_client_logout (ImapClient *ic)
|
|
|
|
{
|
|
|
|
if (!ic)
|
|
|
|
return;
|
|
|
|
|
2007-07-25 11:28:17 -07:00
|
|
|
E_FREE (ic->prev.data);
|
2007-06-20 22:46:45 -07:00
|
|
|
if (ic->server)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
char out[1024];
|
|
|
|
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i LOGOUT", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
|
|
|
ecore_con_server_del (ic->server);
|
|
|
|
}
|
|
|
|
ic->server = NULL;
|
|
|
|
ic->state = IMAP_STATE_DISCONNECTED;
|
|
|
|
}
|
|
|
|
|
2007-06-22 06:36:35 -07:00
|
|
|
static void
|
|
|
|
_mail_imap_server_idle (ImapClient *ic)
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
|
|
|
char out[1024];
|
|
|
|
int len;
|
|
|
|
|
2007-06-22 06:36:35 -07:00
|
|
|
if (!ic->idling) return;
|
2007-06-20 22:46:45 -07:00
|
|
|
len = snprintf (out, sizeof (out), "DONE\r\n");
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
2007-06-22 06:36:35 -07:00
|
|
|
ic->idling = 0;
|
2007-08-02 10:13:18 -07:00
|
|
|
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
ic->state = IMAP_STATE_SEARCH_NEW;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
|
|
|
|
2007-06-22 06:36:35 -07:00
|
|
|
static void
|
|
|
|
_mail_imap_server_noop (ImapClient *ic)
|
2007-06-20 22:46:45 -07:00
|
|
|
{
|
|
|
|
char out[1024];
|
|
|
|
int len;
|
|
|
|
|
|
|
|
len = snprintf (out, sizeof (out), "A%04i NOOP\r\n", ic->cmd++);
|
|
|
|
ecore_con_server_send (ic->server, out, len);
|
2007-08-02 10:13:18 -07:00
|
|
|
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_UNSEEN;
|
|
|
|
//ic->state = IMAP_STATE_SEARCH_RECENT;
|
|
|
|
ic->state = IMAP_STATE_SEARCH_NEW;
|
2007-06-20 22:46:45 -07:00
|
|
|
}
|
2007-07-25 11:27:21 -07:00
|
|
|
|
|
|
|
static int
|
|
|
|
elements (char *p)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
if (!p) return 0;
|
2007-11-07 10:31:27 -08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (*p) count++;
|
|
|
|
p = strchr (p, ' ');
|
|
|
|
if (p) p++;
|
|
|
|
}
|
|
|
|
while (p);
|
2007-07-25 11:27:21 -07:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
find_rn (char *data, unsigned int size)
|
|
|
|
{
|
|
|
|
while (size >= 2)
|
|
|
|
{
|
|
|
|
if ((*data == '\r') && (*(data + 1) == '\n')) return data;
|
|
|
|
data++;
|
|
|
|
size--;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|