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

📄 telnet.cc

📁 这是关于远程登陆TELNET 的源代码 已经测试过的。
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (c) 1988, 1990 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * From: @(#)telnet.c	5.53 (Berkeley) 3/22/91 */char telnet_rcsid[] = "$Id: telnet.cc,v 1.36 2000/07/23 03:24:53 dholland Exp $";#include <string.h>#include <sys/types.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <arpa/telnet.h>#include <ctype.h>#include "ring.h"#include "defines.h"#include "externs.h"#include "types.h"#include "environ.h"#include "proto.h"#include "ptrarray.h"#include "netlink.h"#include "terminal.h"/* * Due to lossage in some linux distributions/kernel releases/libc versions * this must come *after* termios.h (which is included in externs.h) */#include <termcap.h>#ifdef USE_NCURSES#include <term.h>#endif#define	strip(x)	((x)&0x7f)static unsigned char subbuffer[SUBBUFSIZE];static unsigned char *subpointer, *subend;	 /* buffer for sub-options */#define	SB_CLEAR()	subpointer = subbuffer;#define	SB_TERM()	{ subend = subpointer; SB_CLEAR(); }#define	SB_ACCUM(c)	if (subpointer < (subbuffer+sizeof subbuffer)) { \  *subpointer++ = (c); \			 }#define	SB_GET()	(*subpointer++)#define	SB_PEEK()	(*subpointer)#define	SB_EOF()	(subpointer >= subend)#define	SB_LEN()	(subend - subpointer)char	options[256];		/* The combined options */char	do_dont_resp[256];char	will_wont_resp[256];inteight = 0,  autologin = 0,	/* Autologin anyone? */  skiprc = 0,  connected,  showoptions,  In3270,		/* Are we in 3270 mode? */  ISend,		/* trying to send network data in */  debug = 0,  crmod,  crlf,		/* Should '\r' be mapped to <CR><LF> (or <CR><NUL>)? */#if	defined(TN3270)  noasynchtty = 0,/* User specified "-noasynch" on command line */  noasynchnet = 0,/* User specified "-noasynch" on command line */  askedSGA = 0,	/* We have talked about suppress go ahead */#endif	/* defined(TN3270) */  telnetport,  SYNCHing,	/* we are in TELNET SYNCH mode */  flushout,	/* flush output */  autoflush = 0,	/* flush output when interrupting? */  autosynch,	/* send interrupt characters with SYNCH? */  localflow,	/* we handle flow control locally */  localchars,	/* we recognize interrupt/quit */  donelclchars,	/* the user has set "localchars" */  donebinarytoggle,	/* the user has put us in binary */  dontlecho,	/* do we suppress local echoing right now? */  globalmode;char *prompt = 0;cc_t escapechar;cc_t rlogin;#ifdef	KLUDGELINEMODEcc_t echoc;#endif/* * Telnet receiver states for fsm */#define	TS_DATA		0#define	TS_IAC		1#define	TS_WILL		2#define	TS_WONT		3#define	TS_DO		4#define	TS_DONT		5#define	TS_CR		6#define	TS_SB		7		/* sub-option collection */#define	TS_SE		8		/* looking for sub-option end */static int telrcv_state;sigjmp_buf toplevel;sigjmp_buf peerdied;int flushline;int linemode;#ifdef	KLUDGELINEMODEint kludgelinemode = 1;#endif/* * The following are some clocks used to decide how to interpret * the relationship between various variables. */Clocks clocks;#ifdef	notdefModelist modelist[] = {  { "telnet command mode", COMMAND_LINE },  { "character-at-a-time mode", 0 },  { "character-at-a-time mode (local echo)", LOCAL_ECHO|LOCAL_CHARS },  { "line-by-line mode (remote echo)", LINE | LOCAL_CHARS },  { "line-by-line mode", LINE | LOCAL_ECHO | LOCAL_CHARS },  { "line-by-line mode (local echoing suppressed)", LINE | LOCAL_CHARS },  { "3270 mode", 0 },};#endif/* * Initialize telnet environment. */void init_telnet(void) {  env_init();  cmdtab_init();    SB_CLEAR();  memset(options, 0, sizeof(options));    connected = In3270 = ISend = localflow = donebinarytoggle = 0;    SYNCHing = 0;    /* Don't change NetTrace */    escapechar = CONTROL(']');  rlogin = _POSIX_VDISABLE;#ifdef	KLUDGELINEMODE  echoc = CONTROL('E');#endif    flushline = 1;  telrcv_state = TS_DATA;}#if 0#include <stdarg.h>static void printring(Ring *ring, const char *format, ...) {  va_list ap;  char buffer[100];		/* where things go */  char *ptr;  char *string;  int i;    va_start(ap, format);    ptr = buffer;    while ((i = *format++) != 0) {    if (i == '%') {      i = *format++;      switch (i) {      case 'c':	*ptr++ = va_arg(ap, int);	break;      case 's':	string = va_arg(ap, char *);	ring->supply_data(buffer, ptr-buffer);	ring->supply_data(string, strlen(string));	ptr = buffer;	break;      case 0:	ExitString("printring: trailing %%.\n", 1);	/*NOTREACHED*/      default:	ExitString("printring: unknown format character.\n", 1);	/*NOTREACHED*/      }    }     else {      *ptr++ = i;    }  }  ring->supply_data(buffer, ptr-buffer);}#endif/* * These routines are in charge of sending option negotiations * to the other side. * * The basic idea is that we send the negotiation if either side * is in disagreement as to what the current state should be. */void send_do(int c, int init) {  if (init) {    if (((do_dont_resp[c] == 0) && my_state_is_do(c)) ||	my_want_state_is_do(c))      return;    set_my_want_state_do(c);    do_dont_resp[c]++;  }  NET2ADD(IAC, DO);  NETADD(c);  printoption("SENT", DO, c);}void send_dont(int c, int init) {  if (init) {    if (((do_dont_resp[c] == 0) && my_state_is_dont(c)) ||	my_want_state_is_dont(c))      return;    set_my_want_state_dont(c);    do_dont_resp[c]++;  }  NET2ADD(IAC, DONT);  NETADD(c);  printoption("SENT", DONT, c);}void send_will(int c, int init) {  if (init) {    if (((will_wont_resp[c] == 0) && my_state_is_will(c)) ||	my_want_state_is_will(c))      return;    set_my_want_state_will(c);    will_wont_resp[c]++;  }  NET2ADD(IAC, WILL);  NETADD(c);  printoption("SENT", WILL, c);}void send_wont(int c, int init) {  if (init) {    if (((will_wont_resp[c] == 0) && my_state_is_wont(c)) ||	my_want_state_is_wont(c))      return;    set_my_want_state_wont(c);    will_wont_resp[c]++;  }  NET2ADD(IAC, WONT);  NETADD(c);  printoption("SENT", WONT, c);}void willoption(int option) {  int new_state_ok = 0;    if (do_dont_resp[option]) {    --do_dont_resp[option];    if (do_dont_resp[option] && my_state_is_do(option))      --do_dont_resp[option];  }    if ((do_dont_resp[option] == 0) && my_want_state_is_dont(option)) {    switch (option) {    case TELOPT_ECHO:#if defined(TN3270)      /*       * The following is a pain in the rear-end.       * Various IBM servers (some versions of Wiscnet,       * possibly Fibronics/Spartacus, and who knows who       * else) will NOT allow us to send "DO SGA" too early       * in the setup proceedings.  On the other hand,       * 4.2 servers (telnetd) won't set SGA correctly.       * So, we are stuck.  Empirically (but, based on       * a VERY small sample), the IBM servers don't send       * out anything about ECHO, so we postpone our sending       * "DO SGA" until we see "WILL ECHO" (which 4.2 servers       * DO send).       */      {	if (askedSGA == 0) {	  askedSGA = 1;	  if (my_want_state_is_dont(TELOPT_SGA))	    send_do(TELOPT_SGA, 1);	}      }      /* Fall through */    case TELOPT_EOR:#endif /* TN3270 */    case TELOPT_BINARY:    case TELOPT_SGA:      settimer(modenegotiated);      /* FALL THROUGH */    case TELOPT_STATUS:      new_state_ok = 1;      break;          case TELOPT_TM:      if (flushout)	flushout = 0;      /*       * Special case for TM.  If we get back a WILL,       * pretend we got back a WONT.       */      set_my_want_state_dont(option);      set_my_state_dont(option);      return;			/* Never reply to TM will's/wont's */          case TELOPT_LINEMODE:    default:      break;    }        if (new_state_ok) {      set_my_want_state_do(option);      send_do(option, 0);      setconnmode(0);		/* possibly set new tty mode */    }     else {      do_dont_resp[option]++;      send_dont(option, 0);    }  }  set_my_state_do(option);}void wontoption(int option) {  if (do_dont_resp[option]) {    --do_dont_resp[option];    if (do_dont_resp[option] && my_state_is_dont(option))      --do_dont_resp[option];  }    if ((do_dont_resp[option] == 0) && my_want_state_is_do(option)) {        switch (option) {      #ifdef	KLUDGELINEMODE    case TELOPT_SGA:      if (!kludgelinemode)	break;      /* FALL THROUGH */#endif    case TELOPT_ECHO:      settimer(modenegotiated);      break;          case TELOPT_TM:      if (flushout)	flushout = 0;      set_my_want_state_dont(option);      set_my_state_dont(option);      return;		/* Never reply to TM will's/wont's */          default:      break;    }    set_my_want_state_dont(option);    if (my_state_is_do(option))      send_dont(option, 0);    setconnmode(0);			/* Set new tty mode */  }   else if (option == TELOPT_TM) {    /*     * Special case for TM.     */    if (flushout)      flushout = 0;    set_my_want_state_dont(option);  }  set_my_state_dont(option);}static void dooption(int option) {  int new_state_ok = 0;    if (will_wont_resp[option]) {    --will_wont_resp[option];    if (will_wont_resp[option] && my_state_is_will(option))      --will_wont_resp[option];  }    if (will_wont_resp[option] == 0) {    if (my_want_state_is_wont(option)) {            switch (option) {	      case TELOPT_TM:	/*	 * Special case for TM.  We send a WILL, but pretend	 * we sent WONT.	 */	send_will(option, 0);	set_my_want_state_wont(TELOPT_TM);	set_my_state_wont(TELOPT_TM);	return;	#	if defined(TN3270)      case TELOPT_EOR:		/* end of record */#	endif	/* defined(TN3270) */      case TELOPT_BINARY:		/* binary mode */      case TELOPT_NAWS:		/* window size */      case TELOPT_TSPEED:		/* terminal speed */      case TELOPT_LFLOW:		/* local flow control */      case TELOPT_TTYPE:		/* terminal type option */      case TELOPT_SGA:		/* no big deal */      case TELOPT_ENVIRON:	/* environment variable option */	new_state_ok = 1;	break;	      case TELOPT_XDISPLOC:	/* X Display location */	if (env_getvalue("DISPLAY", 0))	  new_state_ok = 1;	break;	      case TELOPT_LINEMODE:#ifdef	KLUDGELINEMODE	kludgelinemode = 0;	send_do(TELOPT_SGA, 1);#endif	set_my_want_state_will(TELOPT_LINEMODE);	send_will(option, 0);	set_my_state_will(TELOPT_LINEMODE);	slc_init();	return;	      case TELOPT_ECHO:		/* We're never going to echo... */      default:	break;      }            if (new_state_ok) {	set_my_want_state_will(option);	send_will(option, 0);	setconnmode(0);			/* Set new tty fmode */      }       else {	will_wont_resp[option]++;	send_wont(option, 0);      }    }     else {      /*       * Handle options that need more things done after the       * other side has acknowledged the option.       */      switch (option) {      case TELOPT_LINEMODE:#ifdef	KLUDGELINEMODE	kludgelinemode = 0;	send_do(TELOPT_SGA, 1);#endif	set_my_state_will(option);	slc_init();	send_do(TELOPT_SGA, 0);	return;      }    }  }  set_my_state_will(option);}static void dontoption(int option) {  if (will_wont_resp[option]) {    --will_wont_resp[option];    if (will_wont_resp[option] && my_state_is_wont(option))      --will_wont_resp[option];  }    if ((will_wont_resp[option] == 0) && my_want_state_is_will(option)) {    switch (option) {

⌨️ 快捷键说明

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