]> granicus.if.org Git - mutt/commitdiff
patch-bac.command-2
authorThomas Roessler <roessler@does-not-exist.org>
Mon, 21 Aug 2000 11:30:28 +0000 (11:30 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Mon, 21 Aug 2000 11:30:28 +0000 (11:30 +0000)
imap/auth_anon.c
imap/auth_cram.c
imap/auth_gss.c
imap/auth_login.c
imap/auth_sasl.c
imap/browse.c
imap/command.c
imap/imap.c
imap/imap_private.h
imap/message.c

index a7fd87ff6e96d70f0a906799e1e74fb4e6dc8f09..d9e48289e1b39075ab9c211333c20c2823a4794f 100644 (file)
@@ -41,7 +41,7 @@ imap_auth_res_t imap_auth_anon (IMAP_DATA* idata)
   imap_cmd_start (idata, "AUTHENTICATE ANONYMOUS");
 
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_RESPOND)
@@ -53,7 +53,7 @@ imap_auth_res_t imap_auth_anon (IMAP_DATA* idata)
   mutt_socket_write (idata->conn, "ZHVtbXkK\r\n"); /* base64 ("dummy") */
 
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
   
   if (rc != IMAP_CMD_DONE)
index 00e0f0d9ecbd5639a05ebb62136963a06cc50daf..f41ef4c528b4804e84447f2f0ec26e4c2e580b96 100644 (file)
@@ -58,7 +58,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata)
    * correspond to that of an RFC 822 'msg-id' [RFC822] as described in [POP3].
    */
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
   
   if (rc != IMAP_CMD_RESPOND)
@@ -103,7 +103,7 @@ imap_auth_res_t imap_auth_cram_md5 (IMAP_DATA* idata)
   mutt_socket_write (idata->conn, ibuf);
 
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_DONE)
index bf59c019b17e8d88ef0cd47c6bd5f25e2a6e9455..b1f03a37560d0f667fa640f9fb297f4cb09e846b 100644 (file)
@@ -90,7 +90,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
 
   /* expect a null continuation response ("+") */
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_RESPOND)
@@ -127,7 +127,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
       /* end authentication attempt */
       mutt_socket_write (idata->conn, "*\r\n");
       do
-       rc = imap_cmd_resp (idata);
+       rc = imap_cmd_step (idata);
       while (rc == IMAP_CMD_CONTINUE);
       goto bail;
     }
