From 557a77d1dbefa3549b6d29a9b5b8b44e30c0a630 Mon Sep 17 00:00:00 2001 From: Thomas Roessler Date: Tue, 3 Jul 2001 09:50:03 +0000 Subject: Fix #677. From Brendan Cully. --- imap/imap.c | 72 +++++++++++++++++++++++++++++------------------------ imap/imap_private.h | 3 +-- imap/message.c | 39 ++++++++++++++++++----------- 3 files changed, 64 insertions(+), 50 deletions(-) (limited to 'imap') diff --git a/imap/imap.c b/imap/imap.c index cfb65efa..046d1c2a 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -778,22 +778,17 @@ static void imap_set_flag (IMAP_DATA* idata, int aclbit, int flag, * flag: enum of flag type on which to filter * changed: include only changed messages in message set * Returns: number of messages in message set (0 if no matches) */ -int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag, - int changed) +int imap_make_msg_set (IMAP_DATA* idata, BUFFER* buf, int flag, int changed) { HEADER** hdrs; /* sorted local copy */ int count = 0; /* number of messages in message set */ int match = 0; /* whether current message matches flag condition */ - int setstart = 0; /* start of current message range */ - char* tmp; + unsigned int setstart = 0; /* start of current message range */ int n; short oldsort; /* we clobber reverse, must restore it */ - - /* sanity-check */ - if (!buf || buflen < 2) - return 0; - - *buf = '\0'; + /* assuming 32-bit UIDs */ + char uid[12]; + int started = 0; /* make copy of header pointers to sort in natural order */ hdrs = safe_calloc (idata->ctx->msgcount, sizeof (HEADER*)); @@ -808,8 +803,6 @@ int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag, Sort = oldsort; } - tmp = safe_malloc (buflen); - for (n = 0; n < idata->ctx->msgcount; n++) { match = 0; @@ -833,19 +826,23 @@ int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag, if (setstart == 0) { setstart = HEADER_DATA (hdrs[n])->uid; - if (!buf[0]) - snprintf (buf, buflen, "%u", HEADER_DATA (hdrs[n])->uid); + if (started == 0) + { + snprintf (uid, sizeof (uid), "%u", HEADER_DATA (hdrs[n])->uid); + mutt_buffer_addstr (buf, uid); + started = 1; + } else { - strncpy (tmp, buf, buflen); - snprintf (buf, buflen, "%s,%u", tmp, HEADER_DATA (hdrs[n])->uid); + snprintf (uid, sizeof (uid), ",%u", HEADER_DATA (hdrs[n])->uid); + mutt_buffer_addstr (buf, uid); } } /* tie up if the last message also matches */ else if (n == idata->ctx->msgcount-1) { - strncpy (tmp, buf, buflen); - snprintf (buf, buflen, "%s:%u", tmp, HEADER_DATA (hdrs[n])->uid); + snprintf (uid, sizeof (uid), ":%u", HEADER_DATA (hdrs[n])->uid); + mutt_buffer_addstr (buf, uid); } } /* this message is not expunged and doesn't match. End current set. */ @@ -853,14 +850,13 @@ int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag, { if (HEADER_DATA (hdrs[n-1])->uid > setstart) { - strncpy (tmp, buf, buflen); - snprintf (buf, buflen, "%s:%u", tmp, HEADER_DATA (hdrs[n-1])->uid); + snprintf (uid, sizeof (uid), ":%u", HEADER_DATA (hdrs[n])->uid); + mutt_buffer_addstr (buf, uid); } setstart = 0; } } - safe_free ((void**) &tmp); safe_free ((void**) &hdrs); return count; @@ -876,9 +872,9 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) { IMAP_DATA* idata; CONTEXT* appendctx = NULL; - char buf[HUGE_STRING]; + BUFFER cmd; char flags[LONG_STRING]; - char tmp[LONG_STRING]; + char uid[11]; int deleted; int n; int err_continue = M_NO; /* continue on error? */ @@ -901,28 +897,30 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) /* This function is only called when the calling code expects the context * to be changed. */ - imap_allow_reopen (ctx); + imap_allow_reopen (ctx); if ((rc = imap_check_mailbox (ctx, index_hint)) != 0) return rc; + 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)) { - deleted = imap_make_msg_set (idata, buf, sizeof (buf), M_DELETE, 1); + mutt_buffer_addstr (&cmd, "UID STORE "); + deleted = imap_make_msg_set (idata, &cmd, M_DELETE, 1); /* if we have a message set, then let's delete */ if (deleted) { mutt_message (_("Marking %d messages deleted..."), deleted); - snprintf (tmp, sizeof (tmp), "UID STORE %s +FLAGS.SILENT (\\Deleted)", - buf); + mutt_buffer_addstr (&cmd, " +FLAGS.SILENT (\\Deleted)"); /* mark these messages as unchanged so second pass ignores them. Done * here so BOGUS UW-IMAP 4.7 SILENT FLAGS updates are ignored. */ for (n = 0; n < ctx->msgcount; n++) if (ctx->hdrs[n]->deleted && ctx->hdrs[n]->changed) ctx->hdrs[n]->active = 0; - if (imap_exec (idata, tmp, 0) != 0) + if (imap_exec (idata, cmd.data, 0) != 0) { mutt_error (_("Expunge failed")); mutt_sleep (1); @@ -942,6 +940,11 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) 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 attachments have been deleted we delete the message and reupload * it. This works better if we're expunging, of course. */ if (ctx->hdrs[n]->attach_del) @@ -984,19 +987,20 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) mutt_remove_trailing_ws (flags); - snprintf (buf, sizeof (buf), "UID STORE %d -FLAGS.SILENT (%s)", - HEADER_DATA (ctx->hdrs[n])->uid, flags); + mutt_buffer_addstr (&cmd, " -FLAGS.SILENT ("); } else - snprintf (buf, sizeof (buf), "UID STORE %d FLAGS.SILENT (%s)", - HEADER_DATA (ctx->hdrs[n])->uid, flags); + 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, buf, 0) != 0) && + if (*flags && (imap_exec (idata, cmd.data, 0) != 0) && (err_continue != M_YES)) { err_continue = imap_continue ("imap_sync_mailbox: STORE failed", @@ -1030,6 +1034,8 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) rc = 0; out: + if (cmd.data) + FREE (&cmd.data); if (appendctx) { mx_fastclose_mailbox (appendctx); diff --git a/imap/imap_private.h b/imap/imap_private.h index 7dbcafac..7efd9c55 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -190,8 +190,7 @@ typedef struct /* -- private IMAP functions -- */ /* imap.c */ int imap_create_mailbox (IMAP_DATA* idata, char* mailbox); -int imap_make_msg_set (IMAP_DATA* idata, char* buf, size_t buflen, int flag, - int changed); +int imap_make_msg_set (IMAP_DATA* idata, BUFFER* buf, int flag, int changed); int imap_open_connection (IMAP_DATA* idata); IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags); int imap_parse_list_response(IMAP_DATA* idata, char** name, int* noselect, diff --git a/imap/message.c b/imap/message.c index 8b6b8cce..26acae96 100644 --- a/imap/message.c +++ b/imap/message.c @@ -510,8 +510,8 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg) int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) { IMAP_DATA* idata; - char buf[HUGE_STRING]; - char cmd[LONG_STRING]; + BUFFER cmd; + char uid[11]; char mbox[LONG_STRING]; char mmbox[LONG_STRING]; int rc; @@ -540,7 +540,10 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) return 1; } - imap_fix_path (idata, mx.mbox, cmd, sizeof (cmd)); + imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox)); + + memset (&cmd, 0, sizeof (cmd)); + mutt_buffer_addstr (&cmd, "UID COPY "); /* Null HEADER* means copy tagged messages */ if (!h) @@ -556,26 +559,28 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) return 1; } } - - rc = imap_make_msg_set (idata, buf, sizeof (buf), M_TAG, 0); + + rc = imap_make_msg_set (idata, &cmd, M_TAG, 0); if (!rc) { dprint (1, (debugfile, "imap_copy_messages: No messages tagged\n")); goto fail; } - mutt_message (_("Copying %d messages to %s..."), rc, cmd); + mutt_message (_("Copying %d messages to %s..."), rc, mbox); } else { - mutt_message (_("Copying message %d to %s..."), h->index+1, cmd); - snprintf (buf, sizeof (buf), "%u", HEADER_DATA (h)->uid); + mutt_message (_("Copying message %d to %s..."), h->index+1, mbox); + snprintf (uid, sizeof (uid), "%u", HEADER_DATA (h)->uid); + mutt_buffer_addstr (&cmd, uid); } /* let's get it on */ - strncpy (mbox, cmd, sizeof (mbox)); - imap_munge_mbox_name (mmbox, sizeof (mmbox), cmd); - snprintf (cmd, sizeof (cmd), "UID COPY %s %s", buf, mmbox); - rc = imap_exec (idata, cmd, IMAP_CMD_FAIL_OK); + mutt_buffer_addstr (&cmd, " "); + imap_munge_mbox_name (mmbox, sizeof (mmbox), mbox); + mutt_buffer_addstr (&cmd, mmbox); + + rc = imap_exec (idata, cmd.data, IMAP_CMD_FAIL_OK); if (rc == -2) { /* bail out if command failed for reasons other than nonexistent target */ @@ -585,8 +590,8 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) goto fail; } dprint (2, (debugfile, "imap_copy_messages: server suggests TRYCREATE\n")); - snprintf (buf, sizeof (buf), _("Create %s?"), mbox); - if (option (OPTCONFIRMCREATE) && mutt_yesorno (buf, 1) < 1) + snprintf (mmbox, sizeof (mmbox), _("Create %s?"), mbox); + if (option (OPTCONFIRMCREATE) && mutt_yesorno (mmbox, 1) < 1) { mutt_clear_error (); goto fail; @@ -595,7 +600,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) goto fail; /* try again */ - rc = imap_exec (idata, cmd, 0); + rc = imap_exec (idata, cmd.data, 0); } if (rc != 0) { @@ -624,10 +629,14 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) } } + if (cmd.data) + FREE (&cmd.data); FREE (&mx.mbox); return 0; fail: + if (cmd.data) + FREE (&cmd.data); FREE (&mx.mbox); return -1; } -- cgit v1.2.3