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

📄 state.c

📁 里面包含了telnet的客户端和服务器端
💻 C
📖 第 1 页 / 共 3 页
字号:
	    set_termbuf();	    break;	case TELOPT_ECHO:	/* we should stop echoing */#ifdef	LINEMODE#ifdef	KLUDGELINEMODE	    if (lmodetype == NO_LINEMODE)#else    	    if (his_state_is_wont(TELOPT_LINEMODE))#endif#endif	    {		init_termbuf();		tty_setecho(0);		set_termbuf();	    }	    break;	case TELOPT_SGA:#if defined(LINEMODE) && defined(KLUDGELINEMODE)	    /*	     * If kludge linemode is in use, then we	     * must process an incoming do SGA for	     * linemode purposes.	     */	    if (lmodetype == KLUDGE_LINEMODE) {		/*		 * The client is asking us to turn		 * linemode on.		 */		clientstat(TELOPT_LINEMODE, WILL, 0);		/*		 * If we did not turn line mode on,		 * then what do we say?  Will SGA?		 * This violates design of telnet.		 * Gross.  Very Gross.		 */	    }	    break;#else	    set_my_want_state_wont(option);	    if (my_state_is_will(option))		send_wont(option, 0);	    set_my_state_wont(option);	    if (turn_on_sga ^= 1) send_will(option,1);	    return;#endif	/* defined(LINEMODE) && defined(KLUDGELINEMODE) */	    	 default:	    break;	}	set_my_want_state_wont(option);	if (my_state_is_will(option))	    send_wont(option, 0);    }    set_my_state_wont(option);}/* * suboption() * *	Look at the sub-option buffer, and try to be helpful to the other * side. * *	Currently we recognize: * *	Terminal type is *	Linemode *	Window size *	Terminal speed */void suboption(void) {    int subchar;    DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});    subchar = SB_GET();    switch (subchar) {     case TELOPT_TSPEED: {	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;    }    case TELOPT_TTYPE: {		/* Yaaaay! */	static char terminalname[41];	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 */	}	terminaltype = terminalname;	while ((terminaltype < (terminalname + sizeof (terminalname) -1) ) &&	       !SB_EOF()) 	{	    int c;	    c = SB_GET();	    if (isupper(c)) {		c = tolower(c);	    }	    *terminaltype++ = c;    /* accumulate name */	}	*terminaltype = 0;	terminaltype = terminalname;	break;    }    case TELOPT_NAWS: {	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;    }#ifdef	LINEMODE    case TELOPT_LINEMODE: {	register int request;	if (his_state_is_wont(TELOPT_LINEMODE))	/* Ignore if option disabled */		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);		(void) 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 */#endif    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';	(void)setenv("DISPLAY", (char *)subpointer, 1);	break;    }  /* end of case TELOPT_XDISPLOC */    case TELOPT_ENVIRON: {	register int c;	register char *cp, *varp, *valp;	if (SB_EOF())		return;	c = SB_GET();	if (c == TELQUAL_IS)		settimer(environsubopt);	else if (c != TELQUAL_INFO)		return;	while (!SB_EOF() && SB_GET() != ENV_VAR)		;	if (SB_EOF())		return;	cp = varp = (char *)subpointer;	valp = 0;	while (!SB_EOF()) {	    switch (c = SB_GET()) {	    case ENV_VALUE:		*cp = '\0';		cp = valp = (char *)subpointer;		break;			    case ENV_VAR:		*cp = '\0';		if (envvarok(varp)) {		    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:	        /* I think this test is correct... */		if (cp < subbuffer+sizeof(subbuffer)-1) *cp++ = c;		break;	    }	}	*cp = '\0';	if (envvarok(varp)) {	    if (valp)		(void)setenv(varp, valp, 1);	    else		unsetenv(varp);	}	break;    }  /* end of case TELOPT_ENVIRON */#if defined(AUTHENTICATE)    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#if defined(ENCRYPT)    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    default:	break;    }  /* end of switch */}  /* end of suboption */#ifdef LINEMODEstatic void doclientstat(void) {    clientstat(TELOPT_LINEMODE, WILL, 0);}#endif#define	ADD(c)	 *ncp++ = c;#define	ADD_DATA(c) { *ncp++ = c; if (c == SE) *ncp++ = c; }void send_status(void) {    unsigned char statusbuf[256];    register unsigned char *ncp;    register unsigned char i;        ncp = 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 < NTELOPTS; i++) {	if (my_want_state_is_will(i)) {	    ADD(WILL);	    ADD_DATA(i);	    if (i == IAC) ADD(IAC);	}	if (his_want_state_is_will(i)) {	    ADD(DO);	    ADD_DATA(i);	    if (i == IAC) ADD(IAC);	}    }    if (his_want_state_is_will(TELOPT_LFLOW)) {	ADD(SB);	ADD(TELOPT_LFLOW);	ADD(flowmode);	ADD(SE);    }#ifdef LINEMODE    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);	if (editmode == IAC) ADD(IAC);	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);    }#endif	/* LINEMODE */    ADD(IAC);    ADD(SE);    writenet(statusbuf, ncp - statusbuf);    netflush();	/* Send it on its way */    DIAG(TD_OPTIONS, {printsub('>', statusbuf, ncp - statusbuf); netflush();});}/* check that variable is safe to pass to login or shell */#if 0  /* insecure version */static int envvarok(char *varp) {    if (strncmp(varp, "LD_", strlen("LD_")) &&	strncmp(varp, "ELF_LD_", strlen("ELF_LD_")) &&	strncmp(varp, "AOUT_LD_", strlen("AOUT_LD_")) &&	strncmp(varp, "_RLD_", strlen("_RLD_")) &&	strcmp(varp, "LIBPATH") &&	strcmp(varp, "ENV") &&	strcmp(varp, "IFS"))     {	return 1;    }     else {	/* optionally syslog(LOG_INFO) here */	return 0;    }}#elsestatic int envvarok(char *varp) {    /*     * Allow only these variables.     */    if (!strcmp(varp, "TERM")) return 1;    if (!strcmp(varp, "DISPLAY")) return 1;    if (!strcmp(varp, "USER")) return 1;    if (!strcmp(varp, "LOGNAME")) return 1;    if (!strcmp(varp, "POSIXLY_CORRECT")) return 1;    /* optionally syslog(LOG_INFO) here */    return 0;}#endif

⌨️ 快捷键说明

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