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

📄 telnetdaaa.c

📁 经典的unix下telnetd代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	init_termdriver(f, p, interrupt, sendbrk);#endif#if	defined(SO_OOBINLINE)	(void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE,				(char *)&on, sizeof on);#endif	/* defined(SO_OOBINLINE) */#ifdef	SIGTSTP	(void) signal(SIGTSTP, SIG_IGN);#endif#ifdef	SIGTTOU	/*	 * Ignoring SIGTTOU keeps the kernel from blocking us	 * in ttioct() in /sys/tty.c.	 */	(void) signal(SIGTTOU, SIG_IGN);#endif	(void) signal(SIGCHLD, cleanup);#if	defined(CRAY2) && defined(UNICOS5)	/*	 * Cray-2 will send a signal when pty modes are changed by slave	 * side.  Set up signal handler now.	 */	if ((int)signal(SIGUSR1, termstat) < 0)		perror("signal");	else if (ioctl(p, TCSIGME, (char *)SIGUSR1) < 0)		perror("ioctl:TCSIGME");	/*	 * Make processing loop check terminal characteristics early on.	 */	termstat();#endif#ifdef  TIOCNOTTY	{		register int t;		t = open(_PATH_TTY, O_RDWR);		if (t >= 0) {			(void) ioctl(t, TIOCNOTTY, (char *)0);			(void) close(t);		}	}#endif#if	defined(CRAY) && defined(NEWINIT) && defined(TIOCSCTTY)	(void) setsid();	ioctl(p, TIOCSCTTY, 0);#endif	/*	 * Show banner that getty never gave.	 *	 * We put the banner in the pty input buffer.  This way, it	 * gets carriage return null processing, etc., just like all	 * other pty --> client data.	 */#if	!defined(CRAY) || !defined(NEWINIT)	if (getenv("USER"))		hostinfo = 0;#endif	if (getent(defent, "default") == 1) {		char *Getstr();		char *cp=defstrs;		HE = Getstr("he", &cp);		HN = Getstr("hn", &cp);		IM = Getstr("im", &cp);		if (HN && *HN) {			(void) strncpy(host_name, HN, sizeof(host_name)-1);			hostname[sizeof(host_name)-1] = '\0';		}		if (IM == 0)			IM = "";	} else {		IM = DEFAULT_IM;		HE = 0;	}	edithost(HE, host_name);	if (hostinfo && *IM)		putf(IM, ptyibuf2);	if (pcc)		(void) strncat(ptyibuf2, ptyip, pcc+1);	ptyip = ptyibuf2;	pcc = strlen(ptyip);#ifdef	LINEMODE	/*	 * Last check to make sure all our states are correct.	 */	init_termbuf();	localstat();#endif	/* LINEMODE */	DIAG(TD_REPORT,		{sprintf(nfrontp, "td: Entering processing loop\r\n");		 nfrontp += strlen(nfrontp);});#ifdef	convex	startslave(host);#endif	nfd = ((f > p) ? f : p) + 1;	for (;;) {		fd_set ibits, obits, xbits;		register int c;		if (ncc < 0 && pcc < 0)			break;#if	defined(CRAY2) && defined(UNICOS5)		if (needtermstat)			_termstat();#endif	/* defined(CRAY2) && defined(UNICOS5) */		FD_ZERO(&ibits);		FD_ZERO(&obits);		FD_ZERO(&xbits);		/*		 * Never look for input if there's still		 * stuff in the corresponding output buffer		 */		if (nfrontp - nbackp || pcc > 0) {			FD_SET(f, &obits);		} else {			FD_SET(p, &ibits);		}		if (pfrontp - pbackp || ncc > 0) {			FD_SET(p, &obits);		} else {			FD_SET(f, &ibits);		}		if (!SYNCHing) {			FD_SET(f, &xbits);		}		if ((c = select(nfd, &ibits, &obits, &xbits,						(struct timeval *)0)) < 1) {			if (c == -1) {				if (errno == EINTR) {					continue;				}			}			sleep(5);			continue;		}		/*		 * Any urgent data?		 */		if (FD_ISSET(net, &xbits)) {		    SYNCHing = 1;		}		/*		 * Something to read from the network...		 */		if (FD_ISSET(net, &ibits)) {#if	!defined(SO_OOBINLINE)			/*			 * In 4.2 (and 4.3 beta) 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;			(void) ioctl(net, SIOCATMARK, (char *)&atmark);			if (atmark) {			    ncc = recv(net, netibuf, sizeof (netibuf), MSG_OOB);			    if ((ncc == -1) && (errno == EINVAL)) {				ncc = read(net, netibuf, sizeof (netibuf));				if (sequenceIs(didnetreceive, gotDM)) {				    SYNCHing = stilloob(net);				}			    }			} else {			    ncc = read(net, netibuf, sizeof (netibuf));			}		    } else {			ncc = read(net, netibuf, sizeof (netibuf));		    }		    settimer(didnetreceive);#else	/* !defined(SO_OOBINLINE)) */		    ncc = read(net, netibuf, sizeof (netibuf));#endif	/* !defined(SO_OOBINLINE)) */		    if (ncc < 0 && errno == EWOULDBLOCK)			ncc = 0;		    else {			if (ncc <= 0) {			    break;			}			netip = netibuf;		    }		    DIAG((TD_REPORT | TD_NETDATA),			    {sprintf(nfrontp, "td: netread %d chars\r\n", ncc);			     nfrontp += strlen(nfrontp);});		    DIAG(TD_NETDATA, printdata("nd", netip, ncc));		}		/*		 * Something to read from the pty...		 */		if (FD_ISSET(p, &ibits)) {#ifndef	STREAMSPTY			pcc = read(p, ptyibuf, BUFSIZ);#else			pcc = readstream(p, ptyibuf, BUFSIZ);#endif			/*			 * On some systems, if we try to read something			 * off the master side before the slave side is			 * opened, we get EIO.			 */			if (pcc < 0 && (errno == EWOULDBLOCK ||#ifdef	EAGAIN					errno == EAGAIN ||#endif					errno == EIO)) {				pcc = 0;			} else {				if (pcc <= 0)					break;#if	!defined(CRAY2) || !defined(UNICOS5)#ifdef	LINEMODE				/*				 * If ioctl from pty, pass it through net				 */				if (ptyibuf[0] & TIOCPKT_IOCTL) {					copy_termbuf(ptyibuf+1, pcc-1);					localstat();					pcc = 1;				}#endif	/* LINEMODE */				if (ptyibuf[0] & TIOCPKT_FLUSHWRITE) {					netclear();	/* clear buffer back */#ifndef	NO_URGENT					/*					 * There are client telnets on some					 * operating systems get screwed up					 * royally if we send them urgent					 * mode data.					 */					*nfrontp++ = IAC;					*nfrontp++ = DM;					neturg = nfrontp-1; /* off by one XXX */					DIAG(TD_OPTIONS,					    printoption("td: send IAC", DM));#endif				}				if (his_state_is_will(TELOPT_LFLOW) &&				    (ptyibuf[0] &				     (TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))) {					int newflow =					    ptyibuf[0] & TIOCPKT_DOSTOP ? 1 : 0;					if (newflow != flowmode) {						flowmode = newflow;						(void) sprintf(nfrontp,							"%c%c%c%c%c%c",							IAC, SB, TELOPT_LFLOW,							flowmode ? LFLOW_ON								 : LFLOW_OFF,							IAC, SE);						nfrontp += 6;						DIAG(TD_OPTIONS, printsub('>',						    (unsigned char *)nfrontp-4,						    4););					}				}				pcc--;				ptyip = ptyibuf+1;#else	/* defined(CRAY2) && defined(UNICOS5) */				if (!uselinemode) {					unpcc = pcc;					unptyip = ptyibuf;					pcc = term_output(&unptyip, ptyibuf2,								&unpcc, BUFSIZ);					ptyip = ptyibuf2;				} else					ptyip = ptyibuf;#endif	/* defined(CRAY2) && defined(UNICOS5) */			}		}		while (pcc > 0) {			if ((&netobuf[BUFSIZ] - nfrontp) < 2)				break;			c = *ptyip++ & 0377, pcc--;			if (c == IAC)				*nfrontp++ = c;#if	defined(CRAY2) && defined(UNICOS5)			else if (c == '\n' &&				     my_state_is_wont(TELOPT_BINARY) && newmap)				*nfrontp++ = '\r';#endif	/* defined(CRAY2) && defined(UNICOS5) */			*nfrontp++ = c;			if ((c == '\r') && (my_state_is_wont(TELOPT_BINARY))) {				if (pcc > 0 && ((*ptyip & 0377) == '\n')) {					*nfrontp++ = *ptyip++ & 0377;					pcc--;				} else					*nfrontp++ = '\0';			}		}#if	defined(CRAY2) && defined(UNICOS5)		/*		 * If chars were left over from the terminal driver,		 * note their existence.		 */		if (!uselinemode && unpcc) {			pcc = unpcc;			unpcc = 0;			ptyip = unptyip;		}#endif	/* defined(CRAY2) && defined(UNICOS5) */		if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0)			netflush();		if (ncc > 0)			telrcv();		if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0)			ptyflush();	}	cleanup(0);}  /* end of telnet */#ifndef	TCSIG# ifdef	TIOCSIG#  define TCSIG TIOCSIG# endif#endif#ifdef	STREAMSPTYint flowison = -1;  /* current state of flow: -1 is unknown */int readstream(p, ibuf, bufsize)	int p;	char *ibuf;	int bufsize;{	int flags = 0;	int ret = 0;	struct termios *tsp;	struct termio *tp;	struct iocblk *ip;	char vstop, vstart;	int ixon;	int newflow;	strbufc.maxlen = BUFSIZ;	strbufc.buf = (char *)ctlbuf;	strbufd.maxlen = bufsize-1;	strbufd.len = 0;	strbufd.buf = ibuf+1;	ibuf[0] = 0;	ret = getmsg(p, &strbufc, &strbufd, &flags);	if (ret < 0)  /* error of some sort -- probably EAGAIN */		return(-1);	if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {		/* data message */		if (strbufd.len > 0) {			/* real data */			return(strbufd.len + 1);	/* count header char */		} else {			/* nothing there */			errno = EAGAIN;			return(-1);		}	}	/*	 * It's a control message.  Return 1, to look at the flag we set	 */	switch (ctlbuf[0]) {	case M_FLUSH:		if (ibuf[1] & FLUSHW)			ibuf[0] = TIOCPKT_FLUSHWRITE;		return(1);	case M_IOCTL:		ip = (struct iocblk *) (ibuf+1);		switch (ip->ioc_cmd) {		case TCSETS:		case TCSETSW:		case TCSETSF:			tsp = (struct termios *)					(ibuf+1 + sizeof(struct iocblk));			vstop = tsp->c_cc[VSTOP];			vstart = tsp->c_cc[VSTART];			ixon = tsp->c_iflag & IXON;			break;		case TCSETA:		case TCSETAW:		case TCSETAF:			tp = (struct termio *) (ibuf+1 + sizeof(struct iocblk));			vstop = tp->c_cc[VSTOP];			vstart = tp->c_cc[VSTART];			ixon = tp->c_iflag & IXON;			break;		default:			errno = EAGAIN;			return(-1);		}		newflow =  (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;		if (newflow != flowison) {  /* it's a change */			flowison = newflow;			ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;			return(1);		}	}	/* nothing worth doing anything about */	errno = EAGAIN;	return(-1);}#endif /* STREAMSPTY *//* * Send interrupt to process on other side of pty. * If it is in raw mode, just write NULL; * otherwise, write intr char. */	voidinterrupt(){	ptyflush();	/* half-hearted */#if defined(STREAMSPTY) && defined(TIOCSIGNAL)	/* Streams PTY style ioctl to post a signal */	{		int sig = SIGINT;		(void) ioctl(pty, TIOCSIGNAL, &sig);		(void) ioctl(pty, I_FLUSH, FLUSHR);	}#else#ifdef	TCSIG	(void) ioctl(pty, TCSIG, (char *)SIGINT);#else	/* TCSIG */	init_termbuf();	*pfrontp++ = slctab[SLC_IP].sptr ?			(unsigned char)*slctab[SLC_IP].sptr : '\177';#endif	/* TCSIG */#endif}/* * Send quit to process on other side of pty. * If it is in raw mode, just write NULL; * otherwise, write quit char. */	voidsendbrk(){	ptyflush();	/* half-hearted */#ifdef	TCSIG	(void) ioctl(pty, TCSIG, (char *)SIGQUIT);#else	/* TCSIG */	init_termbuf();	*pfrontp++ = slctab[SLC_ABORT].sptr ?			(unsigned char)*slctab[SLC_ABORT].sptr : '\034';#endif	/* TCSIG */}	voidsendsusp(){#ifdef	SIGTSTP	ptyflush();	/* half-hearted */# ifdef	TCSIG	(void) ioctl(pty, TCSIG, (char *)SIGTSTP);# else	/* TCSIG */	*pfrontp++ = slctab[SLC_SUSP].sptr ?			(unsigned char)*slctab[SLC_SUSP].sptr : '\032';# endif	/* TCSIG */#endif	/* SIGTSTP */}/* * When we get an AYT, if ^T is enabled, use that.  Otherwise, * just send back "[Yes]". */	voidrecv_ayt(){#if	defined(SIGINFO) && defined(TCSIG)	if (slctab[SLC_AYT].sptr && *slctab[SLC_AYT].sptr != _POSIX_VDISABLE) {		(void) ioctl(pty, TCSIG, (char *)SIGINFO);		return;	}#endif	(void) strcpy(nfrontp, "\r\n[Yes]\r\n");	nfrontp += 9;}	voiddoeof(){	init_termbuf();#if	defined(LINEMODE) && defined(USE_TERMIO) && (VEOF == VMIN)	if (!tty_isediting()) {		extern char oldeofc;		*pfrontp++ = oldeofc;		return;	}#endif	*pfrontp++ = slctab[SLC_EOF].sptr ?			(unsigned char)*slctab[SLC_EOF].sptr : '\004';}

⌨️ 快捷键说明

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