diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 2001-05-30 23:00:44 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 2001-05-30 23:00:44 +0000 |
commit | e26c1c7e8f3ecb631b0ff4b677ad119c94b236d6 (patch) | |
tree | 678dc87e579a4dbda74cffc485faa1b38ebde008 | |
parent | 284a9737fd0fa1044f430bbf3d6f0daedc25c6f0 (diff) |
Socket API clean-up from Brendan Cully.
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | enter.c | 1 | ||||
-rw-r--r-- | imap/command.c | 21 | ||||
-rw-r--r-- | imap/imap.c | 16 | ||||
-rw-r--r-- | mutt_sasl.c | 24 | ||||
-rw-r--r-- | mutt_sasl.h | 2 | ||||
-rw-r--r-- | mutt_socket.c | 84 | ||||
-rw-r--r-- | mutt_socket.h | 8 | ||||
-rw-r--r-- | mutt_ssl.c | 6 | ||||
-rw-r--r-- | mutt_ssl_nss.c | 8 | ||||
-rw-r--r-- | mutt_tunnel.c | 3 |
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 \ @@ -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); @@ -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) { |