[balsa] Gmime-2.6 build fix; IMAP ACL optimization.



commit 8380f3272a67df07c560a49184e97898a9d652c8
Author: Pawel Salek <pawsa0 gmail com>
Date:   Sat Feb 20 18:51:15 2010 +0100

    Gmime-2.6 build fix; IMAP ACL optimization.
    
    * libbalsa/gmime-gpgme-signature.c: add missing #include config.h
      that broke rawhide build.
    * libbalsa/imap/imap-commands.c: issue SELECT+MYRIGHTS together
      whenever necessary to save one RTT.
    * libbalsa/imap/imap-handle.c: add imap_cmd_exec_cmds() helper.
    * libbalsa/imap/imap_private.h: and its prototype.

 libbalsa/gmime-gpgme-signature.c |    4 ++
 libbalsa/imap/imap-commands.c    |   36 +++++++++++++-------
 libbalsa/imap/imap-handle.c      |   65 +++++++++++++++++++++++++++++++++++++-
 libbalsa/imap/imap_private.h     |    3 ++
 4 files changed, 94 insertions(+), 14 deletions(-)
---
diff --git a/libbalsa/gmime-gpgme-signature.c b/libbalsa/gmime-gpgme-signature.c
index bc4d27f..d78441b 100644
--- a/libbalsa/gmime-gpgme-signature.c
+++ b/libbalsa/gmime-gpgme-signature.c
@@ -19,6 +19,10 @@
  * 02111-1307, USA.
  */
 
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
+# include "config.h"
+#endif                          /* HAVE_CONFIG_H */
+
 #include <gpgme.h>
 #include <string.h>
 #include <glib.h>
