From 4365eac25f44517cc6cc5dcde6585feb9e89d81e Mon Sep 17 00:00:00 2001 From: Nathan Dushman Date: Thu, 23 Jan 2003 22:03:12 +0000 Subject: [PATCH] The attached patch provides improved support for IMAP ACLs (on 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 | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++- flags.c | 54 ++++++++++++++++++++++++++++++++++++++++++++- imap/imap.c | 8 ++++++- pager.c | 40 +++++++++++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 4 deletions(-) diff --git a/curs_main.c b/curs_main.c index 2cc2ada23..ed4a4140a 100644 --- a/curs_main.c +++ b/curs_main.c @@ -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 9eedbea37..cba37978f 100644 --- a/flags.c +++ b/flags.c @@ -21,6 +21,10 @@ #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) diff --git a/imap/imap.c b/imap/imap.c index f9feccdf4..18852aa1b 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -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 4d7b9206a..a92557199 100644 --- 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); -- 2.40.0