Here is a patch to add some support for read-only IMAP folders.
This is most useful if you have multiple copies of mutt open, but
it also allows you to open a folder read-only and not have to
worry about flags getting changed. Toggling read-only still
doesn't work correctly - you may lose your 'N' flags if you open
a folder normally and switch to read-only.
I've also decided to try using UID FETCH, although I'm not sure if
older IMAP servers support it, but then again I'm not sure if
anyone's using any really old IMAP servers. The main advantage is
in the case of multiple clients, where one client is deleting
messages and the other isn't getting notification. I'm
experiencing that on my UW-IMAP 4.6 server. On the other hand,
this server seems to have all sorts of terrible problems with this
scenario, so I'm not sure how well the code functions. It's a
two-line change so far, it's experimental, and it's the only IMAP
code in an #if 0 block...
In no particular order:
-* Mutt doesn't detect when a mailbox has only been opened read-only
- (because, say, another process has it open), so it lets you store
- changes that it can't commit.
- --> just pick up the [READ-ONLY] in the tagged response, set mutt's flag
+* Mutt doesn't display untagged [ALERT] responses to the user. Pointed out
+ by Larry P Schrof <schrof@cig.mot.com>
+ 19991220
+
+* Mutt displays 'mailbox externally modified' messages constantly if the
+ server provides spurious untagged EXISTS responses. Mutt should handle
+ those gracefully, I guess.
* ~h searches download the entire folder, setting everything to \Seen in
the process.
may see occasional segfaults. Solving this cleanly requires some major
architectural updates. Until that happens, I recommend you keep
backup copies of messages you're composing from within your editor.
+ Tommi Komulainen's keepalive patch for edit sessions may work for you,
+ though. Committed to CVS late November 1999, I think.
* Sometimes hdr->env seems to be NULL, according to other users' core
files. I haven't been able to reproduce this, and am not sure how
- to track it down. But it's very naughty indeed.
+ to track it down. But it's very naughty indeed. It appears to be the
+ result of spurious mx_close_mailbox calls handling the untagged
+ BYE response.
* Mutt marks your connection for logout as soon as you say quit, even if
you bail out with ^G later.
* The mutt_pretty routines don't work well when the delimiter isn't '/'.
Brendan Cully <brendan@kublai.com>
-Updated 19991110
+Updated 20000125
* Server-side copy
* Fast sync
* Secure login (GSSAPI and CRAM-MD5)
-* More and better segfaults
* Attach messages from IMAP folders
-* Use an IMAP path as your Maildir (set folder='')
+* Use an IMAP path as your Maildir (set folder={...})
* Preserve message keywords
* Preserve deleted messages if you don't choose to expunge them
* Delete mailboxes (from the browser)
* Multiple IMAP usernames
+* Read-only folder support (toggling read-only is buggy, though)
+* More and better segfaults
* Commands for creating/deleting folders on the server, since users may not
otherwise be able to do this on IMAP servers.
+ Delete done, still must implement create.
PRIORITY: [** ]
PRIORITY: [** ]
+* Create a logout command, so users can reconnect with different account
+ information without quitting mutt. Note: Tommi Komulainen's
+ multiple-account code makes this unnecessary - just use an account of
+ the form {username@host}
+
+ PRIORITY: [* ]
+
Brendan Cully <brendan@kublai.com>
-Updated: 19991119
+Updated: 19991227
mx_fastclose_mailbox (idata->selected_ctx);
return (-1);
}
+ else if (mutt_strncasecmp ("NO", s, 2) == 0)
+ {
+ /* Display the warning message from the server */
+ mutt_error (s+3);
+ sleep (1);
+ }
else
{
dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
snprintf (buf, sizeof (buf), "DELETE %s", mbox);
if (imap_exec (buf, sizeof (buf), CTX_DATA, buf, 0) != 0)
- {
- imap_error ("imap_delete_mailbox", buf);
return -1;
- }
return 0;
}
mutt_message (_("Reopening mailbox... %s"), CTX_DATA->selected_mailbox);
imap_quote_string (buf, sizeof (buf), CTX_DATA->selected_mailbox);
imap_make_sequence (seq, sizeof (seq));
- snprintf (bufout, sizeof (bufout), "%s SELECT %s\r\n", seq, buf);
+ snprintf (bufout, sizeof (bufout), "%s %s %s\r\n", seq,
+ ctx->readonly ? "EXAMINE" : "SELECT", buf);
mutt_socket_write (CTX_DATA->conn, bufout);
do
}
}
while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+ /* check for READ-ONLY notification */
+ if (!strncmp (imap_get_qualifier (buf), "[READ-ONLY]", 11))
+ {
+ dprint (2, (debugfile, "Mailbox is read-only.\n"));
+ ctx->readonly = 1;
+ }
if (!imap_code (buf))
{
char buf[LONG_STRING];
if (mutt_socket_open_connection (conn) < 0)
- {
- return (-1);
- }
+ return -1;
idata->state = IMAP_CONNECTED;
{
mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
- return (-1);
+ return -1;
}
if (mutt_strncmp ("* OK", buf, 4) == 0)
{
mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
- return (-1);
+ return -1;
}
}
else if (mutt_strncmp ("* PREAUTH", buf, 9) == 0)
{
mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
- return (-1);
+ return -1;
}
}
else
imap_error ("imap_open_connection()", buf);
mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
- return (-1);
+ return -1;
}
idata->state = IMAP_AUTHENTICATED;
mutt_message (_("Selecting %s..."), idata->selected_mailbox);
imap_quote_string (buf, sizeof(buf), idata->selected_mailbox);
imap_make_sequence (seq, sizeof (seq));
- snprintf (bufout, sizeof (bufout), "%s SELECT %s\r\n", seq, buf);
+ snprintf (bufout, sizeof (bufout), "%s %s %s\r\n", seq,
+ ctx->readonly ? "EXAMINE" : "SELECT", buf);
mutt_socket_write (conn, bufout);
idata->state = IMAP_SELECTED;
}
}
while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+ /* check for READ-ONLY notification */
+ if (!strncmp (imap_get_qualifier (buf), "[READ-ONLY]", 11))
+ {
+ dprint (2, (debugfile, "Mailbox is read-only.\n"));
+ ctx->readonly = 1;
+ }
/* dump the mailbox flags we've found */
if (debuglevel > 2)
}
imap_make_sequence (seq, sizeof (seq));
+#if 0
snprintf (buf, sizeof (buf), "%s FETCH %d RFC822\r\n", seq,
ctx->hdrs[msgno]->index + 1);
+#else
+ snprintf (buf, sizeof (buf), "%s UID FETCH %d RFC822\r\n", seq,
+ HEADER_DATA(ctx->hdrs[msgno])->uid);
+#endif
mutt_socket_write (CTX_DATA->conn, buf);
do
{