Redirect slirp traffic to/from qemu character device (Gleb Natapov)
Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6240 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									4dda406337
								
							
						
					
					
						commit
						e1c5a2b334
					
				@ -20,13 +20,16 @@ void slirp_output(const uint8_t *pkt, int pkt_len);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int slirp_redir(int is_udp, int host_port,
 | 
					int slirp_redir(int is_udp, int host_port,
 | 
				
			||||||
                struct in_addr guest_addr, int guest_port);
 | 
					                struct in_addr guest_addr, int guest_port);
 | 
				
			||||||
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
 | 
					int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
 | 
				
			||||||
                   int guest_port);
 | 
					                   int guest_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern const char *tftp_prefix;
 | 
					extern const char *tftp_prefix;
 | 
				
			||||||
extern char slirp_hostname[33];
 | 
					extern char slirp_hostname[33];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void slirp_stats(void);
 | 
					void slirp_stats(void);
 | 
				
			||||||
 | 
					void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
 | 
				
			||||||
 | 
							int size);
 | 
				
			||||||
 | 
					size_t slirp_socket_can_recv(int addr_low_byte, int guest_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -51,3 +51,4 @@ extern uint8_t client_ethaddr[6];
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void if_encap(const uint8_t *ip_data, int ip_data_len);
 | 
					void if_encap(const uint8_t *ip_data, int ip_data_len);
 | 
				
			||||||
 | 
					ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags);
 | 
				
			||||||
 | 
				
			|||||||
