]> granicus.if.org Git - mutt/commitdiff
More IMAP clean-up from Brendan Cully.
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 18 Jul 2000 14:38:13 +0000 (14:38 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 18 Jul 2000 14:38:13 +0000 (14:38 +0000)
imap/auth.c
imap/auth_gss.c
imap/browse.c
imap/command.c
imap/imap.c
imap/imap_private.h
imap/message.c
imap/socket.c

index 0f6254d2cf4bab8d1863468a7e365da800d6afb3..77f25c0d48966aeb161410e2ac4706338a886c57 100644 (file)
@@ -98,13 +98,11 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
   char ibuf[LONG_STRING], obuf[LONG_STRING];
   unsigned char hmac_response[MD5_DIGEST_LEN];
   int len;
-  char seq[SEQLEN+1];
 
   dprint (2, (debugfile, "Attempting CRAM-MD5 login...\n"));
   mutt_message _("Authenticating (CRAM-MD5)...");
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (obuf, LONG_STRING, "%s AUTHENTICATE CRAM-MD5\r\n", seq);
-  mutt_socket_write (idata->conn, obuf);
+
+  imap_cmd_start (idata, "AUTHENTICATE CRAM-MD5");
 
   /* From RFC 2195:
    * The data encoded in the first ready response contains a presumptively
@@ -112,7 +110,7 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
    * primary host name of the server. The syntax of the unencoded form must
    * correspond to that of an RFC 822 'msg-id' [RFC822] as described in [POP3].
    */
-  if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+  if (mutt_socket_readln (ibuf, sizeof (ibuf), idata->conn) < 0)
   {
     dprint (1, (debugfile, "Error receiving server response.\n"));
 
@@ -184,41 +182,39 @@ static int imap_auth_cram_md5 (IMAP_DATA* idata, const char* user,
 
 static int imap_auth_anon (IMAP_DATA* idata)
 {
-  char ibuf[LONG_STRING], obuf[LONG_STRING];
-  char seq[SEQLEN+1];
+  char buf[LONG_STRING];
 
   dprint (2, (debugfile, "Attempting anonymous login...\n"));
   mutt_message _("Authenticating (anonymous)...");
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (obuf, LONG_STRING, "%s AUTHENTICATE ANONYMOUS\r\n", seq);
-  mutt_socket_write (idata->conn, obuf);
 
-  if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+  imap_cmd_start (idata, "AUTHENTICATE ANONYMOUS");
+
+  if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
   {
     dprint (1, (debugfile, "Error receiving server response.\n"));
 
     return -1;
   }
 
-  if (ibuf[0] != '+')
+  if (buf[0] != '+')
   {
-    dprint (1, (debugfile, "Invalid response from server: %s\n", ibuf));
+    dprint (1, (debugfile, "Invalid response from server.\n"));
 
     return -1;
   }
 
-  strfcpy (ibuf, "ZHVtbXkK\r\n", sizeof (ibuf));       /* base64 ("dummy") */
+  strfcpy (buf, "ZHVtbXkK\r\n", sizeof (buf));         /* base64 ("dummy") */
 
-  mutt_socket_write (idata->conn, ibuf);
+  mutt_socket_write (idata->conn, buf);
 
-  if (mutt_socket_readln (ibuf, LONG_STRING, idata->conn) < 0)
+  if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
   {
     dprint (1, (debugfile, "Error receiving server response.\n"));
 
     return -1;
   }
 
-  if (imap_code (ibuf))
+  if (imap_code (buf))
   {
     dprint (2, (debugfile, "Anonymous login complete.\n"));
 
@@ -226,11 +222,10 @@ static int imap_auth_anon (IMAP_DATA* idata)
   }
 
   dprint (2, (debugfile, "Anonymous login failed.\n"));
+
   return -1;
 }
 
-
-
 /* imap_authenticate: loop until success or user abort. At each loop, all
  *   supported authentication methods are tried, from strongest to weakest.
  *   Currently available:
index d334a0ad35791fe06ddf2f6430c75f7bde8a16c1..effe47dd443ebf5ef2b62ae3be64a1ed5a6977de 100644 (file)
@@ -54,8 +54,6 @@ int imap_auth_gss (IMAP_DATA* idata, const char* user)
   char buf1[GSS_BUFSIZE], buf2[GSS_BUFSIZE], server_conf_flags;
   unsigned long buf_size;
 
-  char seq[16];
-
   dprint (2, (debugfile, "Attempting GSS login...\n"));
 
   /* get an IMAP service ticket for the server */
@@ -81,9 +79,8 @@ int imap_auth_gss (IMAP_DATA* idata, const char* user)
 #endif
   /* now begin login */
   mutt_message _("Authenticating (GSSAPI)...");
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf1, sizeof (buf1), "%s AUTHENTICATE GSSAPI\r\n", seq);
-  mutt_socket_write (idata->conn, buf1);
+
+  imap_cmd_start (idata, "AUTHENTICATE GSSAPI");
 
   /* expect a null continuation response ("+") */
   if (mutt_socket_readln (buf1, sizeof (buf1), idata->conn) < 0)
index a8676b37fbe5263833ec0be184c07be52f775519..f039fb9d86d5fd667453e4c8f117be7062cba834 100644 (file)
 #include "imap_private.h"
 
 /* -- forward declarations -- */
-static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
-  struct browser_state *state, short isparent);
+static int browse_add_list_result (CONNECTION* conn, const char* cmd,
+  struct browser_statestate, short isparent);
 static void imap_add_folder (char delim, char *folder, int noselect,
   int noinferiors, struct browser_state *state, short isparent);
 static int compare_names(struct folder_file *a, struct folder_file *b);
-static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen, 
+static int browse_get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen, 
   IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns);
