summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2000-07-06 06:36:45 +0000
committerThomas Roessler <roessler@does-not-exist.org>2000-07-06 06:36:45 +0000
commit585a2cf18f58c3b0080fabcb680192c6963e1653 (patch)
tree5e1ad952e9736fc1dcb8b39c61483bb6150d5008 /imap
parent14b04925c28e0e355eea981e0fca6fb127149323 (diff)
More IMAP fixes from Brendan Cully.
Diffstat (limited to 'imap')
-rw-r--r--imap/browse.c2
-rw-r--r--imap/command.c5
-rw-r--r--imap/imap.c27
-rw-r--r--imap/imap_private.h1
-rw-r--r--imap/imap_socket.h11
-rw-r--r--imap/message.c21
-rw-r--r--imap/socket.c101
-rw-r--r--imap/util.c20
8 files changed, 109 insertions, 79 deletions
diff --git a/imap/browse.c b/imap/browse.c
index 4ac57f14..5e6c85b6 100644
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -66,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 (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
if (!idata || (idata->state == IMAP_DISCONNECTED))
diff --git a/imap/command.c b/imap/command.c
index cfa7deba..28c6bee9 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -257,9 +257,10 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
idata->status = IMAP_BYE;
if (idata->state == IMAP_SELECTED)
mx_fastclose_mailbox (idata->selected_ctx);
- mutt_socket_close_connection (idata->conn);
+ mutt_socket_close (idata->conn);
idata->state = IMAP_DISCONNECTED;
- return (-1);
+
+ return -1;
}
else if (option (OPTIMAPSERVERNOISE) && (mutt_strncasecmp ("NO", s, 2) == 0))
{
diff --git a/imap/imap.c b/imap/imap.c
index c796c2d5..67a8ebbc 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -421,15 +421,16 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
{
char buf[LONG_STRING];
- if (mutt_socket_open_connection (conn) < 0)
+ if (mutt_socket_open (conn) < 0)
return -1;
idata->state = IMAP_CONNECTED;
if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
{
- mutt_socket_close_connection (conn);
+ mutt_socket_close (conn);
idata->state = IMAP_DISCONNECTED;
+
return -1;
}
@@ -438,7 +439,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
if (imap_check_capabilities(idata) != 0
|| imap_authenticate (idata, conn) != 0)
{
- mutt_socket_close_connection (conn);
+ mutt_socket_close (conn);
idata->state = IMAP_DISCONNECTED;
return -1;
}
@@ -447,7 +448,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
{
if (imap_check_capabilities(idata) != 0)
{
- mutt_socket_close_connection (conn);
+ mutt_socket_close (conn);
idata->state = IMAP_DISCONNECTED;
return -1;
}
@@ -455,7 +456,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
else
{
imap_error ("imap_open_connection()", buf);
- mutt_socket_close_connection (conn);
+ mutt_socket_close (conn);
idata->state = IMAP_DISCONNECTED;
return -1;
}
@@ -540,7 +541,7 @@ int imap_open_mailbox (CONTEXT *ctx)
return -1;
}
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
if (!idata || (idata->state != IMAP_AUTHENTICATED))
@@ -551,7 +552,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 (&mx, 1);
+ conn = mutt_socket_find (&mx, 1);
conn->data = idata;
idata->conn = conn;
}
@@ -721,7 +722,7 @@ int imap_select_mailbox (CONTEXT* ctx, const char* path)
return -1;
/* and that it's on the same server as the current folder */
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
if (!CTX_DATA || !CONN_DATA || (CTX_DATA->conn != CONN_DATA->conn))
{
dprint(2, (debugfile,
@@ -755,7 +756,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
ctx->magic = M_IMAP;
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -838,7 +839,7 @@ int imap_close_connection (CONTEXT *ctx)
while (mutt_strncmp (seq, buf, SEQLEN) != 0);
mutt_clear_error ();
}
- mutt_socket_close_connection (CTX_DATA->conn);
+ mutt_socket_close (CTX_DATA->conn);
CTX_DATA->state = IMAP_DISCONNECTED;
CTX_DATA->conn->data = NULL;
return 0;
@@ -1197,7 +1198,7 @@ int imap_mailbox_check (char *path, int new)
if (imap_parse_path (path, &mx))
return -1;
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1377,7 +1378,7 @@ int imap_subscribe (char *path, int subscribe)
if (imap_parse_path (path, &mx))
return (-1);
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
if (!idata || (idata->state == IMAP_DISCONNECTED))
@@ -1433,7 +1434,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
return -1;
}
- conn = mutt_socket_select_connection (&mx, 0);
+ conn = mutt_socket_find (&mx, 0);
idata = CONN_DATA;
/* don't open a new socket just for completion */
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 2572efe1..ae5847da 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -187,6 +187,7 @@ void imap_free_header_data (void** data);
int imap_read_headers (CONTEXT* ctx, int msgbegin, int msgend);
/* util.c */
+int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2);
int imap_continue (const char* msg, const char* resp);
void imap_error (const char* where, const char* msg);
char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path,
diff --git a/imap/imap_socket.h b/imap/imap_socket.h
index 8a164928..d868fd6e 100644
--- a/imap/imap_socket.h
+++ b/imap/imap_socket.h
@@ -36,16 +36,19 @@ typedef struct _connection
int (*write) (struct _connection *conn, const char *buf);
int (*open) (struct _connection *conn);
int (*close) (struct _connection *conn);
-} CONNECTION;
+ /* status bits */
+ int up : 1;
+} CONNECTION;
+int mutt_socket_open (CONNECTION* conn);
+int mutt_socket_close (CONNECTION* conn);
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 (const IMAP_MBOX *mx, int newconn);
-int mutt_socket_open_connection (CONNECTION *conn);
-int mutt_socket_close_connection (CONNECTION *conn);
+
+CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn);
int raw_socket_read (CONNECTION *conn);
int raw_socket_write (CONNECTION *conn, const char *buf);
diff --git a/imap/message.c b/imap/message.c
index 8bf9c91e..197edba2 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -56,7 +56,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
IMAP_HEADER *h, *h0;
const char *want_headers = "DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO LINES X-LABEL";
int using_body_peek = 0;
- int c;
fetchlast = 0;
@@ -164,6 +163,13 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
return -1;
}
imap_read_bytes (fp, CTX_DATA->conn, bytes);
+ /* make sure headers are followed by ONE blank line (separator
+ * for mutt_read_rfc822_header) */
+ do
+ fseek (fp, -2, SEEK_CUR);
+ while (fgetc (fp) == '\n');
+ fputs ("\n\n", fp);
+
/* we may have other fields of the FETCH _after_ the literal
* (eg Domino puts FLAGS here). Nothing wrong with that, either.
* This all has to go - we should accept literals and nonliterals
@@ -257,15 +263,6 @@ int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
h = h->next;
/* hdata is freed later */
safe_free ((void **) &h0);
-
- /*
- * skip over additional \n characters - Courier IMAP seems to
- * put them here.
- */
-
- while ((c = fgetc (fp)) == '\n')
- ;
- ungetc (c, fp);
}
fclose(fp);
@@ -597,8 +594,8 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
return -1;
}
- /* check that the save-to folder is on the same server */
- if (mutt_socket_select_connection (&mx, 0) != CTX_DATA->conn)
+ /* check that the save-to folder is in the same account */
+ if (!imap_account_match (&(CTX_DATA->conn->mx), &mx))
{
dprint (3, (debugfile, "imap_copy_message: %s not same server as %s\n",
dest, ctx->path));
diff --git a/imap/socket.c b/imap/socket.c
index d621f923..adf7b3e5 100644
--- a/imap/socket.c
+++ b/imap/socket.c
@@ -1,5 +1,7 @@
/*
* Copyright (C) 1998 Michael R. Elkins <me@cs.hmc.edu>
+ * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2000 Tommi Komulainen <Tommi.Komulainen@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,18 +36,29 @@
#include <string.h>
/* support for multiple socket connections */
-
static CONNECTION *Connections = NULL;
+/* forward declarations */
+static int socket_connect (CONNECTION* conn, struct sockaddr_in sin,
+ int verbose);
+static CONNECTION* socket_new_conn ();
/* Wrappers */
-int mutt_socket_open_connection (CONNECTION *conn)
+int mutt_socket_open (CONNECTION* conn)
{
- return conn->open (conn);
+ int rc;
+
+ rc = conn->open (conn);
+ if (!rc)
+ conn->up = 1;
+
+ return rc;
}
-int mutt_socket_close_connection (CONNECTION *conn)
+int mutt_socket_close (CONNECTION* conn)
{
+ conn->up = 0;
+
return conn->close (conn);
}
@@ -55,8 +68,6 @@ int mutt_socket_write (CONNECTION *conn, const char *buf)
return conn->write (conn, buf);
}
-
-
/* simple read buffering to speed things up. */
int mutt_socket_readchar (CONNECTION *conn, char *c)
{
@@ -99,28 +110,9 @@ int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
return r;
}
-/* imap_account_match: compare account info (host/port/user) */
-static int imap_account_match (const IMAP_MBOX *m1, const IMAP_MBOX *m2)
+CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn)
{
- const char *user = ImapUser ? ImapUser : NONULL (Username);
-
- if (mutt_strcasecmp (m1->host, m2->host))
- return 0;
- if (m1->port != m2->port)
- return 0;
-
- 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;
+ CONNECTION* conn;
if (! newconn)
{
@@ -132,11 +124,11 @@ CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
conn = conn->next;
}
}
- conn = (CONNECTION *) safe_calloc (1, sizeof (CONNECTION));
- conn->fd = -1;
+
+ conn = socket_new_conn ();
memcpy (&conn->mx, mx, sizeof (conn->mx));
conn->mx.mbox = 0;
- conn->preconnect = safe_strdup (ImapPreconnect);
+
conn->next = Connections;
Connections = conn;
@@ -161,16 +153,15 @@ CONNECTION *mutt_socket_select_connection (const IMAP_MBOX *mx, int newconn)
* make sure we've got all the context we need. */
void imap_logout_all (void)
{
- CONNECTION* conn, *tmp;
- char buf[LONG_STRING];
+ CONNECTION* conn;
+ char buf[SHORT_STRING];
char seq[SEQLEN+1];
conn = Connections;
while (conn)
{
- /* what's up here? the last connection doesn't seem to be used */
- if (conn->fd >= 0)
+ if (conn->up)
{
snprintf (buf, sizeof (buf), _("Closing connection to %s..."),
conn->mx.host);
@@ -188,31 +179,33 @@ void imap_logout_all (void)
}
while (mutt_strncmp (buf, seq, SEQLEN) != 0);
mutt_clear_error ();
+
+ mutt_socket_close (conn);
}
- tmp = conn;
- conn = conn->next;
+ Connections = conn->next;
- mutt_socket_close_connection (tmp);
-
- if (tmp->data) {
+ if (conn->data) {
dprint (2, (debugfile,
"imap_logout_all: Connection still has valid CONTEXT?!\n"));
}
- free (tmp);
+ free (conn);
+
+ conn = Connections;
}
}
-
-static int try_socket_and_connect (CONNECTION *conn, struct sockaddr_in sin,
- int verbose)
+/* socket_connect: attempt to bind a socket and connect to it */
+static int socket_connect (CONNECTION* conn, struct sockaddr_in sin,
+ int verbose)
{
if ((conn->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
{
if (verbose)
mutt_perror ("socket");
- return (-1);
+
+ return -1;
}
if (connect (conn->fd, (struct sockaddr *) &sin, sizeof (sin)) < 0)
@@ -223,12 +216,25 @@ static int try_socket_and_connect (CONNECTION *conn, struct sockaddr_in sin,
mutt_perror ("connect");
sleep (1);
}
- return (-1);
+
+ return -1;
}
return 0;
}
+/* socket_new_conn: allocate and initialise a new connection. */
+static CONNECTION* socket_new_conn ()
+{
+ CONNECTION* conn;
+
+ conn = (CONNECTION *) safe_calloc (1, sizeof (CONNECTION));
+ conn->preconnect = safe_strdup (ImapPreconnect);
+ conn->fd = -1;
+
+ return conn;
+}
+
int raw_socket_close (CONNECTION *conn)
{
int ret = close (conn->fd);
@@ -272,7 +278,7 @@ int raw_socket_open (CONNECTION *conn)
if (do_preconnect && first_try_without_preconnect)
{
verbose = FALSE;
- if (try_socket_and_connect (conn, sin, verbose) == 0)
+ if (socket_connect (conn, sin, verbose) == 0)
return 0;
}
@@ -294,5 +300,6 @@ int raw_socket_open (CONNECTION *conn)
}
verbose = TRUE;
- return try_socket_and_connect (conn, sin, verbose);
+
+ return socket_connect (conn, sin, verbose);
}
diff --git a/imap/util.c b/imap/util.c
index 6e959fc4..e36d91d2 100644
--- a/imap/util.c
+++ b/imap/util.c
@@ -34,6 +34,26 @@
#include <errno.h>
+/* imap_account_match: compare account info (host/port/user) */
+int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2)
+{
+ const char* user = ImapUser ? ImapUser : NONULL (Username);
+
+ if (mutt_strcasecmp (m1->host, m2->host))
+ return 0;
+ if (m1->port != m2->port)
+ return 0;
+
+ 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;
+}
+
/* imap_continue: display a message and ask the user if she wants to
* go on. */
int imap_continue (const char* msg, const char* resp)