Added new mail code, split into different source files for easier fixes and

patches.


SVN revision: 23379
master
Christopher Michael 17 years ago
parent 48705856d9
commit 8496d55257
  1. 299
      imap.c
  2. 49
      imap.h
  3. 107
      mbox.c
  4. 20
      mbox.h
  5. 97
      mdir.c
  6. 20
      mdir.h
  7. 144
      pop.c
  8. 29
      pop.h

299
imap.c

@ -0,0 +1,299 @@
#include <e.h>
#include "e_mod_main.h"
#include "imap.h"
static ImapServer *_mail_imap_server_get(Ecore_Con_Server *server);
static ImapClient *_mail_imap_client_get(Config_Box *cb);
static int _mail_imap_server_add(void *data, int type, void *event);
static int _mail_imap_server_del(void *data, int type, void *event);
static int _mail_imap_server_data(void *data, int type, void *event);
static void _mail_imap_server_logout(ImapServer *is);
static Evas_List *iservers;
void
_mail_imap_check_mail(void *data)
{
Ecore_Con_Type type = ECORE_CON_REMOTE_SYSTEM;
Evas_List *l, *j;
for (l = iservers; l; l = l->next)
{
ImapServer *is;
is = l->data;
is->data = data;
if (!is->server)
{
if (!is->add_handler)
is->add_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _mail_imap_server_add, NULL);
if (!is->del_handler)
is->del_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _mail_imap_server_del, NULL);
if (!is->data_handler)
is->data_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _mail_imap_server_data, NULL);
for (j = is->clients; j; j = j->next)
{
ImapClient *ic;
ic = j->data;
if (!ic->server->server)
{
if (ecore_con_ssl_available_get() && (ic->config->ssl))
type |= ECORE_CON_USE_SSL;
ic->server->server = ecore_con_server_connect(type, ic->config->host, ic->config->port, NULL);
ic->server->state = IMAP_STATE_DISCONNECTED;
ic->server->cmd = 0;
}
}
}
is->current = evas_list_nth(is->clients, 0);
}
}
void
_mail_imap_add_mailbox(void *data)
{
ImapClient *ic;
Config_Box *cb;
cb = data;
if (!cb) return;
ic = _mail_imap_client_get(cb);
ic->server->clients = evas_list_append(ic->server->clients, ic);
}
void
_mail_imap_del_mailbox(void *data)
{
ImapClient *ic;
Config_Box *cb;
cb = data;
if (!cb) return;
ic = _mail_imap_client_get(cb);
ic->server->clients = evas_list_remove(ic->server->clients, ic);
}
void
_mail_imap_shutdown()
{
if (!iservers) return;
while (iservers)
{
ImapServer *is;
is = iservers->data;
if (is->add_handler)
ecore_event_handler_del(is->add_handler);
if (is->del_handler)
ecore_event_handler_del(is->del_handler);
if (is->data_handler)
ecore_event_handler_del(is->data_handler);
iservers = evas_list_remove_list(iservers, iservers);
free(is);
}
}
/* PRIVATES */
static ImapServer *
_mail_imap_server_get(Ecore_Con_Server *server)
{
Evas_List *l;
for (l = iservers; l; l = l->next)
{
ImapServer *is;
is = l->data;
if (is->server == server)
return is;
}
return NULL;
}
static ImapClient *
_mail_imap_client_get(Config_Box *cb)
{
ImapServer *is;
ImapClient *ic;
Evas_List *l, *j;
int found = 0;
if ((!iservers) || (evas_list_count(iservers) <= 0))
{
is = E_NEW(ImapServer, 1);
is->server = NULL;
is->cmd = 0;
is->state = IMAP_STATE_DISCONNECTED;
iservers = evas_list_append(iservers, is);
}
for (l = iservers; l; l = l->next)
{
is = l->data;
if (!is->clients) continue;
for (j = is->clients; j; j = j->next)
{
ic = j->data;
if (!ic->config) continue;
if ((!strcmp(ic->config->host, cb->host)) &&
(!strcmp(ic->config->user, cb->user)) &&
(!strcmp(ic->config->pass, cb->pass)))
{
found = 1;
break;
}
}
if (found) break;
}
if (!found)
{
ic = E_NEW(ImapClient, 1);
ic->config = cb;
ic->server = is;
ic->config->num_new = 0;
ic->config->num_total = 0;
}
return ic;
}
static int
_mail_imap_server_add(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Add *ev = event;
ImapServer *is;
is = _mail_imap_server_get(ev->server);
if (!is) return 1;
is->state = IMAP_STATE_CONNECTED;
is->cmd = 0;
return 0;
}
static int
_mail_imap_server_del(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Del *ev = event;
ImapServer *is;
is = _mail_imap_server_get(ev->server);
if (!is) return 1;
if (is->state == IMAP_STATE_DISCONNECTED)
printf("Imap Server Disconnected\n");
else
is->state = IMAP_STATE_DISCONNECTED;
ecore_con_server_del(is->server);
is->server = NULL;
if (is->count > 0)
_mail_set_text(is->data, is->count);
return 0;
}
static int
_mail_imap_server_data(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Data *ev = event;
ImapServer *is;
ImapClient *ic;
int len, num = 0, total = 0;
char in[1024], out[1024], *spc;
size_t slen;
is = _mail_imap_server_get(ev->server);
if (!is) return 1;
if (is->state == IMAP_STATE_DISCONNECTED) return 1;
len = sizeof(in) - 1;
len = (len > ev->size) ? (ev->size) : (len);
memcpy(in, ev->data, len);
in[len] = 0;
if (spc = strchr(in, ' '))
{
slen = strlen(spc);
if ((slen > 5) && (!strncmp(spc + 1, "NO ", 3)))
{
_mail_imap_server_logout(is);
printf("Imap Failure: %s\n", spc + 4);
return 0;
}
else if ((slen > 6) && (!strncmp(spc + 1, "BAD ", 4)))
{
_mail_imap_server_logout(is);
printf("Imap Bad Command: %s\n", spc + 5);
return 0;
}
}
ic = is->current;
is->state++;
switch (is->state)
{
case IMAP_STATE_SERVER_READY:
len = snprintf(out, sizeof(out), "A%03i LOGIN %s %s\r\n", ++is->cmd, ic->config->user, ic->config->pass);
ecore_con_server_send(ev->server, out, len);
break;
case IMAP_STATE_LOGGED_IN:
len = snprintf(out, sizeof(out), "A%03i STATUS %s (MESSAGES UNSEEN)\r\n", ++is->cmd, ic->config->new_path);
ecore_con_server_send(ev->server, out, len);
break;
case IMAP_STATE_STATUS_OK:
if (sscanf(in, "* STATUS %*s (MESSAGES %i UNSEEN %i)", &total, &num) == 2)
{
is->count += num;
ic->config->num_new = num;
ic->config->num_total = total;
is->clients = evas_list_next(is->clients);
if (is->clients)
{
is->current = is->clients->data;
if (is->current)
{
ic = is->current;
is->state = IMAP_STATE_SERVER_READY;
}
else
{
_mail_imap_server_logout(is);
ic = NULL;
}
}
else
{
_mail_imap_server_logout(is);
ic = NULL;
}
}
if (!ic) break;
default:
break;
}
return 0;
}
static void
_mail_imap_server_logout(ImapServer *is)
{
int len;
char out[1024];
if (!is) return;
if (is->state >= IMAP_STATE_LOGGED_IN)
{
len = snprintf(out, sizeof(out), "A%03i LOGOUT", ++is->cmd);
ecore_con_server_send(is->server, out, len);
}
ecore_con_server_del(is->server);
is->server = NULL;
is->state = IMAP_STATE_DISCONNECTED;
}

