balsa r8102 - in trunk: . libbalsa/imap



Author: pawels
Date: Thu Mar 19 20:15:25 2009
New Revision: 8102
URL: http://svn.gnome.org/viewvc/balsa?rev=8102&view=rev

Log:
* libbalsa/imap/imap-handle.c: make IDLE startup asynchronous.
* libbalsa/imap/imap_private.h: provide EAT_LINE macro.
* libbalsa/imap/imap-commands.c: use it.


Modified:
   trunk/ChangeLog
   trunk/balsa.spec.in
   trunk/libbalsa/imap/imap-commands.c
   trunk/libbalsa/imap/imap-handle.c
   trunk/libbalsa/imap/imap_private.h

Modified: trunk/balsa.spec.in
==============================================================================
--- trunk/balsa.spec.in	(original)
+++ trunk/balsa.spec.in	Thu Mar 19 20:15:25 2009
@@ -94,7 +94,7 @@
 
 desktop-file-install $RPM_BUILD_ROOT%{_datadir}/applications/balsa.desktop \
         --vendor=fedora \
-        --add-category=X-Fedora \
+        --add-category=Email \
         --dir=$RPM_BUILD_ROOT%{_datadir}/applications \
         --copy-name-to-generic-name \
         --delete-original

Modified: trunk/libbalsa/imap/imap-commands.c
==============================================================================
--- trunk/libbalsa/imap/imap-commands.c	(original)
+++ trunk/libbalsa/imap/imap-commands.c	Thu Mar 19 20:15:25 2009
@@ -540,7 +540,7 @@
 	rc = imap_cmd_step (handle, cmdno);
       } while (rc == IMR_UNTAGGED);
       if(rc != IMR_RESPOND) return rc;
-      while( (c=sio_getc(handle->sio)) != -1 && c != '\n');
+      EAT_LINE(handle, c);
       if(c == -1) {
 	imap_handle_disconnect(handle);
 	return IMR_SEVERED;

Modified: trunk/libbalsa/imap/imap-handle.c
==============================================================================
--- trunk/libbalsa/imap/imap-handle.c	(original)
+++ trunk/libbalsa/imap/imap-handle.c	Thu Mar 19 20:15:25 2009
@@ -146,12 +146,14 @@
   handle->using_tls = 0;
 #endif
   handle->tls_mode = IMAP_TLS_ENABLED;
+  handle->idle_state = IDLE_INACTIVE;
   handle->cmd_info = NULL;
   handle->status_resps = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                NULL, NULL);
 
   handle->info_cb  = NULL;
   handle->info_arg = NULL;
+  handle->op_cancelled = 0;
   handle->enable_anonymous = 0;
   handle->enable_client_sort = 0;
   handle->enable_binary    = 0;
