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));
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
* Preserve message keywords
* Preserve deleted messages if you don't choose to expunge them
* Delete mailboxes (from the browser)
+* Multiple IMAP usernames
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,
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])
{
/* 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)
{
{
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
{
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);
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;
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;
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;
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))
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))
{
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;
}
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));
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--;
}
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;
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);
}
}
/* 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);
}
{
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));
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);
}
{
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);
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));
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);
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))
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))
/* 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;
}
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));
do
{
+ char *pc;
+
if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
break;
{
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,
{
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))
/* 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);
{
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))
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);
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))
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
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;
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 */
/* 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';
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,
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;
#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);
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);
#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,
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];
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);
#include <string.h>
#include "mutt.h"
+#include "imap.h"
#include "imap_socket.h"
#include "mutt_menu.h"
#include "mutt_curses.h"
{
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)
{
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)
#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
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;
}
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;
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)
{
{
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;
/* 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)
#ifdef USE_SSL
+#include "imap.h"
#include "imap_socket.h"
#include "imap_ssl.h"
#endif