[balsa] Support older IMAP server



commit 6f0bccfeae1a10f6df68703827eb8921c619695a
Author: Peter Bloomfield <peterbloomfield bellsouth net>
Date:   Sat Jul 10 06:29:37 2010 -0400

    Support older IMAP server
    
    	* libbalsa/imap/imap-handle.c
    	(ir_capability_data): check for "RIGHTS=" capability to
    	distinguish RFC-4013-compliant server;
    	(extract_acl): check for "cd" rights when server does not comply with
    	RFC 4013.
    	* libbalsa/imap/imap-handle.h: add IMCAP_RIGHTS to ImapCapability
    	enum.
    	* libbalsa/imap/libimap.h: add IMAP_ACL_OBS_CREATE and
    	IMAP_ACL_OBS_DELETE to ImapAclType enum, and define
    	IMAP_RIGHTS_CAN_WRITE(rights) macro.
    	* libbalsa/mailbox_imap.c
    	(imap_acl_to_str): show "cd" rights when server does not comply with
    	RFC 4013;
    	(libbalsa_mailbox_imap_get_selected_handle): use
    	IMAP_RIGHTS_CAN_WRITE(rights) macro.

 ChangeLog                   |   21 +++++++++++++++++++++
 libbalsa/imap/imap-handle.c |   12 ++++++++++--
 libbalsa/imap/imap-handle.h |    3 ++-
 libbalsa/imap/libimap.h     |   10 +++++++++-
 libbalsa/mailbox_imap.c     |    9 +++++----
 5 files changed, 47 insertions(+), 8 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index db67d7a..dda6cf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2010-07-10  Peter Bloomfield
+
+	Support IMAP server that complies with RFC 2086 but not with
+	RFC 4013.
+
+	* libbalsa/imap/imap-handle.c
+	(ir_capability_data): check for "RIGHTS=" capability to
+	distinguish RFC-4013-compliant server;
+	(extract_acl): check for "cd" rights when server does not comply with
+	RFC 4013.
+	* libbalsa/imap/imap-handle.h: add IMCAP_RIGHTS to ImapCapability
+	enum.
+	* libbalsa/imap/libimap.h: add IMAP_ACL_OBS_CREATE and
+	IMAP_ACL_OBS_DELETE to ImapAclType enum, and define
+	IMAP_RIGHTS_CAN_WRITE(rights) macro.
+	* libbalsa/mailbox_imap.c
+	(imap_acl_to_str): show "cd" rights when server does not comply with
+	RFC 4013;
+	(libbalsa_mailbox_imap_get_selected_handle): use
+	IMAP_RIGHTS_CAN_WRITE(rights) macro.
+
 2010-07-07  Peter Bloomfield
 
 	* libbalsa/libbalsa.c (libbalsa_date_to_utf8): return NULL when
