Enlightenment CVS committal

Author  : tsauerbeck
Project : misc
Module  : embrace

Dir     : misc/embrace/src/plugins/imap


Modified Files:
        imap.c 


Log Message:
merged Sebastian Dransfeld's patch that implements 'connection sharing'
===================================================================
RCS file: /cvsroot/enlightenment/misc/embrace/src/plugins/imap/imap.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -3 -r1.18 -r1.19
--- imap.c      29 Jun 2005 16:28:05 -0000      1.18
+++ imap.c      3 Sep 2005 12:24:01 -0000       1.19
@@ -1,5 +1,5 @@
 /*
- * $Id: imap.c,v 1.18 2005/06/29 16:28:05 tsauerbeck Exp $
+ * $Id: imap.c,v 1.19 2005/09/03 12:24:01 tsauerbeck Exp $
  * vim:noexpandtab:ts=4:sw=4:sts=4
  *
  * Copyright (C) 2004 Embrace project.
@@ -38,32 +38,94 @@
        STATE_STATUS_OK
 } State;
 
+typedef struct {
+       char *host;
+       int port;
+       bool use_ssl;
+       char *user;
+       char *pass;
+
+       Evas_List *clients;
+       Evas_List *current;
+
+       Ecore_Timer *timer;
+       double interval;
+
+       Ecore_Con_Server *server;
+       State state;
+       int command_no;
+} ImapServer;
+
 #define MIN_INTERVAL 60
 #define LOGOUT() \
-       if (state >= STATE_LOGGED_IN) { \
+       if (server->state >= STATE_LOGGED_IN) { \
                len = snprintf (outbuf, sizeof (outbuf), \
-                               "A%03i LOGOUT", command_no); \
-               ecore_con_server_send (ev->server, outbuf, len); \
+                               "A%03i LOGOUT", ++server->command_no); \
+               ecore_con_server_send (server->server, outbuf, len); \
        } \
 \
-       ecore_con_server_del (ev->server); \
-       mailbox_property_set (mb, "server", NULL);
+       ecore_con_server_del (server->server); \
+       server->server = NULL;
 
 static EmbracePlugin *plugin = NULL;
+static Evas_List *servers = NULL;
 
-static int on_server_add (void *udata, int type, void *event)
+static ImapServer *find_server (Ecore_Con_Server *server)
 {
-       Ecore_Con_Event_Server_Add *ev = event;
-       MailBox *mb;
+       Evas_List *l;
+
+       for (l = servers; l; l = l->next) {
+               ImapServer *current = l->data;
+
+               if (current->server == server)
+                       return current;
+       }
+
+       return NULL;
+}
+
+static ImapServer *find_server_by_mailbox (MailBox *mb)
+{
+       Evas_List *l;
+       char *host;
+       int port;
+       int use_ssl;
+       char *user;
+       char *pass;
 
-       mb = ecore_con_server_data_get (ev->server);
        assert (mb);
 
-       if (mailbox_plugin_get (mb) != plugin)
+       host = mailbox_property_get (mb, "host");
+       port = (int) mailbox_property_get (mb, "port");
+       use_ssl = (int) mailbox_property_get (mb, "ssl");
+       user = mailbox_property_get (mb, "user");
+       pass = mailbox_property_get (mb, "pass");
+
+       for (l = servers; l; l = l->next) {
+               ImapServer *current = l->data;
+
+               if (port == current->port && use_ssl == current->use_ssl &&
+                   !strcmp (host, current->host) &&
+                   !strcmp (user, current->user) &&
+                   !strcmp (pass, current->pass))
+                       return current;
+       }
+
+       return NULL;
+}
+
+static int on_server_add (void *udata, int type, void *event)
+{
+       Ecore_Con_Event_Server_Add *ev = event;
+       ImapServer *server;
+
+       /* Make sure this event is for us */
+       server = find_server (ev->server);
+       if (!server)
                return 1;
 
-       mailbox_property_set (mb, "state", (void *) STATE_CONNECTED);
-       mailbox_property_set (mb, "command_no", (void *) 0);
+       server->state = STATE_CONNECTED;
+       server->command_no = 0;
 
        return 0;
 }
