sys_bsd.c

来自「Linux下的socks的程序源程序,用于socks的代理服务」· C语言 代码 · 共 1,208 行 · 第 1/2 页

C
1,208
字号
	if (f & MODE_OUTBIN) {		tmp_tc.c_cflag &= ~(CSIZE|PARENB);		tmp_tc.c_cflag |= CS8;		tmp_tc.c_oflag &= ~OPOST;	} else {		tmp_tc.c_cflag &= ~(CSIZE|PARENB);		tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);		tmp_tc.c_oflag |= OPOST;	}#endif	onoff = 1;    }    if (f != -1) {#ifdef	SIGTSTP	static SIG_FUNC_RET susp();#endif	/* SIGTSTP */#ifdef	SIGINFO	static SIG_FUNC_RET ayt();#endif	/* SIGINFO */#ifdef	SIGTSTP	(void) signal(SIGTSTP, susp);#endif	/* SIGTSTP */#ifdef	SIGINFO	(void) signal(SIGINFO, ayt);#endif	/* SIGINFO */#if	defined(USE_TERMIO) && defined(NOKERNINFO)	tmp_tc.c_lflag |= NOKERNINFO;#endif	/*	 * We don't want to process ^Y here.  It's just another	 * character that we'll pass on to the back end.  It has	 * to process it because it will be processed when the	 * user attempts to read it, not when we send it.	 */#ifndef	USE_TERMIO	ltc.t_dsuspc = _POSIX_VDISABLE;#else# ifdef	VDSUSP	tmp_tc.c_cc[VDSUSP] = (cc_t)(_POSIX_VDISABLE);# endif#endif#ifdef	USE_TERMIO	/*	 * If the VEOL character is already set, then use VEOL2,	 * otherwise use VEOL.	 */	esc = (rlogin != _POSIX_VDISABLE) ? rlogin : escape;	if ((tmp_tc.c_cc[VEOL] != esc)# ifdef	VEOL2	    && (tmp_tc.c_cc[VEOL2] != esc)# endif	    ) {		if (tmp_tc.c_cc[VEOL] == (cc_t)(_POSIX_VDISABLE))		    tmp_tc.c_cc[VEOL] = esc;# ifdef	VEOL2		else if (tmp_tc.c_cc[VEOL2] == (cc_t)(_POSIX_VDISABLE))		    tmp_tc.c_cc[VEOL2] = esc;# endif	}#else	if (tc.t_brkc == (cc_t)(_POSIX_VDISABLE))		tc.t_brkc = esc;#endif    } else {#ifdef	SIGINFO	SIG_FUNC_RET ayt_status();	(void) signal(SIGINFO, ayt_status);#endif	/* SIGINFO */#ifdef	SIGTSTP	(void) signal(SIGTSTP, SIG_DFL);#if defined(SOLARIS) || defined(_SEQUENT_) || defined(ISC)	sigrelse(SIGTSTP);# else#  if !defined(LINUX) && !defined(SCO)	(void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));#  endif /* LINUX */# endif#endif	/* SIGTSTP */#ifndef USE_TERMIO	ltc = oltc;	tc = otc;	sb = ottyb;	lmode = olmode;#else	tmp_tc = old_tc;#endif    }#ifndef USE_TERMIO    ioctl(tin, TIOCLSET, (char *)&lmode);    ioctl(tin, TIOCSLTC, (char *)&ltc);    ioctl(tin, TIOCSETC, (char *)&tc);    ioctl(tin, TIOCSETN, (char *)&sb);#else    if (tcsetattr(tin, TCSADRAIN, &tmp_tc) < 0)	tcsetattr(tin, TCSANOW, &tmp_tc);#endif#if	(!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR))#if defined(FIONBIO)    ioctl(tin, FIONBIO, (char *)&onoff);    ioctl(tout, FIONBIO, (char *)&onoff);#else#ifdef O_NDELAY    if (onoff) {        fcntl(tin, F_SETFL, (fcntl(tin, F_GETFL, 0) | O_NDELAY));        fcntl(tout, F_SETFL, (fcntl(tout, F_GETFL, 0) | O_NDELAY));    } else {        fcntl(tin, F_SETFL, (fcntl(tin, F_GETFL, 0) &~ O_NDELAY));        fcntl(tout, F_SETFL, (fcntl(tout, F_GETFL, 0) &~ O_NDELAY));    }#endif#endif#endif	/* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */#if	defined(TN3270)    if (noasynchtty == 0) {	ioctl(tin, FIOASYNC, (char *)&onoff);    }#endif	/* defined(TN3270) */}#ifndef	B19200# define B19200 B9600#endif#ifndef	B38400# define B38400 B19200#endif/* * This code assumes that the values B0, B50, B75... * are in ascending order.  They do not have to be * contiguous. */struct termspeeds {	long speed;	long value;} termspeeds[] = {	{ 0,     B0 },     { 50,    B50 },   { 75,    B75 },	{ 110,   B110 },   { 134,   B134 },  { 150,   B150 },	{ 200,   B200 },   { 300,   B300 },  { 600,   B600 },	{ 1200,  B1200 },  { 1800,  B1800 }, { 2400,  B2400 },	{ 4800,  B4800 },  { 9600,  B9600 }, { 19200, B19200 },	{ 38400, B38400 }, { -1,    B38400 }};    voidTerminalSpeeds(ispeed, ospeed)    long *ispeed;    long *ospeed;{    register struct termspeeds *tp;    register long in, out;    out = cfgetospeed(&old_tc);    in = cfgetispeed(&old_tc);    if (in == 0)	in = out;    tp = termspeeds;    while ((tp->speed != -1) && (tp->value < in))	tp++;    *ispeed = tp->speed;    tp = termspeeds;    while ((tp->speed != -1) && (tp->value < out))	tp++;    *ospeed = tp->speed;}    intTerminalWindowSize(rows, cols)    long *rows, *cols;{#ifdef	TIOCGWINSZ    struct winsize ws;    if (ioctl(fileno(stdin), TIOCGWINSZ, (char *)&ws) >= 0) {	*rows = ws.ws_row;	*cols = ws.ws_col;	return 1;    }#endif	/* TIOCGWINSZ */    return 0;}    intNetClose(fd)    int	fd;{    return close(fd);}    voidNetNonblockingIO(fd, onoff)    int fd;    int onoff;{#ifdef FIONBIO      ioctl(fd, FIONBIO, (char *)&onoff);#else#ifdef O_NDELAY    if (onoff)        fcntl(fd, F_SETFL, (fcntl(fd, F_GETFL, 0) | O_NDELAY));    else        fcntl(fd, F_SETFL, (fcntl(fd, F_GETFL, 0) &~ O_NDELAY));#endif#endif}#if	defined(TN3270)    voidNetSigIO(fd, onoff)    int fd;    int onoff;{    ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */}    voidNetSetPgrp(fd)    int fd;{    int myPid;    myPid = getpid();    fcntl(fd, F_SETOWN, myPid);}#endif	/*defined(TN3270)*//* * Various signal handling routines. */    /* ARGSUSED */    static SIG_FUNC_RETdeadpeer(sig)    int sig;{	setcommandmode();	longjmp(peerdied, -1);}    /* ARGSUSED */    static SIG_FUNC_RETintr(sig)    int sig;{#ifdef SOLARIS    (void) signal(SIGINT, intr);#endif    if (localchars) {	intp();	return;    }    setcommandmode();    longjmp(toplevel, -1);}    /* ARGSUSED */    static SIG_FUNC_RETintr2(sig)    int sig;{#ifdef SOLARIS    (void) signal(SIGQUIT, intr2);#endif    if (localchars) {#ifdef	KLUDGELINEMODE	if (kludgelinemode)	    sendbrk();	else#endif	    sendabort();	return;    }}#ifdef	SIGTSTP    /* ARGSUSED */    static SIG_FUNC_RETsusp(sig)    int sig;{    if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())	return;    if (localchars)	sendsusp();}#endif#ifdef	SIGWINCH    /* ARGSUSED */    static SIG_FUNC_RETsendwin(sig)    int sig;{    if (connected) {	sendnaws();    }}#endif#ifdef	SIGINFO    /* ARGSUSED */    static SIG_FUNC_RETayt(sig)    int sig;{    if (connected)	sendayt();    else	ayt_status();}#endif    voidsys_telnet_init(){    (void) signal(SIGINT, intr);    (void) signal(SIGQUIT, intr2);    (void) signal(SIGPIPE, deadpeer);#ifdef	SIGWINCH    (void) signal(SIGWINCH, sendwin);#endif#ifdef	SIGTSTP    (void) signal(SIGTSTP, susp);#endif#ifdef	SIGINFO    (void) signal(SIGINFO, ayt);#endif    setconnmode(0);    NetNonblockingIO(net, 1);#if	defined(TN3270)    if (noasynchnet == 0) {			/* DBX can't handle! */	NetSigIO(net, 1);	NetSetPgrp(net);    }#endif	/* defined(TN3270) */#if	defined(SO_OOBINLINE)    if (SetSockOpt(net, SOL_SOCKET, SO_OOBINLINE, 1) == -1) {	perror("SetSockOpt");    }#endif	/* defined(SO_OOBINLINE) */}/* * Process rings - * *	This routine tries to fill up/empty our various rings. * *	The parameter specifies whether this is a poll operation, *	or a block-until-something-happens operation. * *	The return value is 1 if something happened, 0 if not. */    intprocess_rings(netin, netout, netex, ttyin, ttyout, poll)    int poll;		/* If 0, then block until something to do */{    register int c;		/* One wants to be a bit careful about setting returnValue		 * to one, since a one implies we did some useful work,		 * and therefore probably won't be called to block next		 * time (TN3270 mode only).		 */    int returnValue = 0;    static struct timeval TimeValue = { 0 };    if (netout) {	FD_SET(net, &obits);    }     if (ttyout) {	FD_SET(tout, &obits);    }#if	defined(TN3270)    if (ttyin) {	FD_SET(tin, &ibits);    }#else	/* defined(TN3270) */    if (ttyin) {	FD_SET(tin, &ibits);    }#endif	/* defined(TN3270) */#if	defined(TN3270)    if (netin) {	FD_SET(net, &ibits);    }#   else /* !defined(TN3270) */    if (netin) {	FD_SET(net, &ibits);    }#   endif /* !defined(TN3270) */    if (netex) {	FD_SET(net, &xbits);    }    if ((c = select(16, &ibits, &obits, &xbits,			(poll == 0)? (struct timeval *)0 : &TimeValue)) < 0) {	if (c == -1) {		    /*		     * we can get EINTR if we are in line mode,		     * and the user does an escape (TSTP), or		     * some other signal generator.		     */	    if (errno == EINTR) {		return 0;	    }#	    if defined(TN3270)		    /*		     * we can get EBADF if we were in transparent		     * mode, and the transcom process died.		    */	    if (errno == EBADF) {			/*			 * zero the bits (even though kernel does it)			 * to make sure we are selecting on the right			 * ones.			*/		FD_ZERO(&ibits);		FD_ZERO(&obits);		FD_ZERO(&xbits);		return 0;	    }#	    endif /* defined(TN3270) */		    /* I don't like this, does it ever happen? */	    printf("sleep(5) from telnet, after select\r\n");	    sleep(5);	}	return 0;    }    /*     * Any urgent data?     */    if (FD_ISSET(net, &xbits)) {	FD_CLR(net, &xbits);	SYNCHing = 1;	(void) ttyflush(1);	/* flush already enqueued data */    }    /*     * Something to read from the network...     */    if (FD_ISSET(net, &ibits)) {	int canread;	FD_CLR(net, &ibits);	canread = ring_empty_consecutive(&netiring);#if	!defined(SO_OOBINLINE)	    /*	     * In 4.2 (and some early 4.3) systems, the	     * OOB indication and data handling in the kernel	     * is such that if two separate TCP Urgent requests	     * come in, one byte of TCP data will be overlaid.	     * This is fatal for Telnet, but we try to live	     * with it.	     *	     * In addition, in 4.2 (and...), a special protocol	     * is needed to pick up the TCP Urgent data in	     * the correct sequence.	     *	     * What we do is:  if we think we are in urgent	     * mode, we look to see if we are "at the mark".	     * If we are, we do an OOB receive.  If we run	     * this twice, we will do the OOB receive twice,	     * but the second will fail, since the second	     * time we were "at the mark", but there wasn't	     * any data there (the kernel doesn't reset	     * "at the mark" until we do a normal read).	     * Once we've read the OOB data, we go ahead	     * and do normal reads.	     *	     * There is also another problem, which is that	     * since the OOB byte we read doesn't put us	     * out of OOB state, and since that byte is most	     * likely the TELNET DM (data mark), we would	     * stay in the TELNET SYNCH (SYNCHing) state.	     * So, clocks to the rescue.  If we've "just"	     * received a DM, then we test for the	     * presence of OOB data when the receive OOB	     * fails (and AFTER we did the normal mode read	     * to clear "at the mark").	     */	if (SYNCHing) {	    int atmark;	    static int bogus_oob = 0, first = 1;	    ioctl(net, SIOCATMARK, (char *)&atmark);	    if (atmark) {		c = recv(net, netiring.supply, canread, MSG_OOB);		if ((c == -1) && (errno == EINVAL)) {		    c = recv(net, netiring.supply, canread, 0);		    if (clocks.didnetreceive < clocks.gotDM) {			SYNCHing = stilloob(net);		    }		} else if (first && c > 0) {		    /*		     * Bogosity check.  Systems based on 4.2BSD		     * do not return an error if you do a second		     * recv(MSG_OOB).  So, we do one.  If it		     * succeeds and returns exactly the same		     * data, then assume that we are running		     * on a broken system and set the bogus_oob		     * flag.  (If the data was different, then		     * we probably got some valid new data, so		     * increment the count...)		     */		    int i;		    i = recv(net, netiring.supply + c, canread - c, MSG_OOB);		    if (i == c &&			  bcmp(netiring.supply, netiring.supply + c, i) == 0) {			bogus_oob = 1;			first = 0;		    } else if (i < 0) {			bogus_oob = 0;			first = 0;		    } else			c += i;		}		if (bogus_oob && c > 0) {		    int i;		    /*		     * Bogosity.  We have to do the read		     * to clear the atmark to get out of		     * an infinate loop.		     */		    i = read(net, netiring.supply + c, canread - c);		    if (i > 0)			c += i;		}	    } else {		c = recv(net, netiring.supply, canread, 0);	    }	} else {	    c = recv(net, netiring.supply, canread, 0);	}	settimer(didnetreceive);#else	/* !defined(SO_OOBINLINE) */	c = recv(net, netiring.supply, canread, 0);#endif	/* !defined(SO_OOBINLINE) */	if (c < 0 && errno == EWOULDBLOCK) {	    c = 0;	} else if (c <= 0) {	    return -1;	}	if (netdata) {	    Dump('<', netiring.supply, c);	}	if (c)	    ring_supplied(&netiring, c);	returnValue = 1;    }    /*     * Something to read from the tty...     */    if (FD_ISSET(tin, &ibits)) {	FD_CLR(tin, &ibits);	c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));	if (c < 0 && errno == EWOULDBLOCK) {	    c = 0;	} else {	    /* EOF detection for line mode!!!! */	    if ((c == 0) && MODE_LOCAL_CHARS(globalmode) && isatty(tin)) {			/* must be an EOF... */		*ttyiring.supply = termEofChar;		c = 1;	    }	    if (c <= 0) {		return -1;	    }	    if (termdata) {		Dump('<', ttyiring.supply, c);	    }	    ring_supplied(&ttyiring, c);	}	returnValue = 1;		/* did something useful */    }    if (FD_ISSET(net, &obits)) {	FD_CLR(net, &obits);	returnValue |= netflush();    }    if (FD_ISSET(tout, &obits)) {	FD_CLR(tout, &obits);	returnValue |= (ttyflush(SYNCHing|flushout) > 0);    }    return returnValue;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?