2 * Copyright (C) 2000 Manoj Kasichainula <manoj@io.com>
3 * Copyright (C) 2001 Brendan Cully <brendan@kublai.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 #include "mutt_socket.h"
22 #include "mutt_tunnel.h"
24 #include <netinet/in.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
31 /* -- data types -- */
39 /* forward declarations */
40 static int tunnel_socket_open (CONNECTION*);
41 static int tunnel_socket_close (CONNECTION*);
42 static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len);
43 static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len);
45 /* -- public functions -- */
46 int mutt_tunnel_socket_setup (CONNECTION *conn)
48 conn->open = tunnel_socket_open;
49 conn->close = tunnel_socket_close;
50 conn->read = tunnel_socket_read;
51 conn->write = tunnel_socket_write;
56 static int tunnel_socket_open (CONNECTION *conn)
63 tunnel = (TUNNEL_DATA*) safe_malloc (sizeof (TUNNEL_DATA));
64 conn->sockdata = tunnel;
66 mutt_message (_("Connecting with \"%s\"..."), Tunnel);
68 if ((rc = pipe (pin)) == -1)
73 if ((rc = pipe (pout)) == -1)
79 mutt_block_signals_system ();
80 if ((pid = fork ()) == 0)
82 mutt_unblock_signals_system (0);
83 if (dup2 (pout[0], STDIN_FILENO) < 0 || dup2 (pin[1], STDOUT_FILENO) < 0)
89 close (STDERR_FILENO);
91 /* Don't let the subprocess think it can use the controlling tty */
94 execl (EXECSHELL, "sh", "-c", Tunnel, NULL);
97 mutt_unblock_signals_system (1);
105 mutt_perror ("fork");
108 if (close (pin[1]) < 0 || close (pout[0]) < 0)
109 mutt_perror ("close");
111 fcntl (pin[0], F_SETFD, FD_CLOEXEC);
112 fcntl (pout[1], F_SETFD, FD_CLOEXEC);
114 tunnel->readfd = pin[0];
115 tunnel->writefd = pout[1];
118 conn->fd = 42; /* stupid hack */
123 static int tunnel_socket_close (CONNECTION* conn)
125 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
127 close (tunnel->readfd);
128 close (tunnel->writefd);
129 waitpid (tunnel->pid, NULL, 0);
130 FREE (&conn->sockdata);
135 static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len)
137 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
140 rc = read (tunnel->readfd, buf, len);
143 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,
151 static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len)
153 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
156 rc = write (tunnel->writefd, buf, len);
159 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,