@ -0,0 +1,49 @@
#ifndef IMAP_H
#define IMAP_H
#include <e.h>
#include "e_mod_main.h"
typedef struct _ImapServer ImapServer;
typedef struct _ImapClient ImapClient;
typedef enum
{
IMAP_STATE_DISCONNECTED,
IMAP_STATE_CONNECTED,
IMAP_STATE_SERVER_READY,
IMAP_STATE_LOGGED_IN,
IMAP_STATE_STATUS_OK
} ImapState;
struct _ImapServer
{
Ecore_Con_Server *server;
Evas_List *clients;
ImapClient *current;
int cmd, count;
ImapState state;
void *data;
Ecore_Event_Handler *add_handler;
Ecore_Event_Handler *del_handler;
Ecore_Event_Handler *data_handler;
};
struct _ImapClient
{
Config_Box *config;
ImapServer *server;
};
void _mail_imap_check_mail(void *data);
void _mail_imap_add_mailbox(void *data);
void _mail_imap_del_mailbox(void *data);
void _mail_imap_shutdown();
#endif
//imap.1and1.com
//m39988144-2/3
////testing/2
//

107
mbox.c

@ -0,0 +1,107 @@
#include <e.h>
#include "e_mod_main.h"
#include "mbox.h"
static Evas_List *mboxes;
static void _mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path);
void
_mail_mbox_add_mailbox(void *data, void *data2)
{
MboxClient *mb;
Config_Box *cb;
cb = data2;
if (!cb) return;
mb = E_NEW(MboxClient, 1);
mb->config = cb;
mb->data = data;
mb->config->num_new = 0;
mb->config->num_total = 0;
mb->monitor = ecore_file_monitor_add(cb->new_path, _mail_mbox_check, mb);
mboxes = evas_list_append(mboxes, mb);
}
void
_mail_mbox_del_mailbox(void *data)
{
Config_Box *cb;
Evas_List *l;
cb = data;
if (!cb) return;
for (l = mboxes; l; l = l->next)
{
MboxClient *mb;
mb = l->data;
if (!mb) continue;
if (mb->config != cb) continue;
if (mb->monitor)
ecore_file_monitor_del(mb->monitor);
mboxes = evas_list_remove(mboxes, mb);
free(mb);
break;
}
}
void
_mail_mbox_shutdown()
{
if (!mboxes) return;
while (mboxes)
{
MboxClient *mb;
mb = mboxes->data;
if (mb->monitor)
ecore_file_monitor_del(mb->monitor);
mboxes = evas_list_remove_list(mboxes, mboxes);
free(mb);
}
}
/* PRIVATES */
static void
_mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path)
{
MboxClient *mb;
Config_Box *cb;
FILE *f;
char buf[1024];
int total = 0, unread = 0;
int header;
mb = data;
if (!mb) return;
cb = mb->config;
if (!cb) return;
if (!cb->new_path) return;
if (!(f = fopen(cb->new_path, "r")))
return;
mb->config->num_new = 0;
mb->config->num_total = 0;
while (fgets(buf, sizeof(buf), f))
{
if (buf[0] == '\n')
header = 0;
else if (!strncmp(buf, "From ", 5))
{
header = 1;
mb->config->num_total++;
mb->config->num_new++;
}
else if ((header) && (!strncmp(buf, "Status: ", 7)) && (strchr(buf, 'R')))
mb->config->num_new--;
}
fclose(f);
_mail_set_text(mb->data, mb->config->num_new);
}

