summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2001-05-30 23:00:44 +0000
committerThomas Roessler <roessler@does-not-exist.org>2001-05-30 23:00:44 +0000
commite26c1c7e8f3ecb631b0ff4b677ad119c94b236d6 (patch)
tree678dc87e579a4dbda74cffc485faa1b38ebde008
parent284a9737fd0fa1044f430bbf3d6f0daedc25c6f0 (diff)
Socket API clean-up from Brendan Cully.
-rw-r--r--Makefile.am6
-rw-r--r--enter.c1
-rw-r--r--imap/command.c21
-rw-r--r--imap/imap.c16
-rw-r--r--mutt_sasl.c24
-rw-r--r--mutt_sasl.h2
-rw-r--r--mutt_socket.c84
-rw-r--r--mutt_socket.h8
-rw-r--r--mutt_ssl.c6
-rw-r--r--mutt_ssl_nss.c8
-rw-r--r--mutt_tunnel.c3
11 files changed, 105 insertions, 74 deletions
diff --git a/Makefile.am b/Makefile.am
index 5565fd82..f6bf7e63 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,7 +6,7 @@ EXTRA_PROGRAMS = mutt_dotlock pgpring makedoc
if BUILD_IMAP
IMAP_SUBDIR = imap
-IMAP_INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/imap
+IMAP_INCLUDES = -I$(top_srcdir)/imap
endif
SUBDIRS = m4 po intl doc contrib $(IMAP_SUBDIR)
@@ -55,9 +55,7 @@ CPP=@CPP@
DEFS=-DSHAREDIR=\"$(sharedir)\" -DSYSCONFDIR=\"$(sysconfdir)\" \
-DBINDIR=\"$(bindir)\" -DHAVE_CONFIG_H=1
-# top_srcdir is for building outside of the source tree
-INCLUDES=-I$(top_srcdir) -I. $(IMAP_INCLUDES) \
- -Iintl -I$(includedir)
+INCLUDES=-I. -I$(top_srcdir) $(IMAP_INCLUDES) -Iintl -I$(includedir)
non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c \
pgpmicalg.c gnupgparse.c sha1.h \
diff --git a/enter.c b/enter.c
index 9b047fcb..94fde5c9 100644
--- a/enter.c
+++ b/enter.c
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 1996-2000 Michael R. Elkins <me@cs.hmc.edu>
* Copyright (C) 2000 Edmund Grimley Evans <edmundo@rano.org>
diff --git a/imap/command.c b/imap/command.c
index 1d7e3cf8..2f90dc48 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -111,12 +111,11 @@ int imap_cmd_step (IMAP_DATA* idata)
cmd->blen));
}
- if ((c = mutt_socket_readln (cmd->buf + len, cmd->blen - len,
- idata->conn)) < 0)
+ c = mutt_socket_readln (cmd->buf + len, cmd->blen - len, idata->conn);
+ if (c <= 0)
{
- dprint (1, (debugfile, "imap_cmd_step: Error while reading server response, closing connection.\n"));
- mutt_socket_close (idata->conn);
- idata->status = IMAP_FATAL;
+ dprint (1, (debugfile, "imap_cmd_step: Error reading server response.\n"));
+ cmd_handle_fatal (idata);
return IMAP_CMD_BAD;
}
@@ -196,7 +195,10 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
safe_free ((void**) &out);
if (rc < 0)
+ {
+ cmd_handle_fatal (idata);
return -1;
+ }
do
rc = imap_cmd_step (idata);
@@ -207,17 +209,10 @@ int imap_exec (IMAP_DATA* idata, const char* cmd, int flags)
if (rc != IMAP_CMD_OK)
{
- char *pc;
-
if (flags & IMAP_CMD_FAIL_OK)
return -2;
dprint (1, (debugfile, "imap_exec: command failed: %s\n", idata->cmd.buf));
- pc = idata->cmd.buf;
- pc = imap_next_word (pc);
- mutt_error ("%s", pc);
- mutt_sleep (2);
-
return -1;
}
@@ -282,7 +277,7 @@ static void cmd_handle_fatal (IMAP_DATA* idata)
(idata->reopen & IMAP_REOPEN_ALLOW) &&
!idata->ctx->closing)
{
- idata->status = IMAP_BYE;
+ idata->status = 0;
idata->state = IMAP_DISCONNECTED;
mx_fastclose_mailbox (idata->ctx);
}
diff --git a/imap/imap.c b/imap/imap.c
index 7d9c9d77..a5a616e2 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -160,6 +160,8 @@ int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes)
if (mutt_socket_readchar (idata->conn, &c) != 1)
{
dprint (1, (debugfile, "imap_read_literal: error during read, %ld bytes read\n", pos));
+ idata->status = IMAP_FATAL;
+
return -1;
}
@@ -358,11 +360,7 @@ int imap_open_connection (IMAP_DATA* idata)
int rc;
if (mutt_socket_open (idata->conn) < 0)
- {
- mutt_error (_("Connection to %s failed."), idata->conn->account.host);
- mutt_sleep (1);
return -1;
- }
idata->state = IMAP_CONNECTED;
@@ -380,7 +378,7 @@ int imap_open_connection (IMAP_DATA* idata)
{
if ((rc = query_quadoption (OPT_SSLSTARTTLS,
_("Secure connection with TLS?"))) == -1)
- goto bail;
+ goto err_close_conn;
if (rc == M_YES) {
if ((rc = imap_exec (idata, "STARTTLS", IMAP_CMD_FAIL_OK)) == -1)
goto bail;
@@ -425,9 +423,10 @@ int imap_open_connection (IMAP_DATA* idata)
imap_get_delim (idata);
return 0;
+ err_close_conn:
+ mutt_socket_close (idata->conn);
bail:
FREE (&idata->capstr);
- mutt_socket_close (idata->conn);
idata->state = IMAP_DISCONNECTED;
return -1;
}
@@ -1041,7 +1040,7 @@ void imap_close_mailbox (CONTEXT* ctx)
(ctx == idata->ctx))
{
if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
- imap_error ("CLOSE failed", idata->cmd.buf);
+ mutt_error (_("CLOSE failed"));
idata->reopen &= IMAP_REOPEN_ALLOW;
idata->state = IMAP_AUTHENTICATED;
@@ -1086,10 +1085,7 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
ImapLastCheck = now;
if (imap_exec (idata, "NOOP", 0) != 0)
- {
- imap_error ("imap_check_mailbox", idata->cmd.buf);
return -1;
- }
}
if (idata->check_status & IMAP_NEWMAIL_PENDING)
diff --git a/mutt_sasl.c b/mutt_sasl.c
index 1b1b7a40..91e190ff 100644
--- a/mutt_sasl.c
+++ b/mutt_sasl.c
@@ -44,7 +44,7 @@ static int mutt_sasl_cb_pass (sasl_conn_t* conn, void* context, int id,
/* socket wrappers for a SASL security layer */
static int mutt_sasl_conn_open (CONNECTION* conn);
static int mutt_sasl_conn_close (CONNECTION* conn);
-static int mutt_sasl_conn_read (CONNECTION* conn);
+static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len);
static int mutt_sasl_conn_write (CONNECTION* conn, const char* buf,
size_t count);
@@ -400,7 +400,7 @@ static int mutt_sasl_conn_close (CONNECTION* conn)
return rc;
}
-static int mutt_sasl_conn_read (CONNECTION* conn)
+static int mutt_sasl_conn_read (CONNECTION* conn, char* buf, size_t len)
{
SASL_DATA* sasldata;
int rc;
@@ -409,13 +409,13 @@ static int mutt_sasl_conn_read (CONNECTION* conn)
sasldata = (SASL_DATA*) conn->sockdata;
- /* if we still have data in our read buffer, copy it into conn->inbuf */
+ /* if we still have data in our read buffer, copy it into buf */
if (sasldata->blen > sasldata->bpos)
{
- olen = (sasldata->blen - sasldata->bpos > sizeof (conn->inbuf)) ?
- sizeof (conn->inbuf) : sasldata->blen - sasldata->bpos;
+ olen = (sasldata->blen - sasldata->bpos > len) ? len :
+ sasldata->blen - sasldata->bpos;
- memcpy (conn->inbuf, sasldata->buf+sasldata->bpos, olen);
+ memcpy (buf, sasldata->buf+sasldata->bpos, olen);
sasldata->bpos += olen;
return olen;
@@ -433,11 +433,11 @@ static int mutt_sasl_conn_read (CONNECTION* conn)
do
{
/* call the underlying read function to fill the buffer */
- rc = (sasldata->read) (conn);
+ rc = (sasldata->read) (conn, buf, len);
if (rc <= 0)
goto out;
- rc = sasl_decode (sasldata->saslconn, conn->inbuf, rc, &sasldata->buf,
+ rc = sasl_decode (sasldata->saslconn, buf, rc, &sasldata->buf,
&sasldata->blen);
if (rc != SASL_OK)
{
@@ -448,16 +448,16 @@ static int mutt_sasl_conn_read (CONNECTION* conn)
}
while (!sasldata->blen);
- olen = (sasldata->blen - sasldata->bpos > sizeof (conn->inbuf)) ?
- sizeof (conn->inbuf) : sasldata->blen - sasldata->bpos;
+ olen = (sasldata->blen - sasldata->bpos > len) ? len :
+ sasldata->blen - sasldata->bpos;
- memcpy (conn->inbuf, sasldata->buf, olen);
+ memcpy (buf, sasldata->buf, olen);
sasldata->bpos += olen;
rc = olen;
}
else
- rc = (sasldata->read) (conn);
+ rc = (sasldata->read) (conn, buf, len);
out:
conn->sockdata = sasldata;
diff --git a/mutt_sasl.h b/mutt_sasl.h
index 3505eafe..1e236c0c 100644
--- a/mutt_sasl.h
+++ b/mutt_sasl.h
@@ -46,7 +46,7 @@ typedef struct
void* sockdata;
int (*open) (CONNECTION* conn);
int (*close) (CONNECTION* conn);
- int (*read) (CONNECTION* conn);
+ int (*read) (CONNECTION* conn, char* buf, size_t len);
int (*write) (CONNECTION* conn, const char* buf, size_t count);
}
SASL_DATA;
diff --git a/mutt_socket.c b/mutt_socket.c
index f00e09f1..6fc74539 100644
--- a/mutt_socket.c
+++ b/mutt_socket.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1998 Michael R. Elkins <me@cs.hmc.edu>
- * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2001 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
@@ -40,12 +40,16 @@
static CONNECTION *Connections = NULL;
/* forward declarations */
+static int socket_preconnect (void);
static int socket_connect (int fd, struct sockaddr* sa);
static CONNECTION* socket_new_conn ();
/* Wrappers */
int mutt_socket_open (CONNECTION* conn)
{
+ if (socket_preconnect ())
+ return -1;
+
return conn->open (conn);
}
@@ -63,6 +67,29 @@ int mutt_socket_close (CONNECTION* conn)
return rc;
}
+int mutt_socket_read (CONNECTION* conn, char* buf, size_t len)
+{
+ int rc;
+
+ if (conn->fd < 0)
+ {
+ dprint (1, (debugfile, "mutt_socket_read: attempt to read from closed connection\n"));
+ return -1;
+ }
+
+ rc = conn->read (conn, buf, len);
+ /* EOF */
+ if (rc == 0)
+ {
+ mutt_error (_("Connection to %s closed"), conn->account.host);
+ mutt_sleep (2);
+ }
+ if (rc <= 0)
+ mutt_socket_close (conn);
+
+ return rc;
+}
+
int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg)
{
int rc;
@@ -101,15 +128,23 @@ int mutt_socket_readchar (CONNECTION *conn, char *c)
if (conn->bufpos >= conn->available)
{
if (conn->fd >= 0)
- conn->available = conn->read (conn);
+ conn->available = conn->read (conn, conn->inbuf, sizeof (conn->inbuf));
else
{
- dprint (1, (debugfile, "mutt_socket_readchar: attempt to read closed from connection.\n"));
+ dprint (1, (debugfile, "mutt_socket_readchar: attempt to read from closed connection.\n"));
return -1;
}
conn->bufpos = 0;
+ if (conn->available == 0)
+ {
+ mutt_error (_("Connection to %s closed"), conn->account.host);
+ mutt_sleep (2);
+ }
if (conn->available <= 0)
- return conn->available; /* returns 0 for EOF or -1 for other error */
+ {
+ mutt_socket_close (conn);
+ return -1;
+ }
}
*c = conn->inbuf[conn->bufpos];
conn->bufpos++;
@@ -120,6 +155,7 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg)
{
char ch;
int i;
+ int rc;
for (i = 0; i < buflen-1; i++)
{
@@ -128,6 +164,7 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg)
buf[i] = '\0';
return -1;
}
+
if (ch == '\n')
break;
buf[i] = ch;
@@ -229,16 +266,16 @@ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account)
return conn;
}
-int mutt_socket_preconnect (void)
+static int socket_preconnect (void)
{
int rc;
int save_errno;
if (mutt_strlen (Preconnect))
{
- dprint (1, (debugfile, "Executing preconnect: %s\n", Preconnect));
+ dprint (2, (debugfile, "Executing preconnect: %s\n", Preconnect));
rc = mutt_system (Preconnect);
- dprint (1, (debugfile, "Preconnect result: %d\n", rc));
+ dprint (2, (debugfile, "Preconnect result: %d\n", rc));
if (rc)
{
save_errno = errno;
@@ -256,12 +293,8 @@ int mutt_socket_preconnect (void)
static int socket_connect (int fd, struct sockaddr* sa)
{
int sa_size;
- int rc;
int save_errno;
- if ((rc = mutt_socket_preconnect ()))
- return rc;
-
if (sa->sa_family == AF_INET)
sa_size = sizeof (struct sockaddr_in);
#ifdef HAVE_GETADDRINFO
@@ -313,14 +346,32 @@ int raw_socket_close (CONNECTION *conn)
return ret;
}
-int raw_socket_read (CONNECTION *conn)
+int raw_socket_read (CONNECTION* conn, char* buf, size_t len)
{
- return read (conn->fd, conn->inbuf, LONG_STRING);
+ int rc;
+
+ if ((rc = read (conn->fd, buf, len)) == -1)
+ {
+ mutt_error (_("Error talking to %s (%s)"), conn->account.host,
+ strerror (errno));
+ mutt_sleep (2);
+ }
+
+ return rc;
}
int raw_socket_write (CONNECTION* conn, const char* buf, size_t count)
{
- return write (conn->fd, buf, count);
+ int rc;
+
+ if ((rc = write (conn->fd, buf, count)) == -1)
+ {
+ mutt_error (_("Error talking to %s (%s)"), conn->account.host,
+ strerror (errno));
+ mutt_sleep (2);
+ }
+
+ return rc;
}
int raw_socket_open (CONNECTION* conn)
@@ -424,8 +475,9 @@ int raw_socket_open (CONNECTION* conn)
{
mutt_error (_("Could not connect to %s (%s)."), conn->account.host,
(rc > 0) ? strerror (rc) : _("unknown error"));
- sleep (2);
+ mutt_sleep (2);
+ return -1;
}
- return rc;
+ return 0;
}
diff --git a/mutt_socket.h b/mutt_socket.h
index e508ee31..ce191fbd 100644
--- a/mutt_socket.h
+++ b/mutt_socket.h
@@ -44,7 +44,7 @@ typedef struct _connection
struct _connection *next;
void *sockdata;
- int (*read) (struct _connection *conn);
+ int (*read) (struct _connection* conn, char* buf, size_t len);
int (*write) (struct _connection *conn, const char *buf, size_t count);
int (*open) (struct _connection *conn);
int (*close) (struct _connection *conn);
@@ -52,6 +52,7 @@ typedef struct _connection
int mutt_socket_open (CONNECTION* conn);
int mutt_socket_close (CONNECTION* conn);
+int mutt_socket_read (CONNECTION* conn, char* buf, size_t len);
int mutt_socket_readchar (CONNECTION *conn, char *c);
#define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,M_SOCK_LOG_CMD)
int mutt_socket_readln_d (char *buf, size_t buflen, CONNECTION *conn, int dbg);
@@ -63,10 +64,7 @@ CONNECTION* mutt_socket_head (void);
void mutt_socket_free (CONNECTION* conn);
CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account);
-/* other methods may call this to try preconnect code */
-int mutt_socket_preconnect (void);
-
-int raw_socket_read (CONNECTION *conn);
+int raw_socket_read (CONNECTION* conn, char* buf, size_t len);
int raw_socket_write (CONNECTION* conn, const char* buf, size_t count);
int raw_socket_open (CONNECTION *conn);
int raw_socket_close (CONNECTION *conn);
diff --git a/mutt_ssl.c b/mutt_ssl.c
index b6ac5594..e55d229c 100644
--- a/mutt_ssl.c
+++ b/mutt_ssl.c
@@ -72,7 +72,7 @@ sslsockdata;
int ssl_init (void);
static int add_entropy (const char *file);
static int ssl_check_certificate (sslsockdata * data);
-static int ssl_socket_read (CONNECTION * conn);
+static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len);
static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len);
static int ssl_socket_open (CONNECTION * conn);
static int ssl_socket_close (CONNECTION * conn);
@@ -242,10 +242,10 @@ int ssl_socket_setup (CONNECTION * conn)
return 0;
}
-int ssl_socket_read (CONNECTION * conn)
+static int ssl_socket_read (CONNECTION* conn, char* buf, size_t len)
{
sslsockdata *data = conn->sockdata;
- return SSL_read (data->ssl, conn->inbuf, LONG_STRING);
+ return SSL_read (data->ssl, buf, len);
}
int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len)
diff --git a/mutt_ssl_nss.c b/mutt_ssl_nss.c
index 12d3cc45..dbb61c3d 100644
--- a/mutt_ssl_nss.c
+++ b/mutt_ssl_nss.c
@@ -237,9 +237,6 @@ mutt_nss_bad_cert (void *arg, PRFileDesc * fd)
return i;
}
-/* TODO: this currently doesn't support the `Preconnect', it should be
- * moved out of raw_socket_open() into a generic function instead.
- */
static int
mutt_nss_socket_open (CONNECTION * con)
{
@@ -359,10 +356,9 @@ mutt_nss_socket_close (CONNECTION * con)
}
static int
-mutt_nss_socket_read (CONNECTION * con)
+mutt_nss_socket_read (CONNECTION* conn, char* buf, size_t len)
{
- return PR_Read (((mutt_nss_t *) con->sockdata)->fd, con->inbuf,
- LONG_STRING);
+ return PR_Read (((mutt_nss_t*) conn->sockdata)->fd, buf, len);
}
static int
diff --git a/mutt_tunnel.c b/mutt_tunnel.c
index 0f26e6e7..4a07b991 100644
--- a/mutt_tunnel.c
+++ b/mutt_tunnel.c
@@ -56,9 +56,6 @@ static int tunnel_socket_open (CONNECTION *conn)
mutt_message (_("Connecting with \"%s\"..."), Tunnel);
- if ((rc = mutt_socket_preconnect ()))
- return rc;
-
rc = socketpair (PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv);
if (rc == -1)
{