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.
25 #include "mutt_socket.h"
26 #include "mutt_tunnel.h"
28 #include <netinet/in.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
35 /* -- data types -- */
42 /* forward declarations */
43 static int tunnel_socket_open (CONNECTION *);
44 static int tunnel_socket_close (CONNECTION *);
45 static int tunnel_socket_read (CONNECTION * conn, char *buf, size_t len);
46 static int tunnel_socket_write (CONNECTION * conn, const char *buf,
49 /* -- public functions -- */
50 int mutt_tunnel_socket_setup (CONNECTION * conn)
52 conn->conn_open = tunnel_socket_open;
53 conn->conn_close = tunnel_socket_close;
54 conn->conn_read = tunnel_socket_read;
55 conn->conn_write = tunnel_socket_write;
60 static int tunnel_socket_open (CONNECTION * conn)
67 tunnel = (TUNNEL_DATA *) safe_malloc (sizeof (TUNNEL_DATA));
68 conn->sockdata = tunnel;
70 mutt_message (_("Connecting with \"%s\"..."), Tunnel);
72 if ((rc = pipe (pin)) == -1) {
76 if ((rc = pipe (pout)) == -1) {
81 mutt_block_signals_system ();
82 if ((pid = fork ()) == 0) {
83 mutt_unblock_signals_system (0);
84 if (dup2 (pout[0], STDIN_FILENO) < 0 || dup2 (pin[1], STDOUT_FILENO) < 0)
90 close (STDERR_FILENO);
92 /* Don't let the subprocess think it can use the controlling tty */
95 execl (EXECSHELL, "sh", "-c", Tunnel, NULL);
98 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);
142 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,
150 static int tunnel_socket_write (CONNECTION * conn, const char *buf,
153 TUNNEL_DATA *tunnel = (TUNNEL_DATA *) conn->sockdata;
156 rc = write (tunnel->writefd, buf, len);
158 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,