-static int verify_namespace (CONNECTION *conn, IMAP_NAMESPACE_INFO *nsi, 
-  int nns);
+static int browse_verify_namespace (IMAP_DATA* idata,
+  IMAP_NAMESPACE_INFO* nsi, int nns);
 
 int imap_init_browse (char *path, struct browser_state *state)
 {
@@ -44,7 +44,6 @@ int imap_init_browse (char *path, struct browser_state *state)
   char nsbuf[LONG_STRING];
   char mbox[LONG_STRING];
   char list_cmd[5];
-  char seq[16];
   IMAP_NAMESPACE_INFO nsi[16];
   int home_namespace = 0;
   int n;
@@ -91,10 +90,10 @@ int imap_init_browse (char *path, struct browser_state *state)
     if (mutt_bit_isset(idata->capabilities,NAMESPACE))
     {
       mutt_message _("Getting namespaces...");
-      if (get_namespace (idata, nsbuf, sizeof (nsbuf), 
+      if (browse_get_namespace (idata, nsbuf, sizeof (nsbuf), 
                         nsi, sizeof (nsi),  &nns) != 0)
        return -1;
-      if (verify_namespace (conn, nsi, nns) != 0)
+      if (browse_verify_namespace (idata, nsi, nns) != 0)
        return -1;
     }
     /* What if you have a shared namespace of ""? You'll never be
@@ -135,10 +134,8 @@ int imap_init_browse (char *path, struct browser_state *state)
      * aren't already going to */
     if (mbox[n-1] != idata->delim)
     {
-      imap_make_sequence (seq, sizeof (seq));
-      snprintf (buf, sizeof (buf), "%s %s \"\" \"%s\"\r\n", seq, list_cmd,
-        mbox);
-      mutt_socket_write (conn, buf);
+      snprintf (buf, sizeof (buf), "%s \"\" \"%s\"", list_cmd, mbox);
+      imap_cmd_start (idata, buf);
       do 
       {
         if (imap_parse_list_response(conn, buf, sizeof(buf), &cur_folder,
@@ -157,7 +154,7 @@ int imap_init_browse (char *path, struct browser_state *state)
           }
         }
       }
-      while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+      while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
     }
 
     /* if we're descending a folder, mark it as current in browser_state */
@@ -184,22 +181,13 @@ int imap_init_browse (char *path, struct browser_state *state)
        * had the parent not exist? */
       ctmp = mbox[n];
       mbox[n] = '\0';
-#if 0
-      /* List it to see if it can be selected */
-      dprint (2, (debugfile, "imap_init_browse: listing possible parent %s\n", mbox));
-      imap_make_sequence (seq, sizeof (seq));
-      snprintf (buf, sizeof (buf), "%s %s \"\" \"%s\"\r\n", seq, 
-        list_cmd, mbox);
-      /* add this entry as a superior, if we aren't tab-completing */
-      if (showparents && add_list_result (conn, seq, buf, state, 1))
-          return -1;
-#else
+
       if (showparents)
       {
        dprint (2, (debugfile, "imap_init_browse: adding parent %s\n", mbox));
        imap_add_folder (idata->delim, mbox, 1, 0, state, 1);
       }
-#endif
+
       /* if our target isn't a folder, we are in our superior */
       if (!state->folder)
       {
@@ -241,18 +229,14 @@ int imap_init_browse (char *path, struct browser_state *state)
      * namespace is not "", so we have to list it explicitly. We ask the 
      * server to see if it has descendants. */
     dprint (4, (debugfile, "imap_init_browse: adding INBOX\n"));
-    imap_make_sequence (seq, sizeof (seq));
-    snprintf (buf, sizeof (buf), "%s LIST \"\" \"INBOX\"\r\n", seq);
-    if (add_list_result (conn, seq, buf, state, 0))
+    if (browse_add_list_result (conn, "LIST \"\" \"INBOX\"", state, 0))
       return -1;
   }
 
   nsup = state->entrylen;
 
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%%\"\r\n", seq, 
-    list_cmd, mbox);
-  if (add_list_result (conn, seq, buf, state, 0))
+  snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"", list_cmd, mbox);
+  if (browse_add_list_result (conn, buf, state, 0))
     return -1;
 
   qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]),
