]> granicus.if.org Git - neomutt/commitdiff
Tommi Komulainen's multiple IMAP usernames patch.
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 9 Dec 1999 11:17:04 +0000 (11:17 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 9 Dec 1999 11:17:04 +0000 (11:17 +0000)
14 files changed:
browser.c
doc/manual.sgml.head
imap/README
imap/auth.c
imap/browse.c
imap/imap.c
imap/imap.h
imap/imap_private.h
imap/imap_socket.h
imap/imap_ssl.c
imap/message.c
imap/socket.c
imap/util.c
init.c

index 0973ebaeed925b0a256f20aef1c4d53a3efc2357..0f4f04ce18e6f904c63c1a5bb8a9b2068187052f 100644 (file)
--- a/browser.c
+++ b/browser.c
@@ -808,16 +808,15 @@ void _mutt_select_file (char *f, size_t flen, int buffy,
        else
         {
          char msg[LONG_STRING];
-         char* mbox;
+         IMAP_MBOX mx;
          int nentry = menu->current;
          
-         imap_parse_path (state.entry[nentry].name, NULL, 0, NULL,
-            NULL, &mbox);
+         imap_parse_path (state.entry[nentry].name, &mx);
          snprintf (msg, sizeof (msg), _("Really delete mailbox \"%s\"?"),
-            mbox);
+            mx.mbox);
          if (mutt_yesorno (msg, M_NO) == M_YES)
           {
-           if (!imap_delete_mailbox (Context, mbox))
+           if (!imap_delete_mailbox (Context, mx.mbox))
             {
              /* free the mailbox from the browser */
              safe_free ((void **) &((state.entry)[nentry].name));
index 66278a8b8c188e4dd7a068240fc1d014274b0844..ead39e7ff08e2854d960482add18089dcbac40e4 100644 (file)
@@ -1959,11 +1959,14 @@ server, you should use <tt>{imapserver}path/to/folder</tt> where
 You can select an alternative port by specifying it with the server, ie:
 <tt/{imapserver:port}inbox/.
 
+You can also specify different username for each folder, ie:
+<tt/{username@imapserver[:port]}inbox/.
+
 If Mutt was compiled with SSL support (by running the <em/configure/
 script with the <em/--enable-ssl/ flag), connections to IMAP servers
 can be encrypted. This naturally requires that the server supports
 SSL encrypted connections. To access a folder with IMAP/SSL, you should
-use <tt>{imapserver[:port]/ssl}path/to/folder</tt> as your 
+use <tt>{[username@]imapserver[:port]/ssl}path/to/folder</tt> as your 
 folder path.
 
 Note that not all servers use / as the hierarchy separator.  Mutt should
index b45706ad5a7df297faa538053598871c1f6b6704..d12712bcd5b7e78e1bcb450563a15fb3ec78c4f1 100644 (file)
@@ -26,3 +26,4 @@ New features vs. the stable distribution:
 * Preserve message keywords
 * Preserve deleted messages if you don't choose to expunge them
 * Delete mailboxes (from the browser)
+* Multiple IMAP usernames
index 6f85acc208a94460276ef9387cac8392aa80d75b..73ac9fb090fdd91f9251536f535bddcb44a477d0 100644 (file)
@@ -121,7 +121,7 @@ static int imap_auth_gss (IMAP_DATA* idata, const char* user)
   dprint (2, (debugfile, "Attempting GSS login...\n"));
 
   /* get an IMAP service ticket for the server */
-  snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->server);
+  snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->mx.host);
   request_buf.value = buf1;
   request_buf.length = strlen (buf1) + 1;
   maj_stat = gss_import_name (&min_stat, &request_buf, gss_nt_service_name,
@@ -477,17 +477,22 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn)
 
   while (r != 0)
   {
-    if (!ImapUser)
+    if (! (conn->mx.flags & M_IMAP_USER))
     {
-      strfcpy (user, NONULL(Username), sizeof (user));
-      if (mutt_get_field (_("IMAP Username: "), user, sizeof (user), 0) != 0)
+      if (!ImapUser)
       {
-       user[0] = 0;
-       return (-1);
+       strfcpy (user, NONULL(Username), sizeof (user));
+       if (mutt_get_field (_("IMAP Username: "), user, sizeof (user), 0) != 0)
+       {
+         user[0] = 0;
+         return (-1);
+       }
       }
+      else
+       strfcpy (user, ImapUser, sizeof (user));
     }
     else
-      strfcpy (user, ImapUser, sizeof (user));
+      strfcpy (user, conn->mx.user, sizeof (user));
 
     if (!user[0])
     {
@@ -519,16 +524,21 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn)
     /* attempt CRAM-MD5 if available */
     if (mutt_bit_isset (idata->capabilities, ACRAM_MD5))
     {
-      if (!ImapCRAMKey)
+      if (!(conn->mx.flags & M_IMAP_CRAM))
       {
-        ckey[0] = '\0';
-        snprintf (buf, sizeof (buf), _("CRAM key for %s@%s: "), user,
-          conn->server);
-        if (mutt_get_field (buf, ckey, sizeof (ckey), M_PASS) != 0)
-          return -1;
+       if (!ImapCRAMKey)
+       {
+         ckey[0] = '\0';
+         snprintf (buf, sizeof (buf), _("CRAM key for %s@%s: "), user,
+                   conn->mx.host);
+         if (mutt_get_field (buf, ckey, sizeof (ckey), M_PASS) != 0)
+           return -1;
+       }
+       else
+         strfcpy (ckey, ImapCRAMKey, sizeof (ckey));
       }
       else
-        strfcpy (ckey, ImapCRAMKey, sizeof (ckey));
+        strfcpy (ckey, conn->mx.pass, sizeof (ckey));
 
       if (*ckey)
       {
@@ -536,9 +546,16 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn)
        {
          mutt_error _("CRAM-MD5 authentication failed.");
          sleep (1);
+         if (!(conn->mx.flags & M_IMAP_CRAM))
+           FREE (&ImapCRAMKey);
+         conn->mx.flags &= ~M_IMAP_CRAM;
        }
        else
+       {
+         strfcpy (conn->mx.pass, ckey, sizeof (conn->mx.pass));
+         conn->mx.flags |= M_IMAP_CRAM;
          return 0;
+       }
       }
       else
       {
@@ -549,18 +566,23 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn)
     else
       dprint (2, (debugfile, "CRAM-MD5 authentication is not available\n"));
         
-    if (!ImapPass)
+    if (! (conn->mx.flags & M_IMAP_PASS))
     {
-      pass[0]=0;
-      snprintf (buf, sizeof (buf), _("Password for %s@%s: "), user, conn->server);
-      if (mutt_get_field (buf, pass, sizeof (pass), M_PASS) != 0 ||
-         !pass[0])
+      if (!ImapPass)
       {
-       return (-1);
+       pass[0]=0;
+       snprintf (buf, sizeof (buf), _("Password for %s@%s: "), user, conn->mx.host);
+       if (mutt_get_field (buf, pass, sizeof (pass), M_PASS) != 0 ||
+           !pass[0])
+       {
+         return (-1);
+       }
       }
+      else
+       strfcpy (pass, ImapPass, sizeof (pass));
     }
     else
-      strfcpy (pass, ImapPass, sizeof (pass));
+      strfcpy (pass, conn->mx.pass, sizeof (pass));
 
     imap_quote_string (q_user, sizeof (q_user), user);
     imap_quote_string (q_pass, sizeof (q_pass), pass);
@@ -580,17 +602,22 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn)
       mutt_error _("Login failed.");
       sleep (1);
 
-      FREE (&ImapUser);
-      FREE (&ImapPass);
+      if (!(conn->mx.flags & M_IMAP_USER))
+       FREE (&ImapUser);
+      if (!(conn->mx.flags & M_IMAP_PASS))
+       FREE (&ImapPass);
+      conn->mx.flags &= ~M_IMAP_PASS;
     }
     else
     {
       /* If they have a successful login, we may as well cache the 
        * user/password. */
-      if (!ImapUser)
-       ImapUser = safe_strdup (user);
-      if (!ImapPass)
-       ImapPass = safe_strdup (pass);
+      if (!(conn->mx.flags & M_IMAP_USER))
+       strfcpy (conn->mx.user, user, sizeof (conn->mx.user));
+      if (!(conn->mx.flags & M_IMAP_PASS))
+       strfcpy (conn->mx.pass, pass, sizeof (conn->mx.pass));
+      
+      conn->mx.flags |= (M_IMAP_USER | M_IMAP_PASS);
     }
   }
   return 0;
