summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--imap/command.c14
-rw-r--r--mutt_socket.c5
-rw-r--r--mutt_ssl.c2
-rw-r--r--mutt_tunnel.c85
4 files changed, 81 insertions, 25 deletions
diff --git a/imap/command.c b/imap/command.c
index 55ab7d06..39b001d2 100644
--- a/imap/command.c
+++ b/imap/command.c
@@ -235,6 +235,12 @@ int imap_cmd_running (IMAP_DATA* idata)
* the index is refreshed, for instance. */
void imap_cmd_finish (IMAP_DATA* idata)
{
+ if (idata->status == IMAP_FATAL)
+ {
+ cmd_handle_fatal (idata);
+ return;
+ }
+
if (!(idata->state == IMAP_SELECTED) || idata->ctx->closing)
return;
@@ -273,13 +279,17 @@ void imap_cmd_finish (IMAP_DATA* idata)
/* cmd_handle_fatal: when IMAP_DATA is in fatal state, do what we can */
static void cmd_handle_fatal (IMAP_DATA* idata)
{
+ idata->status = IMAP_FATAL;
+
if ((idata->state == IMAP_SELECTED) &&
(idata->reopen & IMAP_REOPEN_ALLOW) &&
!idata->ctx->closing)
{
- idata->status = 0;
- idata->state = IMAP_DISCONNECTED;
mx_fastclose_mailbox (idata->ctx);
+ mutt_error (_("Mailbox closed"));
+ mutt_sleep (1);
+ idata->state = IMAP_DISCONNECTED;
+ idata->status = 0;
}
}
diff --git a/mutt_socket.c b/mutt_socket.c
index 6fc74539..ff1e7f81 100644
--- a/mutt_socket.c
+++ b/mutt_socket.c
@@ -155,7 +155,6 @@ 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++)
{
@@ -341,9 +340,7 @@ static CONNECTION* socket_new_conn ()
int raw_socket_close (CONNECTION *conn)
{
- int ret = close (conn->fd);
- if (ret == 0) conn->fd = -1;
- return ret;
+ return close (conn->fd);
}
int raw_socket_read (CONNECTION* conn, char* buf, size_t len)
diff --git a/mutt_ssl.c b/mutt_ssl.c
index e55d229c..aa48ad2f 100644
--- a/mutt_ssl.c
+++ b/mutt_ssl.c
@@ -363,8 +363,6 @@ int ssl_socket_close (CONNECTION * conn)
return raw_socket_close (conn);
}
-
-
static char *x509_get_part (char *line, const char *ndx)
{
static char ret[SHORT_STRING];
diff --git a/mutt_tunnel.c b/mutt_tunnel.c
index 1ecb6d09..12aadce3 100644
--- a/mutt_tunnel.c
+++ b/mutt_tunnel.c
@@ -25,16 +25,22 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
/* -- data types -- */
typedef struct
{
pid_t pid;
+ int readfd;
+ int writefd;
} TUNNEL_DATA;
/* forward declarations */
static int tunnel_socket_open (CONNECTION*);
static int tunnel_socket_close (CONNECTION*);
+static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len);
+static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len);
/* -- public functions -- */
int mutt_tunnel_socket_setup (CONNECTION *conn)
@@ -45,8 +51,8 @@ int mutt_tunnel_socket_setup (CONNECTION *conn)
conn->open = tunnel_socket_open;
conn->close = tunnel_socket_close;
- conn->read = raw_socket_read;
- conn->write = raw_socket_write;
+ conn->read = tunnel_socket_read;
+ conn->write = tunnel_socket_write;
return 0;
}
@@ -56,14 +62,18 @@ static int tunnel_socket_open (CONNECTION *conn)
TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
int pid;
int rc;
- int sv[2];
+ int pin[2], pout[2];
mutt_message (_("Connecting with \"%s\"..."), Tunnel);
- rc = socketpair (PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv);
- if (rc == -1)
+ if ((rc = pipe (pin)) == -1)
+ {
+ mutt_perror ("pipe");
+ return -1;
+ }
+ if ((rc = pipe (pout)) == -1)
{
- mutt_perror ("socketpair");
+ mutt_perror ("pipe");
return -1;
}
@@ -71,12 +81,13 @@ static int tunnel_socket_open (CONNECTION *conn)
if ((pid = fork ()) == 0)
{
mutt_unblock_signals_system (0);
- if (close (sv[0]) < 0 ||
- dup2 (sv[1], STDIN_FILENO) < 0 ||
- dup2 (sv[1], STDOUT_FILENO) < 0 ||
- close (STDERR_FILENO) ||
- close (sv[1]) < 0)
+ if (dup2 (pout[0], STDIN_FILENO) < 0 || dup2 (pin[1], STDOUT_FILENO) < 0)
_exit (127);
+ close (pin[0]);
+ close (pin[1]);
+ close (pout[0]);
+ close (pout[1]);
+ close (STDERR_FILENO);
/* Don't let the subprocess think it can use the controlling tty */
setsid ();
@@ -88,28 +99,68 @@ static int tunnel_socket_open (CONNECTION *conn)
if (pid == -1)
{
- close (sv[0]);
- close (sv[1]);
+ close (pin[0]);
+ close (pin[1]);
+ close (pout[0]);
+ close (pout[1]);
mutt_perror ("fork");
return -1;
}
- if (close(sv[1]) < 0)
+ if (close (pin[1]) < 0 || close (pout[0]) < 0)
mutt_perror ("close");
- conn->fd = sv[0];
+ fcntl (pin[0], F_SETFD, FD_CLOEXEC);
+ fcntl (pout[1], F_SETFD, FD_CLOEXEC);
+
+ tunnel->readfd = pin[0];
+ tunnel->writefd = pout[1];
tunnel->pid = pid;
+ conn->fd = 42; /* stupid hack */
+
return 0;
}
static int tunnel_socket_close (CONNECTION* conn)
{
TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
- int rc;
- rc = close (conn->fd);
+ close (tunnel->readfd);
+ close (tunnel->writefd);
waitpid (tunnel->pid, NULL, 0);
FREE (&conn->sockdata);
+ return 0;
+}
+
+static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len)
+{
+ TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
+ int rc;
+
+ rc = read (tunnel->readfd, buf, len);
+ if (rc == -1)
+ {
+ mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,
+ strerror (errno));
+ mutt_sleep (1);
+ }
+
+ return rc;
+}
+
+static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len)
+{
+ TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
+ int rc;
+
+ rc = write (tunnel->writefd, buf, len);
+ if (rc == -1)
+ {
+ mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,
+ strerror (errno));
+ mutt_sleep (1);
+ }
+
return rc;
}