@@ -272,10 +256,10 @@ int imap_init_browse (char *path, struct browser_state *state)
   return 0;
 }
 
-static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
-                           struct browser_state *state, short isparent)
+static int browse_add_list_result (CONNECTION* conn, const char* cmd,
+  struct browser_state* state, short isparent)
 {
-  IMAP_DATA *idata = CONN_DATA;
+  IMAP_DATAidata = CONN_DATA;
   char buf[LONG_STRING];
   char *name;
   int noselect;
@@ -285,11 +269,11 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
   if (imap_parse_path (state->folder, &mx))
   {
     dprint (2, (debugfile,
-      "add_list_result: current folder %s makes no sense\n", state->folder));
+      "browse_add_list_result: current folder %s makes no sense\n", state->folder));
     return -1;
   }
 
-  mutt_socket_write (conn, cmd);
+  imap_cmd_start (idata, cmd);
 
   do 
   {
@@ -308,8 +292,9 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
           isparent);
     }
   }
-  while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
-  return (0);
+  while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
+
+  return 0;
 }
 
 /* imap_add_folder: add a folder name to the browser list, formatting it as
@@ -376,11 +361,10 @@ static int compare_names(struct folder_file *a, struct folder_file *b)
   return mutt_strcmp(a->name, b->name);
 }
 
-static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen, 
-                         IMAP_NAMESPACE_INFO *nsi, int nsilen, int *nns)
+static int browse_get_namespace (IMAP_DATA* idata, char* nsbuf, int nsblen,
+  IMAP_NAMESPACE_INFO* nsi, int nsilen, int* nns)
 {
   char buf[LONG_STRING];
-  char seq[16];
   char *s;
   int n;
   char ns[LONG_STRING];
@@ -391,10 +375,8 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
   *nns = 0;
   nsbuf[nsblen-1] = '\0';
 
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf, sizeof (buf), "%s NAMESPACE\r\n", seq);
-
-  mutt_socket_write (idata->conn, buf);
+  imap_cmd_start (idata, "NAMESPACE");
+  
   do 
   {
     if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
@@ -452,7 +434,7 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
              /* skip "" namespaces, they are already listed at the root */
              if ((ns[0] != '\0') && (nsbused < nsblen) && (*nns < nsilen))
              {
-               dprint (4, (debugfile, "get_namespace: adding %s\n", ns));
+               dprint (3, (debugfile, "browse_get_namespace: adding %s\n", ns));
                nsi->type = type;
                /* Cyrus doesn't append the delimiter to the namespace,
                 * but UW-IMAP does. We'll strip it here and add it back
@@ -479,47 +461,47 @@ static int get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen,
       }
     }
   }
-  while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+  while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
+
   return 0;
 }
 
 /* Check which namespaces have contents */
-static int verify_namespace (CONNECTION *conn, IMAP_NAMESPACE_INFO *nsi, 
-  int nns)
+static int browse_verify_namespace (IMAP_DATA* idata,
+  IMAP_NAMESPACE_INFO *nsi, int nns)
 {
   char buf[LONG_STRING];
-  char seq[16];
   int i = 0;
   char *name;
   char delim;
 
   for (i = 0; i < nns; i++, nsi++)
   {
-    imap_make_sequence (seq, sizeof (seq));
     /* Cyrus gives back nothing if the % isn't added. This may return lots
      * of data in some cases, I guess, but I currently feel that's better
      * than invisible namespaces */
     if (nsi->delim)
-      snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%c%%\"\r\n", seq,
+      snprintf (buf, sizeof (buf), "%s \"\" \"%s%c%%\"",
                option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix,
                nsi->delim);
     else
-      snprintf (buf, sizeof (buf), "%s %s \"\" \"%s%%\"\r\n", seq,
+      snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"",
                option (OPTIMAPLSUB) ? "LSUB" : "LIST", nsi->prefix);
-    
-    mutt_socket_write (conn, buf);
+
+    imap_cmd_start (idata, buf);
 
     nsi->listable = 0;
     nsi->home_namespace = 0;
     do 
     {
-      if (imap_parse_list_response(conn, buf, sizeof(buf), &name,
+      if (imap_parse_list_response(idata->conn, buf, sizeof(buf), &name,
           &(nsi->noselect), &(nsi->noinferiors), &delim) != 0)
        return -1;
       nsi->listable |= (name != NULL);
     }
-    while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+    while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
   }
-  return (0);
+
+  return 0;
 }
 
index 722b3973558be7a96dc6bda4bf20455b58dd804d..0a534fe62d2725f71b9c1101f9f7d874e54ce10a 100644 (file)
@@ -29,7 +29,9 @@
 #include <stdlib.h>
 
 /* forward declarations */
+static void cmd_make_sequence (char* buf, size_t buflen);
 static void cmd_parse_capabilities (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", 
@@ -37,10 +39,29 @@ static char *Capabilities[] = {"IMAP4", "IMAP4rev1", "STATUS", "ACL",
   "LOGIN-REFERRALS", "MAILBOX-REFERRALS", "QUOTA", "SCAN", "SORT", 
   "THREAD=ORDEREDSUBJECT", "UIDPLUS", "AUTH=ANONYMOUS", 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)
+{
+  char* out;
+  int outlen;
+
+  cmd_make_sequence (idata->seq, sizeof (idata->seq));
+  /* seq, space, cmd, \r\n\0 */
+  outlen = strlen (idata->seq) + strlen (cmd) + 4;
+  out = (char*) safe_malloc (outlen);
+  snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
+
+  mutt_socket_write (idata->conn, out);
+
+  safe_free ((void**) &out);
+}
+
 /* 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 (const char* seq, IMAP_DATA* idata)
+void imap_cmd_finish (IMAP_DATA* idata)
 {
   if (!(idata->state == IMAP_SELECTED) || idata->selected_ctx->closing)
   {
@@ -63,9 +84,6 @@ void imap_cmd_finish (const char* seq, IMAP_DATA* idata)
       /* read new mail messages */
       dprint (1, (debugfile, "imap_cmd_finish: fetching new mail\n"));
 
-      while (count > idata->selected_ctx->hdrmax)
-       mx_alloc_memory (idata->selected_ctx);
-
       count = imap_read_headers (idata->selected_ctx, 
         idata->selected_ctx->msgcount, count - 1) + 1;
       idata->check_status = IMAP_NEW_MAIL;
@@ -113,14 +131,13 @@ int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
 {
   char* out;
   int outlen;
-  char seq[SEQLEN+1];
 
   /* create sequence for command */
-  imap_make_sequence (seq, sizeof (seq));
+  cmd_make_sequence (idata->seq, sizeof (idata->seq));
   /* seq, space, cmd, \r\n\0 */
-  outlen = strlen (seq) + strlen (cmd) + 4;
+  outlen = strlen (idata->seq) + strlen (cmd) + 4;
   out = (char*) safe_malloc (outlen);
-  snprintf (out, outlen, "%s %s\r\n", seq, cmd);
+  snprintf (out, outlen, "%s %s\r\n", idata->seq, cmd);
 
   mutt_socket_write_d (idata->conn, out,
     flags & IMAP_CMD_PASS ? IMAP_LOG_PASS : IMAP_LOG_CMD);
@@ -135,9 +152,9 @@ int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
     if (buf[0] == '*' && imap_handle_untagged (idata, buf) != 0)
       return -1;
   }
-  while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+  while (mutt_strncmp (buf, idata->seq, SEQLEN) != 0);
 
-  imap_cmd_finish (seq, idata);
+  imap_cmd_finish (idata);
 
   if (!imap_code (buf))
   {
@@ -212,47 +229,9 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
        idata->status = IMAP_EXPUNGE;
   }
   else if (mutt_strncasecmp ("CAPABILITY", s, 10) == 0)
-    /* parse capabilities */
     cmd_parse_capabilities (idata, s);
   else if (mutt_strncasecmp ("MYRIGHTS", s, 8) == 0)
-  {
-    s = imap_next_word (s);
-    s = imap_next_word (s);
-    while (*s && !isspace(*s))
-    {
-      switch (*s) 
-      {
-       case 'l':
-         mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
-         break;
-       case 'r':
-         mutt_bit_set (idata->rights, IMAP_ACL_READ);
-         break;
-       case 's':
-         mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
-         break;
-       case 'w':
-         mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
-         break;
-       case 'i':
-         mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
-         break;
-       case 'p':
-         mutt_bit_set (idata->rights, IMAP_ACL_POST);
-         break;
-       case 'c':
-         mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
-         break;
-       case 'd':
-         mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
-         break;
-       case 'a':
-         mutt_bit_set (idata->rights, IMAP_ACL_ADMIN);
-         break;
-      }
-      s++;
-    }
-  }
+    cmd_parse_myrights (idata, s);
   else if (mutt_strncasecmp ("BYE", s, 3) == 0)
   {
     /* server shut down our connection */
@@ -274,16 +253,14 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
     sleep (1);
   }
   else
-  {
     dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
-               s));
-  }
+      s));
 
   return 0;
 }
 
