]> granicus.if.org Git - neomutt/commitdiff
The attached patch provides improved support for IMAP ACLs (on
authorNathan Dushman <nhd+mutt@andrew.cmu.edu>
Thu, 23 Jan 2003 22:03:12 +0000 (22:03 +0000)
committerNathan Dushman <nhd+mutt@andrew.cmu.edu>
Thu, 23 Jan 2003 22:03:12 +0000 (22:03 +0000)
servers that support them).  This means that mutt will now write the
Seen flag in mailboxes that allow it, even if the mailbox doesn't
allow other changes.

curs_main.c
flags.c
imap/imap.c
pager.c

index 2cc2ada236eb47b2c0531d65b543bc6168bfd0d9..ed4a4140a78dade0a0f7a06637d959408b8862c9 100644 (file)
@@ -30,7 +30,7 @@
 #endif
 
 #ifdef USE_IMAP
-#include "imap.h"
+#include "imap_private.h"
 #endif
 
 #include "mutt_crypt.h"
@@ -78,6 +78,17 @@ static const char *No_visible = N_("No visible messages.");
                                break; \
                        }
 
+#ifdef USE_IMAP 
+/* the error message returned here could be better. */
+#define CHECK_IMAP_ACL(aclbit) if (Context->magic == M_IMAP) \
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,aclbit)){ \
+                       mutt_flushinp(); \
+                       mutt_error ("Operation not permitted by the IMAP ACL for this mailbox"); \
+                       break; \
+               }
+#endif
+
 #define CHECK_ATTACH if(option(OPTATTACHMSG)) \
                     {\
                        mutt_flushinp (); \
@@ -744,6 +755,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        CHECK_ATTACH;
        mutt_pattern_func (M_DELETE, _("Delete messages matching: "));
        menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
@@ -901,6 +917,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        if (mutt_pattern_func (M_UNDELETE, _("Undelete messages matching: ")) == 0)
          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        break;
@@ -1342,6 +1363,10 @@ int mutt_index_menu (void)
        }
 #endif
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_WRITE);
+#endif
+
         if (tag)
         {
          for (j = 0; j < Context->vcount; j++)
@@ -1377,6 +1402,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_SEEN);
+#endif
+
        if (tag)
        {
          for (j = 0; j < Context->vcount; j++)
@@ -1489,6 +1519,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+       
+/* #ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_WRITE);
+#endif */
+
        if (mutt_change_flag (tag ? NULL : CURHDR, (op == OP_MAIN_SET_FLAG)) == 0)
        {
          menu->redraw = REDRAW_STATUS;
@@ -1627,6 +1662,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+       
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        if (tag)
        {
          mutt_tag_set_flag (M_DELETE, 1);
@@ -1667,6 +1707,10 @@ int mutt_index_menu (void)
         CHECK_VISIBLE;
        CHECK_READONLY;
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        rc = mutt_thread_set_flag (CURHDR, M_DELETE, 1,
                                   op == OP_DELETE_THREAD ? 0 : 1);
 
@@ -1716,6 +1760,10 @@ int mutt_index_menu (void)
        }
 #endif
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_INSERT);
+#endif
+
         mutt_edit_message (Context, tag ? NULL : CURHDR);
        menu->redraw = REDRAW_FULL;
 
@@ -1814,6 +1862,10 @@ int mutt_index_menu (void)
         CHECK_VISIBLE;
        CHECK_READONLY;
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_SEEN);
+#endif
+
        rc = mutt_thread_set_flag (CURHDR, M_READ, 1,
                                   op == OP_MAIN_READ_THREAD ? 0 : 1);
 
@@ -1896,6 +1948,11 @@ int mutt_index_menu (void)
        CHECK_MSGCOUNT;
         CHECK_VISIBLE;
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+       
        if (tag)
        {
          mutt_tag_set_flag (M_DELETE, 0);
@@ -1922,6 +1979,10 @@ int mutt_index_menu (void)
         CHECK_VISIBLE;
        CHECK_READONLY;
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        rc = mutt_thread_set_flag (CURHDR, M_DELETE, 0,
                                   op == OP_UNDELETE_THREAD ? 0 : 1);
 
diff --git a/flags.c b/flags.c
index 9eedbea37ab90d4049d92abf4b65453d733049fd..cba37978f796dfca8266f9e2527c418f1bc745de 100644 (file)
--- a/flags.c
+++ b/flags.c
 #include "sort.h"
 #include "mx.h"
 
+#ifdef USE_IMAP
+#include "imap_private.h"
+#endif
+
 void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
 {
   int changed = h->changed;
@@ -33,9 +37,17 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
   switch (flag)
   {
     case M_DELETE:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_DELETE))
+                       return;
+#endif
+
       if (bf)
       {
-       if (!h->deleted)
+       if (!h->deleted && !ctx->readonly)
        {
          h->deleted = 1;
          if (upd_ctx) ctx->deleted++;
@@ -76,6 +88,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
       break;
 
     case M_NEW:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN))
+                       return;
+#endif
+
       if (bf)
       {
        if (h->read || h->old)
@@ -103,6 +123,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
       break;
 
     case M_OLD:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN))
+                       return;
+#endif
+
       if (bf)
       {
        if (!h->old)
@@ -125,6 +153,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
       break;
 
     case M_READ:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_SEEN))