@@ -71,16 +133,15 @@
 static int on_server_data (void *udata, int type, void *event)
 {
        Ecore_Con_Event_Server_Data *ev = event;
+       ImapServer *server;
        MailBox *mb;
-       State state;
        char inbuf[1024], outbuf[256], *spc;
-       int total = 0, unseen = 0, len, command_no;
+       int total = 0, unseen = 0, len;
        size_t slen;
 
-       mb = ecore_con_server_data_get (ev->server);
-       assert (mb);
-
-       if (mailbox_plugin_get (mb) != plugin)
+       /* Make sure this event is for us */
+       server = find_server (ev->server);
+       if (!server)
                return 1;
 
        /* take the data and make a NUL-terminated string out of it */
@@ -91,11 +152,7 @@
        inbuf[len] = 0;
        embrace_strstrip (inbuf);
 
-       state = (State) mailbox_property_get (mb, "state");
-       assert (state != STATE_DISCONNECTED);
-
-       command_no = (int) mailbox_property_get (mb, "command_no");
-       mailbox_property_set (mb, "command_no", (void *) ++command_no);
+       assert (server->state != STATE_DISCONNECTED);
 
        if ((spc = strchr (inbuf, ' '))) {
                slen = strlen (spc);
@@ -111,22 +168,15 @@
                }
        }
 
-       mailbox_property_set (mb, "state", (void *) ++state);
+       mb = server->current->data;
+       server->state++;
 
-       switch (state) {
+       switch (server->state) {
                case STATE_SERVER_READY:
                        len = snprintf (outbuf, sizeof (outbuf),
                                        "A%03i LOGIN %s %s\r\n",
-                                       command_no,
-                                       (char *) mailbox_property_get (mb, 
"user"),
-                                       (char *) mailbox_property_get (mb, 
"pass"));
-                       ecore_con_server_send (ev->server, outbuf, len);
-                       break;
-               case STATE_LOGGED_IN:
-                       len = snprintf (outbuf, sizeof (outbuf),
-                                       "A%03i STATUS %s (MESSAGES UNSEEN)\r\n",
-                                       command_no,
-                                       (char *) mailbox_property_get (mb, 
"path"));
+                                       ++server->command_no,
+                                       server->user, server->pass);
                        ecore_con_server_send (ev->server, outbuf, len);
                        break;
                case STATE_STATUS_OK:
@@ -135,9 +185,28 @@
                                mailbox_unseen_set (mb, unseen);
                                mailbox_total_set (mb, total);
 
-                               LOGOUT ();
+                               server->current = server->current->next;
+
+                               if (server->current) {
+                                       mb = server->current->data;
+                                       server->state = STATE_LOGGED_IN;
+                               } else {
+                                       mb = NULL;
+                                       LOGOUT ();
+                               }
+                       } else {
+                               assert (false);
                        }
 
+                       /* Fall through if we got another mailbox to check */
+                       if (!mb)
+                               break;
+               case STATE_LOGGED_IN:
+                       len = snprintf (outbuf, sizeof (outbuf),
+                                       "A%03i STATUS %s (MESSAGES UNSEEN)\r\n",
+                                       ++server->command_no,
+                                       (char *) mailbox_property_get (mb, 
"path"));
+                       ecore_con_server_send (ev->server, outbuf, len);
                        break;
                default:
                        assert (false);
@@ -149,92 +218,167 @@
 static int on_server_del (void *udata, int type, void *event)
 {
        Ecore_Con_Event_Server_Del *ev = event;
-       MailBox *mb;
-       char *host;
+       ImapServer *server;
 
-       mb = ecore_con_server_data_get (ev->server);
-       assert (mb);
-
-       if (mailbox_plugin_get (mb) != plugin)
+       /* Make sure this event is for us */
+       server = find_server (ev->server);
+       if (!server)
                return 1;
 
-       host = (char *) mailbox_property_get (mb, "host");
-
-       if (mailbox_property_get (mb, "state") == STATE_DISCONNECTED)
-               fprintf (stderr, "[imap] cannot connect to '%s'\n", host);
+       if (server->state == STATE_DISCONNECTED)
+               fprintf (stderr, "[imap] cannot connect to '%s'\n", 
server->host);
        else {
-               mailbox_property_set (mb, "state", STATE_DISCONNECTED);
-               fprintf (stderr, "[imap] lost connection to '%s'\n", host);
+               server->state = STATE_DISCONNECTED;
+               fprintf (stderr, "[imap] lost connection to '%s'\n", 
server->host);
        }
 
-       ecore_con_server_del (ev->server);
-       mailbox_property_set (mb, "server", NULL);
+       ecore_con_server_del (server->server);
+       server->server = NULL;
 
        return 0;
 }
 