-/* imap_make_sequence: make a tag suitable for starting an IMAP command */
-void imap_make_sequence (char *buf, size_t buflen)
+/* cmd_make_sequence: make a tag suitable for starting an IMAP command */
+static void cmd_make_sequence (char* buf, size_t buflen)
 {
   static int sequence = 0;
   
@@ -310,3 +287,48 @@ static void cmd_parse_capabilities (IMAP_DATA *idata, char *s)
     s = imap_next_word (s);
   }   
 }
+
+/* cmd_parse_myrights: set rights bits according to MYRIGHTS response */
+static void cmd_parse_myrights (IMAP_DATA* idata, char* s)
+{
+  s = imap_next_word (s);
+  s = imap_next_word (s);
+
+  /* zero out current rights set */
+  memset (idata->rights, 0, sizeof (idata->rights));
+
+  while (*s && !isspace(*s))
+  {
+    switch (*s) 
+    {
+      case 'l':
+       mutt_bit_set (idata->rights, IMAP_ACL_LOOKUP);
+       break;
+      case 'r':
+       mutt_bit_set (idata->rights, IMAP_ACL_READ);
+       break;
+      case 's':
+       mutt_bit_set (idata->rights, IMAP_ACL_SEEN);
+       break;
+      case 'w':
+       mutt_bit_set (idata->rights, IMAP_ACL_WRITE);
+       break;
+      case 'i':
+       mutt_bit_set (idata->rights, IMAP_ACL_INSERT);
+       break;
+      case 'p':
+       mutt_bit_set (idata->rights, IMAP_ACL_POST);
+       break;
+      case 'c':
+       mutt_bit_set (idata->rights, IMAP_ACL_CREATE);
+       break;
+      case 'd':
+       mutt_bit_set (idata->rights, IMAP_ACL_DELETE);
+       break;
+      case 'a':
+       mutt_bit_set (idata->rights, IMAP_ACL_ADMIN);
+       break;
+    }
+    s++;
+  }
+}
index dd73f03171758aaa52c627fc3a47bb26cb170b8d..e446d03bc300d52bf41038ea86b2290200fc26da 100644 (file)
@@ -172,7 +172,6 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
   int old_msgcount;
   char buf[LONG_STRING];
   char bufout[LONG_STRING];