@ -0,0 +1,20 @@
#ifndef MBOX_H
#define MBOX_H
#include <e.h>
#include "e_mod_main.h"
typedef struct _MboxClient MboxClient;
struct _MboxClient
{
void *data;
Config_Box *config;
Ecore_File_Monitor *monitor;
};
void _mail_mbox_add_mailbox(void *data, void *data2);
void _mail_mbox_del_mailbox(void *data);
void _mail_mbox_shutdown();
#endif

@ -0,0 +1,97 @@
#include <e.h>
#include "e_mod_main.h"
#include "mdir.h"
static Evas_List *mdirs;
static void _mail_mdir_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path);
static int _mail_mdir_get_files(const char *path);
void
_mail_mdir_add_mailbox(void *data, void *data2)
{
MdirClient *mc;
Config_Box *cb;
cb = data2;
if (!cb) return;
mc = E_NEW(MdirClient, 1);
mc->config = cb;
mc->data = data;
mc->config->num_new = 0;
mc->config->num_total = 0;
mc->monitor = ecore_file_monitor_add(cb->new_path, _mail_mdir_check, mc);
mdirs = evas_list_append(mdirs, mc);
}
void
_mail_mdir_del_mailbox(void *data)
{
Config_Box *cb;
Evas_List *l;
cb = data;
if (!cb) return;
for (l = mdirs; l; l = l->next)
{
MdirClient *mc;
mc = l->data;
if (!mc) continue;
if (mc->config != cb) continue;
mdirs = evas_list_remove(mdirs, mc);
free(mc);
break;
}
}
void
_mail_mdir_shutdown()
{
if (!mdirs) return;
while (mdirs)
{
MdirClient *mc;
mc = mdirs->data;
if (mc->monitor)
ecore_file_monitor_del(mc->monitor);
mdirs = evas_list_remove_list(mdirs, mdirs);
free(mc);
}
}
/* PRIVATES */
static void
_mail_mdir_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path)
{
MdirClient *mc;
mc = data;
if (!mc) return;
mc->config->num_total = _mail_mdir_get_files(mc->config->cur_path);
mc->config->num_new = _mail_mdir_get_files(mc->config->new_path);
_mail_set_text(mc->data, mc->config->num_new);
}
static int
_mail_mdir_get_files(const char *path)
{
Ecore_List *l;
char *item;
int i = 0;
l = ecore_file_ls(path);
ecore_list_goto_first(l);
while ((item = (char *)ecore_list_next(l)) != NULL)
{
if ((!strcmp(item, ".")) || (!strcmp(item, ".."))) continue;
i++;
}
ecore_list_destroy(l);
return i;
}

@ -0,0 +1,20 @@
#ifndef MDIR_H
#define MDIR_H
#include <e.h>
#include "e_mod_main.h"
typedef struct _MdirClient MdirClient;
struct _MdirClient
{
void *data;
Config_Box *config;
Ecore_File_Monitor *monitor;
};
void _mail_mdir_add_mailbox(void *data, void *data2);
void _mail_mdir_del_mailbox(void *data);
void _mail_mdir_shutdown();
#endif