-static bool imap_check (MailBox *mb)
+static bool imap_server_check (ImapServer *server)
 {
        Ecore_Con_Type type = ECORE_CON_REMOTE_SYSTEM;
-       Ecore_Con_Server *server;
-       char *host;
-       int port;
 
-       host = mailbox_property_get (mb, "host"),
-       port = (int) mailbox_property_get (mb, "port");
-
-       assert (host);
-       assert (port);
+       assert (server);
 
-       if (mailbox_property_get (mb, "server")) {
-               fprintf (stderr, "[imap] already connected to '%s'\n", host);
+       if (server->server) {
+               fprintf (stderr, "[imap] already connected to '%s'\n", 
server->host);
                return false;
        }
 
        if (ecore_con_ssl_available_get () &&
-           mailbox_property_get (mb, "ssl"))
+           server->use_ssl)
                type |= ECORE_CON_USE_SSL;
 
-       server = ecore_con_server_connect (type, host, port, mb);
-
-       mailbox_property_set (mb, "state", STATE_DISCONNECTED);
-       mailbox_property_set (mb, "server", server);
+       server->server = ecore_con_server_connect (type, server->host,
+                                                  server->port, NULL);
+       server->state = STATE_DISCONNECTED;
+       server->current = server->clients;
 
        return true;
 }
 
+static bool imap_check (MailBox *mb)
+{
+       ImapServer *server;
+       bool ret = true;
+
+       assert (mb);
+
+       server = (ImapServer *) mailbox_property_get (mb, "server");
+       if (server)
+               ret = imap_server_check (server);
+
+       return ret;
+}
+
 static int on_timer (void *udata)
 {
-       imap_check (udata);
+       imap_server_check (udata);
 
        return 1;
 }
 
-static bool imap_add_mailbox (MailBox *mb)
+static ImapServer *create_server (MailBox *mb)
 {
-       Ecore_Timer *timer;
-       int interval;
+       ImapServer *s;
+
+       s = calloc (1, sizeof (ImapServer));
+       if (!s)
+               return NULL;
+
+       s->interval = MAX (mailbox_poll_interval_get (mb), MIN_INTERVAL);
+       s->timer = ecore_timer_add (s->interval, on_timer, s);
+       if (!s->timer) {
+               free (s);
+               return NULL;
+       }
+
+       s->host = strdup (mailbox_property_get (mb, "host"));
+       s->port = (int) mailbox_property_get (mb, "port");
+       s->use_ssl = (bool) mailbox_property_get (mb, "ssl");
+       s->user = strdup (mailbox_property_get (mb, "user"));
+       s->pass = strdup (mailbox_property_get (mb, "pass"));
+       s->state = STATE_DISCONNECTED;
+
+       return s;
+}
+
+static bool imap_add_server (MailBox *mb)
+{
+       ImapServer *server;
+       double interval;
 
        assert (mb);
 
-       interval = MAX (mailbox_poll_interval_get (mb), MIN_INTERVAL);
+       /* did we already create a server for this mailbox? */
+       server = find_server_by_mailbox (mb);
+       if (!server) {
+               server = create_server (mb);
+               if (!server)
+                       return false;
+
+               servers = evas_list_append (servers, server);
+       } else {
+               interval = MAX (mailbox_poll_interval_get (mb), MIN_INTERVAL);
+               if (interval < server->interval) {
+                       server->interval = interval;
+                       ecore_timer_del (server->timer);
+
+                       server->timer = ecore_timer_add (server->interval,
+                                                        on_timer, server);
+                       if (!server->timer) {
+                               free (server);
+                               return false;
+                       }
+               }
+       }
+
+       server->clients = evas_list_append (server->clients, mb);
+       mailbox_property_set (mb, "server", server);
 
-       if (!(timer = ecore_timer_add (interval, on_timer, mb)))
-               return false;
+       return true;
+}
+
+static bool imap_remove_server (ImapServer *server, MailBox *mb)
+{
+       assert (server);
+       assert (mb);
+
+       /* FIXME: reschedule server timer */
+       server->clients = evas_list_remove (server->clients, mb);
+       if (!server->clients) {
+               free (server->host);
+               free (server->user);
+               free (server->pass);
 
-       mailbox_property_set (mb, "timer", timer);
+               ecore_timer_del (server->timer);
+
+               servers = evas_list_remove (servers, server);
+               free (server);
+       }
 
        return true;
 }
 
+static bool imap_add_mailbox (MailBox *mb)
+{
+       assert (mb);
+
+       return imap_add_server (mb);
+}
+
 static bool imap_remove_mailbox (MailBox *mb)
 {
-       Ecore_Timer *timer;
+       ImapServer *server;
 
        assert (mb);
 
-       if ((timer = mailbox_property_get (mb, "timer")))
-               ecore_timer_del (timer);
+       if ((server = mailbox_property_get (mb, "server")))
+               imap_remove_server (server, mb);
 
        free (mailbox_property_get (mb, "host"));
        free (mailbox_property_get (mb, "user"));




-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to