* Copyright notice from original mutt:
* Copyright (C) 1996-8 Michael R. Elkins <me@mutt.org>
* Copyright (C) 1996-9 Brandon Long <blong@fiction.net>
- * Copyright (C) 1999-2003 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2005 Brendan Cully <brendan@kublai.com>
*
* This file is part of mutt-ng, see http://www.muttng.org/.
* It's licensed under the GNU General Public License,
#include "mutt.h"
#include "mutt_curses.h"
#include "mx.h"
-#include "mailbox.h"
#include "globals.h"
#include "sort.h"
#include "browser.h"
# include "mutt_ssl.h"
#endif
+#include "lib/mem.h"
+#include "lib/intl.h"
+#include "lib/str.h"
+#include "lib/debug.h"
+
#include <unistd.h>
#include <ctype.h>
#include <string.h>
else if (mutt_bit_isset (idata->capabilities, STATUS))
snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox);
else {
- dprint (2, (debugfile, "imap_access: STATUS not supported?\n"));
+ debug_print (2, ("STATUS not supported?\n"));
return -1;
}
if (imap_exec (idata, buf, IMAP_CMD_FAIL_OK) < 0) {
- dprint (1, (debugfile, "imap_access: Can't check STATUS of %s\n", mbox));
+ debug_print (1, ("Can't check STATUS of %s\n", mbox));
return -1;
}
int r = 0;
- dprint (2, (debugfile, "imap_read_literal: reading %ld bytes\n", bytes));
+ debug_print (2, ("reading %ld bytes\n", bytes));
for (pos = 0; pos < bytes; pos++) {
if (mutt_socket_readchar (idata->conn, &c) != 1) {
- dprint (1,
- (debugfile,
- "imap_read_literal: error during read, %ld bytes read\n",
- pos));
+ debug_print (1, ("error during read, %ld bytes read\n", pos));
idata->status = IMAP_FATAL;
return -1;
#endif
fputc (c, fp);
#ifdef DEBUG
- if (debuglevel >= IMAP_LOG_LTRL)
- fputc (c, debugfile);
+ if (DebugLevel >= IMAP_LOG_LTRL)
+ fputc (c, DebugFile);
#endif
}
h = idata->ctx->hdrs[i];
if (h->index == -1) {
- dprint (2,
- (debugfile, "Expunging message UID %d.\n",
- HEADER_DATA (h)->uid));
+ debug_print (2, ("Expunging message UID %d.\n", HEADER_DATA (h)->uid));
h->active = 0;
while (rc == IMAP_CMD_CONTINUE);
if (rc != IMAP_CMD_OK) {
- dprint (1, (debugfile, "imap_get_delim: failed.\n"));
+ debug_print (1, ("failed.\n"));
return -1;
}
- dprint (2, (debugfile, "Delimiter: %c\n", idata->delim));
+ debug_print (2, ("Delimiter: %c\n", idata->delim));
return -1;
}
if (!imap_authenticate (idata)) {
idata->state = IMAP_AUTHENTICATED;
if (idata->conn->ssf)
- dprint (2, (debugfile, "Communication encrypted at %d bits\n",
- idata->conn->ssf));
+ debug_print (2, ("Communication encrypted at %d bits\n", idata->conn->ssf));
}
else
mutt_account_unsetpass (&idata->conn->account);
/* sanity-check string */
if (ascii_strncasecmp ("FLAGS", s, 5) != 0) {
- dprint (1, (debugfile, "imap_get_flags: not a FLAGS response: %s\n", s));
+ debug_print (1, ("not a FLAGS response: %s\n", s));
return NULL;
}
s += 5;
SKIPWS (s);
if (*s != '(') {
- dprint (1, (debugfile, "imap_get_flags: bogus FLAGS response: %s\n", s));
+ debug_print (1, ("bogus FLAGS response: %s\n", s));
return NULL;
}
/* note bad flags response */
if (*s != ')') {
- dprint (1, (debugfile,
- "imap_get_flags: Unterminated FLAGS response: %s\n", s));
+ debug_print (1, ("Unterminated FLAGS response: %s\n", s));
mutt_free_list (hflags);
return NULL;
if (ascii_strncasecmp ("FLAGS", pc, 5) == 0) {
/* don't override PERMANENTFLAGS */
if (!idata->flags) {
- dprint (2, (debugfile, "Getting mailbox FLAGS\n"));
+ debug_print (2, ("Getting mailbox FLAGS\n"));
if ((pc = imap_get_flags (&(idata->flags), pc)) == NULL)
goto fail;
}
}
/* PERMANENTFLAGS are massaged to look like FLAGS, then override FLAGS */
else if (ascii_strncasecmp ("OK [PERMANENTFLAGS", pc, 18) == 0) {
- dprint (2, (debugfile, "Getting mailbox PERMANENTFLAGS\n"));
+ debug_print (2, ("Getting mailbox PERMANENTFLAGS\n"));
/* safe to call on NULL */
mutt_free_list (&(idata->flags));
/* skip "OK [PERMANENT" so syntax is the same as FLAGS */
#ifdef USE_HCACHE
/* save UIDVALIDITY for the header cache */
else if (ascii_strncasecmp ("OK [UIDVALIDITY", pc, 14) == 0) {
- dprint (2, (debugfile, "Getting mailbox UIDVALIDITY\n"));
+ debug_print (2, ("Getting mailbox UIDVALIDITY\n"));
pc += 3;
pc = imap_next_word (pc);
- sscanf (pc, "%u", &(idata->uid_validity));
+ sscanf (pc, "%lu", &(idata->uid_validity));
}
#endif
else {
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"));
+ debug_print (2, ("Mailbox is read-only.\n"));
ctx->readonly = 1;
}
#ifdef DEBUG
/* dump the mailbox flags we've found */
- if (debuglevel > 2) {
+ if (DebugLevel > 2) {
if (!idata->flags)
- dprint (3, (debugfile, "No folder flags found\n"));
+ debug_print (3, ("No folder flags found\n"));
else {
LIST *t = idata->flags;
- dprint (3, (debugfile, "Mailbox flags: "));
+ debug_print (3, ("Mailbox flags:\n"));
t = t->next;
while (t) {
- dprint (3, (debugfile, "[%s] ", t->data));
+ debug_print (3, ("[%s]\n", t->data));
t = t->next;
}
- dprint (3, (debugfile, "\n"));
}
}
#endif
if (mutt_bit_isset (idata->capabilities, ACL)) {
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)))
+ if (!(mutt_bit_isset (idata->rights, ACL_DELETE) ||
+ mutt_bit_isset (idata->rights, ACL_SEEN) ||
+ mutt_bit_isset (idata->rights, ACL_WRITE) ||
+ mutt_bit_isset (idata->rights, ACL_INSERT)))
ctx->readonly = 1;
}
/* assume we have all rights if ACL is unavailable */
else {
- mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
- mutt_bit_set (idata->rights, IMAP_ACL_READ);
- mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
- mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
- mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
- mutt_bit_set (idata->rights, IMAP_ACL_POST);
- mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
- mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
+ mutt_bit_set (idata->rights, ACL_LOOKUP);
+ mutt_bit_set (idata->rights, ACL_READ);
+ mutt_bit_set (idata->rights, ACL_SEEN);
+ mutt_bit_set (idata->rights, ACL_WRITE);
+ mutt_bit_set (idata->rights, ACL_INSERT);
+ mutt_bit_set (idata->rights, ACL_POST);
+ mutt_bit_set (idata->rights, ACL_CREATE);
+ mutt_bit_set (idata->rights, ACL_DELETE);
}
ctx->hdrmax = count;
goto fail;
}
- dprint (2,
- (debugfile, "imap_open_mailbox: msgcount is %d\n", ctx->msgcount));
+ debug_print (2, ("msgcount is %d\n", ctx->msgcount));
FREE (&mx.mbox);
return 0;
/*
int imap_close_connection (CONTEXT *ctx)
{
- dprint (1, (debugfile, "imap_close_connection(): closing connection\n"));
+ debug_print (1, (debugfile, "imap_close_connection(): closing connection\n"));
if (CTX_DATA->status != IMAP_BYE)
{
mutt_message _("Closing connection to IMAP server...");
return count;
}
+/* Update the IMAP server to reflect the flags a single message. */
+
+int imap_sync_message (IMAP_DATA *idata, HEADER *hdr, BUFFER *cmd,
+ int *err_continue)
+{
+ char flags[LONG_STRING];
+ char uid[11];
+
+ hdr->changed = 0;
+
+ snprintf (uid, sizeof (uid), "%u", HEADER_DATA(hdr)->uid);
+ cmd->dptr = cmd->data;
+ mutt_buffer_addstr (cmd, "UID STORE ");
+ mutt_buffer_addstr (cmd, uid);
+
+ flags[0] = '\0';
+
+ imap_set_flag (idata, ACL_SEEN, hdr->read, "\\Seen ",
+ flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, hdr->flagged,
+ "\\Flagged ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, hdr->replied,
+ "\\Answered ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_DELETE, hdr->deleted,
+ "\\Deleted ", flags, sizeof (flags));
+
+ /* now make sure we don't lose custom tags */
+ if (mutt_bit_isset (idata->rights, ACL_WRITE))
+ imap_add_keywords (flags, hdr, idata->flags, sizeof (flags));
+
+ mutt_remove_trailing_ws (flags);
+
+ /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
+ * explicitly revoke all system flags (if we have permission) */
+ if (!*flags)
+ {
+ imap_set_flag (idata, ACL_SEEN, 1, "\\Seen ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, 1, "\\Flagged ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_WRITE, 1, "\\Answered ", flags, sizeof (flags));
+ imap_set_flag (idata, ACL_DELETE, 1, "\\Deleted ", flags, sizeof (flags));
+
+ mutt_remove_trailing_ws (flags);
+
+ mutt_buffer_addstr (cmd, " -FLAGS.SILENT (");
+ } else
+ mutt_buffer_addstr (cmd, " FLAGS.SILENT (");
+
+ mutt_buffer_addstr (cmd, flags);
+ mutt_buffer_addstr (cmd, ")");
+
+ /* dumb hack for bad UW-IMAP 4.7 servers spurious FLAGS updates */
+ hdr->active = 0;
+
+ /* after all this it's still possible to have no flags, if you
+ * have no ACL rights */
+ if (*flags && (imap_exec (idata, cmd->data, 0) != 0) &&
+ err_continue && (*err_continue != M_YES))
+ {
+ *err_continue = imap_continue ("imap_sync_message: STORE failed",
+ idata->cmd.buf);
+ if (*err_continue != M_YES)
+ return -1;
+ }
+
+ hdr->active = 1;
+ idata->ctx->changed--;
+
+ return 0;
+}
+
/* update the IMAP server to reflect message changes done within mutt.
* Arguments
* ctx: the current context
IMAP_DATA *idata;
CONTEXT *appendctx = NULL;
BUFFER cmd;
- char flags[LONG_STRING];
- char uid[11];
int deleted;
int n;
int err_continue = M_NO; /* continue on error? */
idata = (IMAP_DATA *) ctx->data;
if (idata->state != IMAP_SELECTED) {
- dprint (2, (debugfile, "imap_sync_mailbox: no mailbox selected\n"));
+ debug_print (2, ("no mailbox selected\n"));
return -1;
}
memset (&cmd, 0, sizeof (cmd));
/* if we are expunging anyway, we can do deleted messages very quickly... */
- if (expunge && mutt_bit_isset (idata->rights, IMAP_ACL_DELETE)) {
+ if (expunge && mutt_bit_isset (idata->rights, ACL_DELETE)) {
mutt_buffer_addstr (&cmd, "UID STORE ");
deleted = imap_make_msg_set (idata, &cmd, M_DELETE, 1);
/* save status changes */
for (n = 0; n < ctx->msgcount; n++) {
if (ctx->hdrs[n]->active && ctx->hdrs[n]->changed) {
- ctx->hdrs[n]->changed = 0;
mutt_message (_("Saving message status flags... [%d/%d]"), n + 1,
ctx->msgcount);
- snprintf (uid, sizeof (uid), "%u", HEADER_DATA (ctx->hdrs[n])->uid);
- cmd.dptr = cmd.data;
- mutt_buffer_addstr (&cmd, "UID STORE ");
- mutt_buffer_addstr (&cmd, uid);
-
/* if the message has been rethreaded or attachments have been deleted
* we delete the message and reupload it.
* This works better if we're expunging, of course. */
if (ctx->hdrs[n]->refs_changed || ctx->hdrs[n]->irt_changed ||
ctx->hdrs[n]->attach_del) {
- dprint (3,
- (debugfile,
- "imap_sync_mailbox: Attachments to be deleted, falling back to _mutt_save_message\n"));
+ debug_print (3, ("Attachments to be deleted, falling back to _mutt_save_message\n"));
if (!appendctx)
appendctx = mx_open_mailbox (ctx->path, M_APPEND | M_QUIET, NULL);
if (!appendctx) {
- dprint (1,
- (debugfile,
- "imap_sync_mailbox: Error opening mailbox in append mode\n"));
+ debug_print (1, ("Error opening mailbox in append mode\n"));
}
else
_mutt_save_message (ctx->hdrs[n], appendctx, 1, 0, 0);
}
- flags[0] = '\0';
-
- imap_set_flag (idata, IMAP_ACL_SEEN, ctx->hdrs[n]->read, "\\Seen ",
- flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, ctx->hdrs[n]->flagged,
- "\\Flagged ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, ctx->hdrs[n]->replied,
- "\\Answered ", flags, sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_DELETE, ctx->hdrs[n]->deleted,
- "\\Deleted ", flags, sizeof (flags));
-
- /* now make sure we don't lose custom tags */
- if (mutt_bit_isset (idata->rights, IMAP_ACL_WRITE))
- imap_add_keywords (flags, ctx->hdrs[n], idata->flags, sizeof (flags));
-
- mutt_remove_trailing_ws (flags);
-
- /* UW-IMAP is OK with null flags, Cyrus isn't. The only solution is to
- * explicitly revoke all system flags (if we have permission) */
- if (!*flags) {
- imap_set_flag (idata, IMAP_ACL_SEEN, 1, "\\Seen ", flags,
- sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Flagged ", flags,
- sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_WRITE, 1, "\\Answered ", flags,
- sizeof (flags));
- imap_set_flag (idata, IMAP_ACL_DELETE, 1, "\\Deleted ", flags,
- sizeof (flags));
-
- mutt_remove_trailing_ws (flags);
-
- mutt_buffer_addstr (&cmd, " -FLAGS.SILENT (");
- }
- else
- mutt_buffer_addstr (&cmd, " FLAGS.SILENT (");
-
- mutt_buffer_addstr (&cmd, flags);
- mutt_buffer_addstr (&cmd, ")");
-
- /* dumb hack for bad UW-IMAP 4.7 servers spurious FLAGS updates */
- ctx->hdrs[n]->active = 0;
-
- /* after all this it's still possible to have no flags, if you
- * have no ACL rights */
- if (*flags && (imap_exec (idata, cmd.data, 0) != 0) &&
- (err_continue != M_YES)) {
- err_continue = imap_continue ("imap_sync_mailbox: STORE failed",
- idata->cmd.buf);
- if (err_continue != M_YES) {
- rc = -1;
- goto out;
- }
- }
- ctx->hdrs[n]->active = 1;
+ if (imap_sync_message (idata, ctx->hdrs[n], &cmd, &err_continue) < 0) {
+ rc = -1;
+ goto out;
+ }
}
}
ctx->changed = 0;
/* We must send an EXPUNGE command if we're not closing. */
if (expunge && !(ctx->closing) &&
- mutt_bit_isset (idata->rights, IMAP_ACL_DELETE)) {
+ mutt_bit_isset (idata->rights, ACL_DELETE)) {
mutt_message _("Expunging messages from server...");
/* Set expunge bit so we don't get spurious reopened messages */
* command on a mailbox that you have selected
*/
- if (mutt_strcmp (mbox_unquoted, idata->mailbox) == 0
+ if (safe_strcmp (mbox_unquoted, idata->mailbox) == 0
|| (ascii_strcasecmp (mbox_unquoted, "INBOX") == 0
- && mutt_strcasecmp (mbox_unquoted, idata->mailbox) == 0)) {
+ && safe_strcasecmp (mbox_unquoted, idata->mailbox) == 0)) {
strfcpy (buf, "NOOP", sizeof (buf));
}
else if (mutt_bit_isset (idata->capabilities, IMAP4REV1) ||
/* The mailbox name may or may not be quoted here. We could try to
* munge the server response and compare with quoted (or vise versa)
* but it is probably more efficient to just strncmp against both. */
- if (mutt_strncmp (mbox_unquoted, s, mutt_strlen (mbox_unquoted)) == 0
- || mutt_strncmp (mbox, s, mutt_strlen (mbox)) == 0) {
+ if (safe_strncmp (mbox_unquoted, s, safe_strlen (mbox_unquoted)) == 0
+ || safe_strncmp (mbox, s, safe_strlen (mbox)) == 0) {
s = imap_next_word (s);
s = imap_next_word (s);
if (isdigit ((unsigned char) *s)) {
if (*s != '0') {
msgcount = atoi (s);
- dprint (2,
- (debugfile, "%d new messages in %s\n", msgcount, path));
+ debug_print (2, ("%d new messages in %s\n", msgcount, path));
}
}
}
else
- dprint (1,
- (debugfile,
- "imap_mailbox_check: STATUS response doesn't match requested mailbox.\n"));
+ debug_print (1, ("STATUS response doesn't match requested mailbox.\n"));
}
}
while (rc == IMAP_CMD_CONTINUE);
char mbox[LONG_STRING];
IMAP_MBOX mx;
- if (!mx_is_imap (path) || imap_parse_path (path, &mx)) {
+ if (mx_get_magic (path) == M_IMAP || imap_parse_path (path, &mx)) {
mutt_error (_("Bad mailbox name"));
return -1;
}
/* verify passed in path is an IMAP path */
if (imap_parse_path (path, &mx)) {
- dprint (2, (debugfile, "imap_complete: bad path %s\n", path));
+ debug_print (2, ("bad path %s\n", path));
return -1;
}
/* if the folder isn't selectable, append delimiter to force browse
* to enter it on second tab. */
if (noselect) {
- clen = strlen (list_word);
+ clen = safe_strlen (list_word);
list_word[clen++] = delim;
list_word[clen] = '\0';
}
/* copy in first word */
if (!completions) {
strfcpy (completion, list_word, sizeof (completion));
- matchlen = strlen (completion);
+ matchlen = safe_strlen (completion);
completions++;
continue;
}
/* reconnect if connection was lost */
int imap_reconnect (CONTEXT * ctx)
{
- IMAP_DATA *imap_data = (IMAP_DATA *) ctx->data;
+ IMAP_DATA *imap_data;
+
+ if (!ctx)
+ return (-1);
+
+ imap_data = (IMAP_DATA *) ctx->data;
if (imap_data) {
if (imap_data->status == IMAP_CONNECTED)