From 7389749571a6ae54f425039529e00180d502b264 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Mon, 12 Jun 2006 10:03:52 +0000 Subject: [PATCH] Ok, pop mail now works again :) General bug fixes when setting mail count on the module. Minor edc changes. Better cleanup when closing the module. SVN revision: 23396 --- e_mod_main.c | 50 +++++----- e_mod_main.h | 21 +++- imap.c | 18 +++- mail.edc | 2 +- mbox.c | 13 ++- mdir.c | 14 ++- pop.c | 263 ++++++++++++++++++++++++++++++++++++++++----------- pop.h | 8 +- 8 files changed, 295 insertions(+), 94 deletions(-) diff --git a/e_mod_main.c b/e_mod_main.c index a96343a..defa068 100644 --- a/e_mod_main.c +++ b/e_mod_main.c @@ -24,24 +24,6 @@ #include "mdir.h" #include "mbox.h" -typedef struct _Instance Instance; -typedef struct _Mail Mail; - -struct _Instance -{ - E_Gadcon_Client *gcc; - Evas_Object *mail_obj; - Mail *mail; - Ecore_Exe *exe; - Ecore_Timer *check_timer; -}; - -struct _Mail -{ - Instance *inst; - Evas_Object *mail_obj; -}; - /* Func Protos for Gadcon */ static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style); static void _gc_shutdown(E_Gadcon_Client *gcc); @@ -126,6 +108,7 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) inst->check_timer = ecore_timer_add((ci->check_time * 60.0), _mail_cb_check, inst); break; case MAIL_TYPE_POP: + _mail_pop_add_mailbox(cb); if (!inst->check_timer) inst->check_timer = ecore_timer_add((ci->check_time * 60.0), _mail_cb_check, inst); break; @@ -409,6 +392,7 @@ e_modapi_shutdown(E_Module *m) _mail_imap_del_mailbox(cb); break; case MAIL_TYPE_POP: + _mail_pop_del_mailbox(cb); break; case MAIL_TYPE_MDIR: _mail_mdir_del_mailbox(cb); @@ -431,6 +415,10 @@ e_modapi_shutdown(E_Module *m) mail_config->items = evas_list_remove_list(mail_config->items, mail_config->items); free(ci); } + _mail_imap_shutdown(); + _mail_pop_shutdown(); + _mail_mdir_shutdown(); + _mail_mbox_shutdown(); free(mail_config); mail_config = NULL; E_CONFIG_DD_FREE(conf_box_edd); @@ -496,7 +484,7 @@ _mail_cb_check(void *data) Instance *inst = data; Config_Item *ci; Evas_List *l; - int have_imap = 0; + int have_imap = 0, have_pop = 0; if (!inst) return 1; ci = _mail_config_item_get(inst->gcc->id); @@ -506,6 +494,7 @@ _mail_cb_check(void *data) Config_Box *cb; cb = l->data; + if (!cb) continue; switch (cb->type) { case MAIL_TYPE_MDIR: @@ -513,7 +502,7 @@ _mail_cb_check(void *data) case MAIL_TYPE_MBOX: break; case MAIL_TYPE_POP: - _mail_pop_check_mail(inst, cb); + have_pop = 1; break; case MAIL_TYPE_IMAP: have_imap = 1; @@ -521,20 +510,21 @@ _mail_cb_check(void *data) } } if (have_imap) _mail_imap_check_mail(inst); + if (have_pop) _mail_pop_check_mail(inst); return 1; } void -_mail_set_text(void *data, int count) +_mail_set_text(void *data) { Instance *inst = data; char buf[1024]; if (!inst) return; - if (count > 0) + if (inst->count > 0) { - snprintf(buf, sizeof(buf), "%d", count); + snprintf(buf, sizeof(buf), "%d", inst->count); edje_object_part_text_set(inst->mail->mail_obj, "new_label", buf); edje_object_signal_emit(inst->mail->mail_obj, "new_mail", ""); } @@ -545,6 +535,18 @@ _mail_set_text(void *data, int count) } } +void +_mail_start_exe(void *data) +{ + Config_Box *cb; + + cb = data; + if (!cb) return; + + exit_handler = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _mail_cb_exe_exit, cb); + cb->exe = ecore_exe_run(cb->exec, cb); +} + static int _mail_cb_exe_exit(void *data, int type, void *event) { @@ -583,6 +585,7 @@ _mail_box_added(const char *ci_name, const char *box_name) _mail_imap_add_mailbox(cb); break; case MAIL_TYPE_POP: + _mail_pop_add_mailbox(cb); break; case MAIL_TYPE_MDIR: _mail_mdir_add_mailbox(inst, cb); @@ -637,6 +640,7 @@ _mail_box_deleted(const char *ci_name, const char *box_name) _mail_imap_del_mailbox(cb); break; case MAIL_TYPE_POP: + _mail_pop_del_mailbox(cb); break; case MAIL_TYPE_MDIR: _mail_mdir_del_mailbox(cb); diff --git a/e_mod_main.h b/e_mod_main.h index ab8b73f..67ecdc5 100644 --- a/e_mod_main.h +++ b/e_mod_main.h @@ -14,6 +14,24 @@ typedef enum typedef struct _Config Config; typedef struct _Config_Item Config_Item; typedef struct _Config_Box Config_Box; +typedef struct _Instance Instance; +typedef struct _Mail Mail; + +struct _Instance +{ + E_Gadcon_Client *gcc; + Evas_Object *mail_obj; + Mail *mail; + Ecore_Exe *exe; + Ecore_Timer *check_timer; + int count; +}; + +struct _Mail +{ + Instance *inst; + Evas_Object *mail_obj; +}; struct _Config { @@ -66,7 +84,8 @@ void _mail_config_updated(const char *id); void _mail_box_config_updated(E_Config_Dialog *cfd); void _mail_box_deleted(const char *ci_name, const char *box_name); void _mail_box_added(const char *ci_name, const char *box_name); -void _mail_set_text(void *data, int count); +void _mail_set_text(void *data); +void _mail_start_exe(void *data); extern Config *mail_config; diff --git a/imap.c b/imap.c index d43e860..7486bc8 100644 --- a/imap.c +++ b/imap.c @@ -3,7 +3,7 @@ #include "imap.h" static ImapServer *_mail_imap_server_get(Ecore_Con_Server *server); -static ImapClient *_mail_imap_client_get(Config_Box *cb); +static ImapClient *_mail_imap_client_get(void *data); 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); @@ -114,13 +114,17 @@ _mail_imap_server_get(Ecore_Con_Server *server) } static ImapClient * -_mail_imap_client_get(Config_Box *cb) +_mail_imap_client_get(void *data) { ImapServer *is; ImapClient *ic; + Config_Box *cb; Evas_List *l, *j; int found = 0; + cb = data; + if (!cb) return NULL; + if ((!iservers) || (evas_list_count(iservers) <= 0)) { is = E_NEW(ImapServer, 1); @@ -178,6 +182,7 @@ _mail_imap_server_del(void *data, int type, void *event) { Ecore_Con_Event_Server_Del *ev = event; ImapServer *is; + Instance *inst; is = _mail_imap_server_get(ev->server); if (!is) return 1; @@ -189,9 +194,10 @@ _mail_imap_server_del(void *data, int type, void *event) ecore_con_server_del(is->server); is->server = NULL; - if (is->count > 0) - _mail_set_text(is->data, is->count); - + inst = is->data; + inst->count = is->count; + _mail_set_text(inst); + return 0; } @@ -251,6 +257,8 @@ _mail_imap_server_data(void *data, int type, void *event) is->count += num; ic->config->num_new = num; ic->config->num_total = total; + if ((num > 0) && (ic->config->use_exec) && (ic->config->exec)) + _mail_start_exe(ic->config); is->clients = evas_list_next(is->clients); if (is->clients) diff --git a/mail.edc b/mail.edc index 2906f7c..0a163d5 100644 --- a/mail.edc +++ b/mail.edc @@ -80,7 +80,7 @@ collections type: TEXT; clip_to: "clip"; effect: SOFT_SHADOW; - mouse_events: 0; + mouse_events: 1; description { state: "default" 0.0; diff --git a/mbox.c b/mbox.c index b77a720..a828244 100644 --- a/mbox.c +++ b/mbox.c @@ -4,7 +4,7 @@ static Evas_List *mboxes; -static void _mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path); +static void _mail_mbox_check_mail(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path); void _mail_mbox_add_mailbox(void *data, void *data2) @@ -20,7 +20,7 @@ _mail_mbox_add_mailbox(void *data, void *data2) 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); + mb->monitor = ecore_file_monitor_add(cb->new_path, _mail_mbox_check_mail, mb); mboxes = evas_list_append(mboxes, mb); } @@ -66,7 +66,7 @@ _mail_mbox_shutdown() /* PRIVATES */ static void -_mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path) +_mail_mbox_check_mail(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path) { MboxClient *mb; Config_Box *cb; @@ -74,6 +74,7 @@ _mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event char buf[1024]; int total = 0, unread = 0; int header; + Instance *inst; mb = data; if (!mb) return; @@ -103,5 +104,9 @@ _mail_mbox_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event } fclose(f); - _mail_set_text(mb->data, mb->config->num_new); + inst = mb->data; + inst->count = mb->config->num_new; + _mail_set_text(inst); + if ((mb->config->num_new > 0) && (mb->config->use_exec) && (mb->config->exec)) + _mail_start_exe(mb->config); } diff --git a/mdir.c b/mdir.c index 245f7e9..0d8047b 100644 --- a/mdir.c +++ b/mdir.c @@ -4,7 +4,7 @@ static Evas_List *mdirs; -static void _mail_mdir_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path); +static void _mail_mdir_check_mail(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path); static int _mail_mdir_get_files(const char *path); void @@ -21,7 +21,7 @@ _mail_mdir_add_mailbox(void *data, void *data2) 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); + mc->monitor = ecore_file_monitor_add(cb->new_path, _mail_mdir_check_mail, mc); mdirs = evas_list_append(mdirs, mc); } @@ -65,17 +65,21 @@ _mail_mdir_shutdown() /* PRIVATES */ static void -_mail_mdir_check(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path) +_mail_mdir_check_mail(void *data, Ecore_File_Monitor *monitor, Ecore_File_Event event, const char *path) { MdirClient *mc; + Instance *inst; 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); + inst = mc->data; + inst->count = mc->config->num_new; + _mail_set_text(inst); + if ((mc->config->num_new > 0) && (mc->config->use_exec) && (mc->config->exec)) + _mail_start_exe(mc->config); } static int diff --git a/pop.c b/pop.c index 7576cba..7a9a169 100644 --- a/pop.c +++ b/pop.c @@ -2,36 +2,106 @@ #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); +static PopClient *_mail_pop_client_get(void *data); +static PopClient *_mail_pop_client_get_from_server(void *data); +static void _mail_pop_client_quit(void *data); + +static Evas_List *pclients; void -_mail_pop_check_mail(void *data, void *data2) +_mail_pop_check_mail(void *data) +{ + Ecore_Con_Type type = ECORE_CON_REMOTE_SYSTEM; + Evas_List *l; + Instance *inst; + + inst = data; + if (!inst) return; + + for (l = pclients; l; l = l->next) + { + PopClient *pc; + Config_Box *cb; + + pc = l->data; + if (!pc) continue; + pc->data = inst; + if (!pc->server) + { + if (!pc->add_handler) + pc->add_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _mail_pop_server_add, NULL); + if (!pc->del_handler) + pc->del_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _mail_pop_server_del, NULL); + if (!pc->data_handler) + pc->data_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _mail_pop_server_data, NULL); + + if ((ecore_con_ssl_available_get()) && (pc->config->ssl)) + type |= ECORE_CON_USE_SSL; + pc->server = ecore_con_server_connect(type, pc->config->host, pc->config->port, pc); + pc->state = POP_STATE_DISCONNECTED; + } + } +} + +void +_mail_pop_add_mailbox(void *data) { PopClient *pc; - Ecore_Con_Type type = ECORE_CON_REMOTE_SYSTEM; Config_Box *cb; - cb = data2; + cb = data; if (!cb) return; - - pc = E_NEW(PopClient, 1); - pc->data = data; - pc->config = cb; + pc = _mail_pop_client_get(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; + pclients = evas_list_append(pclients, pc); +} + +void +_mail_pop_del_mailbox(void *data) +{ + PopClient *pc; + Config_Box *cb; + + cb = data; + if (!cb) return; + pc = _mail_pop_client_get(cb); + if (pc->server) + _mail_pop_client_quit(pc); + if (pc->add_handler) + ecore_event_handler_del(pc->add_handler); + if (pc->del_handler) + ecore_event_handler_del(pc->del_handler); + if (pc->data_handler) + ecore_event_handler_del(pc->data_handler); + pclients = evas_list_remove(pclients, pc); +} + +void +_mail_pop_shutdown() +{ + if (!pclients) return; + + while (pclients) + { + PopClient *pc; + + pc = pclients->data; + if (!pc) continue; + if (pc->server) + _mail_pop_client_quit(pc); + if (pc->add_handler) + ecore_event_handler_del(pc->add_handler); + if (pc->del_handler) + ecore_event_handler_del(pc->del_handler); + if (pc->data_handler) + ecore_event_handler_del(pc->data_handler); + pclients = evas_list_remove_list(pclients, pclients); + free(pc); + } } /* PRIVATES */ @@ -41,8 +111,9 @@ _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 = _mail_pop_client_get_from_server(ev->server); + if (!pc) return 1; + pc->state = POP_STATE_CONNECTED; return 0; } @@ -52,20 +123,18 @@ _mail_pop_server_del(void *data, int type, void *event) { Ecore_Con_Event_Server_Del *ev = event; PopClient *pc; + Instance *inst; - pc = data; + pc = _mail_pop_client_get_from_server(ev->server); if (!pc) return 1; - ecore_con_server_del(pc->server); + if (pc->state = POP_STATE_DISCONNECTED) + printf("Pop Server Disconnected\n"); + + ecore_con_server_del(ev->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); - + pc->state = POP_STATE_DISCONNECTED; + return 0; } @@ -74,13 +143,15 @@ _mail_pop_server_data(void *data, int type, void *event) { Ecore_Con_Event_Server_Data *ev = event; PopClient *pc; + Instance *inst; 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; + pc = _mail_pop_client_get_from_server(ev->server); + if (!pc) return 1; + if (pc->state == POP_STATE_DISCONNECTED) return 1; + + inst = pc->data; len = sizeof(in) -1; len = (((len) > (ev->size)) ? ev->size : len); @@ -90,39 +161,30 @@ _mail_pop_server_data(void *data, int type, void *event) if (!strncmp(in, "-ERR", 4)) { printf("ERROR: %s\n", in); - pc->state = POP_STATE_DISCONNECTED; - ecore_con_server_del(ev->server); - pc->server = NULL; + _mail_pop_client_quit(pc); 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; + _mail_pop_client_quit(pc); return 0; } - if (pc->state == POP_STATE_CONNECTED) - pc->state++; - + 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) @@ -130,15 +192,108 @@ _mail_pop_server_data(void *data, int type, void *event) 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; + inst->count = num; + _mail_pop_client_quit(pc); + if ((num > 0) && (pc->config->use_exec) && (pc->config->exec)) + _mail_start_exe(pc->config); break; default: break; - } - return 0; + } + return 0; +} + +static PopClient * +_mail_pop_client_get(void *data) +{ + PopClient *pc; + Evas_List *l; + Config_Box *cb; + int found = 0; + + cb = data; + if (!cb) return NULL; + + if ((!pclients) || (evas_list_count(pclients) <= 0)) + { + pc = E_NEW(PopClient, 1); + pc->server = NULL; + pc->state = POP_STATE_DISCONNECTED; + pc->config = cb; + if (!pc->add_handler) + pc->add_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _mail_pop_server_add, NULL); + if (!pc->del_handler) + pc->del_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _mail_pop_server_del, NULL); + if (!pc->data_handler) + pc->data_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _mail_pop_server_data, NULL); + } + + for (l = pclients; l; l = l->next) + { + pc = l->data; + if (!pc) continue; + if (!pc->config) continue; + if ((!strcmp(pc->config->host, cb->host)) && + (!strcmp(pc->config->user, cb->user)) && + (!strcmp(pc->config->pass, cb->pass))) + { + found = 1; + break; + } + } + if (!found) + { + pc = E_NEW(PopClient, 1); + pc->server = NULL; + pc->state = POP_STATE_DISCONNECTED; + pc->config = cb; + if (!pc->add_handler) + pc->add_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, _mail_pop_server_add, NULL); + if (!pc->del_handler) + pc->del_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, _mail_pop_server_del, NULL); + if (!pc->data_handler) + pc->data_handler = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, _mail_pop_server_data, NULL); + } + return pc; +} + +static PopClient * +_mail_pop_client_get_from_server(void *data) +{ + Ecore_Con_Server *server = data; + Evas_List *l; + + if (!pclients) return NULL; + for (l = pclients; l; l = l->next) + { + PopClient *pc; + + pc = l->data; + if (!pc) continue; + if (!pc->server) continue; + if (pc->server == server) + return pc; + } + return NULL; +} + +static void +_mail_pop_client_quit(void *data) +{ + PopClient *pc; + int len; + char out[1024]; + + pc = data; + if (!pc) return; + if (pc->state >= POP_STATE_CONNECTED) + { + len = snprintf(out, sizeof(out), "QUIT\r\n"); + ecore_con_server_send(pc->server, out, len); + } + ecore_con_server_del(pc->server); + pc->server = NULL; + pc->state = POP_STATE_DISCONNECTED; + + _mail_set_text(pc->data); } diff --git a/pop.h b/pop.h index cda7249..4fff942 100644 --- a/pop.h +++ b/pop.h @@ -22,8 +22,14 @@ struct _PopClient PopState state; Config_Box *config; Ecore_Con_Server *server; + Ecore_Event_Handler *add_handler; + Ecore_Event_Handler *del_handler; + Ecore_Event_Handler *data_handler; }; -void _mail_pop_check_mail(void *data, void *data2); +void _mail_pop_check_mail(void *data); +void _mail_pop_add_mailbox(void *data); +void _mail_pop_del_mailbox(void *data); +void _mail_pop_shutdown(); #endif