-  char seq[8];
   char *pc = NULL;
   int count = 0;
   int msg_mod = 0;
@@ -227,9 +226,9 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
 
   mutt_message (_("Reopening mailbox... %s"), CTX_DATA->selected_mailbox);
   imap_munge_mbox_name (buf, sizeof (buf), CTX_DATA->selected_mailbox);
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (bufout, sizeof (bufout), "%s STATUS %s (MESSAGES)\r\n", seq, buf);
-  mutt_socket_write (CTX_DATA->conn, bufout);
+  snprintf (bufout, sizeof (bufout), "STATUS %s (MESSAGES)", buf);
+
+  imap_cmd_start (CTX_DATA, bufout);
 
   do
   {
@@ -260,7 +259,7 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
        return -1;
     }
   }
-  while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+  while (mutt_strncmp (CTX_DATA->seq, buf, mutt_strlen (CTX_DATA->seq)) != 0);
 
   if (!imap_code (buf))
   {
@@ -360,17 +359,13 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint)
 static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn)
 {
   char buf[LONG_STRING];
-  char seq[8];
   char *s;
 
   /* assume that the delim is /.  If this fails, we're in bigger trouble
    * than getting the delim wrong */
   idata->delim = '/';
 
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf, sizeof (buf), "%s LIST \"\" \"\"\r\n", seq);
-
-  mutt_socket_write (conn, buf);
+  imap_cmd_start (idata, "LIST \"\" \"\"");
 
   do 
   {
@@ -399,7 +394,7 @@ static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn)
       }
     }
   }
-  while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+  while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
   return 0;
 }
 
@@ -551,7 +546,6 @@ int imap_open_mailbox (CONTEXT *ctx)
   IMAP_DATA *idata;
   char buf[LONG_STRING];
   char bufout[LONG_STRING];
-  char seq[SEQLEN+1];
   int count = 0;
   int n;
   IMAP_MBOX mx;