diff --git a/libbalsa/imap/imap-commands.c b/libbalsa/imap/imap-commands.c
index 4f628a3..a33411b 100644
--- a/libbalsa/imap/imap-commands.c
+++ b/libbalsa/imap/imap-commands.c
@@ -184,8 +184,9 @@ ImapResponse
 imap_mbox_select_unlocked(ImapMboxHandle* handle, const char *mbox,
                           gboolean *readonly_mbox)
 {
-  gchar* cmd, *mbx7;
+  gchar *mbx7;
   ImapResponse rc;
+  char* cmds[3];
 
   IMAP_REQUIRED_STATE3(handle, IMHS_CONNECTED, IMHS_AUTHENTICATED,
                        IMHS_SELECTED, IMR_BAD);
@@ -202,25 +203,34 @@ imap_mbox_select_unlocked(ImapMboxHandle* handle, const char *mbox,
 
   mbx7 = imap_utf8_to_mailbox(mbox);
 
-  cmd = g_strdup_printf("SELECT \"%s\"", mbx7);
+  cmds[0] = g_strdup_printf("SELECT \"%s\"", mbx7);
+  if (imap_mbox_handle_can_do(handle, IMCAP_ACL)) {
+    cmds[1] = g_strdup_printf("MYRIGHTS \"%s\"", mbx7);
+    cmds[2] = NULL;
+  } else {
+    cmds[1] = NULL;
+  }
   g_free(mbx7);
-  rc= imap_cmd_exec(handle, cmd);
-  g_free(cmd);
+
+  if(handle->mbox != mbox) { /* we do not "reselect" */
+    g_free(handle->mbox);
+    handle->mbox = g_strdup(mbox);
+  }
+
+  rc= imap_cmd_exec_cmds(handle, (const char**)&cmds[0], 0);
+
+  g_free(cmds[0]);
+  g_free(cmds[1]);
+
   if(rc == IMR_OK) {
-    if(handle->mbox != mbox) { /* we do not "reselect" */
-      g_free(handle->mbox);
-      handle->mbox = g_strdup(mbox);
-    }
     handle->state = IMHS_SELECTED;
     if(readonly_mbox) {
-      /* FIXME - issue MYRIGHTS in the same packet as SELECT */
-      ImapResponse myrights_rc =
-	imap_mbox_fetch_my_rights_unlocked(handle);
       *readonly_mbox = handle->readonly_mbox;
-      if (myrights_rc != IMR_OK && myrights_rc != IMR_NO)
-	rc = myrights_rc; /* Bad things happened, report it. */
     }
   } else { /* remove even traces of untagged responses */
+    g_free(handle->mbox);
+    handle->mbox = NULL;
+
     imap_mbox_resize_cache(handle, 0);
     mbox_view_dispose(&handle->mbox_view);
     g_signal_emit_by_name(G_OBJECT(handle), "exists-notify");
diff --git a/libbalsa/imap/imap-handle.c b/libbalsa/imap/imap-handle.c
index a4fffc8..ae21fc6 100644
--- a/libbalsa/imap/imap-handle.c
+++ b/libbalsa/imap/imap-handle.c
@@ -2121,6 +2121,67 @@ imap_cmd_exec_cmdno(ImapMboxHandle* handle, const char* cmd,
   return rc;
 }
 
+/** Executes a set of commands, and wait for the response from the
+ * server.  Handles all untagged responses that arrive in meantime.
+ * Returns ImapResponse.
+ * @param handle the IMAP connection handle
+ * @param cmds the NULL-terminated vector of IMAP commands.
+ * @param rc_to_return the 0-based number of the "important" IMAP
+ * command in the sequence that we want to have the return code for.
+ */
+ImapResponse
+imap_cmd_exec_cmds(ImapMboxHandle* handle, const char** cmds,
+		   unsigned rc_to_return)
+{
+  unsigned cmd_count;
+  ImapResponse rc = IMR_OK, ret_rc = IMR_OK;
+  unsigned *cmdnos;
+
+  g_return_val_if_fail(handle, IMR_BAD);
+  if (handle->state == IMHS_DISCONNECTED)
+    return IMR_SEVERED;
+
+  if (!imap_handle_idle_disable(handle)) return IMR_SEVERED;
+
+  for (cmd_count=0; cmds[cmd_count]; ++cmd_count)
+    ;
+  cmdnos = g_malloc(cmd_count*sizeof(unsigned));
+  
+  for (cmd_count=0; cmds[cmd_count]; ++cmd_count) {
+    if (imap_cmd_start(handle, cmds[cmd_count], &cmdnos[cmd_count])<0) {
+      rc = IMR_SEVERED;   /* irrecoverable connection error. */
+      break;
+    }
+  }
+  if (rc == IMR_OK) {
+    g_return_val_if_fail(handle->state != IMHS_DISCONNECTED && 1, IMR_BAD);
+    sio_flush(handle->sio);
+    if(handle->state == IMHS_DISCONNECTED)
+      rc = IMR_SEVERED;
+    else {
+      for (cmd_count=0; cmds[cmd_count]; ++cmd_count) {
+	do {
+	  rc = imap_cmd_step (handle, cmdnos[cmd_count]);
+	} while (rc == IMR_UNTAGGED);
+
+	if ( !(rc == IMR_OK || rc == IMR_NO || rc == IMR_BAD) ) {
+	  ret_rc = rc;
+	  break;
+	}
+
+	if (cmd_count == rc_to_return)
+	  ret_rc = rc;
+
+      }
+    }
+  }
+  g_free(cmdnos);
+      
+  imap_handle_idle_enable(handle, IDLE_TIMEOUT);
+
+  return ret_rc;
+}
+
 int
 imap_handle_write(ImapMboxHandle *conn, const char *buf, size_t len)
 {
@@ -3023,8 +3084,10 @@ ir_myrights(ImapMboxHandle *h)
   if (mbox && eol == ' ') {
     if (strcmp(mbox, mbx7))
       fprintf(stderr, "expected MYRIGHTS for %s, not for %s\n", mbx7, mbox);
-    else
+    else {
       retval = extract_acl(h, "\n", &h->rights, NULL);
+      h->has_rights = 1;
+    }
   }
   free(mbx7);
   free(mbox);
diff --git a/libbalsa/imap/imap_private.h b/libbalsa/imap/imap_private.h
index 7456648..b0be074 100644
--- a/libbalsa/imap/imap_private.h
+++ b/libbalsa/imap/imap_private.h
@@ -192,6 +192,9 @@ ImapResponse imap_cmd_exec_cmdno(ImapMboxHandle* handle, const char* cmd,
 				 unsigned *cmdno);
 #define imap_cmd_exec(h, c) imap_cmd_exec_cmdno((h),(c),NULL)
 
+ImapResponse imap_cmd_exec_cmds(ImapMboxHandle* handle, const char** cmds,
+				unsigned rc_to_return);
+
 ImapResponse imap_cmd_issue(ImapMboxHandle* handle, const char* cmd);
 char* imap_mbox_gets(ImapMboxHandle *h, char* buf, size_t sz);
 



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