⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys_bsd.c

📁 linux下c语言编写的telnet客户端程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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	void ayt_status();	(void) signal(SIGINFO, (void (*)(int))ayt_status);#endif#ifdef	SIGTSTP	(void) signal(SIGTSTP, SIG_DFL);# ifndef SOLARIS	(void) sigsetmask(sigblock(0) & ~(1<<(SIGTSTP-1)));# else	SOLARIS	(void) sigrelse(SIGTSTP);# endif	SOLARIS#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(sysV88)    ioctl(tin, FIONBIO, (char *)&onoff);    ioctl(tout, FIONBIO, (char *)&onoff);# endif#endif	/* (!defined(TN3270)) || ((!defined(NOT43)) || defined(PUTCHAR)) */#if	defined(TN3270)    if (noasynchtty == 0) {	ioctl(tin, FIOASYNC, (char *)&onoff);    }#endif	/* defined(TN3270) */}/* * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD). */#if B4800 != 4800#define	DECODE_BAUD#endif#ifdef	DECODE_BAUD#ifndef	B7200#define B7200   B4800#endif#ifndef	B14400#define B14400  B9600#endif#ifndef	B19200# define B19200 B14400#endif#ifndef	B28800#define B28800  B19200#endif#ifndef	B38400# define B38400 B28800#endif#ifndef B57600#define B57600  B38400#endif#ifndef B76800#define B76800  B57600#endif#ifndef B115200#define B115200 B76800#endif#ifndef B230400#define B230400 B115200#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 },   { 7200,  B7200 },  { 9600,   B9600 },	{ 14400,  B14400 },  { 19200, B19200 }, { 28800,  B28800 },	{ 38400,  B38400 },  { 57600, B57600 }, { 115200, B115200 },	{ 230400, B230400 }, { -1,    B230400 }};#endif	/* DECODE_BAUD */    voidTerminalSpeeds(long *ispeed, long *ospeed){#ifdef	DECODE_BAUD    struct termspeeds *tp;#endif	/* DECODE_BAUD */    long in, out;    out = cfgetospeed(&old_tc);    in = cfgetispeed(&old_tc);    if (in == 0)	in = out;#ifdef	DECODE_BAUD    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;#else	/* DECODE_BAUD */	*ispeed = in;	*ospeed = out;#endif	/* DECODE_BAUD */}    intTerminalWindowSize(long *rows, long *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(int fd){    return close(fd);}    voidNetNonblockingIO(int fd, int onoff){    ioctl(fd, FIONBIO, (char *)&onoff);}#if	defined(TN3270)    voidNetSigIO(int fd, int onoff){    ioctl(fd, FIOASYNC, (char *)&onoff);	/* hear about input */}    voidNetSetPgrp(int fd){    int myPid;    myPid = getpid();    fcntl(fd, F_SETOWN, myPid);}#endif	/*defined(TN3270)*//* * Various signal handling routines. */    /* ARGSUSED */    voiddeadpeer(int sig){    (void)sig;    setcommandmode();    siglongjmp(peerdied, -1);}    /* ARGSUSED */    voidintr(int sig){    (void)sig;    if (localchars) {	intp();	return;    }    setcommandmode();    siglongjmp(toplevel, -1);}    /* ARGSUSED */    voidintr2(int sig){    (void)sig;    if (localchars) {#ifdef	KLUDGELINEMODE	if (kludgelinemode)	    sendbrk();	else#endif	    sendabort();	return;    }}#ifdef	SIGTSTP    /* ARGSUSED */    voidsusp(int sig){    (void)sig;    if ((rlogin != _POSIX_VDISABLE) && rlogin_susp())	return;    if (localchars)	sendsusp();}#endif#ifdef	SIGWINCH    /* ARGSUSED */    voidsendwin(int sig){    (void)sig;    if (connected) {	sendnaws();    }}#endif#ifdef	SIGINFO    /* ARGSUSED */    voidayt(int sig){    (void)sig;    if (connected)	sendayt();    else	ayt_status();}#endif    voidsys_telnet_init(void){    (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(int netin, int netout, int netex, int ttyin, int ttyout, int poll)	/* If poll == 0, then block until something to do */{    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, 0 };    int maxfd = -1;    int tmp;    if ((netout || netin || netex) && net > maxfd)	maxfd = net;    if (ttyout && tout > maxfd)	maxfd = tout;    if (ttyin && tin > maxfd)	maxfd = tin;    tmp = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask);    if (tmp > fdsn) {	if (ibitsp)	    free(ibitsp);	if (obitsp)	    free(obitsp);	if (xbitsp)	    free(xbitsp);	fdsn = tmp;	if ((ibitsp = (fd_set *)malloc(fdsn)) == NULL)	    err(1, "malloc");	if ((obitsp = (fd_set *)malloc(fdsn)) == NULL)	    err(1, "malloc");	if ((xbitsp = (fd_set *)malloc(fdsn)) == NULL)	    err(1, "malloc");	memset(ibitsp, 0, fdsn);	memset(obitsp, 0, fdsn);	memset(xbitsp, 0, fdsn);    }    if (netout)	FD_SET(net, obitsp);    if (ttyout)	FD_SET(tout, obitsp);    if (ttyin)	FD_SET(tin, ibitsp);    if (netin)	FD_SET(net, ibitsp);    if (netex)	FD_SET(net, xbitsp);    if ((c = select(maxfd+1, ibitsp, obitsp, xbitsp,      (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.			*/		memset(ibitsp, 0, fdsn);		memset(obitsp, 0, fdsn);		memset(xbitsp, 0, fdsn);		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, xbitsp)) {	FD_CLR(net, xbitsp);	SYNCHing = 1;	(void) ttyflush(1);	/* flush already enqueued data */    }    /*     * Something to read from the network...     */    if (FD_ISSET(net, ibitsp)) {	int canread;	FD_CLR(net, ibitsp);	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 &&			 memcmp(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, (char *)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, ibitsp)) {	FD_CLR(tin, ibitsp);	c = TerminalRead(ttyiring.supply, ring_empty_consecutive(&ttyiring));	if (c < 0 && errno == EIO)	    c = 0;	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, obitsp)) {	FD_CLR(net, obitsp);	returnValue |= netflush();    }    if (FD_ISSET(tout, obitsp)) {	FD_CLR(tout, obitsp);	returnValue |= (ttyflush(SYNCHing|flushout) > 0);    }    return returnValue;}

⌨️ 快捷键说明

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