X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=imap%2Fimap.c;h=6b372300bdd11885687760ab758ab09f80d27949;hp=90eae147652613985089e25d673b27e6c5ec605e;hb=82d5d8ffc8cd4cf837736187eba9ddfd8b2e2f7f;hpb=93f817273e1c70071cd5471594600bc70f12f0ff diff --git a/imap/imap.c b/imap/imap.c index 90eae14..6b37230 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -47,7 +47,9 @@ static int imap_check_capabilities (IMAP_DATA * idata); static void imap_set_flag (IMAP_DATA * idata, int aclbit, int flag, const char *str, char *flags, size_t flsize); -/* imap_access: Check permissions on an IMAP mailbox. */ +/* imap_access: Check permissions on an IMAP mailbox. + * TODO: ACL checks. Right now we assume if it exists we can + * mess with it. */ int imap_access (const char *path, int flags) { IMAP_DATA *idata; @@ -67,10 +69,16 @@ int imap_access (const char *path, int flags) } imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); + + /* we may already be in the folder we're checking */ + if (!ascii_strcmp(idata->mailbox, mx.mbox)) { + FREE (&mx.mbox); + return 0; + } + FREE (&mx.mbox); imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); - /* TODO: ACL checks. Right now we assume if it exists we can mess with it. */ if (mutt_bit_isset (idata->capabilities, IMAP4REV1)) snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox); else if (mutt_bit_isset (idata->capabilities, STATUS)) @@ -694,9 +702,8 @@ int imap_open_mailbox_append (CONTEXT * ctx) { CONNECTION *conn; IMAP_DATA *idata; - char buf[LONG_STRING], mbox[LONG_STRING]; + char buf[LONG_STRING]; char mailbox[LONG_STRING]; - int r; IMAP_MBOX mx; if (imap_parse_path (ctx->path, &mx)) @@ -705,52 +712,31 @@ int imap_open_mailbox_append (CONTEXT * ctx) /* in APPEND mode, we appear to hijack an existing IMAP connection - * ctx is brand new and mostly empty */ - if (!(idata = imap_conn_find (&(mx.account), 0))) - goto fail; + if (!(idata = imap_conn_find (&(mx.account), 0))) { + FREE(&mx.mbox); + return (-1); + } conn = idata->conn; ctx->magic = M_IMAP; ctx->data = idata; - /* check mailbox existance */ - imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox)); - imap_munge_mbox_name (mbox, sizeof (mbox), mailbox); - - if (mutt_bit_isset (idata->capabilities, IMAP4REV1)) - snprintf (buf, sizeof (buf), "STATUS %s (UIDVALIDITY)", mbox); - else if (mutt_bit_isset (idata->capabilities, STATUS)) - /* We have no idea what the other guy wants. UW imapd 8.3 wants this - * (but it does not work if another mailbox is selected) */ - snprintf (buf, sizeof (buf), "STATUS %s (UID-VALIDITY)", mbox); - else { - /* STATUS not supported */ - mutt_message _("Unable to append to IMAP mailboxes at this server"); - - goto fail; - } + FREE(&mx.mbox); - r = imap_exec (idata, buf, IMAP_CMD_FAIL_OK); - if (r == -2) { - /* command failed cause folder doesn't exist */ - snprintf (buf, sizeof (buf), _("Create %s?"), mailbox); - if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1) - goto fail; + /* really we should also check for W_OK */ + if (!imap_access (ctx->path, F_OK)) + return 0; - if (imap_create_mailbox (idata, mailbox) < 0) - goto fail; - } - else if (r == -1) - /* Hmm, some other failure */ - goto fail; + snprintf (buf, sizeof (buf), _("Create %s?"), mailbox); + if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1) + return -1; - FREE (&mx.mbox); - return 0; + if (imap_create_mailbox (idata, mailbox) < 0) + return -1; -fail: - FREE (&mx.mbox); - return -1; + return (0); } /* imap_logout: Gracefully log out of server. */ @@ -968,13 +954,6 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) return -1; } - /* CLOSE purges deleted messages. If we don't want to purge them, we must - * tell imap_close_mailbox not to issue the CLOSE command */ - if (expunge) - idata->noclose = 0; - else - idata->noclose = 1; - /* This function is only called when the calling code expects the context * to be changed. */ imap_allow_reopen (ctx); @@ -1017,7 +996,7 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) /* 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 || + if ((ctx->hdrs[n]->env && (ctx->hdrs[n]->env->refs_changed || ctx->hdrs[n]->env->irt_changed)) || ctx->hdrs[n]->attach_del) { debug_print (3, ("Attachments to be deleted, falling back to _mutt_save_message\n")); if (!appendctx) @@ -1046,11 +1025,17 @@ int imap_sync_mailbox (CONTEXT * ctx, int expunge, int *index_hint) idata->reopen |= IMAP_EXPUNGE_EXPECTED; if (imap_exec (idata, "EXPUNGE", 0) != 0) { imap_error (_("imap_sync_mailbox: EXPUNGE failed"), idata->cmd.buf); - rc = -1; + rc = imap_reconnect (ctx); goto out; } } + if (expunge && ctx->closing) { + if (imap_exec (idata, "CLOSE", 0)) + mutt_error (_("CLOSE failed")); + idata->state = IMAP_AUTHENTICATED; + } + rc = 0; out: if (cmd.data) @@ -1062,7 +1047,7 @@ out: return rc; } -/* imap_close_mailbox: issue close command if neccessary, reset IMAP_DATA */ +/* imap_close_mailbox: clean up IMAP data in CONTEXT */ void imap_close_mailbox (CONTEXT * ctx) { IMAP_DATA *idata; @@ -1073,13 +1058,16 @@ void imap_close_mailbox (CONTEXT * ctx) if (!idata) return; - if ((idata->status != IMAP_FATAL) && - (idata->state == IMAP_SELECTED) && (ctx == idata->ctx)) { - if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0)) - mutt_error (_("CLOSE failed")); + if (ctx == idata->ctx) { + if (idata->state != IMAP_FATAL && idata->state == IMAP_SELECTED) { + /* mx_close_mailbox won't sync if there are no deleted messages + * and the mailbox is unchanged, so we may have to close here */ + if (!ctx->deleted && imap_exec (idata, "CLOSE", 0)) + mutt_error (_("CLOSE failed")); + idata->state = IMAP_AUTHENTICATED; + } idata->reopen &= IMAP_REOPEN_ALLOW; - idata->state = IMAP_AUTHENTICATED; FREE (&(idata->mailbox)); mutt_free_list (&idata->flags); idata->ctx = NULL; @@ -1176,7 +1164,7 @@ int imap_mailbox_check (char *path, int new) * command on a mailbox that you have selected */ - if (safe_strcmp (mbox_unquoted, idata->mailbox) == 0 + if (mutt_strcmp (mbox_unquoted, idata->mailbox) == 0 || (ascii_strcasecmp (mbox_unquoted, "INBOX") == 0 && safe_strcasecmp (mbox_unquoted, idata->mailbox) == 0)) { strfcpy (buf, "NOOP", sizeof (buf)); @@ -1203,8 +1191,8 @@ int imap_mailbox_check (char *path, int new) /* 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 (safe_strncmp (mbox_unquoted, s, safe_strlen (mbox_unquoted)) == 0 - || safe_strncmp (mbox, s, safe_strlen (mbox)) == 0) { + if (safe_strncmp (mbox_unquoted, s, mutt_strlen (mbox_unquoted)) == 0 + || safe_strncmp (mbox, s, mutt_strlen (mbox)) == 0) { s = imap_next_word (s); s = imap_next_word (s); if (isdigit ((unsigned char) *s)) { @@ -1392,14 +1380,14 @@ int imap_complete (char *dest, size_t dlen, char *path) /* if the folder isn't selectable, append delimiter to force browse * to enter it on second tab. */ if (noselect) { - clen = safe_strlen (list_word); + clen = mutt_strlen (list_word); list_word[clen++] = delim; list_word[clen] = '\0'; } /* copy in first word */ if (!completions) { strfcpy (completion, list_word, sizeof (completion)); - matchlen = safe_strlen (completion); + matchlen = mutt_strlen (completion); completions++; continue; }