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 -- */
43 /* forward declarations */
44 static int tunnel_socket_open (CONNECTION*);
45 static int tunnel_socket_close (CONNECTION*);
46 static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len);
47 static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len);
49 /* -- public functions -- */
50 int mutt_tunnel_socket_setup (CONNECTION *conn)
52 conn->open = tunnel_socket_open;
53 conn->close = tunnel_socket_close;
54 conn->read = tunnel_socket_read;
55 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)
77 if ((rc = pipe (pout)) == -1)
83 mutt_block_signals_system ();
84 if ((pid = fork ()) == 0)
86 mutt_unblock_signals_system (0);
87 if (dup2 (pout[0], STDIN_FILENO) < 0 || dup2 (pin[1], STDOUT_FILENO) < 0)
93 close (STDERR_FILENO);
95 /* Don't let the subprocess think it can use the controlling tty */
98 execl (EXECSHELL, "sh", "-c", Tunnel, NULL);
101 mutt_unblock_signals_system (1);
109 mutt_perror ("fork");
112 if (close (pin[1]) < 0 || close (pout[0]) < 0)
113 mutt_perror ("close");
115 fcntl (pin[0], F_SETFD, FD_CLOEXEC);
116 fcntl (pout[1], F_SETFD, FD_CLOEXEC);
118 tunnel->readfd = pin[0];
119 tunnel->writefd = pout[1];
122 conn->fd = 42; /* stupid hack */
127 static int tunnel_socket_close (CONNECTION* conn)
129 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
131 close (tunnel->readfd);
132 close (tunnel->writefd);
133 waitpid (tunnel->pid, NULL, 0);
134 FREE (&conn->sockdata);
139 static int tunnel_socket_read (CONNECTION* conn, char* buf, size_t len)
141 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
144 rc = read (tunnel->readfd, buf, len);
147 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,
155 static int tunnel_socket_write (CONNECTION* conn, const char* buf, size_t len)
157 TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->sockdata;
160 rc = write (tunnel->writefd, buf, len);
163 mutt_error (_("Tunnel error talking to %s: %s"), conn->account.host,