@@ -142,7 +142,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
     if (maj_stat == GSS_S_CONTINUE_NEEDED)
     {
       do
-       rc = imap_cmd_resp (idata);
+       rc = imap_cmd_step (idata);
       while (rc == IMAP_CMD_CONTINUE);
 
       if (rc != IMAP_CMD_RESPOND)
@@ -163,7 +163,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
 
   /* get security flags and buffer size */
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_RESPOND)
@@ -230,7 +230,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
 
   /* Joy of victory or agony of defeat? */
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
   if (rc != IMAP_CMD_DONE)
   {
index 731f14f3c5a5d6f0c4a9064e1c39a3d236ef7c06..fff5baa6884992cc0e2487e2c562ce95c984a96a 100644 (file)
@@ -29,6 +29,12 @@ imap_auth_res_t imap_auth_login (IMAP_DATA* idata)
   char buf[STRING];
   int rc;
 
+  if (mutt_bit_isset (idata->capabilities, LOGINDISABLED))
+  {
+    mutt_message _("LOGIN disabled on this server.");
+    return IMAP_AUTH_UNAVAIL;
+  }
+
   if (mutt_account_getuser (&idata->conn->account))
     return IMAP_AUTH_FAILURE;
   if (mutt_account_getpass (&idata->conn->account))
index 5e01331b97f39b434a6990c8e818382f9f6ae23f..b628d8fc3989f134fd351d43cc41796cc1d85d09 100644 (file)
@@ -98,7 +98,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
   while (rc == SASL_CONTINUE)
   {
     do
-      irc = imap_cmd_resp (idata);
+      irc = imap_cmd_step (idata);
     while (irc == IMAP_CMD_CONTINUE);
 
     if (irc == IMAP_CMD_FAIL)
@@ -147,7 +147,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
   }
 
   while (irc != IMAP_CMD_DONE)
-    if ((irc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((irc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
   if (rc != SASL_OK)
index 1571a705366589fc961c8dcc453df161e2e86a5d..cd3b0470ad0d6226609af5fb3ced5ecf9d7d2aca 100644 (file)
@@ -347,7 +347,7 @@ static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen,
   
   do 
   {
-    if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
     s = imap_next_word (idata->buf);
index 609f04e666640fd97031da4a0f541b82458d90e7..a406c942efc987b3ab9d35369fc3d610e3f55f46 100644 (file)
 #define IMAP_CMD_BUFSIZE 512
 
 /* forward declarations */
+static void cmd_finish (IMAP_DATA* idata);
+static void cmd_handle_fatal (IMAP_DATA* idata);
+static int cmd_handle_untagged (IMAP_DATA* idata);
 static void cmd_make_sequence (char* buf, size_t buflen);
 static void cmd_parse_capabilities (IMAP_DATA* idata, char* s);
 static void cmd_parse_expunge (IMAP_DATA* idata, char* s);
 static void cmd_parse_myrights (IMAP_DATA* idata, char* s);
 
-static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL", 
-  "NAMESPACE", "AUTH=CRAM-MD5", "AUTH=KERBEROS_V4", "AUTH=GSSAPI", 
-  "AUTH=LOGIN", "AUTH-LOGIN", "AUTH=PLAIN", "AUTH=SKEY", "IDLE", 
-  "LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT", 
-  "THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", NULL};
+static char *Capabilities[] = {
+  "IMAP4",
+  "IMAP4rev1",
+  "STATUS",
+  "ACL", 
+  "NAMESPACE",
+  "AUTH=CRAM-MD5",
+  "AUTH=GSSAPI",
+  "AUTH=ANONYMOUS",
+  "STARTTLS",
+  "LOGINDISABLED",
+
+  NULL
+};
 
 /* imap_cmd_start: Given an IMAP command, send it to the server.
  *   Currently a minor convenience, but helps to route all IMAP commands
  *   through a single interface. */
-void imap_cmd_start (IMAP_DATA* idata, const char* cmd)
+int imap_cmd_start (IMAP_DATA* idata, const char* cmd)
 {
   char* out;
   int outlen;
+  int rc = 0;
+
+  if (idata->status == IMAP_FATAL)
+  {
+    cmd_handle_fatal (idata);
+    return IMAP_CMD_FAIL;
+  }
 
   cmd_make_sequence (idata->seq, sizeof (idata->seq));
   /* seq, space, cmd, \r\n\0 */
@@ -57,20 +76,28 @@ void imap_cmd_start (IMAP_DATA* idata, const char* cmd)
   out = (char*) safe_malloc (outlen);
   snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
 
-  mutt_socket_write (idata->conn, out);
+  rc = mutt_socket_write (idata->conn, out);
 
-  safe_free ((void**) &out);
+  FREE (&out);
+
+  return (rc < 0) ? IMAP_CMD_FAIL : 0;
 }
 
-/* imap_cmd_resp: Reads server responses from an IMAP command, detects
+/* imap_cmd_step: Reads server responses from an IMAP command, detects
  *   tagged completion response, handles untagged messages, can read
  *   arbitrarily large strings (using malloc, so don't make it _too_
  *   large!). */
-int imap_cmd_resp (IMAP_DATA* idata)
+int imap_cmd_step (IMAP_DATA* idata)
 {
   unsigned int len = 0;
   int c;
 
+  if (idata->status == IMAP_FATAL)
+  {
+    cmd_handle_fatal (idata);
+    return IMAP_CMD_FAIL;
+  }
+
   /* read into buffer, expanding buffer as necessary until we have a full
    * line */
   do
@@ -79,15 +106,14 @@ int imap_cmd_resp (IMAP_DATA* idata)
     {
       safe_realloc ((void**) &idata->buf, idata->blen + IMAP_CMD_BUFSIZE);
       idata->blen = idata->blen + IMAP_CMD_BUFSIZE;
-      dprint (3, (debugfile, "imap_cmd_resp: grew buffer to %u bytes\n", idata->blen));
+      dprint (3, (debugfile, "imap_cmd_step: grew buffer to %u bytes\n", idata->blen));
     }
 
     if ((c = mutt_socket_readln (idata->buf + len, idata->blen - len,
       idata->conn)) < 0)
     {
-      dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response, closing connection.\n"));
+      dprint (1, (debugfile, "imap_cmd_step: Error while reading server response, closing connection.\n"));
       mutt_socket_close (idata->conn);
-      idata->state = IMAP_DISCONNECTED;
       idata->status = IMAP_FATAL;
       return IMAP_CMD_FAIL;
     }
@@ -104,12 +130,12 @@ int imap_cmd_resp (IMAP_DATA* idata)
   {
     safe_realloc ((void**) &idata->buf, IMAP_CMD_BUFSIZE);
     idata->blen = IMAP_CMD_BUFSIZE;
-    dprint (3, (debugfile, "imap_cmd_resp: shrank buffer to %u bytes\n", idata->blen));
+    dprint (3, (debugfile, "imap_cmd_step: shrank buffer to %u bytes\n", idata->blen));
   }
   
   /* handle untagged messages. The caller still gets its shot afterwards. */
   if (!strncmp (idata->buf, "* ", 2) &&
-      imap_handle_untagged (idata, idata->buf))
+      cmd_handle_untagged (idata))
     return IMAP_CMD_FAIL;
 
   /* server demands a continuation response from us */
@@ -119,59 +145,13 @@ int imap_cmd_resp (IMAP_DATA* idata)
   /* tagged completion code */
   if (!mutt_strncmp (idata->buf, idata->seq, SEQLEN))
   {
-    imap_cmd_finish (idata);
+    cmd_finish (idata);
     return IMAP_CMD_DONE;
   }
 
   return IMAP_CMD_CONTINUE;
 }
 
-/* imap_cmd_finish: When the caller has finished reading command responses,
- *   it must call this routine to perform cleanup (eg fetch new mail if
- *   detected, do expunge) */
-void imap_cmd_finish (IMAP_DATA* idata)
-{
-  if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
-  {
-    idata->status = 0;
-    mutt_clear_error ();
-    return;
-  }
-  
-  if ((idata->status == IMAP_NEW_MAIL || 
-       (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
-      && (idata->reopen & IMAP_REOPEN_ALLOW))
-  {
-    int count = idata->newMailCount;
-
-    if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
-       ((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING))  
-       && count > idata->ctx->msgcount)
-    {
-      /* read new mail messages */
-      dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n"));
-
-      count = imap_read_headers (idata->ctx, idata->ctx->msgcount, count-1)+1;
-      idata->check_status = IMAP_NEW_MAIL;
-      idata->reopen &= ~IMAP_NEWMAIL_PENDING;
-    }
-    else
-    {
-      imap_expunge_mailbox (idata);
-      idata->check_status = IMAP_REOPENED;
-      idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
-    }
-
-  }
-  else if (!(idata->reopen & IMAP_REOPEN_ALLOW))
-  {
-    if (idata->status == IMAP_NEW_MAIL)
-      idata->reopen |= IMAP_NEWMAIL_PENDING;
-  }
-
-  idata->status = 0;
-}
-
 /* imap_code: returns 1 if the command result was OK, or 0 if NO or BAD */
 int imap_code (const char *s)
 {
@@ -194,6 +174,12 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
   int outlen;
   int rc;
 
+  if (idata->status == IMAP_FATAL)
+  {
+    cmd_handle_fatal (idata);
+    return -1;
+  }
+
   /* create sequence for command */
   cmd_make_sequence (idata->seq, sizeof (idata->seq));
   /* seq, space, cmd, \r\n\0 */
@@ -201,13 +187,15 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
   out = (char*) safe_malloc (outlen);
   snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
 
-  mutt_socket_write_d (idata->conn, out,
+  rc = mutt_socket_write_d (idata->conn, out,
     flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD);
-
   safe_free ((void**) &out);
 
+  if (rc < 0)
+    return -1;
+
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_DONE)
@@ -232,13 +220,62 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
   return 0;
 }
 
-/* imap_handle_untagged: fallback parser for otherwise unhandled messages. */
-int imap_handle_untagged (IMAP_DATA* idata, char* s)
+/* cmd_finish: When the caller has finished reading command responses,
+ *   it must call this routine to perform cleanup (eg fetch new mail if
+ *   detected, do expunge). Called automatically by imap_cmd_step */
+static void cmd_finish (IMAP_DATA* idata)
 {
-  char *pn;
+  if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
+  {
+    mutt_clear_error ();
+    return;
+  }
+  
+  if ((idata->reopen & IMAP_REOPEN_ALLOW) &&
+      (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
+  {
+    int count = idata->newMailCount;
+
+    if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
+       (idata->reopen & IMAP_NEWMAIL_PENDING)
+       && count > idata->ctx->msgcount)
+    {
+      /* read new mail messages */
+      dprint (2, (debugfile, "cmd_finish: Fetching new mail\n"));
+      count = imap_read_headers (idata, idata->ctx->msgcount, count-1)+1;
+      /* check_status: curs_main uses imap_check_mailbox to detect
+       *   whether the index needs updating */
+      idata->check_status = IMAP_NEWMAIL_PENDING;
+      idata->reopen &= ~IMAP_NEWMAIL_PENDING;
+    }
+    else
+    {
+      dprint (2, (debugfile, "cmd_finish: Expunging mailbox\n"));
+      imap_expunge_mailbox (idata);
+      idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
+    }
+  }
+
+  idata->status = 0;
+}
+
+/* cmd_handle_fatal: when IMAP_DATA is in fatal state, do what we can */
+static void cmd_handle_fatal (IMAP_DATA* idata)
+{
+  if ((idata->state == IMAP_SELECTED) &&
+      (idata->reopen & IMAP_REOPEN_ALLOW) &&
+      !idata->ctx->closing)
+    mx_fastclose_mailbox (idata->ctx);
+}
+
+/* cmd_handle_untagged: fallback parser for otherwise unhandled messages. */
+static int cmd_handle_untagged (IMAP_DATA* idata)
+{
+  char* s;
+  char* pn;
   int count;
 
-  s = imap_next_word (s);
+  s = imap_next_word (idata->buf);
 
   if ((idata->state == IMAP_SELECTED) && isdigit (*s))
   {
@@ -263,22 +300,21 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
         */
        mutt_error _("Fatal error.  Message count is out of sync!");
        idata->status = IMAP_FATAL;
-       mx_fastclose_mailbox (idata->ctx);
        return -1;
       }
       /* at least the InterChange server sends EXISTS messages freely,
        * even when there is no new mail */
       else if (count == idata->ctx->msgcount)
        dprint (3, (debugfile,
-          "imap_handle_untagged: superfluous EXISTS message.\n"));
+          "cmd_handle_untagged: superfluous EXISTS message.\n"));
       else
       {
        if (!(idata->reopen & IMAP_EXPUNGE_PENDING))
         {
           dprint (2, (debugfile,
-            "imap_handle_untagged: New mail in %s - %d messages total.\n",
+            "cmd_handle_untagged: New mail in %s - %d messages total.\n",
             idata->mailbox, count));
-         idata->status = IMAP_NEW_MAIL;
+         idata->reopen |= IMAP_NEWMAIL_PENDING;
         }
        idata->newMailCount = count;
       }
index 86ec6511364283f0e701bfb15604f960e997dea4..c122df693329c9d34ca26b3fb37073d0ae74b72f 100644 (file)
@@ -231,210 +231,6 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
   mutt_sort_headers (idata->ctx, 1);
 }
 
-#if 0
-/* imap_reopen_mailbox: Reopen an imap mailbox.  This is used when the
- * server sends an EXPUNGE message, indicating that some messages may have
- * been deleted. This is a heavy handed approach, as it reparses all of the
- * headers, but it should guarantee correctness.  Later, we might implement
- * something to actually only remove the messages that are marked
- * EXPUNGE.
- */
-int imap_reopen_mailbox (IMAP_DATA* idata)
-{
-  HEADER **old_hdrs;
-  CONTEXT* ctx;
-  int old_msgcount;
-  char buf[LONG_STRING];
-  char bufout[LONG_STRING];
-  char *pc = NULL;
-  int count = 0;
-  int msg_mod = 0;
-  int n;
-  int i, j;
-  int index_hint_set;
-
-  ctx = idata->ctx;
-
-  ctx->quiet = 1;
-
-  if (Sort != SORT_ORDER)
-  {
-    short old_sort;
-
-    old_sort = Sort;
-    Sort = SORT_ORDER;
-    mutt_sort_headers (ctx, 1);
-    Sort = old_sort;
-  }
-
-  old_hdrs = NULL;
-  old_msgcount = 0;
-
-  /* simulate a close */
-  hash_destroy (&ctx->id_hash, NULL);
-  hash_destroy (&ctx->subj_hash, NULL);
-  safe_free ((void **) &ctx->v2r);
-  if (ctx->readonly)
-  {
-    for (i = 0; i < ctx->msgcount; i++)
-      mutt_free_header (&(ctx->hdrs[i])); /* nothing to do! */
-    safe_free ((void **) &ctx->hdrs);
-  }
-  else
-  {
-    /* save the old headers */
-    old_msgcount = ctx->msgcount;
-    old_hdrs = ctx->hdrs;
-    ctx->hdrs = NULL;
-  }
-
-  ctx->hdrmax = 0;      /* force allocation of new headers */
-  ctx->msgcount = 0;
-  ctx->vcount = 0;
-  ctx->tagged = 0;
-  ctx->deleted = 0;
-  ctx->new = 0;
-  ctx->unread = 0;
-  ctx->flagged = 0;
-  ctx->changed = 0;
-  ctx->id_hash = hash_create (1031);
-  ctx->subj_hash = hash_create (1031);
-
-  mutt_message (_("Reopening mailbox... %s"), CTX_DATA->mailbox);
-  imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->mailbox);
-  snprintf (bufout, sizeof (bufout), "STATUS %s (MESSAGES)", buf);
-
-  imap_cmd_start (CTX_DATA, bufout);
-
-  do
-  {
-    if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0)
-      break;
-
-    if (buf[0] == '*')
-    {
-      pc = buf + 2;
-
-      if (!mutt_strncasecmp ("STATUS", pc, 6) &&
-         (pc = (char *) mutt_stristr (pc, "MESSAGES")))
-      {
-       char* pn;
-       
-       /* skip "MESSAGES" */
-       pc += 8;
-       SKIPWS (pc);
-       pn = pc;
-
-       while (*pc && isdigit (*pc))
-         pc++;
-       *pc++ = 0;
-       n = atoi (pn);
-       count = n;
-      }
-      else if (imap_handle_untagged (CTX_DATA, buf) != 0)
-       return -1;
-    }
-  }
-  while (mutt_strncmp (CTX_DATA->seq, buf, mutt_strlen (CTX_DATA->seq)) != 0);
-
-  if (!imap_code (buf))
-  {
-    char *s;
-    s = imap_next_word (buf); /* skip seq */
-    s = imap_next_word (s); /* Skip response */
-    mutt_error ("%s", s);
-    sleep (1);
-    return -1;
-  }
-
-  ctx->hdrmax = count;
-  ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
-  ctx->v2r = safe_malloc (count * sizeof (int));
-  ctx->msgcount = 0;
-  count = imap_read_headers (ctx, 0, count - 1) + 1;
-
-  index_hint_set = 1;
-
-  if (!ctx->readonly)
-  {
-    for (i = 0; i < ctx->msgcount; i++)
-    {
-      int found = 0;
-
-      /* some messages have been deleted, and new  messages have been
-       * appended at the end; the heuristic is that old messages have then
-       * "advanced" towards the beginning of the folder, so we begin the
-       * search at index "i"
-       */
-      for (j = i; j < old_msgcount; j++)
-      {
-       if (old_hdrs[j] == NULL)
-         continue;
-       if (mbox_strict_cmp_headers (ctx->hdrs[i], old_hdrs[j]))
-       {
-         found = 1;
-         break;
-       }
-      }
-      if (!found)
-      {
-       for (j = 0; j < i && j < old_msgcount; j++)
-       {
-         if (old_hdrs[j] == NULL)
-           continue;
-         if (mbox_strict_cmp_headers (ctx->hdrs[i], old_hdrs[j]))
-         {
-           found = 1;
-           break;
-         }
-       }
-      }
-      if (found)
-      {
-       /* this is best done here */
-/*
-       if (!index_hint_set && *index_hint == j)
-         *index_hint = i;
-*/
-
-       if (old_hdrs[j]->changed)
-       {
-         /* Only update the flags if the old header was changed;
-          * otherwise, the header may have been modified
-          * externally, and we don't want to lose _those_ changes 
-          */
-         
-         mutt_set_flag (ctx, ctx->hdrs[i], M_FLAG, old_hdrs[j]->flagged);
-         mutt_set_flag (ctx, ctx->hdrs[i], M_REPLIED, old_hdrs[j]->replied);
-         mutt_set_flag (ctx, ctx->hdrs[i], M_OLD, old_hdrs[j]->old);
-         mutt_set_flag (ctx, ctx->hdrs[i], M_READ, old_hdrs[j]->read);
-       }
-       mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, old_hdrs[j]->deleted);
-       mutt_set_flag (ctx, ctx->hdrs[i], M_TAG, old_hdrs[j]->tagged);
-
-       /* we don't need this header any more */
-       mutt_free_header (&(old_hdrs[j]));
-      }
-    }
-
-    /* free the remaining old headers */
-    for (j = 0; j < old_msgcount; j++)
-    {
-      if (old_hdrs[j])
-      {
-       mutt_free_header (&(old_hdrs[j]));
-       msg_mod = 1;
-      }
-    }
-    safe_free ((void **) &old_hdrs);
-  }
-
-  ctx->quiet = 0;
-
-  return 0;
-}
-#endif
-
 static int imap_get_delim (IMAP_DATA *idata)
 {
   char *s;
@@ -448,7 +244,7 @@ static int imap_get_delim (IMAP_DATA *idata)
 
   do 
   {
-    if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
     s = imap_next_word (idata->buf);
@@ -572,7 +368,7 @@ int imap_open_connection (IMAP_DATA* idata)
 
   idata->state = IMAP_CONNECTED;
 
-  if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+  if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
     goto bail;
 
   if (mutt_strncmp ("* OK", idata->buf, 4) == 0)
@@ -685,6 +481,9 @@ int imap_open_mailbox (CONTEXT* ctx)
   /* once again the context is new */
   ctx->data = idata;
 
+  if (idata->status == IMAP_FATAL)
+    return -1;
+
   /* Clean up path and replace the one in the ctx */
   imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   FREE(&(idata->mailbox));
@@ -713,7 +512,7 @@ int imap_open_mailbox (CONTEXT* ctx)
   {
     char *pc;
     
-    if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
     pc = idata->buf + 2;
@@ -722,7 +521,7 @@ int imap_open_mailbox (CONTEXT* ctx)
     {
       /* imap_handle_untagged will have picked up the EXISTS message and
        * set the NEW_MAIL flag. We clear it here. */
-      idata->status = 0;
+      idata->reopen &= ~IMAP_NEWMAIL_PENDING;
       count = idata->newMailCount;
       idata->newMailCount = 0;
     }
@@ -821,7 +620,7 @@ int imap_open_mailbox (CONTEXT* ctx)
   ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
   ctx->v2r = safe_malloc (count * sizeof (int));
   ctx->msgcount = 0;
-  count = imap_read_headers (ctx, 0, count - 1) + 1;
+  count = imap_read_headers (idata, 0, count - 1) + 1;
 
   dprint (1, (debugfile, "imap_open_mailbox(): msgcount is %d\n", ctx->msgcount));
   return 0;
@@ -894,7 +693,7 @@ void imap_logout (IMAP_DATA* idata)
    * receive a bye response (so it doesn't freak out and close the conn) */
   idata->status = IMAP_BYE;
   imap_cmd_start (idata, "LOGOUT");
-  while (imap_cmd_resp (idata) == IMAP_CMD_CONTINUE)
+  while (imap_cmd_step (idata) == IMAP_CMD_CONTINUE)
     ;
 }
 
@@ -1167,7 +966,9 @@ void imap_close_mailbox (CONTEXT* ctx)
 
   idata->reopen &= IMAP_REOPEN_ALLOW;
 
-  if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx))
+  if ((idata->status != IMAP_FATAL) &&
+      (idata->state == IMAP_SELECTED) &&
+      (ctx == idata->ctx))
   {
     if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
       imap_error ("CLOSE failed", idata->buf);
@@ -1193,7 +994,7 @@ void imap_close_mailbox (CONTEXT* ctx)
 /* use the NOOP command to poll for new mail
  *
  * return values:
- *     M_REOPENED      mailbox has been reopened
+ *     M_REOPENED      mailbox has been externally modified
  *     M_NEW_MAIL      new mail has arrived!
  *     0               no change
  *     -1              error
@@ -1224,17 +1025,20 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
   {
     if (ImapCheckTimeout) checktime += t;
 
-    idata->check_status = 0;
     if (imap_exec (idata, "NOOP", 0) != 0)
     {
       imap_error ("imap_check_mailbox", idata->buf);
       return -1;
     }
     
-    if (idata->check_status == IMAP_NEW_MAIL)
+    if (idata->check_status & IMAP_NEWMAIL_PENDING)
+    {
+      idata->check_status &= ~IMAP_NEWMAIL_PENDING;
       return M_NEW_MAIL;
-    if (idata->check_status == IMAP_REOPENED)
-      return M_REOPENED;
+    }
+    
+    /* TODO: we should be able to detect external changes and return
+     *   M_REOPENED here. */
   }
   
   return 0;
@@ -1305,7 +1109,7 @@ int imap_mailbox_check (char* path, int new)
 
   do 
   {
-    if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
     s = imap_next_word (idata->buf);
@@ -1352,7 +1156,7 @@ int imap_parse_list_response(IMAP_DATA* idata, char **name, int *noselect,
 
   *name = NULL;
 
-  rc = imap_cmd_resp (idata);
+  rc = imap_cmd_step (idata);
   if (rc == IMAP_CMD_DONE)
     return 0;
   if (rc != IMAP_CMD_CONTINUE)
@@ -1400,7 +1204,7 @@ int imap_parse_list_response(IMAP_DATA* idata, char **name, int *noselect,
     { 
       if (imap_get_literal_count(idata->buf, &bytes) < 0)
        return -1;
-      if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+      if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
        return -1;
       *name = idata->buf;
     }
index 412e9521c5566e299e7c2cbfbeb1ff3ffa3cb7d4..b574ee819d2893ea48d261e747130bf6b7a31a22 100644 (file)
@@ -54,7 +54,6 @@
 enum
 {
   IMAP_FATAL = 1,
-  IMAP_NEW_MAIL,
   IMAP_BYE,
   IMAP_REOPENED
 };
@@ -92,7 +91,7 @@ enum
   RIGHTSMAX
 };
 
-/* Capabilities */
+/* Capabilities we are interested in */
 enum
 {
   IMAP4 = 0,
@@ -101,21 +100,10 @@ enum
   ACL,                         /* RFC 2086: IMAP4 ACL extension */
   NAMESPACE,                           /* RFC 2342: IMAP4 Namespace */
   ACRAM_MD5,                   /* RFC 2195: CRAM-MD5 authentication */
-  AKERBEROS_V4,                        /* AUTH=KERBEROS_V4 */
   AGSSAPI,                     /* RFC 1731: GSSAPI authentication */
-  /* From here down, we don't care */
-  ALOGIN,                      /* AUTH=LOGIN */
-  AUTH_LOGIN,                  /* AUTH-LOGIN */
-  APLAIN,                      /* AUTH=PLAIN */
-  ASKEY,                       /* AUTH=SKEY */
-  IDLE,                                /* RFC 2177: IMAP4 IDLE command */
-  LOGIN_REFERRALS,             /* LOGIN-REFERRALS */
-  MAILBOX_REFERRALS,           /* MAILBOX-REFERRALS */
-  SCAN,
-  SORT,
-  TORDEREDSUBJECT,             /* THREAD=ORDEREDSUBJECT */
-  UIDPLUS,                     /* RFC 2859: IMAP4 UIDPLUS extension */
   AUTH_ANON,                   /* AUTH=ANONYMOUS */
+  STARTTLS,                    /* RFC 2595: STARTTLS */
+  LOGINDISABLED,               /*           LOGINDISABLED */
 
   CAPMAX
 };
@@ -149,7 +137,6 @@ typedef struct
   CONNECTION *conn;
   unsigned char state;
   unsigned char status;
-  unsigned char check_status;
   unsigned char capabilities[(CAPMAX + 7)/8];
   char seq[SEQLEN+1];
   /* command input buffer */
@@ -169,6 +156,7 @@ typedef struct
   char delim;
   CONTEXT *ctx;
   char *mailbox;
+  unsigned short check_status;
   unsigned char reopen;
   unsigned char rights[(RIGHTSMAX + 7)/8];
   unsigned int newMailCount;
@@ -193,24 +181,21 @@ int imap_parse_list_response(IMAP_DATA* idata, char** name, int* noselect,
   int* noinferiors, char* delim);
 int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes);
 void imap_expunge_mailbox (IMAP_DATA* idata);
-int imap_reopen_mailbox (IMAP_DATA* idata);
 void imap_logout (IMAP_DATA* idata);
 
 /* auth.c */
 int imap_authenticate (IMAP_DATA* idata);
 
 /* command.c */
-void imap_cmd_start (IMAP_DATA* idata, const char* cmd);
-int imap_cmd_resp (IMAP_DATA* idata);
-void imap_cmd_finish (IMAP_DATA* idata);
+int imap_cmd_start (IMAP_DATA* idata, const char* cmd);
+int imap_cmd_step (IMAP_DATA* idata);
 int imap_code (const char* s);
 int imap_exec (IMAP_DATA* idata, const char* cmd, int flags);
-int imap_handle_untagged (IMAP_DATA* idata, char* s);
 
 /* message.c */
 void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags);
 void imap_free_header_data (void** data);
-int imap_read_headers (CONTEXT* ctx, int msgbegin, int msgend);
+int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend);
 
 /* util.c */
 int imap_continue (const char* msg, const char* resp);
index 74c4da858f1fc25e1b9b93d46786ec334f1aa450..ad25e9183ffc9305a95a793d74bbac1e63009437 100644 (file)
@@ -43,9 +43,9 @@ static char* msg_parse_flags (IMAP_HEADER* h, char* s);
  * msgno of the last message read. It will return a value other than
  * msgend if mail comes in while downloading headers (in theory).
  */
-int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
+int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
 {
-  IMAP_DATA* idata;
+  CONTEXT* ctx;
   char buf[LONG_STRING];
   char hdrreq[STRING];
   FILE *fp;
@@ -56,8 +56,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
   int fetchlast = 0;
   const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
 
-  idata = (IMAP_DATA*) ctx->data;
-  
+  ctx = idata->ctx;
+
   /* define search string */
   if (mutt_bit_isset (idata->capabilities,IMAP4REV1))
   {
@@ -84,8 +84,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
   unlink (tempfile);
 
   /* make sure context has room to hold the mailbox */
-  while ((msgend) >= ctx->hdrmax)
-    mx_alloc_memory (ctx);
+  while ((msgend) >= idata->ctx->hdrmax)
+    mx_alloc_memory (idata->ctx);
 
   for (msgno = msgbegin; msgno <= msgend ; msgno++)
   {
@@ -123,11 +123,11 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
     {
       mfhrc = 0;
 
-      rc = imap_cmd_resp (idata);
+      rc = imap_cmd_step (idata);
       if (rc != IMAP_CMD_CONTINUE)
        break;
 
-      if ((mfhrc = msg_fetch_header (ctx, &h, idata->buf, fp)) == -1)
+      if ((mfhrc = msg_fetch_header (idata->ctx, &h, idata->buf, fp)) == -1)
        continue;
       else if (mfhrc < 0)
        break;
@@ -175,12 +175,12 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
     /* h.data shouldn't be freed here, it is kept in ctx->headers */
 
     /* in case we get new mail while fetching the headers */
-    if (idata->status == IMAP_NEW_MAIL)
+    if (idata->reopen & IMAP_NEWMAIL_PENDING)
     {
       msgend = idata->newMailCount - 1;
       while ((msgend) >= ctx->hdrmax)
        mx_alloc_memory (ctx);
-      idata->status = 0;
+      idata->status &= ~IMAP_NEWMAIL_PENDING;
     }
   }
 
@@ -247,7 +247,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   imap_cmd_start (idata, buf);
   do
   {
-    if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+    if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
       break;
 
     pc = idata->buf;
@@ -279,7 +279,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
          if (imap_read_literal (msg->fp, idata, bytes) < 0)
            goto bail;
          /* pick up trailing line */
-         if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
+         if ((rc = imap_cmd_step (idata)) != IMAP_CMD_CONTINUE)
            goto bail;
          pc = idata->buf;
 
@@ -423,7 +423,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
   imap_cmd_start (idata, buf);
 
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (rc != IMAP_CMD_RESPOND)
@@ -461,7 +461,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
   fclose (fp);
 
   do
-    rc = imap_cmd_resp (idata);
+    rc = imap_cmd_step (idata);
   while (rc == IMAP_CMD_CONTINUE);
 
   if (!imap_code (idata->buf))
@@ -663,7 +663,7 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp)
    * (eg Domino puts FLAGS here). Nothing wrong with that, either.
    * This all has to go - we should accept literals and nonliterals
    * interchangeably at any time. */
-  if (imap_cmd_resp (idata) != IMAP_CMD_CONTINUE)
+  if (imap_cmd_step (idata) != IMAP_CMD_CONTINUE)
     return -2;
   
   if (msg_parse_fetch (h, idata->buf) == -1)