diff --git a/libbalsa/imap/imap-handle.c b/libbalsa/imap/imap-handle.c
index ae21fc6..7b65b6a 100644
--- a/libbalsa/imap/imap-handle.c
+++ b/libbalsa/imap/imap-handle.c
@@ -2370,7 +2370,7 @@ ir_capability_data(ImapMboxHandle *handle)
   static const char* capabilities[] = {
     "IMAP4", "IMAP4rev1", "STATUS",
     "AUTH=ANONYMOUS", "AUTH=CRAM-MD5", "AUTH=GSSAPI", "AUTH=PLAIN",
-    "ACL", "BINARY", "CHILDREN",
+    "ACL", "RIGHTS=", "BINARY", "CHILDREN",
     "COMPRESS=DEFLATE",
     "ESEARCH", "IDLE", "LITERAL+",
     "LOGINDISABLED", "MULTIAPPEND", "NAMESPACE", "QUOTA", "SASL-IR",
@@ -2387,7 +2387,8 @@ ir_capability_data(ImapMboxHandle *handle)
   do {
     c = imap_get_atom(handle->sio, atom, sizeof(atom));
     for (x=0; x<ELEMENTS(capabilities); x++)
-      if (g_ascii_strcasecmp(atom, capabilities[x]) == 0) {
+      if (g_ascii_strncasecmp(atom, capabilities[x],
+                              strlen(capabilities[x])) == 0) {
 	handle->capabilities[x] = 1;
 	break;
       }
@@ -3046,6 +3047,9 @@ ir_quota(ImapMboxHandle *h)
  *
  * Scan h's input stream for valid ACL flags (lrswipkxtea).  Note that 'c', 'd'
  * and cr are ignored according to RFC 4314, sect. 2.1.1.
+ * But note also that a server that complies with the older RFC 2086 and not
+ * with RFC 4314 uses 'c' and 'd'; we can distinguish this case because it
+ * does not advertise "RIGHTS=" capability.
  */
 static ImapResponse
 extract_acl(ImapMboxHandle *h, const char *eject, ImapAclType *acl, int *eol)
@@ -3055,6 +3059,10 @@ extract_acl(ImapMboxHandle *h, const char *eject, ImapAclType *acl, int *eol)
   int c;
   char* p;
 
+  if (!imap_mbox_handle_can_do(h, IMCAP_RIGHTS)) {
+    /* workaround for RFC 2086- but not RFC 4314-compliant server */
+    rights = "lrswipkxteacd";
+  }
   *acl = IMAP_ACL_NONE;
   while ((c = sio_getc(h->sio)) != -1 && !strchr(eject, c)) {
     if ((p = strchr(rights, c))) {
diff --git a/libbalsa/imap/imap-handle.h b/libbalsa/imap/imap-handle.h
index 692c170..8da5d87 100644
--- a/libbalsa/imap/imap-handle.h
+++ b/libbalsa/imap/imap-handle.h
@@ -62,7 +62,8 @@ typedef enum
   IMCAP_ACRAM_MD5,		/* RFC 2195: CRAM-MD5 authentication */
   IMCAP_AGSSAPI,		/* RFC 1731: GSSAPI authentication */
   IMCAP_APLAIN,                 /* RFC 2595: */
-  IMCAP_ACL,			/* RFC 4314: IMAP4 ACL extension */
+  IMCAP_ACL,			/* RFC 2086: IMAP4 ACL extension */
+  IMCAP_RIGHTS,                 /* RFC 4314: IMAP4 RIGHTS= extension */
   IMCAP_BINARY,                 /* RFC 3516 */
   IMCAP_CHILDREN,               /* RFC 3348 */
   IMCAP_COMPRESS_DEFLATE,       /* RFC 4978 */
diff --git a/libbalsa/imap/libimap.h b/libbalsa/imap/libimap.h
index 00be2e0..e087d81 100644
--- a/libbalsa/imap/libimap.h
+++ b/libbalsa/imap/libimap.h
@@ -290,11 +290,19 @@ typedef enum {
   IMAP_ACL_DELETE = 1<<7,   /* 'x': DELETE, RENAME */
   IMAP_ACL_DELMSG = 1<<8,   /* 't': delete messages (\DELETED flag) */
   IMAP_ACL_EXPUNGE = 1<<9,  /* 'e': EXPUNGE */
-  IMAP_ACL_ADMIN = 1<<10    /* 'a': administer (SETACL/DELETEACL/GETACL/LISTRIGHTS) */
+  IMAP_ACL_ADMIN = 1<<10,   /* 'a': administer (SETACL/DELETEACL/GETACL/LISTRIGHTS) */
+  IMAP_ACL_OBS_CREATE = 1<<11,  /* 'c': RFC 2086 "create" */
+  IMAP_ACL_OBS_DELETE = 1<<12   /* 'd': RFC 2086 "delete" */
 } ImapAclType;
 
 #define IMAP_ACL_CAN_WRITE  (IMAP_ACL_WRITE | IMAP_ACL_INSERT | IMAP_ACL_CREATE | \
                              IMAP_ACL_DELETE | IMAP_ACL_DELMSG | IMAP_ACL_EXPUNGE)
+#define IMAP_ACL_OBS_CAN_WRITE (IMAP_ACL_WRITE | IMAP_ACL_INSERT | \
+                                IMAP_ACL_OBS_CREATE | IMAP_ACL_OBS_DELETE)
+#define IMAP_RIGHTS_CAN_WRITE(rights) (((rights) & IMAP_ACL_CAN_WRITE) \
+                                       == IMAP_ACL_CAN_WRITE \
+                                       || ((rights) & IMAP_ACL_OBS_CAN_WRITE) \
+                                       == IMAP_ACL_OBS_CAN_WRITE)
 
 typedef struct {
   gchar* uid;
diff --git a/libbalsa/mailbox_imap.c b/libbalsa/mailbox_imap.c
index cb42b8f..21f2b8f 100644
--- a/libbalsa/mailbox_imap.c
+++ b/libbalsa/mailbox_imap.c
@@ -385,11 +385,12 @@ static char *
 imap_acl_to_str(ImapAclType acl)
 {
     GString *rights;
-    static const char * flags = "lrswipkxtea";
-    int n;
+    /* include "cd" for RFC 2086 support: */
+    static const char * flags = "lrswipkxteacd";
+    unsigned n;
 
     rights = g_string_new("");
-    for (n = 0; n < 11; n++)
+    for (n = 0; n < strlen(flags); n++)
         if (acl & (1 << n))
             rights = g_string_append_c(rights, flags[n]);
     return g_string_free(rights, FALSE);
@@ -992,7 +993,7 @@ libbalsa_mailbox_imap_get_selected_handle(LibBalsaMailboxImap *mimap,
     /* check if we have RFC 4314 acl's for the selected mailbox */
     if (imap_mbox_get_my_rights(mimap->handle, &mimap->rights, FALSE) ==
         IMR_OK) {
-        if ((mimap->rights & IMAP_ACL_CAN_WRITE) != IMAP_ACL_CAN_WRITE)
+        if (!IMAP_RIGHTS_CAN_WRITE(mimap->rights))
             LIBBALSA_MAILBOX(mimap)->readonly = TRUE;
         if (mimap->rights & IMAP_ACL_ADMIN)
             imap_mbox_get_acl(mimap->handle, mimap->path, &mimap->acls);



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