index 5769ec33e1849e4e8be3462f629ee5848c1ff5f4..adb354f756e34cacf00b54847ed89916852db04e 100644 (file)
@@ -43,11 +43,8 @@ int imap_init_browse (char *path, struct browser_state *state)
   char buf[LONG_STRING];
   char nsbuf[LONG_STRING];
   char mbox[LONG_STRING];
-  char host[SHORT_STRING];
-  int port;
   char list_cmd[5];
   char seq[16];
-  char *ipath = NULL;
   IMAP_NAMESPACE_INFO nsi[16];
   int home_namespace = 0;
   int n;
@@ -59,8 +56,9 @@ int imap_init_browse (char *path, struct browser_state *state)
   short showparents = 0;
   int noselect;
   int noinferiors;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (path, host, sizeof (host), &port, NULL, &ipath))
+  if (imap_parse_path (path, &mx))
   {
     mutt_error ("%s is an invalid IMAP path", path);
     return -1;
@@ -68,7 +66,7 @@ int imap_init_browse (char *path, struct browser_state *state)
 
   strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd));
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -84,11 +82,11 @@ int imap_init_browse (char *path, struct browser_state *state)
       return (-1);
   }
 
-  if (ipath[0] == '\0')
+  if (mx.mbox[0] == '\0')
   {
     home_namespace = 1;
     mbox[0] = 0;               /* Do not replace "" with "INBOX" here */
-    ipath = ImapHomeNamespace;
+    mx.mbox = ImapHomeNamespace;
     nns = 0;
     if (mutt_bit_isset(idata->capabilities,NAMESPACE))
     {
@@ -98,13 +96,13 @@ int imap_init_browse (char *path, struct browser_state *state)
       if (verify_namespace (conn, nsi, nns) != 0)
        return (-1);
     }
-    if (!ipath)                /* Any explicitly set imap_home_namespace wins */
+    if (!mx.mbox)              /* Any explicitly set imap_home_namespace wins */
     { 
       for (i = 0; i < nns; i++)
        if (nsi[i].listable &&
            (nsi[i].type == IMAP_NS_PERSONAL || nsi[i].type == IMAP_NS_SHARED))
        {
-         ipath = nsi->prefix;
+         mx.mbox = nsi->prefix;
          nsi->home_namespace = 1;
          break;
        }
@@ -113,9 +111,9 @@ int imap_init_browse (char *path, struct browser_state *state)
 
   mutt_message _("Contacted server, getting folder list...");
 
-  if (ipath && ipath[0] != '\0')
+  if (mx.mbox && mx.mbox[0] != '\0')
   {
-    imap_fix_path (idata, ipath, mbox, sizeof (mbox));
+    imap_fix_path (idata, mx.mbox, mbox, sizeof (mbox));
     n = mutt_strlen (mbox);
 
     dprint (3, (debugfile, "imap_init_browse: mbox: %s\n", mbox));
@@ -153,7 +151,7 @@ int imap_init_browse (char *path, struct browser_state *state)
     if (mbox[n-1] == idata->delim)
     {
       showparents = 1;
-      imap_qualify_path (buf, sizeof (buf), host, port, mbox, NULL);
+      imap_qualify_path (buf, sizeof (buf), &mx, mbox, NULL);
       state->folder = safe_strdup (buf);
       n--;
     }
@@ -182,7 +180,7 @@ int imap_init_browse (char *path, struct browser_state *state)
         mbox[n++] = ctmp;
         ctmp = mbox[n];
         mbox[n] = '\0';
-        imap_qualify_path (buf, sizeof (buf), host, port, mbox, NULL);
+        imap_qualify_path (buf, sizeof (buf), &mx, mbox, NULL);
         state->folder = safe_strdup (buf);
       }
       mbox[n] = ctmp;
@@ -197,7 +195,7 @@ int imap_init_browse (char *path, struct browser_state *state)
         imap_add_folder (idata->delim, relpath, 1, 0, state, 1); 
       if (!state->folder)
       {
-        imap_qualify_path (buf, sizeof (buf), host, port, relpath, NULL);
+        imap_qualify_path (buf, sizeof (buf), &mx, relpath, NULL);
         state->folder = safe_strdup (buf);
       }
     }
@@ -206,7 +204,7 @@ int imap_init_browse (char *path, struct browser_state *state)
   /* no namespace, no folder: set folder to host only */
   if (!state->folder)
   {
-    imap_qualify_path (buf, sizeof (buf), host, port, NULL, NULL);
+    imap_qualify_path (buf, sizeof (buf), &mx, NULL, NULL);
     state->folder = safe_strdup (buf);
   }
 
@@ -248,14 +246,12 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
 {
   IMAP_DATA *idata = CONN_DATA;
   char buf[LONG_STRING];
-  char host[SHORT_STRING];
-  int port;
-  char *curfolder;
   char *name;
   int noselect;
   int noinferiors;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (state->folder, host, sizeof (host), &port, NULL, &curfolder))
+  if (imap_parse_path (state->folder, &mx))
   {
     dprint (2, (debugfile,
       "add_list_result: current folder %s makes no sense\n", state->folder));
@@ -277,7 +273,7 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
       if (isparent)
         noselect = 1;
       /* prune current folder from output */
-      if (isparent || strncmp (name, curfolder, strlen (name)))
+      if (isparent || strncmp (name, mx.mbox, strlen (name)))
         imap_add_folder (idata->delim, name, noselect, noinferiors, state,
           isparent);
     }
@@ -294,12 +290,10 @@ static void imap_add_folder (char delim, char *folder, int noselect,
 {
   char tmp[LONG_STRING];
   char relpath[LONG_STRING];
-  char host[SHORT_STRING];
-  int port;
-  char *curfolder;
   int flen = strlen (folder);
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (state->folder, host, sizeof (host), &port, NULL, &curfolder))
+  if (imap_parse_path (state->folder, &mx))
     return;
 
   imap_unquote_string (folder);
@@ -320,8 +314,8 @@ static void imap_add_folder (char delim, char *folder, int noselect,
   if (isparent)
     strfcpy (relpath, "../", sizeof (relpath));
   /* strip current folder from target, to render a relative path */
-  else if (!strncmp (curfolder, folder, strlen (curfolder)))
-    strfcpy (relpath, folder + strlen (curfolder), sizeof (relpath));
+  else if (!strncmp (mx.mbox, folder, strlen (mx.mbox)))
+    strfcpy (relpath, folder + strlen (mx.mbox), sizeof (relpath));
   else
     strfcpy (relpath, folder, sizeof (relpath));
 
@@ -333,7 +327,7 @@ static void imap_add_folder (char delim, char *folder, int noselect,
 
   if (!noselect)
   {
-    imap_qualify_path (tmp, sizeof (tmp), host, port, folder, NULL);
+    imap_qualify_path (tmp, sizeof (tmp), &mx, folder, NULL);
     (state->entry)[state->entrylen].name = safe_strdup (tmp);
 
     (state->entry)[state->entrylen].desc = safe_strdup (relpath);
@@ -349,7 +343,7 @@ static void imap_add_folder (char delim, char *folder, int noselect,
     trailing_delim[1] = '\0';
     trailing_delim[0] = (flen && folder[flen - 1] != delim) ? delim : '\0';
 
-    imap_qualify_path (tmp, sizeof (tmp), host, port, folder, trailing_delim);
+    imap_qualify_path (tmp, sizeof (tmp), &mx, folder, trailing_delim);
     (state->entry)[state->entrylen].name = safe_strdup (tmp);
 
     if (!isparent && (strlen (relpath) < sizeof (relpath) - 2))
index 959d32f0004fdc4d4f9b3f663d485ec408af3ca7..6830fbee32e06815169dd18354731100d87dd288 100644 (file)
@@ -537,21 +537,18 @@ int imap_open_mailbox (CONTEXT *ctx)
   IMAP_DATA *idata;
   char buf[LONG_STRING];
   char bufout[LONG_STRING];
-  char host[SHORT_STRING];
   char seq[16];
-  char *pc = NULL;
   int count = 0;
   int n;
-  int port;
-  int socktype;
-
-  if (imap_parse_path (ctx->path, host, sizeof (host), &port, &socktype, &pc))
+  IMAP_MBOX mx;
+  
+  if (imap_parse_path (ctx->path, &mx))
   {
     mutt_error ("%s is an invalid IMAP path", ctx->path);
     return -1;
   }
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state != IMAP_AUTHENTICATED))
@@ -562,7 +559,7 @@ int imap_open_mailbox (CONTEXT *ctx)
       /* We need to create a new connection, the current one isn't useful */
       idata = safe_calloc (1, sizeof (IMAP_DATA));
 
-      conn = mutt_socket_select_connection (host, port, socktype);
+      conn = mutt_socket_select_connection (&mx, 1);
       conn->data = idata;
       idata->conn = conn;
     }
@@ -572,10 +569,10 @@ int imap_open_mailbox (CONTEXT *ctx)
   ctx->data = (void *) idata;
 
   /* Clean up path and replace the one in the ctx */
-  imap_fix_path (idata, pc, buf, sizeof (buf));
+  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   FREE(&(idata->selected_mailbox));
   idata->selected_mailbox = safe_strdup (buf);
-  imap_qualify_path (buf, sizeof (buf), host, port, idata->selected_mailbox,
+  imap_qualify_path (buf, sizeof (buf), &mx, idata->selected_mailbox,
     NULL);
 
   FREE (&(ctx->path));
@@ -597,6 +594,8 @@ int imap_open_mailbox (CONTEXT *ctx)
 
   do
   {
+    char *pc;
+    
     if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
       break;
 
@@ -712,18 +711,16 @@ int imap_select_mailbox (CONTEXT* ctx, const char* path)
 {
   IMAP_DATA* idata;
   CONNECTION* conn;
-  char host[SHORT_STRING];
-  int port;
   char curpath[LONG_STRING];
-  char* mbox = NULL;
+  IMAP_MBOX mx;
 
   strfcpy (curpath, path, sizeof (curpath));
   /* check that the target folder makes sense */
-  if (imap_parse_path (curpath, host, sizeof (host), &port, NULL, &mbox))
+  if (imap_parse_path (curpath, &mx))
     return -1;
 
   /* and that it's on the same server as the current folder */
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   if (!CTX_DATA || !CONN_DATA || (CTX_DATA->conn != CONN_DATA->conn))
   {
     dprint(2, (debugfile,
@@ -747,20 +744,17 @@ int imap_open_mailbox_append (CONTEXT *ctx)
 {
   CONNECTION *conn;
   IMAP_DATA *idata;
-  char host[SHORT_STRING];
   char buf[LONG_STRING], mbox[LONG_STRING];
   char mailbox[LONG_STRING];
-  char *pc;
   int r;
-  int port;
-  int socktype;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (ctx->path, host, sizeof (host), &port, &socktype, &pc))
+  if (imap_parse_path (ctx->path, &mx))
     return (-1);
 
   ctx->magic = M_IMAP;
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -779,7 +773,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
 
   /* check mailbox existance */
 
-  imap_fix_path (idata, pc, mailbox, sizeof (mailbox));
+  imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox));
 
   imap_quote_string (mbox, sizeof (mbox), mailbox);
                                
@@ -1167,20 +1161,18 @@ int imap_mailbox_check (char *path, int new)
 {
   CONNECTION *conn;
   IMAP_DATA *idata;
-  char host[SHORT_STRING];
   char buf[LONG_STRING];
   char mbox[LONG_STRING];
   char mbox_unquoted[LONG_STRING];
   char seq[8];
   char *s;
-  char *pc;
   int msgcount = 0;
-  int port;
-
-  if (imap_parse_path (path, host, sizeof (host), &port, NULL, &pc))
+  IMAP_MBOX mx;
+  
+  if (imap_parse_path (path, &mx))
     return -1;
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1200,10 +1192,10 @@ int imap_mailbox_check (char *path, int new)
       return -1;
   }
 
-  imap_fix_path (idata, pc, buf, sizeof (buf));
+  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   /* Update the path, if it fits */
-  if (strlen (buf) < strlen (pc))
-      strcpy (pc, buf);
+  if (strlen (buf) < strlen (mx.mbox))
+      strcpy (mx.mbox, buf);
 
   imap_make_sequence (seq, sizeof (seq));              
   imap_quote_string (mbox, sizeof(mbox), buf);
@@ -1358,14 +1350,12 @@ int imap_subscribe (char *path, int subscribe)
   IMAP_DATA *idata;
   char buf[LONG_STRING];
   char mbox[LONG_STRING];
-  char host[SHORT_STRING];
-  char *ipath = NULL;
-  int port;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (path, host, sizeof (host), &port, NULL, &ipath))
+  if (imap_parse_path (path, &mx))
     return (-1);
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1381,7 +1371,7 @@ int imap_subscribe (char *path, int subscribe)
       return -1;
   }
 
-  imap_fix_path (idata, ipath, buf, sizeof (buf));
+  imap_fix_path (idata, mx.mbox, buf, sizeof (buf));
   if (subscribe)
     mutt_message (_("Subscribing to %s..."), buf);
   else
@@ -1402,12 +1392,9 @@ int imap_subscribe (char *path, int subscribe)
 int imap_complete(char* dest, size_t dlen, char* path) {
   CONNECTION* conn;
   IMAP_DATA* idata;
-  char host[SHORT_STRING];
-  int port;
   char list[LONG_STRING];
   char buf[LONG_STRING];
   char seq[16];
-  char* mbox = NULL;
   char* list_word = NULL;
   int noselect, noinferiors;
   char delim;
@@ -1415,15 +1402,16 @@ int imap_complete(char* dest, size_t dlen, char* path) {
   int clen, matchlen = 0;
   int completions = 0;
   int pos = 0;
+  IMAP_MBOX mx;
 
   /* verify passed in path is an IMAP path */
-  if (imap_parse_path (path, host, sizeof(host), &port, NULL, &mbox))
+  if (imap_parse_path (path, &mx))
   {
     dprint(2, (debugfile, "imap_complete: bad path %s\n", path));
     return -1;
   }
 
-  conn = mutt_socket_select_connection (host, port, 0);
+  conn = mutt_socket_select_connection (&mx, 0);
   idata = CONN_DATA;
 
   /* don't open a new socket just for completion */
@@ -1436,8 +1424,8 @@ int imap_complete(char* dest, size_t dlen, char* path) {
 
   /* reformat path for IMAP list, and append wildcard */
   /* don't use INBOX in place of "" */
-  if (mbox[0])
-    imap_fix_path (idata, mbox, list, sizeof(list));
+  if (mx.mbox[0])
+    imap_fix_path (idata, mx.mbox, list, sizeof(list));
   else
     list[0] = '\0';
 
@@ -1448,7 +1436,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
   mutt_socket_write (conn, buf);
 
   /* and see what the results are */
-  strfcpy (completion, mbox, sizeof(completion));
+  strfcpy (completion, mx.mbox, sizeof(completion));
   do
   {
     if (imap_parse_list_response(conn, buf, sizeof(buf), &list_word,
@@ -1492,7 +1480,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
   if (completions)
   {
     /* reformat output */
-    imap_qualify_path (dest, dlen, host, port, completion, NULL);
+    imap_qualify_path (dest, dlen, &mx, completion, NULL);
     mutt_pretty_mailbox (dest);
 
     return 0;
index 6f86a1ebc7fcd73ea0178688c50dd9cb51c91248..a88479f222eec3c3bdd88d82fe346e1ee58fcf63 100644 (file)
 #include "browser.h"
 #include "mailbox.h"
 
+typedef struct
+{
+  char user[32];
+  char pass[32];
+  char host[128];
+  int port;
+  char type[16];
+  int socktype;
+  char *mbox;
+  int flags;
+} IMAP_MBOX;
+
+
 /* imap.c */
 int imap_check_mailbox (CONTEXT *ctx, int *index_hint);
 int imap_create_mailbox (CONTEXT* idata, char* mailbox);
@@ -47,9 +60,8 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete);
 int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno);
 
 /* util.c */
-int imap_parse_path (char* path, char* host, size_t hlen, int* port,
-  int *socktype, char** mbox);
-void imap_qualify_path (char* dest, size_t len, const char* host, int port,
+int imap_parse_path (const char* path, IMAP_MBOX *mx);
+void imap_qualify_path (char* dest, size_t len, const IMAP_MBOX *mx,
   const char* path, const char* name);
 
 int imap_wait_keepalive (pid_t pid);
index b61e9d08d814ce944b78a814418551575a4faf40..a116a0b04c3c17ec2b6c28f2b37b527317d1d1cc 100644 (file)
 
 #define SEQLEN 5
 
+#define M_IMAP_USER (1<<0)
+#define M_IMAP_PORT (1<<1)
+#define M_IMAP_TYPE (1<<2)
+#define M_IMAP_PASS (1<<3)
+#define M_IMAP_CRAM (1<<4)
+
 enum
 {
   IMAP_FATAL = 1,
index 3fd9d24ebb6cd498bddea340139caab715d7c3b6..ad112b40670e500a4427aab7a81f217f1ca0e6b6 100644 (file)
@@ -22,9 +22,8 @@
 
 typedef struct _connection
 {
-  char *server;
+  IMAP_MBOX mx;
   char *preconnect; /* Actually specific to server, not connection */
-  int port;
   int uses;
   int fd;
   char inbuf[LONG_STRING];
@@ -45,7 +44,7 @@ int mutt_socket_readchar (CONNECTION *conn, char *c);
 int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn);
 int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn);
 int mutt_socket_write (CONNECTION *conn, const char *buf);
-CONNECTION *mutt_socket_select_connection (char *host, int port, int flags);
+CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn);
 int mutt_socket_open_connection (CONNECTION *conn);
 int mutt_socket_close_connection (CONNECTION *conn);
 
index 09c354735242dea86f4df6d7210f4e0e1173a7fc..b4e6db272d24668f00b06b8414e78af81ebd94e2 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "mutt.h"
+#include "imap.h"
 #include "imap_socket.h"
 #include "mutt_menu.h"
 #include "mutt_curses.h"
index 0a89ad3aa6bf7cb33ed92e8775ba9293cba78786..f959187b403ffcb061e4ce9b4fc04ab0730bb339 100644 (file)
@@ -396,19 +396,17 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
 {
   FILE *fp;
   char buf[LONG_STRING];
-  char host[SHORT_STRING];
   char mbox[LONG_STRING];
   char mailbox[LONG_STRING]; 
   char seq[16];
-  char *pc;
-  int port;
   size_t len;
   int c, last;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (ctx->path, host, sizeof (host), &port, NULL, &pc))
+  if (imap_parse_path (ctx->path, &mx))
     return (-1);
 
-  imap_fix_path (CTX_DATA, pc, mailbox, sizeof (mailbox));
+  imap_fix_path (CTX_DATA, mx.mbox, mailbox, sizeof (mailbox));
   
   if ((fp = fopen (msg->path, "r")) == NULL)
   {
@@ -521,27 +519,25 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
   char buf[HUGE_STRING];
   char cmd[LONG_STRING];
   char mbox[LONG_STRING];
-  char host[SHORT_STRING];
-  int port;
-  char* pc;
   int rc;
   int n;
+  IMAP_MBOX mx;
 
-  if (imap_parse_path (dest, host, sizeof (host), &port, NULL, &pc))
+  if (imap_parse_path (dest, &mx))
   {
     dprint (1, (debugfile, "imap_copy_message: bad destination %s\n", dest));
     return -1;
   }
 
   /* check that the save-to folder is on the same server */
-  if (mutt_socket_select_connection (host, port, 0) != CTX_DATA->conn)
+  if (mutt_socket_select_connection (&mx, 0) != CTX_DATA->conn)
   {
     dprint (3, (debugfile, "imap_copy_message: %s not same server as %s\n",
       dest, ctx->path));
     return 1;
   }
 
-  imap_fix_path (CTX_DATA, pc, cmd, sizeof (cmd));
+  imap_fix_path (CTX_DATA, mx.mbox, cmd, sizeof (cmd));
 
   /* Null HEADER* means copy tagged messages */
   if (!h)
index cf921a1227e4a68581231b9ab604096a2784454a..e0783f9ba7a290355fd688085ed94b4318904f31 100644 (file)
@@ -18,7 +18,9 @@
 
 #include "mutt.h"
 #include "globals.h"
+#include "imap.h"
 #include "imap_socket.h"
+#include "imap_private.h"
 #ifdef USE_SSL
 #include "imap_ssl.h"
 #endif
@@ -97,20 +99,29 @@ int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
   return r;
 }
 
-CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
+static int imap_user_match (const IMAP_MBOX *m1, const IMAP_MBOX *m2)
+{
+  const char *user = ImapUser ? ImapUser : NONULL (Username);
+
+  if (m1->flags & m2->flags & M_IMAP_USER)
+    return (!strcmp (m1->user, m2->user));
+  if (m1->flags & M_IMAP_USER)
+    return (!strcmp (m1->user, user));
+  if (m2->flags & M_IMAP_USER)
+    return (!strcmp (m2->user, user));
+  return 1;
+}
+
+CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
 {
   CONNECTION *conn;
 
-#ifdef USE_SSL
-  if (flags != M_NEW_SOCKET && flags != M_NEW_SSL_SOCKET)
-#else
-  if (flags != M_NEW_SOCKET)
-#endif
+  if (! newconn)
   {
     conn = Connections;
     while (conn)
     {
-      if (!mutt_strcmp (host, conn->server) && (port == conn->port))
+      if (!mutt_strcmp (mx->host, conn->mx.host) && (mx->port == conn->mx.port) && imap_user_match (mx, &conn->mx))
        return conn;
       conn = conn->next;
     }
@@ -119,14 +130,14 @@ CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
   conn->bufpos = 0;
   conn->available = 0;
   conn->uses = 0;
-  conn->server = safe_strdup (host);
+  memcpy (&conn->mx, mx, sizeof (conn->mx));
+  conn->mx.mbox = 0;
   conn->preconnect = safe_strdup (ImapPreconnect); 
-  conn->port = port;
   conn->next = Connections;
   Connections = conn;
 
 #ifdef USE_SSL
-  if (flags == M_NEW_SSL_SOCKET) 
+  if (mx->socktype == M_NEW_SSL_SOCKET) 
   {
       conn->read = ssl_socket_read;
       conn->write = ssl_socket_write;
@@ -195,16 +206,16 @@ int raw_socket_open (CONNECTION *conn)
   int first_try_without_preconnect = TRUE; 
 
   memset (&sin, 0, sizeof (sin));
-  sin.sin_port = htons (conn->port);
+  sin.sin_port = htons (conn->mx.port);
   sin.sin_family = AF_INET;
-  if ((he = gethostbyname (conn->server)) == NULL)
+  if ((he = gethostbyname (conn->mx.host)) == NULL)
   {
-    mutt_perror (conn->server);
+    mutt_perror (conn->mx.host);
     return (-1);
   }
   memcpy (&sin.sin_addr, he->h_addr_list[0], he->h_length);
 
-  mutt_message (_("Connecting to %s..."), conn->server); 
+  mutt_message (_("Connecting to %s..."), conn->mx.host); 
 
   if (do_preconnect && first_try_without_preconnect)
   {
@@ -217,7 +228,7 @@ int raw_socket_open (CONNECTION *conn)
   {
     int ret;
 
-    dprint (1,(debugfile,"Preconnect to server %s:\n", conn->server));
+    dprint (1,(debugfile,"Preconnect to server %s:\n", conn->mx.host));
     dprint (1,(debugfile,"\t%s\n", conn->preconnect));
     /* Execute preconnect command */
     ret = mutt_system (conn->preconnect) < 0;
index 81aef5f2adb7691bd3cbe9270931603db7bf223c..720c7cf37449893aff34d7819181d3655ea1d9d8 100644 (file)
@@ -126,98 +126,96 @@ char *imap_next_word (char *s)
 
 /* imap_parse_path: given an IMAP mailbox name, return host, port
  *   and a path IMAP servers will recognise. */
-int imap_parse_path (char* path, char* host, size_t hlen, int* port, 
-  int *socktype, char** mbox)
+int imap_parse_path (const char *path, IMAP_MBOX *mx)
 {
+  char tmp[128];
+  char *c;
   int n;
-  char *pc;
-  char *pt;
-
-  /* set default port */
-  if (port)
-    *port = 0;
-  if (socktype)
-    *socktype = M_NEW_SOCKET;
-  pc = path;
-  if (*pc != '{')
-    return -1;
-  pc++;
-  /* skip over the entire host, but copy in only what we have room for */
-  for (n = 0; *pc && *pc != '}' && *pc != ':' && *pc != '/'; pc++)
-    if (n+1 < hlen)
-      host[n++] = *pc;
-  if (hlen)
-    host[n] = 0;
-
-  /* catch NULL hosts, unless we're deliberately not parsing them */
-  if (hlen && !*host)
+  
+  mx->type[0] = '\0';
+  if (sscanf (path, "{%128[^}]}", tmp) != 1) 
   {
-    dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
     return -1;
   }
-  if (!*pc)
-    return -1;
-  if (*pc == ':')
+  mx->mbox = strchr (path, '}') + 1;
+  
+  /* Defaults */
+  mx->flags = 0;
+  mx->port = IMAP_PORT;
+  mx->socktype = M_NEW_SOCKET;
+
+  if ((c = strrchr (tmp, '@')))
   {
-    char c;
-    pc++;
-    pt = pc;
-    while (*pc && *pc != '}' && *pc != '/') pc++;
-    if (!*pc)
-      return -1;
-    c = *pc;
-    *pc = '\0';
-    if (port)
-      *port = atoi (pt);
-    if (port && !*port)
-    {
-      dprint (1, (debugfile, "imap_parse_path: bad port in %s\n", path));
-      return -1;
-    }
-    *pc = c;
+    *c = '\0';
+    strfcpy (mx->user, tmp, sizeof (mx->user));
+    strfcpy (tmp, c+1, sizeof (tmp));
+    mx->flags |= M_IMAP_USER;
   }
-  if (*pc == '/') 
+  
+  if ((n = sscanf (tmp, "%128[^:/]%128s", mx->host, tmp)) < 1)
   {
-    pc++;
-    pt = pc;
-    while (*pc && *pc != '}') pc++;
-    if (!*pc)
-      return (-1);
-    *pc = '\0';
-#ifdef USE_SSL
-    if (!strcmp (pt, "ssl"))
+    dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
+    return -1;
+  }
+  
+  if (n > 1) {
+    if (sscanf (tmp, ":%d%128s", &mx->port, tmp) >= 1)
+      mx->flags |= M_IMAP_PORT;
+    if (sscanf (tmp, "/%s", mx->type) == 1)
     {
-      if (socktype)
-       *socktype = M_NEW_SSL_SOCKET;
-      if (port && !*port)
-       *port = IMAP_SSL_PORT;
-    } else
+#ifdef USE_SSL
+      if (!strcmp (mx->type, "ssl"))
+      {
+       if (! (mx->flags & M_IMAP_PORT))
+         mx->port = IMAP_SSL_PORT;
+       mx->socktype = M_NEW_SSL_SOCKET;
+       mx->flags |= M_IMAP_TYPE;
+      }
+      else
 #endif
-      return (-1);
-    *pc = '}';
+      {
+       dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path));
+       return (-1);
+      }
+    }
   }
-  pc++;
-  
-  if (port && !*port)
-    *port = IMAP_PORT;
   
-  *mbox = pc;
   return 0;
 }
 
+
 /* imap_qualify_path: make an absolute IMAP folder target, given host, port
  *   and relative path. Use this and maybe it will be easy to convert to
  *   IMAP URLs */
-void imap_qualify_path (char* dest, size_t len, const char* host, int port,
+void imap_qualify_path (char *dest, size_t len, const IMAP_MBOX *mx,
   const char* path, const char* name)
 {
-  if (port == IMAP_PORT)
-    snprintf (dest, len, "{%s}%s%s", host, NONULL (path), NONULL (name));
-  else
-    snprintf (dest, len, "{%s:%d}%s%s", host, port, NONULL (path),
-      NONULL (name));
+  char tmp[128];
+  
+  strcpy (dest, "{");
+  if ((mx->flags & M_IMAP_USER) && (!ImapUser || strcmp (mx->user, ImapUser)))
+  {
+    snprintf (tmp, sizeof (tmp), "%s@", mx->user);
+    strncat (dest, tmp, len);
+  }
+  strncat (dest, mx->host, len);
+  if (mx->flags & M_IMAP_PORT)
+  {
+    snprintf (tmp, sizeof (tmp), ":%d", mx->port);
+    strncat (dest, tmp, len);
+  }
+#ifdef USE_SSL
+  if (mx->flags & M_IMAP_TYPE)
+  {
+    snprintf (tmp, sizeof (tmp), "/%s", mx->type);
+    strncat (dest, tmp, len);
+  }
+#endif
+  snprintf (tmp, sizeof (tmp), "}%s%s", NONULL (path), NONULL (name));
+  strncat (dest, tmp, len);
 }
 
+
 /* imap_quote_string: quote string according to IMAP rules:
  *   surround string with quotes, escape " and \ with \ */
 void imap_quote_string (char *dest, size_t slen, const char *src)
diff --git a/init.c b/init.c
index 6986e39d1cd0faa196147c833434c643f3737d95..55e97f3656679f8856c741631ab5d7c868a07824 100644 (file)
--- a/init.c
+++ b/init.c
@@ -30,6 +30,7 @@
 
 
 #ifdef USE_SSL
+#include "imap.h"
 #include "imap_socket.h"
 #include "imap_ssl.h"
 #endif