Commit e26c1c7e authored by Thomas Roessler's avatar Thomas Roessler

Socket API clean-up from Brendan Cully.

parent 284a9737
......@@ -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 @@ [email protected]@
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 \
......
/*
* Copyright (C) 1996-2000 Michael R. Elkins <[email protected]>
* Copyright (C) 2000 Edmund Grimley Evans <[email protected]>
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
/*
* Copyright (C) 1998 Michael R. Elkins <[email protected]>
* Copyright (C) 1999-2000 Brendan Cully <[email protected]>
* Copyright (C) 1999-2001 Brendan Cully <[email protected]>
* Copyright (C) 1999-2000 Tommi Komulainen <[email protected]>
*
* 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;
}
......@@ -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);
......
......@@ -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)
......
......@@ -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
......
......@@ -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)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment