diff --git a/imap.c b/imap.c new file mode 100644 index 0000000..d43e860 --- /dev/null +++ b/imap.c @@ -0,0 +1,299 @@ +#include +#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; +} diff --git a/imap.h b/imap.h new file mode 100644 index 0000000..f57762f --- /dev/null +++ b/imap.h @@ -0,0 +1,49 @@ +#ifndef IMAP_H +#define IMAP_H + +#include +#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 +// diff --git a/mbox.c b/mbox.c new file mode 100644 index 0000000..b77a720 --- /dev/null +++ b/mbox.c @@ -0,0 +1,107 @@ +#include +#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); +} diff --git a/mbox.h b/mbox.h new file mode 100644 index 0000000..e411269 --- /dev/null +++ b/mbox.h @@ -0,0 +1,20 @@ +#ifndef MBOX_H +#define MBOX_H + +#include +#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 diff --git a/mdir.c b/mdir.c new file mode 100644 index 0000000..245f7e9 --- /dev/null +++ b/mdir.c @@ -0,0 +1,97 @@ +#include +#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; +} diff --git a/mdir.h b/mdir.h new file mode 100644 index 0000000..f1dd182 --- /dev/null +++ b/mdir.h @@ -0,0 +1,20 @@ +#ifndef MDIR_H +#define MDIR_H + +#include +#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 diff --git a/pop.c b/pop.c new file mode 100644 index 0000000..7576cba --- /dev/null +++ b/pop.c @@ -0,0 +1,144 @@ +#include +#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; +} diff --git a/pop.h b/pop.h new file mode 100644 index 0000000..cda7249 --- /dev/null +++ b/pop.h @@ -0,0 +1,29 @@ +#ifndef POP_H +#define POP_H + +#include +#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