]> granicus.if.org Git - neomutt/commitdiff
Fix #677. From Brendan Cully.
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 3 Jul 2001 09:50:03 +0000 (09:50 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 3 Jul 2001 09:50:03 +0000 (09:50 +0000)
imap/imap.c
imap/imap_private.h
imap/message.c
muttlib.c
protos.h

index cfb65efa97676a469be0ccf24170f7c5d3ccf1bc..046d1c2ad9bdba0ec3e70353f98cefbea4455d14 100644 (file)
@@ -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);
index 7dbcafac32cffa8e600370bf54b70edfd7e2968d..7efd9c552b2602695226f9f720b0893b95c0a6e3 100644 (file)
@@ -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,
index 8b6b8cce41fc0586ccdcbae032c77b89730cdb51..26acae96b479e9ae4ca81bcdc13274f253ec663d 100644 (file)
@@ -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;
 }
index 28cc0e3c59e76048cbb87a597db66c3d228385ba..717d9613ed853fe477522614563324b40420b358 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -1226,3 +1226,24 @@ void mutt_sleep (short s)
   else if (s)
     sleep (s);
 }
+
+/* dynamically grows a BUFFER to accomodate s, in increments of 128 bytes.
+ * Always one byte bigger than necessary for the null terminator, and
+ * the buffer is always null-terminated */
+void mutt_buffer_addstr (BUFFER* buf, const char* s)
+{
+  size_t len, offset;
+
+  len = mutt_strlen (s);
+
+  if (buf->dptr + len + 1 > buf->data + buf->dsize)
+  {
+    offset = buf->dptr - buf->data;
+    buf->dsize += len < 128 ? 128 : len + 1;
+    safe_realloc ((void**) &buf->data, buf->dsize);
+    buf->dptr = buf->data + offset;
+  }
+  memcpy (buf->dptr, s, len);
+  buf->dptr += len;
+  *(buf->dptr) = '\0';
+}
index d8718bdfa0705025828e0607365b066805bfd001..396bbb46b71769a1c09f62c2f1360bc641ab1988 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -37,9 +37,7 @@ void _mutt_make_string (char *, size_t, const char *, CONTEXT *,
        HEADER *, format_flag);
 
 int mutt_extract_token (BUFFER *, BUFFER *, int);
-
-int mutt_add_string (BUFFER *, const char *);
-int mutt_add_char (BUFFER *, char);
+void mutt_buffer_addstr (BUFFER*, const char*);
 
 #define mutt_system(x) _mutt_system(x,0)
 int _mutt_system (const char *, int);