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

📄 state.c

📁 linux下telnet服务端的源码实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  DEBUG(debug_options, 1, printsub ('<', subpointer, SB_LEN () + 2));  subchar = SB_GET ();  switch (subchar)    {    case TELOPT_TSPEED:      {	register int xspeed, rspeed;	if (his_state_is_wont (TELOPT_TSPEED))	/* Ignore if option disabled */	  break;	settimer (tspeedsubopt);	if (SB_EOF () || SB_GET () != TELQUAL_IS)	  return;	xspeed = atoi ((char *) subpointer);	while (SB_GET () != ',' && !SB_EOF ());	if (SB_EOF ())	  return;	rspeed = atoi ((char *) subpointer);	clientstat (TELOPT_TSPEED, xspeed, rspeed);	break;      }				/* end of case TELOPT_TSPEED */    case TELOPT_TTYPE:      {					static struct obstack stk;	char *p;		if (his_state_is_wont (TELOPT_TTYPE))	/* Ignore if option disabled */	  break;		settimer (ttypesubopt);	if (SB_EOF () || SB_GET () != TELQUAL_IS)	  return;		/* ??? XXX but, this is the most robust */	if (terminaltype)	  free (terminaltype);		obstack_init (&stk);	while (!SB_EOF ())	  {	    int c = tolower (SB_GET ());	    obstack_1grow (&stk, c);	  }	obstack_1grow (&stk, 0);	p = obstack_finish (&stk);	terminaltype = xstrdup (p);	obstack_free (&stk, NULL);	break;      }				/* end of case TELOPT_TTYPE */    case TELOPT_NAWS:      {	register int xwinsize, ywinsize;	if (his_state_is_wont (TELOPT_NAWS))	/* Ignore if option disabled */	  break;	if (SB_EOF ())	  return;	xwinsize = SB_GET () << 8;	if (SB_EOF ())	  return;	xwinsize |= SB_GET ();	if (SB_EOF ())	  return;	ywinsize = SB_GET () << 8;	if (SB_EOF ())	  return;	ywinsize |= SB_GET ();	clientstat (TELOPT_NAWS, xwinsize, ywinsize);	break;      }				/* end of case TELOPT_NAWS */    case TELOPT_LINEMODE:      {	register int request;	/* Ignore if option disabled */	if (his_state_is_wont (TELOPT_LINEMODE)) 	  break;	/*	 * Process linemode suboptions.	 */	if (SB_EOF ())	  break;		/* garbage was sent */	request = SB_GET ();	/* get will/wont */	if (SB_EOF ())	  break;		/* another garbage check */	if (request == LM_SLC)	  {			/* SLC is not preceeded by WILL or WONT */	    /*	     * Process suboption buffer of slc's	     */	    start_slc (1);	    do_opt_slc (subpointer, subend - subpointer);	    end_slc (0);	    break;	  }	else if (request == LM_MODE)	  {	    if (SB_EOF ())	      return;	    useeditmode = SB_GET ();	/* get mode flag */	    clientstat (LM_MODE, 0, 0);	    break;	  }	if (SB_EOF ())	  break;	switch (SB_GET ())	  {			/* what suboption? */	  case LM_FORWARDMASK:	    /*	     * According to spec, only server can send request for	     * forwardmask, and client can only return a positive response.	     * So don't worry about it.	     */	  default:	    break;	  }	break;      }				/* end of case TELOPT_LINEMODE */    case TELOPT_STATUS:      {	int mode;	if (SB_EOF ())	  break;	mode = SB_GET ();	switch (mode)	  {	  case TELQUAL_SEND:	    if (my_state_is_will (TELOPT_STATUS))	      send_status ();	    break;	  case TELQUAL_IS:	    break;	  default:	    break;	  }	break;      }				/* end of case TELOPT_STATUS */    case TELOPT_XDISPLOC:      {	if (SB_EOF () || SB_GET () != TELQUAL_IS)	  return;	settimer (xdisplocsubopt);	subpointer[SB_LEN ()] = '\0';	setenv ("DISPLAY", (char *) subpointer, 1);	break;      }				/* end of case TELOPT_XDISPLOC */#ifdef	TELOPT_NEW_ENVIRON    case TELOPT_NEW_ENVIRON:#endif    case TELOPT_OLD_ENVIRON:      {	register int c;	register char *cp, *varp, *valp;	if (SB_EOF ())	  return;	c = SB_GET ();	if (c == TELQUAL_IS)	  {	    if (subchar == TELOPT_OLD_ENVIRON)	      settimer (oenvironsubopt);	    else	      settimer (environsubopt);	  }	else if (c != TELQUAL_INFO)	  return;#ifdef	TELOPT_NEW_ENVIRON	if (subchar == TELOPT_NEW_ENVIRON)	  {	    while (!SB_EOF ())	      {		c = SB_GET ();		if ((c == NEW_ENV_VAR) || (c == ENV_USERVAR))		  break;	      }	  }	else#endif	  {#ifdef	ENV_HACK	    /*	     * We only want to do this if we haven't already decided	     * whether or not the other side has its VALUE and VAR	     * reversed.	     */	    if (env_ovar < 0)	      {		register int last = -1;		/* invalid value */		int empty = 0;		int got_var = 0, got_value = 0, got_uservar = 0;		/*		 * The other side might have its VALUE and VAR values		 * reversed.  To be interoperable, we need to determine		 * which way it is.  If the first recognized character		 * is a VAR or VALUE, then that will tell us what		 * type of client it is.  If the fist recognized		 * character is a USERVAR, then we continue scanning		 * the suboption looking for two consecutive		 * VAR or VALUE fields.  We should not get two		 * consecutive VALUE fields, so finding two		 * consecutive VALUE or VAR fields will tell us		 * what the client is.		 */		SB_SAVE ();		while (!SB_EOF ())		  {		    c = SB_GET ();		    switch (c)		      {		      case OLD_ENV_VAR:			if (last < 0 || last == OLD_ENV_VAR			    || (empty && (last == OLD_ENV_VALUE)))			  goto env_ovar_ok;			got_var++;			last = OLD_ENV_VAR;			break;		      case OLD_ENV_VALUE:			if (last < 0 || last == OLD_ENV_VALUE			    || (empty && (last == OLD_ENV_VAR)))			  goto env_ovar_wrong;			got_value++;			last = OLD_ENV_VALUE;			break;		      case ENV_USERVAR:			/* count strings of USERVAR as one */			if (last != ENV_USERVAR)			  got_uservar++;			if (empty)			  {			    if (last == OLD_ENV_VALUE)			      goto env_ovar_ok;			    if (last == OLD_ENV_VAR)			      goto env_ovar_wrong;			  }			last = ENV_USERVAR;			break;		      case ENV_ESC:			if (!SB_EOF ())			  c = SB_GET ();			/* FALL THROUGH */		      default:			empty = 0;			continue;		      }		    empty = 1;		  }		if (empty)		  {		    if (last == OLD_ENV_VALUE)		      goto env_ovar_ok;		    if (last == OLD_ENV_VAR)		      goto env_ovar_wrong;		  }		/*		 * Ok, the first thing was a USERVAR, and there		 * are not two consecutive VAR or VALUE commands,		 * and none of the VAR or VALUE commands are empty.		 * If the client has sent us a well-formed option,		 * then the number of VALUEs received should always		 * be less than or equal to the number of VARs and		 * USERVARs received.		 *		 * If we got exactly as many VALUEs as VARs and		 * USERVARs, the client has the same definitions.		 *		 * If we got exactly as many VARs as VALUEs and		 * USERVARS, the client has reversed definitions.		 */		if (got_uservar + got_var == got_value)		  {		  env_ovar_ok:		    env_ovar = OLD_ENV_VAR;		    env_ovalue = OLD_ENV_VALUE;		  }		else if (got_uservar + got_value == got_var)		  {		  env_ovar_wrong:		    env_ovar = OLD_ENV_VALUE;		    env_ovalue = OLD_ENV_VAR;		    DEBUG(debug_options, 1,			  debug_output_data (				 "ENVIRON VALUE and VAR are reversed!\r\n"));		  }	      }	    SB_RESTORE ();#endif	    while (!SB_EOF ())	      {		c = SB_GET ();		if ((c == env_ovar) || (c == ENV_USERVAR))		  break;	      }	  }	if (SB_EOF ())	  return;	cp = varp = (char *) subpointer;	valp = 0;	while (!SB_EOF ())	  {	    c = SB_GET ();	    if (subchar == TELOPT_OLD_ENVIRON)	      {		if (c == env_ovar)		  c = NEW_ENV_VAR;		else if (c == env_ovalue)		  c = NEW_ENV_VALUE;	      }	    switch (c)	      {	      case NEW_ENV_VALUE:		*cp = '\0';		cp = valp = (char *) subpointer;		break;	      case NEW_ENV_VAR:	      case ENV_USERVAR:		*cp = '\0';		if (valp)		  (void) setenv (varp, valp, 1);		else		  unsetenv (varp);		cp = varp = (char *) subpointer;		valp = 0;		break;	      case ENV_ESC:		if (SB_EOF ())		  break;		c = SB_GET ();		/* FALL THROUGH */	      default:		*cp++ = c;		break;	      }	  }	*cp = '\0';	if (valp)	  (void) setenv (varp, valp, 1);	else	  unsetenv (varp);	break;      }				/* end of case TELOPT_NEW_ENVIRON */#if	defined(AUTHENTICATION)    case TELOPT_AUTHENTICATION:      if (SB_EOF ())	break;      switch (SB_GET ())	{	case TELQUAL_SEND:	case TELQUAL_REPLY:	  /*	   * These are sent by us and cannot be sent by	   * the client.	   */	  break;	case TELQUAL_IS:	  auth_is (subpointer, SB_LEN ());	  break;	case TELQUAL_NAME:	  auth_name (subpointer, SB_LEN ());	  break;	}      break;#endif#ifdef	ENCRYPTION    case TELOPT_ENCRYPT:      if (SB_EOF ())	break;      switch (SB_GET ())	{	case ENCRYPT_SUPPORT:	  encrypt_support (subpointer, SB_LEN ());	  break;	case ENCRYPT_IS:	  encrypt_is (subpointer, SB_LEN ());	  break;	case ENCRYPT_REPLY:	  encrypt_reply (subpointer, SB_LEN ());	  break;	case ENCRYPT_START:	  encrypt_start (subpointer, SB_LEN ());	  break;	case ENCRYPT_END:	  encrypt_end ();	  break;	case ENCRYPT_REQSTART:	  encrypt_request_start (subpointer, SB_LEN ());	  break;	case ENCRYPT_REQEND:	  /*	   * We can always send an REQEND so that we cannot	   * get stuck encrypting.  We should only get this	   * if we have been able to get in the correct mode	   * anyhow.	   */	  encrypt_request_end ();	  break;	case ENCRYPT_ENC_KEYID:	  encrypt_enc_keyid (subpointer, SB_LEN ());	  break;	case ENCRYPT_DEC_KEYID:	  encrypt_dec_keyid (subpointer, SB_LEN ());	  break;	default:	  break;	}      break;#endif /* ENCRYPTION */    default:      break;    }				/* end of switch */}				/* end of suboption */voiddoclientstat (){  clientstat (TELOPT_LINEMODE, WILL, 0);}voidsend_status (){#define ADD(c) \        do { \                if (ep > ncp) \                        *ncp++ = c; \                else \                        goto trunc; \        } while (0)#define ADD_DATA(c) \        do { \                ADD(c); if (c == SE || c == IAC) ADD(c); \        } while (0)  unsigned char statusbuf[256];  unsigned char *ep;  register unsigned char *ncp;  register unsigned char i;  ncp = statusbuf;  ep = statusbuf + sizeof (statusbuf);  netflush ();			/* get rid of anything waiting to go out */  ADD (IAC);  ADD (SB);  ADD (TELOPT_STATUS);  ADD (TELQUAL_IS);  /*   * We check the want_state rather than the current state,   * because if we received a DO/WILL for an option that we   * don't support, and the other side didn't send a DONT/WONT   * in response to our WONT/DONT, then the "state" will be   * WILL/DO, and the "want_state" will be WONT/DONT.  We   * need to go by the latter.   */  for (i = 0; i < (unsigned char) NTELOPTS; i++)    {      if (my_want_state_is_will (i))	{	  ADD (WILL);	  ADD_DATA (i);	}      if (his_want_state_is_will (i))	{	  ADD (DO);	  ADD_DATA (i);	}    }  if (his_want_state_is_will (TELOPT_LFLOW))    {      ADD (SB);      ADD (TELOPT_LFLOW);      if (flowmode)	ADD (LFLOW_ON);      else	ADD (LFLOW_OFF);      ADD (SE);      if (restartany >= 0)	{	  ADD (SB);	  ADD (TELOPT_LFLOW);	  if (restartany)	    ADD (LFLOW_RESTART_ANY);	  else	    ADD (LFLOW_RESTART_XON);	  ADD (SE);	}    }  if (his_want_state_is_will (TELOPT_LINEMODE))    {      unsigned char *cp, *cpe;      int len;      ADD (SB);      ADD (TELOPT_LINEMODE);      ADD (LM_MODE);      ADD_DATA (editmode);      ADD (SE);      ADD (SB);      ADD (TELOPT_LINEMODE);      ADD (LM_SLC);      start_slc (0);      send_slc ();      len = end_slc (&cp);      for (cpe = cp + len; cp < cpe; cp++)	ADD_DATA (*cp);      ADD (SE);    }  ADD (IAC);  ADD (SE);  net_output_datalen (statusbuf, ncp - statusbuf);  netflush ();			/* Send it on its way */  DEBUG(debug_options, 1, printsub ('>', statusbuf, ncp - statusbuf));  return;trunc:  /* XXX bark? */  return;#undef ADD#undef ADD_DATA}

⌨️ 快捷键说明

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