@ -169,7 +169,7 @@ add_exec(ex_ptr, do_pty, exec, addr, port)
 | 
				
			|||||||
	(*ex_ptr)->ex_fport = port;
 | 
						(*ex_ptr)->ex_fport = port;
 | 
				
			||||||
	(*ex_ptr)->ex_addr = addr;
 | 
						(*ex_ptr)->ex_addr = addr;
 | 
				
			||||||
	(*ex_ptr)->ex_pty = do_pty;
 | 
						(*ex_ptr)->ex_pty = do_pty;
 | 
				
			||||||
	(*ex_ptr)->ex_exec = strdup(exec);
 | 
						(*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
 | 
				
			||||||
	(*ex_ptr)->ex_next = tmp_ptr;
 | 
						(*ex_ptr)->ex_next = tmp_ptr;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -108,7 +108,7 @@ sbappend(so, m)
 | 
				
			|||||||
	 * ottherwise it'll arrive out of order, and hence corrupt
 | 
						 * ottherwise it'll arrive out of order, and hence corrupt
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!so->so_rcv.sb_cc)
 | 
						if (!so->so_rcv.sb_cc)
 | 
				
			||||||
	   ret = send(so->s, m->m_data, m->m_len, 0);
 | 
						   ret = slirp_send(so, m->m_data, m->m_len, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret <= 0) {
 | 
						if (ret <= 0) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@
 | 
				
			|||||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 * THE SOFTWARE.
 | 
					 * THE SOFTWARE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "slirp.h"
 | 
					#include "slirp.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* host address */
 | 
					/* host address */
 | 
				
			||||||
@ -736,9 +737,69 @@ int slirp_redir(int is_udp, int host_port,
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
 | 
					int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
 | 
				
			||||||
                  int guest_port)
 | 
					                  int guest_port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return add_exec(&exec_list, do_pty, (char *)args,
 | 
					    return add_exec(&exec_list, do_pty, (char *)args,
 | 
				
			||||||
                    addr_low_byte, htons(guest_port));
 | 
					                    addr_low_byte, htons(guest_port));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (so->s == -1 && so->extra) {
 | 
				
			||||||
 | 
							qemu_chr_write(so->extra, buf, len);
 | 
				
			||||||
 | 
							return len;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return send(so->s, buf, len, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct socket *slirp_find_ctl_socket(int addr_low_byte, int guest_port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct socket *so;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (so = tcb.so_next; so != &tcb; so = so->so_next) {
 | 
				
			||||||
 | 
							if ((so->so_faddr.s_addr & htonl(0xffffff00)) ==
 | 
				
			||||||
 | 
									special_addr.s_addr
 | 
				
			||||||
 | 
									&& (ntohl(so->so_faddr.s_addr) & 0xff) ==
 | 
				
			||||||
 | 
									addr_low_byte
 | 
				
			||||||
 | 
									&& htons(so->so_fport) == guest_port)
 | 
				
			||||||
 | 
								return so;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t slirp_socket_can_recv(int addr_low_byte, int guest_port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct iovec iov[2];
 | 
				
			||||||
 | 
						struct socket *so;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!link_up)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						so = slirp_find_ctl_socket(addr_low_byte, guest_port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!so || so->so_state & SS_NOFDREF)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sopreprbuf(so, iov, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
 | 
				
			||||||
 | 
					        int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    struct socket *so = slirp_find_ctl_socket(addr_low_byte, guest_port);
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    if (!so)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ret = soreadbuf(so, buf, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ret > 0)
 | 
				
			||||||
 | 
					        tcp_output(sototcpcb(so));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										101
									
								
								slirp/socket.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								slirp/socket.c
									
									
									
									
									
								
							@ -5,13 +5,13 @@
 | 
				
			|||||||
 * terms and conditions of the copyright.
 | 
					 * terms and conditions of the copyright.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#define WANT_SYS_IOCTL_H
 | 
					#define WANT_SYS_IOCTL_H
 | 
				
			||||||
#include <slirp.h>
 | 
					#include <slirp.h>
 | 
				
			||||||
#include "ip_icmp.h"
 | 
					#include "ip_icmp.h"
 | 
				
			||||||
#ifdef __sun__
 | 
					#ifdef __sun__
 | 
				
			||||||
#include <sys/filio.h>
 | 
					#include <sys/filio.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include "qemu-common.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void sofcantrcvmore(struct socket *so);
 | 
					static void sofcantrcvmore(struct socket *so);
 | 
				
			||||||
static void sofcantsendmore(struct socket *so);
 | 
					static void sofcantsendmore(struct socket *so);
 | 
				
			||||||
@ -91,31 +91,21 @@ sofree(so)
 | 
				
			|||||||
  free(so);
 | 
					  free(so);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
 | 
				
			||||||
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 | 
					 | 
				
			||||||
 * NOTE: This will only be called if it is select()ed for reading, so
 | 
					 | 
				
			||||||
 * a read() of 0 (or less) means it's disconnected
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
int
 | 
					 | 
				
			||||||
soread(so)
 | 
					 | 
				
			||||||
	struct socket *so;
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int n, nn, lss, total;
 | 
						int n, lss, total;
 | 
				
			||||||
	struct sbuf *sb = &so->so_snd;
 | 
						struct sbuf *sb = &so->so_snd;
 | 
				
			||||||
	int len = sb->sb_datalen - sb->sb_cc;
 | 
						int len = sb->sb_datalen - sb->sb_cc;
 | 
				
			||||||
	struct iovec iov[2];
 | 
					 | 
				
			||||||
	int mss = so->so_tcpcb->t_maxseg;
 | 
						int mss = so->so_tcpcb->t_maxseg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DEBUG_CALL("soread");
 | 
						DEBUG_CALL("sopreprbuf");
 | 
				
			||||||
	DEBUG_ARG("so = %lx", (long )so);
 | 
						DEBUG_ARG("so = %lx", (long )so);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
					 | 
				
			||||||
	 * No need to check if there's enough room to read.
 | 
					 | 
				
			||||||
	 * soread wouldn't have been called if there weren't
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	len = sb->sb_datalen - sb->sb_cc;
 | 
						len = sb->sb_datalen - sb->sb_cc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len <= 0)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	iov[0].iov_base = sb->sb_wptr;
 | 
						iov[0].iov_base = sb->sb_wptr;
 | 
				
			||||||
        iov[1].iov_base = NULL;
 | 
					        iov[1].iov_base = NULL;
 | 
				
			||||||
        iov[1].iov_len = 0;
 | 
					        iov[1].iov_len = 0;
 | 
				
			||||||
@ -156,6 +146,33 @@ soread(so)
 | 
				
			|||||||
			n = 1;
 | 
								n = 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (np)
 | 
				
			||||||
 | 
							*np = n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return iov[0].iov_len + (n - 1) * iov[1].iov_len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 | 
				
			||||||
 | 
					 * NOTE: This will only be called if it is select()ed for reading, so
 | 
				
			||||||
 | 
					 * a read() of 0 (or less) means it's disconnected
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					soread(so)
 | 
				
			||||||
 | 
						struct socket *so;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int n, nn;
 | 
				
			||||||
 | 
						struct sbuf *sb = &so->so_snd;
 | 
				
			||||||
 | 
						struct iovec iov[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUG_CALL("soread");
 | 
				
			||||||
 | 
						DEBUG_ARG("so = %lx", (long )so);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * No need to check if there's enough room to read.
 | 
				
			||||||
 | 
						 * soread wouldn't have been called if there weren't
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						sopreprbuf(so, iov, &n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_READV
 | 
					#ifdef HAVE_READV
 | 
				
			||||||
	nn = readv(so->s, (struct iovec *)iov, n);
 | 
						nn = readv(so->s, (struct iovec *)iov, n);
 | 
				
			||||||
@ -202,6 +219,48 @@ soread(so)
 | 
				
			|||||||
	return nn;
 | 
						return nn;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int soreadbuf(struct socket *so, const char *buf, int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int n, nn, copy = size;
 | 
				
			||||||
 | 
						struct sbuf *sb = &so->so_snd;
 | 
				
			||||||
 | 
						struct iovec iov[2];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DEBUG_CALL("soreadbuf");
 | 
				
			||||||
 | 
						DEBUG_ARG("so = %lx", (long )so);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * No need to check if there's enough room to read.
 | 
				
			||||||
 | 
						 * soread wouldn't have been called if there weren't
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (sopreprbuf(so, iov, &n) < size)
 | 
				
			||||||
 | 
					        goto err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nn = MIN(iov[0].iov_len, copy);
 | 
				
			||||||
 | 
					    memcpy(iov[0].iov_base, buf, nn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    copy -= nn;
 | 
				
			||||||
 | 
					    buf += nn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (copy == 0)
 | 
				
			||||||
 | 
					        goto done;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(iov[1].iov_base, buf, copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					done:
 | 
				
			||||||
 | 
					    /* Update fields */
 | 
				
			||||||
 | 
						sb->sb_cc += size;
 | 
				
			||||||
 | 
						sb->sb_wptr += size;
 | 
				
			||||||
 | 
						if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
 | 
				
			||||||
 | 
							sb->sb_wptr -= sb->sb_datalen;
 | 
				
			||||||
 | 
					    return size;
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sofcantrcvmore(so);
 | 
				
			||||||
 | 
					    tcp_sockclosed(sototcpcb(so));
 | 
				
			||||||
 | 
					    fprintf(stderr, "soreadbuf buffer to small");
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Get urgent data
 | 
					 * Get urgent data
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -255,7 +314,7 @@ sosendoob(so)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (sb->sb_rptr < sb->sb_wptr) {
 | 
						if (sb->sb_rptr < sb->sb_wptr) {
 | 
				
			||||||
		/* We can send it directly */
 | 
							/* We can send it directly */
 | 
				
			||||||
		n = send(so->s, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 | 
							n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 | 
				
			||||||
		so->so_urgc -= n;
 | 
							so->so_urgc -= n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
 | 
							DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
 | 
				
			||||||
@ -276,7 +335,7 @@ sosendoob(so)
 | 
				
			|||||||
			so->so_urgc -= n;
 | 
								so->so_urgc -= n;
 | 
				
			||||||
			len += n;
 | 
								len += n;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		n = send(so->s, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 | 
							n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
		if (n != len)
 | 
							if (n != len)
 | 
				
			||||||
		   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
 | 
							   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
 | 
				
			||||||
@ -348,7 +407,7 @@ sowrite(so)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
 | 
						DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	nn = send(so->s, iov[0].iov_base, iov[0].iov_len,0);
 | 
						nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	/* This should never happen, but people tell me it does *shrug* */
 | 
						/* This should never happen, but people tell me it does *shrug* */
 | 
				
			||||||
	if (nn < 0 && (errno == EAGAIN || errno == EINTR))
 | 
						if (nn < 0 && (errno == EAGAIN || errno == EINTR))
 | 
				
			||||||
@ -365,7 +424,7 @@ sowrite(so)
 | 
				
			|||||||
#ifndef HAVE_READV
 | 
					#ifndef HAVE_READV
 | 
				
			||||||
	if (n == 2 && nn == iov[0].iov_len) {
 | 
						if (n == 2 && nn == iov[0].iov_len) {
 | 
				
			||||||
            int ret;
 | 
					            int ret;
 | 
				
			||||||
            ret = send(so->s, iov[1].iov_base, iov[1].iov_len,0);
 | 
					            ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
 | 
				
			||||||
            if (ret > 0)
 | 
					            if (ret > 0)
 | 
				
			||||||
                nn += ret;
 | 
					                nn += ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -87,5 +87,7 @@ void soisfconnecting _P((register struct socket *));
 | 
				
			|||||||
void soisfconnected _P((register struct socket *));
 | 
					void soisfconnected _P((register struct socket *));
 | 
				
			||||||
void soisfdisconnected _P((struct socket *));
 | 
					void soisfdisconnected _P((struct socket *));
 | 
				
			||||||
void sofwdrain _P((struct socket *));
 | 
					void sofwdrain _P((struct socket *));
 | 
				
			||||||
 | 
					size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
 | 
				
			||||||
 | 
					int soreadbuf(struct socket *so, const char *buf, int size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _SOCKET_H_ */
 | 
					#endif /* _SOCKET_H_ */
 | 
				
			||||||
 | 
				
			|||||||
@ -1281,6 +1281,11 @@ tcp_ctl(so)
 | 
				
			|||||||
		for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
 | 
							for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
 | 
				
			||||||
			if (ex_ptr->ex_fport == so->so_fport &&
 | 
								if (ex_ptr->ex_fport == so->so_fport &&
 | 
				
			||||||
			    command == ex_ptr->ex_addr) {
 | 
								    command == ex_ptr->ex_addr) {
 | 
				
			||||||
 | 
									if (ex_ptr->ex_pty == 3) {
 | 
				
			||||||
 | 
										so->s = -1;
 | 
				
			||||||
 | 
										so->extra = ex_ptr->ex_exec;
 | 
				
			||||||
 | 
										return 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				do_pty = ex_ptr->ex_pty;
 | 
									do_pty = ex_ptr->ex_pty;
 | 
				
			||||||
				goto do_exec;
 | 
									goto do_exec;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user