+                       return;
+#endif
+
       if (bf)
       {
        if (!h->read)
@@ -149,6 +185,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
       break;
 
     case M_REPLIED:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_WRITE))
+                       return;
+#endif
+
       if (bf)
       {
        if (!h->replied)
@@ -174,6 +218,14 @@ void _mutt_set_flag (CONTEXT *ctx, HEADER *h, int flag, int bf, int upd_ctx)
       break;
 
     case M_FLAG:
+
+#ifdef USE_IMAP
+       if (Context->magic == M_IMAP)
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,IMAP_ACL_WRITE))
+                       return;
+#endif
+
       if (bf)
       {
        if (!h->flagged)
index f9feccdf42e394f740194cb6cc638a20601216aa..18852aa1bcf9984a250ea2028b9cdc5519d8518d 100644 (file)
@@ -611,7 +611,8 @@ int imap_open_mailbox (CONTEXT* ctx)
     goto fail;
 
   /* check for READ-ONLY notification */
-  if (!ascii_strncasecmp (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11))
+  if (!ascii_strncasecmp (imap_get_qualifier (idata->cmd.buf), "[READ-ONLY]", 11)  \
+  && !mutt_bit_isset (idata->capabilities, ACL))
   {
     dprint (2, (debugfile, "Mailbox is read-only.\n"));
     ctx->readonly = 1;
@@ -644,6 +645,11 @@ int imap_open_mailbox (CONTEXT* ctx)
   {
     if (imap_check_acl (idata))
       goto fail;
+    if (!(mutt_bit_isset(idata->rights, IMAP_ACL_DELETE) ||
+          mutt_bit_isset(idata->rights, IMAP_ACL_SEEN) ||
+          mutt_bit_isset(idata->rights, IMAP_ACL_WRITE) ||
+          mutt_bit_isset(idata->rights, IMAP_ACL_INSERT)))
+       ctx->readonly = 1;
   }
   /* assume we have all rights if ACL is unavailable */
   else
diff --git a/pager.c b/pager.c
index 4d7b9206ad3c456c80c90d1e96c22a758e458711..a92557199f92e82a92f8176ada185f51c5d1dc08 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -30,7 +30,7 @@
 #include "mx.h"
 
 #ifdef USE_IMAP
-#include "imap.h"
+#include "imap_private.h"
 #endif
 
 #include "mutt_crypt.h"
@@ -75,6 +75,17 @@ static const char *Function_not_permitted_in_attach_message_mode = N_("Function
                        break; \
                     }
 
+#ifdef USE_IMAP 
+/* the error message returned here could be better. */
+#define CHECK_IMAP_ACL(aclbit) if (Context->magic == M_IMAP) \
+               if (mutt_bit_isset (((IMAP_DATA *)Context->data)->capabilities, ACL) \
+               && !mutt_bit_isset(((IMAP_DATA *)Context->data)->rights,aclbit)){ \
+                       mutt_flushinp(); \
+                       mutt_error ("Operation not permitted by the IMAP ACL for this mailbox"); \
+                       break; \
+               }
+#endif
+
 struct q_class_t
 {
   int length;
@@ -2175,6 +2186,11 @@ search_next:
       case OP_DELETE:
        CHECK_MODE(IsHeader (extra));
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        mutt_set_flag (Context, extra->hdr, M_DELETE, 1);
         if (option (OPTDELETEUNTAG))
          mutt_set_flag (Context, extra->hdr, M_TAG, 0);
@@ -2191,6 +2207,10 @@ search_next:
        CHECK_MODE(IsHeader (extra));
        CHECK_READONLY;
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        r = mutt_thread_set_flag (extra->hdr, M_DELETE, 1,
                                  ch == OP_DELETE_THREAD ? 0 : 1);
 
@@ -2319,6 +2339,10 @@ search_next:
        }
 #endif
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_WRITE);
+#endif
+
        mutt_set_flag (Context, extra->hdr, M_FLAG, !extra->hdr->flagged);
        redraw = REDRAW_STATUS | REDRAW_INDEX;
        if (option (OPTRESOLVE))
@@ -2468,6 +2492,11 @@ search_next:
       case OP_TOGGLE_NEW:
        CHECK_MODE(IsHeader (extra));
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_SEEN);
+#endif
+
        if (extra->hdr->read || extra->hdr->old)
          mutt_set_flag (Context, extra->hdr, M_NEW, 1);
        else if (!first)
@@ -2485,6 +2514,11 @@ search_next:
       case OP_UNDELETE:
        CHECK_MODE(IsHeader (extra));
        CHECK_READONLY;
+
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        mutt_set_flag (Context, extra->hdr, M_DELETE, 0);
        redraw = REDRAW_STATUS | REDRAW_INDEX;
        if (option (OPTRESOLVE))
@@ -2499,6 +2533,10 @@ search_next:
        CHECK_MODE(IsHeader (extra));
        CHECK_READONLY;
 
+#ifdef USE_IMAP
+CHECK_IMAP_ACL(IMAP_ACL_DELETE);
+#endif
+
        r = mutt_thread_set_flag (extra->hdr, M_DELETE, 0,
                                  ch == OP_UNDELETE_THREAD ? 0 : 1);