144
pop.c

@ -0,0 +1,144 @@
#include <e.h>
#include "e_mod_main.h"
#include "pop.h"
static Ecore_Event_Handler *add_handler;
static Ecore_Event_Handler *del_handler;
static Ecore_Event_Handler *data_handler;
static int _mail_pop_server_add(void *data, int type, void *event);
static int _mail_pop_server_del(void *data, int type, void *event);
static int _mail_pop_server_data(void *data, int type, void *event);
void
_mail_pop_check_mail(void *data, void *data2)
{
PopClient *pc;
Ecore_Con_Type type = ECORE_CON_REMOTE_SYSTEM;
Config_Box *cb;
cb = data2;
if (!cb) return;
pc = E_NEW(PopClient, 1);
pc->data = data;
pc->config = cb;
pc->config->num_new = 0;
pc->config->num_total = 0;
add_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _mail_pop_server_add, pc);
del_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _mail_pop_server_del, pc);
data_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _mail_pop_server_data, pc);
if ((ecore_con_ssl_available_get()) && (cb->ssl))
type |= ECORE_CON_USE_SSL;
pc->server = ecore_con_server_connect(type, cb->host, cb->port, NULL);
pc->state = POP_STATE_DISCONNECTED;
}
/* PRIVATES */
static int
_mail_pop_server_add(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Add *ev = event;
PopClient *pc;
if (!data) return 1;
pc = data;
pc->state = POP_STATE_CONNECTED;
return 0;
}
static int
_mail_pop_server_del(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Del *ev = event;
PopClient *pc;
pc = data;
if (!pc) return 1;
ecore_con_server_del(pc->server);
pc->server = NULL;
if (add_handler)
ecore_event_handler_del(add_handler);
if (del_handler)
ecore_event_handler_del(del_handler);
if (data_handler)
ecore_event_handler_del(data_handler);
return 0;
}
static int
_mail_pop_server_data(void *data, int type, void *event)
{
Ecore_Con_Event_Server_Data *ev = event;
PopClient *pc;
char in[2048], out[2048];
int len, num = 0, total = 0;
if (!data) return 1;
pc = data;
if ((!pc->server) || (pc->server != ev->server)) return 1;
len = sizeof(in) -1;
len = (((len) > (ev->size)) ? ev->size : len);
memcpy(in, ev->data, len);
in[len] = 0;
if (!strncmp(in, "-ERR", 4))
{
printf("ERROR: %s\n", in);
pc->state = POP_STATE_DISCONNECTED;
ecore_con_server_del(ev->server);
pc->server = NULL;
return 0;
}
else if (strncmp(in, "+OK", 3))
{
printf("Unexpected reply: %s\n", in);
pc->state = POP_STATE_DISCONNECTED;
ecore_con_server_del(ev->server);
pc->server = NULL;
return 0;
}
if (pc->state == POP_STATE_CONNECTED)
pc->state++;
switch (pc->state)
{
case POP_STATE_SERVER_READY:
len = snprintf(out, sizeof(out), "USER %s\r\n", pc->config->user);
ecore_con_server_send(ev->server, out, len);
pc->state = POP_STATE_USER_OK;
break;
case POP_STATE_USER_OK:
len = snprintf(out, sizeof(out), "PASS %s\r\n", pc->config->pass);
ecore_con_server_send(ev->server, out, len);
pc->state = POP_STATE_PASS_OK;
break;
case POP_STATE_PASS_OK:
len = snprintf(out, sizeof(out), "STAT\r\n");
ecore_con_server_send(ev->server, out, len);
pc->state = POP_STATE_STATUS_OK;
break;
case POP_STATE_STATUS_OK:
if (sscanf(in, "+OK %i %i", &num, &total) == 2)
{
pc->config->num_new = num;
pc->config->num_total = num;
}
_mail_set_text(pc->data, num);
ecore_con_server_del(ev->server);
pc->state = POP_STATE_DISCONNECTED;
pc->server = NULL;
break;
default:
break;
}
return 0;
}

29
pop.h

@ -0,0 +1,29 @@
#ifndef POP_H
#define POP_H
#include <e.h>
#include "e_mod_main.h"
typedef struct _PopClient PopClient;
typedef enum
{
POP_STATE_DISCONNECTED,
POP_STATE_CONNECTED,
POP_STATE_SERVER_READY,
POP_STATE_USER_OK,
POP_STATE_PASS_OK,
POP_STATE_STATUS_OK
} PopState;
struct _PopClient
{
void *data;
PopState state;
Config_Box *config;
Ecore_Con_Server *server;
};
void _mail_pop_check_mail(void *data, void *data2);
#endif
Loading…
Cancel
Save