@@ -600,10 +594,10 @@ int imap_open_mailbox (CONTEXT *ctx)
 
   mutt_message (_("Selecting %s..."), idata->selected_mailbox);
   imap_munge_mbox_name (buf, sizeof(buf), idata->selected_mailbox);
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (bufout, sizeof (bufout), "%s %s %s\r\n", seq,
+  snprintf (bufout, sizeof (bufout), "%s %s",
     ctx->readonly ? "EXAMINE" : "SELECT", buf);
-  mutt_socket_write (conn, bufout);
+
+  imap_cmd_start (idata, bufout);
 
   idata->state = IMAP_SELECTED;
 
@@ -658,7 +652,7 @@ int imap_open_mailbox (CONTEXT *ctx)
        return (-1);
     }
   }
-  while (mutt_strncmp (seq, buf, mutt_strlen (seq)) != 0);
+  while (mutt_strncmp (idata->seq, buf, mutt_strlen (idata->seq)) != 0);
   /* check for READ-ONLY notification */
   if (!strncmp (imap_get_qualifier (buf), "[READ-ONLY]", 11))
   {
@@ -836,20 +830,18 @@ int imap_open_mailbox_append (CONTEXT *ctx)
   return 0;
 }
 
-void imap_logout (CONNECTION *conn)
+void imap_logout (IMAP_DATA* idata)
 {
   char buf[LONG_STRING];
-  char seq[8];
 
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf, sizeof (buf), "%s LOGOUT\r\n", seq);
-  mutt_socket_write (conn, buf);
+  imap_cmd_start (idata, "LOGOUT");
+
   do
   {
-    if (mutt_socket_readln (buf, sizeof (buf), conn) < 0)
+    if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0)
       break;
   }
-  while (mutt_strncmp (seq, buf, SEQLEN) != 0);
+  while (mutt_strncmp (idata->seq, buf, SEQLEN) != 0);
 }
 
 int imap_close_connection (CONTEXT *ctx)
@@ -859,7 +851,7 @@ int imap_close_connection (CONTEXT *ctx)
   if (CTX_DATA->status != IMAP_BYE)
   {
     mutt_message _("Closing connection to IMAP server...");
-    imap_logout (CTX_DATA->conn);
+    imap_logout (CTX_DATA);
     mutt_clear_error ();
   }
   mutt_socket_close (CTX_DATA->conn);
@@ -1209,7 +1201,6 @@ int imap_mailbox_check (char *path, int new)
   char buf[LONG_STRING];
   char mbox[LONG_STRING];
   char mbox_unquoted[LONG_STRING];
-  char seq[8];
   char *s;
   int msgcount = 0;
   IMAP_MBOX mx;
@@ -1242,7 +1233,6 @@ int imap_mailbox_check (char *path, int new)
   if (strlen (buf) < strlen (mx.mbox))
       strcpy (mx.mbox, buf);
 
-  imap_make_sequence (seq, sizeof (seq));              
   imap_munge_mbox_name (mbox, sizeof(mbox), buf);
   strfcpy (mbox_unquoted, buf, sizeof (mbox_unquoted));
 
@@ -1254,12 +1244,12 @@ int imap_mailbox_check (char *path, int new)
       || (mutt_strcasecmp (mbox_unquoted, "INBOX") == 0
          && mutt_strcasecmp (mbox_unquoted, idata->selected_mailbox) == 0))
   {
-    snprintf (buf, sizeof (buf), "%s NOOP\r\n", seq);
+    strfcpy (buf, "NOOP", sizeof (buf));
   }
   else if (mutt_bit_isset(idata->capabilities,IMAP4REV1) ||
           mutt_bit_isset(idata->capabilities,STATUS))
   {                            
-    snprintf (buf, sizeof (buf), "%s STATUS %s (%s)\r\n", seq, mbox,
+    snprintf (buf, sizeof (buf), "STATUS %s (%s)", mbox,
       new ? "RECENT" : "MESSAGES");
   }
   else
@@ -1269,7 +1259,7 @@ int imap_mailbox_check (char *path, int new)
       return -1;
   }
 
-  mutt_socket_write (conn, buf);
+  imap_cmd_start (idata, buf);
 
   do 
   {
@@ -1304,9 +1294,9 @@ int imap_mailbox_check (char *path, int new)
       }
     }
   }
-  while ((mutt_strncmp (buf, seq, SEQLEN) != 0));
+  while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0));
 
-  imap_cmd_finish (seq, idata);
+  imap_cmd_finish (idata);
 
   return msgcount;
 }
