/* Copyright (c) 1996-1999 NEC USA, Inc.  All rights reserved.               */
/*                                                                           */
/* The redistribution, use and modification in source or binary forms of     */
/* this software is subject to the conditions set forth in the copyright     */
/* document ("COPYRIGHT") included with this distribution.                   */
#include "socks5p.h"
#include "buffer.h"
#include "addr.h"
#include "protocol.h"
#include "wrap.h"
#include "msg.h"
#include "share.h"

#define BUFLEN 2048

static sig_atomic_t hadsigint = 0;

static RETSIGTYPE HandleINT() {
    hadsigint = 1;
}

int DataRelay(S5IOHandle sd, S5IOInfo *cinfo, int ischild) {
    u_char msgbuf[BUFLEN];
    int n, rval = 0;

    Signal(SIGINT,  HandleINT);
    Signal(SIGQUIT, HandleINT);
    
    for (;;) {
	n = S5IORecv(sd, cinfo, msgbuf, BUFLEN, 0, 0, NULL);

	if (n == 0) break;

	if (n < 0 && errno != EINTR) {
	    if (ischild) kill(ischild, SIGINT);
	    rval = -1;
	    break;
	}

	if (n < 0 && hadsigint) {
	    rval = -1;
	    if (ischild) kill(ischild, SIGINT);
	    else {
	        msgbuf[0] = '\0';
	        if (S5IOSend(sd, cinfo, msgbuf, 1, MSG_OOB, S5_IOFLAGS_RESTART|S5_IOFLAGS_NBYTES, NULL) != 1) break;
	    }

	    hadsigint = 0;
	    continue;
	} else if (n < 0) {
	    if (ischild) kill(ischild, SIGINT);
	    rval = -1;
	    break;
	}

	if (S5IOSend(STDOUT_FILENO, NULL, msgbuf, n, 0, S5_IOFLAGS_RESTART|S5_IOFLAGS_NBYTES, NULL) < 0) {
	    if (ischild) kill(ischild, SIGINT);
	    rval = -1;
	    break;
	}
    }

    Signal(SIGINT,  SIG_DFL);
    Signal(SIGQUIT, SIG_DFL);

    return rval;
}