@@ -340,9 +342,22 @@
   if(ASYNC_DEBUG) printf("async_process() enter loop\n");
   while( (retval = sio_poll(h->sio, TRUE, FALSE, TRUE)) != -1 &&
          (retval & SIO_READ) != 0) {
-    if ( (rc=imap_cmd_step(h, async_cmd)) == IMR_UNKNOWN ||
-         rc == IMR_SEVERED || rc == IMR_BYE || rc == IMR_PROTOCOL ||
-         rc  == IMR_BAD) {
+    rc=imap_cmd_step(h, async_cmd);
+    if(h->idle_state == IDLE_RESPONSE_PENDING) {
+      int c;
+      if(rc != IMR_RESPOND) {
+	g_message("async_process_real() expected IMR_RESPOND but got %d\n", rc);
+	imap_handle_disconnect(h);
+	return FALSE;
+      }
+      EAT_LINE(h, c);
+      if (c == '\n') {
+	h->idle_state = IDLE_ACTIVE;
+	if (ASYNC_DEBUG) printf("IDLE is now ACTIVE\n");
+      }
+    } else if (rc == IMR_UNKNOWN ||
+	rc == IMR_SEVERED || rc == IMR_BYE || rc == IMR_PROTOCOL ||
+	rc  == IMR_BAD) {
       printf("async_process() got unexpected response %i!\n"
              "Last message was: \"%s\" - shutting down connection.\n",
              rc, h->last_msg);
@@ -355,7 +370,7 @@
            async_cmd);
   }
   if(ASYNC_DEBUG) printf("async_process() loop left\n");
-  if(!h->idle_issued && async_cmd == 0) {
+  if(h->idle_state == IDLE_INACTIVE && async_cmd == 0) {
     if(ASYNC_DEBUG) printf("Last async command completed.\n");
     if(h->async_watch_id) {
       g_source_remove(h->async_watch_id);
@@ -365,9 +380,9 @@
   }
   if(ASYNC_DEBUG)
     printf("async_process() sio: %d rc: %d returns %d (%d cmds in queue)\n",
-           retval, rc, !h->idle_issued && async_cmd == 0,
+           retval, rc, h->idle_state == IDLE_INACTIVE && async_cmd == 0,
            g_list_length(h->cmd_info));
-  return h->idle_issued || async_cmd != 0;
+  return h->idle_state != IDLE_INACTIVE || async_cmd != 0;
 }
 
 /* imap_handle_idle_enable: enables calling IDLE command after seconds
@@ -415,8 +430,6 @@
 idle_start(gpointer data)
 {
   ImapMboxHandle *h = (ImapMboxHandle*)data;
-  ImapResponse rc;
-  int c;
   ImapCmdTag tag;
   unsigned asyncno;
 
@@ -429,16 +442,6 @@
   asyncno = imap_make_tag(tag); sio_write(h->sio, tag, strlen(tag));
   sio_write(h->sio, " IDLE\r\n", 7); sio_flush(h->sio);
   cmdi_add_handler(&h->cmd_info, asyncno, cmdi_empty, NULL);
-  do { /* FIXME: we could at this stage just as well watch for
-          response instead of polling. */
-    rc = imap_cmd_step (h, asyncno);
-  } while (rc == IMR_UNTAGGED);
-  if(rc != IMR_RESPOND) {
-    g_message("idle_start() expected IMR_RESPOND but got %d\n", rc);
-    HANDLE_UNLOCK(h);
-    return FALSE;
-  }
-  while( (c=sio_getc(h->sio)) != -1 && c != '\n');
   if(!h->iochannel) {
     h->iochannel = g_io_channel_unix_new(h->sd);
     g_io_channel_set_encoding(h->iochannel, NULL, NULL);
@@ -447,11 +450,7 @@
   h->async_watch_id = g_io_add_watch(h->iochannel, G_IO_IN|G_IO_HUP,
 				     async_process, h);
   h->idle_enable_id = 0;
-  h->idle_issued = 1;
-
-  /* In principle, IMAP server can send some data in the same packet
-     as the RESPOND line. GMail does it. Process it. */
-  async_process_real(h);
+  h->idle_state = IDLE_RESPONSE_PENDING;
 
   HANDLE_UNLOCK(h);
   return FALSE;
@@ -487,7 +486,7 @@
 {
   if( !h->enable_idle || !imap_mbox_handle_can_do(h, IMCAP_IDLE))
     return FALSE;
-  if(h->idle_issued) {
+  if(h->idle_state != IDLE_INACTIVE) {
     fprintf(stderr, "IDLE already enabled\n");
     return FALSE;
   }
@@ -506,9 +505,29 @@
   if(h->async_watch_id) {
     g_source_remove(h->async_watch_id);
     h->async_watch_id = 0;
-    if(h->sio && h->idle_issued) {/* we might have been disconnected before */
+    if(h->sio && h->idle_state == IDLE_RESPONSE_PENDING) {
+      int c;
+      ImapResponse rc;
+      unsigned async_cmd = cmdi_get_pending(h->cmd_info);
+
+      do {
+	rc = imap_cmd_step(h, async_cmd);
+      } while (rc == IMR_UNTAGGED);
+      if(rc != IMR_RESPOND) {
+	imap_handle_disconnect(h);
+	return FALSE;
+      }
+      EAT_LINE(h, c);
+      if(c == -1) {
+	imap_handle_disconnect(h);
+	return FALSE;
+      }
+      h->idle_state = IDLE_ACTIVE;
+    }
+    if (h->sio &&  h->idle_state == IDLE_ACTIVE) {
+      /* we might have been disconnected before */
       sio_write(h->sio,"DONE\r\n",6); sio_flush(h->sio);
-      h->idle_issued = 0;
+      h->idle_state = IDLE_INACTIVE;
     }
   }
   return TRUE;
@@ -716,7 +735,7 @@
   handle->op_cancelled = FALSE;
   handle->has_capabilities = FALSE;
   handle->can_fetch_body = TRUE;
-  handle->idle_issued = FALSE;
+  handle->idle_state = IDLE_INACTIVE;
   if(handle->sio) {
     sio_detach(handle->sio);
     handle->sio = NULL;
@@ -2112,7 +2131,7 @@
   GString *res = NULL;
   if(c=='"') { /* quoted */
     res = g_string_new("");
-    while( (c=sio_getc(sio)) != '"') {
+    while( (c=sio_getc(sio)) != '"' && c != EOF) {
       if(c== '\\')
         c = sio_getc(sio);
       g_string_append_c(res, c);
@@ -2733,7 +2752,7 @@
 ir_flags(ImapMboxHandle *h)
 {
   /* FIXME: implement! */
-  int c; while( (c=sio_getc(h->sio))!=EOF && c != 0x0a);
+  int c; EAT_LINE(h, c);
   return IMR_OK;
 }
 
@@ -3127,7 +3146,7 @@
       } else {
         g_free(key); g_free(val);
       }
-    } while( (c=sio_getc(sio)) != ')');
+    } while( (c=sio_getc(sio)) != ')' && c != EOF);
   } else if(toupper(c) != 'N' || toupper(sio_getc(sio)) != 'I' ||
             toupper(sio_getc(sio)) != 'L') return IMR_PROTOCOL;
   return IMR_OK;

Modified: trunk/libbalsa/imap/imap_private.h
==============================================================================
--- trunk/libbalsa/imap/imap_private.h	(original)
+++ trunk/libbalsa/imap/imap_private.h	Thu Mar 19 20:15:25 2009
@@ -126,8 +126,9 @@
                            inactivity */
   guint async_watch_id;  /* callback to process incoming data */
   ImapTlsMode tls_mode; /* disabled, enabled, required */
+  enum { IDLE_INACTIVE, IDLE_RESPONSE_PENDING, IDLE_ACTIVE }
+    idle_state; /*  IDLE State? */
   unsigned op_cancelled:1; /* last op timed out and was cancelled by user */
-  unsigned idle_issued:1; /*  idle has been issued */
   unsigned readonly_mbox:1;
   unsigned can_fetch_body:1; /* set for servers that always respond
                               * correctly to FETCH x BODY[y]
@@ -162,6 +163,8 @@
 
 #define IS_ATOM_CHAR(c) (strchr("(){ %*\"\\]",(c))==NULL&&(c)>0x1f&&(c)!=0x7f)
 
+#define EAT_LINE(h, c) while( (c=sio_getc(h->sio)) != -1 && c != '\n')
+
 extern const char* msg_flags[6];
 
 void imap_mbox_resize_cache(ImapMboxHandle *h, unsigned new_size);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]