@@ -1436,7 +1426,6 @@ int imap_complete(char* dest, size_t dlen, char* path) {
   IMAP_DATA* idata;
   char list[LONG_STRING];
   char buf[LONG_STRING];
-  char seq[16];
   char* list_word = NULL;
   int noselect, noinferiors;
   char delim;
@@ -1472,10 +1461,10 @@ int imap_complete(char* dest, size_t dlen, char* path) {
     list[0] = '\0';
 
   /* fire off command */
-  imap_make_sequence (seq, sizeof(seq));
-  snprintf (buf, sizeof(buf), "%s %s \"\" \"%s%%\"\r\n", seq, 
+  snprintf (buf, sizeof(buf), "%s \"\" \"%s%%\"",
     option (OPTIMAPLSUB) ? "LSUB" : "LIST", list);
-  mutt_socket_write (conn, buf);
+
+  imap_cmd_start (idata, buf);
 
   /* and see what the results are */
   strfcpy (completion, mx.mbox, sizeof(completion));
@@ -1517,7 +1506,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
       completions++;
     }
   }
-  while (mutt_strncmp(seq, buf, strlen(seq)));
+  while (mutt_strncmp(idata->seq, buf, SEQLEN));
 
   if (completions)
   {
index 0923966e7d0470a51bbe83f6cc36e7af147cb1f2..ea55e25be15ef873efb7e37786a4eefa7b905447 100644 (file)
@@ -147,11 +147,12 @@ typedef struct
   short status;
   short state;
   short check_status;
-  char delim;
   unsigned char capabilities[(CAPMAX + 7)/8];
+  char seq[SEQLEN+1];
   CONNECTION *conn;
 
   /* The following data is all specific to the currently SELECTED mbox */
+  char delim;
   CONTEXT *selected_ctx;
   char *selected_mailbox;
   unsigned char rights[(RIGHTSMAX + 7)/8];
@@ -177,18 +178,18 @@ int imap_parse_list_response(CONNECTION* conn, char* buf, int buflen,
   char** name, int* noselect, int* noinferiors, char* delim);
 int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes);
 int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint);
-void imap_logout (CONNECTION* conn);
+void imap_logout (IMAP_DATA* conn);
 
 /* auth.c */
 int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn);
 
 /* command.c */
-void imap_cmd_finish (const char* seq, IMAP_DATA* idata);
+void imap_cmd_start (IMAP_DATA* idata, const char* cmd);
+void imap_cmd_finish (IMAP_DATA* idata);
 int imap_code (const char* s);
 int imap_exec (char* buf, size_t buflen, IMAP_DATA* idata, const char* cmd,
   int flags);
 int imap_handle_untagged (IMAP_DATA* idata, char* s);
-void imap_make_sequence (char *buf, size_t buflen);
 
 /* message.c */
 void imap_add_keywords (char* s, HEADER* keywords, LIST* mailbox_flags);
index 6c1b2fca66368d08ad795e79060e9b677774f1a5..72574b4df40f3c8dca897ee29ae90d20ebe334a3 100644 (file)
@@ -50,7 +50,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
   char hdrreq[STRING];
   FILE *fp;
   char tempfile[_POSIX_PATH_MAX];
-  char seq[SEQLEN+1];
   int msgno;
   IMAP_HEADER* h;
   int rc;
@@ -93,7 +92,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
 
     if (msgno + 1 > fetchlast)
     {
-      imap_make_sequence (seq, sizeof (seq));
       /*
        * Make one request for everything. This makes fetching headers an
        * order of magnitude faster if you have a large mailbox.
@@ -101,11 +99,12 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
        * If we get more messages while doing this, we make another
        * request for all the new messages.
        */
-      snprintf (buf, sizeof (buf), 
-       "%s FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)\r\n", 
-       seq, msgno + 1, msgend + 1, hdrreq);
+      snprintf (buf, sizeof (buf),
+        "FETCH %d:%d (UID FLAGS INTERNALDATE RFC822.SIZE %s)", msgno + 1,
+        msgend + 1, hdrreq);
+
+      imap_cmd_start (CTX_DATA, buf);
 
-      mutt_socket_write (CTX_DATA->conn, buf);
       fetchlast = msgend + 1;
     }
 
@@ -165,7 +164,8 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
        safe_free ((void**) &h);
       }
     }
-    while ((msgno + 1) >= fetchlast && mutt_strncmp (seq, buf, SEQLEN) != 0);
+    while ((msgno + 1) >= fetchlast && mutt_strncmp (CTX_DATA->seq, buf,
+      SEQLEN) != 0);
 
     /* in case we get new mail while fetching the headers */
     if (CTX_DATA->status == IMAP_NEW_MAIL)
@@ -184,11 +184,11 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
 
 int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
 {
-  char seq[SEQLEN+1];
   char buf[LONG_STRING];
   char path[_POSIX_PATH_MAX];
   char *pc;
   long bytes;
+  int uid;
   IMAP_CACHE *cache;
 
   /* see if we already have the message in our cache */
@@ -221,19 +221,14 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   cache->path = safe_strdup (path);
   if (!(msg->fp = safe_fopen (path, "w+")))
   {
-    safe_free ((void **) &cache->path);
-    return (-1);
+    safe_free ((void**) &cache->path);
+    return -1;
   }
 
-  imap_make_sequence (seq, sizeof (seq));
-#if 0
-  snprintf (buf, sizeof (buf), "%s FETCH %d RFC822\r\n", seq,
-           ctx->hdrs[msgno]->index + 1);
-#else
-  snprintf (buf, sizeof (buf), "%s UID FETCH %d RFC822\r\n", seq,
-           HEADER_DATA(ctx->hdrs[msgno])->uid);
-#endif
-  mutt_socket_write (CTX_DATA->conn, buf);
+  snprintf (buf, sizeof (buf), "UID FETCH %d RFC822",
+    HEADER_DATA(ctx->hdrs[msgno])->uid);
+
+  imap_cmd_start (CTX_DATA, buf);
   do
   {
     if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0)
@@ -251,8 +246,14 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
          pc = imap_next_word (pc);
          if (pc[0] == '(')
            pc++;
-         dprint (2, (debugfile, "Found FETCH word %s\n", pc));
-         if (strncasecmp ("RFC822", pc, 6) == 0)
+         if (strncasecmp ("UID", pc, 3) == 0)
+         {
+           pc = imap_next_word (pc);
+           uid = atoi (pc);
+           if (uid != HEADER_DATA(ctx->hdrs[msgno])->uid)
+             mutt_error (_("The message index is incorrect. Try reopening the mailbox."));
+         }
+         else if (strncasecmp ("RFC822", pc, 6) == 0)
          {
            pc = imap_next_word (pc);
            if (imap_get_literal_count(pc, &bytes) < 0)
@@ -321,12 +322,11 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
        goto bail;
     }
   }
-  while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+  while (mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0);
 
   if (!imap_code (buf))
     goto bail;
     
-  
   /* Update the header information.  Previously, we only downloaded a
    * portion of the headers, those required for the main display.
    */
@@ -371,7 +371,6 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
   char buf[LONG_STRING];
   char mbox[LONG_STRING];
   char mailbox[LONG_STRING]; 
-  char seq[16];
   size_t len;
   int c, last;
   IMAP_MBOX mx;
@@ -396,13 +395,10 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
   }
   rewind (fp);
   
-  mutt_message _("Sending APPEND command ...");
-
   imap_munge_mbox_name (mbox, sizeof (mbox), mailbox);
-  imap_make_sequence (seq, sizeof (seq));
-  snprintf (buf, sizeof (buf), "%s APPEND %s {%d}\r\n", seq, mbox, len);
+  snprintf (buf, sizeof (buf), "APPEND %s {%d}", mbox, len);
 
-  mutt_socket_write (CTX_DATA->conn, buf);
+  imap_cmd_start (CTX_DATA, buf);
 
   do 
   {
@@ -418,7 +414,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
       return (-1);
     }
   }
-  while ((mutt_strncmp (buf, seq, SEQLEN) != 0) && (buf[0] != '+'));
+  while ((mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0) && (buf[0] != '+'));
 
   if (buf[0] != '+')
   {
@@ -462,7 +458,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
     if (buf[0] == '*' && imap_handle_untagged (CTX_DATA, buf) != 0)
       return (-1);
   }
-  while (mutt_strncmp (buf, seq, SEQLEN) != 0);
+  while (mutt_strncmp (buf, CTX_DATA->seq, SEQLEN) != 0);
 
   if (!imap_code (buf))
   {
index 2d8c93dabbbd068bd484d36eac42c63a5a089f0d..b70fc69863e86667c5dcb10061b9e67e6d114237 100644 (file)
@@ -167,7 +167,7 @@ void imap_logout_all (void)
       mutt_message (_("Closing connection to %s..."),
                    conn->mx.host);
       
-      imap_logout (conn);
+      imap_logout (CONN_DATA);
       
       mutt_clear_error ();
 
@@ -176,11 +176,6 @@ void imap_logout_all (void)
     
     Connections = conn->next;
 
-    if (conn->data) {
-      dprint (2, (debugfile,
-        "imap_logout_all: Connection still has valid CONTEXT?!\n"));
-    }
-
     free (conn);
 
     conn = Connections;