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

📄 telnet.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    (void)slc_update();    setconnmode(1);	/* Make sure the character values are set */}voidslc(register unsigned char *cp, int len){	register struct spc *spcp;	register int func,level;	slc_start_reply();	for (; len >= 3; len -=3, cp +=3) {		func = cp[SLC_FUNC];		if (func == 0) {			/*			 * Client side: always ignore 0 function.			 */			continue;		}		if (func > NSLC) {			if ((cp[SLC_FLAGS] & SLC_LEVELBITS) != SLC_NOSUPPORT)				slc_add_reply(func, SLC_NOSUPPORT, 0);			continue;		}		spcp = &spc_data[func];		level = cp[SLC_FLAGS]&(SLC_LEVELBITS|SLC_ACK);		if ((cp[SLC_VALUE] == (unsigned char)spcp->val) &&		    ((level&SLC_LEVELBITS) == (spcp->flags&SLC_LEVELBITS))) {			continue;		}		if (level == (SLC_DEFAULT|SLC_ACK)) {			/*			 * This is an error condition, the SLC_ACK			 * bit should never be set for the SLC_DEFAULT			 * level.  Our best guess to recover is to			 * ignore the SLC_ACK bit.			 */			cp[SLC_FLAGS] &= ~SLC_ACK;		}		if (level == ((spcp->flags&SLC_LEVELBITS)|SLC_ACK)) {			spcp->val = (cc_t)cp[SLC_VALUE];			spcp->flags = cp[SLC_FLAGS];	/* include SLC_ACK */			continue;		}		level &= ~SLC_ACK;		if (level <= (spcp->mylevel&SLC_LEVELBITS)) {			spcp->flags = cp[SLC_FLAGS]|SLC_ACK;			spcp->val = (cc_t)cp[SLC_VALUE];		}		if (level == SLC_DEFAULT) {			if ((spcp->mylevel&SLC_LEVELBITS) != SLC_DEFAULT)				spcp->flags = spcp->mylevel;			else				spcp->flags = SLC_NOSUPPORT;		}		slc_add_reply(func, spcp->flags, spcp->val);	}	slc_end_reply();	if (slc_update())		setconnmode(1);	/* set the  new character values */}voidslc_check(){    register struct spc *spcp;    slc_start_reply();    for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {	if (spcp->valp && spcp->val != *spcp->valp) {	    spcp->val = *spcp->valp;	    if (spcp->val == (cc_t)(_POSIX_VDISABLE))		spcp->flags = SLC_NOSUPPORT;	    else		spcp->flags = spcp->mylevel;	    slc_add_reply(spcp - spc_data, spcp->flags, spcp->val);	}    }    slc_end_reply();    setconnmode(1);}unsigned char slc_reply[128];unsigned char *slc_replyp;voidslc_start_reply(){	slc_replyp = slc_reply;	*slc_replyp++ = IAC;	*slc_replyp++ = SB;	*slc_replyp++ = TELOPT_LINEMODE;	*slc_replyp++ = LM_SLC;}voidslc_add_reply(unsigned char func, unsigned char flags, cc_t value){	if ((*slc_replyp++ = func) == IAC)		*slc_replyp++ = IAC;	if ((*slc_replyp++ = flags) == IAC)		*slc_replyp++ = IAC;	if ((*slc_replyp++ = (unsigned char)value) == IAC)		*slc_replyp++ = IAC;}voidslc_end_reply(){    register int len;    *slc_replyp++ = IAC;    *slc_replyp++ = SE;    len = slc_replyp - slc_reply;    if (len <= 6)	return;    if (NETROOM() > len) {	ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply);	printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2);    }/*@*/else printf("slc_end_reply: not enough room\n");}intslc_update(){	register struct spc *spcp;	int need_update = 0;	for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) {		if (!(spcp->flags&SLC_ACK))			continue;		spcp->flags &= ~SLC_ACK;		if (spcp->valp && (*spcp->valp != spcp->val)) {			*spcp->valp = spcp->val;			need_update = 1;		}	}	return(need_update);}#ifdef	OLD_ENVIRON# ifdef	ENV_HACK/* * Earlier version of telnet/telnetd from the BSD code had * the definitions of VALUE and VAR reversed.  To ensure * maximum interoperability, we assume that the server is * an older BSD server, until proven otherwise.  The newer * BSD servers should be able to handle either definition, * so it is better to use the wrong values if we don't * know what type of server it is. */int env_auto = 1;int old_env_var = OLD_ENV_VAR;int old_env_value = OLD_ENV_VALUE;# else#  define old_env_var OLD_ENV_VAR#  define old_env_value OLD_ENV_VALUE# endif#endifvoidenv_opt(register unsigned char *buf, register int len){	register unsigned char *ep = 0, *epc = 0;	register int i;	switch(buf[0]&0xff) {	case TELQUAL_SEND:		env_opt_start();		if (len == 1) {			env_opt_add(NULL);		} else for (i = 1; i < len; i++) {			switch (buf[i]&0xff) {#ifdef	OLD_ENVIRON			case OLD_ENV_VAR:# ifdef	ENV_HACK				if (telopt_environ == TELOPT_OLD_ENVIRON				    && env_auto) {					/* Server has the same definitions */					old_env_var = OLD_ENV_VAR;					old_env_value = OLD_ENV_VALUE;				}				/* FALL THROUGH */# endif			case OLD_ENV_VALUE:				/*				 * Although OLD_ENV_VALUE is not legal, we will				 * still recognize it, just in case it is an				 * old server that has VAR & VALUE mixed up...				 */				/* FALL THROUGH */#else			case NEW_ENV_VAR:#endif			case ENV_USERVAR:				if (ep) {					*epc = 0;					env_opt_add(ep);				}				ep = epc = &buf[i+1];				break;			case ENV_ESC:				i++;				/*FALL THROUGH*/			default:				if (epc)					*epc++ = buf[i];				break;			}		}		if (ep) {			*epc = 0;			env_opt_add(ep);		}		env_opt_end(1);		break;	case TELQUAL_IS:	case TELQUAL_INFO:		/* Ignore for now.  We shouldn't get it anyway. */		break;	default:		break;	}}#define	OPT_REPLY_SIZE	256unsigned char *opt_reply;unsigned char *opt_replyp;unsigned char *opt_replyend;voidenv_opt_start(){	if (opt_reply)		opt_reply = (unsigned char *)realloc(opt_reply, OPT_REPLY_SIZE);	else		opt_reply = (unsigned char *)malloc(OPT_REPLY_SIZE);	if (opt_reply == NULL) {/*@*/		printf("env_opt_start: malloc()/realloc() failed!!!\n");		opt_reply = opt_replyp = opt_replyend = NULL;		return;	}	opt_replyp = opt_reply;	opt_replyend = opt_reply + OPT_REPLY_SIZE;	*opt_replyp++ = IAC;	*opt_replyp++ = SB;	*opt_replyp++ = telopt_environ;	*opt_replyp++ = TELQUAL_IS;}voidenv_opt_start_info(){	env_opt_start();	if (opt_replyp)	    opt_replyp[-1] = TELQUAL_INFO;}voidenv_opt_add(register unsigned char *ep){	register unsigned char *vp, c;	if (opt_reply == NULL)		/*XXX*/		return;			/*XXX*/	if (ep == NULL || *ep == '\0') {		/* Send user defined variables first. */		env_default(1, 0);		while (ep = env_default(0, 0))			env_opt_add(ep);		/* Now add the list of well know variables.  */		env_default(1, 1);		while (ep = env_default(0, 1))			env_opt_add(ep);		return;	}	vp = env_getvalue(ep);	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +				strlen((char *)ep) + 6 > opt_replyend)	{		register int len;		opt_replyend += OPT_REPLY_SIZE;		len = opt_replyend - opt_reply;		opt_reply = (unsigned char *)realloc(opt_reply, len);		if (opt_reply == NULL) {/*@*/			printf("env_opt_add: realloc() failed!!!\n");			opt_reply = opt_replyp = opt_replyend = NULL;			return;		}		opt_replyp = opt_reply + len - (opt_replyend - opt_replyp);		opt_replyend = opt_reply + len;	}	if (opt_welldefined(ep))#ifdef	OLD_ENVIRON		if (telopt_environ == TELOPT_OLD_ENVIRON)			*opt_replyp++ = old_env_var;		else#endif			*opt_replyp++ = NEW_ENV_VAR;	else		*opt_replyp++ = ENV_USERVAR;	for (;;) {		while (c = *ep++) {			switch(c&0xff) {			case IAC:				*opt_replyp++ = IAC;				break;			case NEW_ENV_VAR:			case NEW_ENV_VALUE:			case ENV_ESC:			case ENV_USERVAR:				*opt_replyp++ = ENV_ESC;				break;			}			*opt_replyp++ = c;		}		if (ep = vp) {#ifdef	OLD_ENVIRON			if (telopt_environ == TELOPT_OLD_ENVIRON)				*opt_replyp++ = old_env_value;			else#endif				*opt_replyp++ = NEW_ENV_VALUE;			vp = NULL;		} else			break;	}}intopt_welldefined(char *ep){	if ((strcmp(ep, "USER") == 0) ||	    (strcmp(ep, "DISPLAY") == 0) ||	    (strcmp(ep, "PRINTER") == 0) ||	    (strcmp(ep, "SYSTEMTYPE") == 0) ||	    (strcmp(ep, "JOB") == 0) ||	    (strcmp(ep, "ACCT") == 0))		return(1);	return(0);}voidenv_opt_end(register int emptyok){	register int len;	len = opt_replyp - opt_reply + 2;	if (emptyok || len > 6) {		*opt_replyp++ = IAC;		*opt_replyp++ = SE;		if (NETROOM() > len) {			ring_supply_data(&netoring, opt_reply, len);			printsub('>', &opt_reply[2], len - 2);		}/*@*/		else printf("slc_end_reply: not enough room\n");	}	if (opt_reply) {		free(opt_reply);		opt_reply = opt_replyp = opt_replyend = NULL;	}}inttelrcv(){    register int c;    register int scc;    register unsigned char *sbp;    int count;    int returnValue = 0;    scc = 0;    count = 0;    while (TTYROOM() > 2) {	if (scc == 0) {	    if (count) {		ring_consumed(&netiring, count);		returnValue = 1;		count = 0;	    }	    sbp = netiring.consume;	    scc = ring_full_consecutive(&netiring);	    if (scc == 0) {		/* No more data coming in */		break;	    }	}	c = *sbp++ & 0xff, scc--; count++;#ifdef	ENCRYPTION	if (decrypt_input)		c = (*decrypt_input)(c);#endif	/* ENCRYPTION */	switch (telrcv_state) {	case TS_CR:	    telrcv_state = TS_DATA;	    if (c == '\0') {		break;	/* Ignore \0 after CR */	    }	    else if ((c == '\n') && my_want_state_is_dont(TELOPT_ECHO) && !crmod) {		TTYADD(c);		break;	    }	    /* Else, fall through */	case TS_DATA:	    if (c == IAC) {		telrcv_state = TS_IAC;		break;	    }#	    if defined(TN3270)	    if (In3270) {		*Ifrontp++ = c;		while (scc > 0) {		    c = *sbp++ & 0377, scc--; count++;#ifdef	ENCRYPTION		    if (decrypt_input)			c = (*decrypt_input)(c);#endif	/* ENCRYPTION */		    if (c == IAC) {			telrcv_state = TS_IAC;			break;		    }		    *Ifrontp++ = c;		}	    } else#	    endif /* defined(TN3270) */		    /*		     * The 'crmod' hack (see following) is needed		     * since we can't * set CRMOD on output only.		     * Machines like MULTICS like to send \r without		     * \n; since we must turn off CRMOD to get proper		     * input, the mapping is done here (sigh).		     */	    if ((c == '\r') && my_want_state_is_dont(TELOPT_BINARY)) {		if (scc > 0) {		    c = *sbp&0xff;#ifdef	ENCRYPTION		    if (decrypt_input)			c = (*decrypt_input)(c);#endif	/* ENCRYPTION */		    if (c == 0) {			sbp++, scc--; count++;			/* a "true" CR */			TTYADD('\r');		    } else if (my_want_state_is_dont(TELOPT_ECHO) &&					(c == '\n')) {			sbp++, scc--; count++;			TTYADD('\n');		    } else {#ifdef	ENCRYPTION		        if (decrypt_input)			    (*decrypt_input)(-1);#endif	/* ENCRYPTION */			TTYADD('\r');			if (crmod) {				TTYADD('\n');			}		    }		} else {		    telrcv_state = TS_CR;		    TTYADD('\r');		    if (crmod) {			    TTYADD('\n');		    }		}	    } else {		TTYADD(c);	    }	    continue;	case TS_IAC:process_iac:	    switch (c) {	    case WILL:		telrcv_state = TS_WILL;		continue;	    case WONT:		telrcv_state = TS_WONT;		continue;	    case DO:		telrcv_state = TS_DO;		continue;	    case DONT:		telrcv_state = TS_DONT;		continue;	    case DM:		    /*		     * We may have missed an urgent notification,		     * so make sure we flush whatever is in the		     * buffer currently.		     */		printoption("RCVD", IAC, DM);		SYNCHing = 1;		(void) ttyflush(1);		SYNCHing = stilloob();		settimer(gotDM);		break;	    case SB:		SB_CLEAR();		telrcv_state = TS_SB;		continue;#	    if defined(TN3270)	    case EOR:		if (In3270) {		    if (Ibackp == Ifrontp) {			Ibackp = Ifrontp = Ibuf;			ISend = 0;	/* should have been! */		    } else {			Ibackp += DataFromNetwork(Ibackp, Ifrontp-Ibackp, 1);			ISend = 1;		    }		}		printoption("RCVD", IAC, EOR);		break;#	    endif /* defined(TN3270) */	    case IAC:#	    if !defined(TN3270)		TTYADD(IAC);#	    else /* !defined(TN3270) */		if (In3270) {		    *Ifrontp++ = IAC;		} else {		    TTYADD(IAC);		}#	    endif /* !defined(TN3270) */		break;	    case NOP:	    case GA:	    default:		printoption("RCVD", IAC, c);		break;	    }	    telrcv_state = TS_DATA;	    continue;	case TS_WILL:	    printoption("RCVD", WILL, c);	    willoption(c);	    SetIn3270();	    telrcv_state = TS_DATA;	    continue;	case TS_WONT:	    printoption("RCVD", WONT, c);	    wontoption(c);	    SetIn3270();	    telrcv_state = TS_DATA;	    continue;	case TS_DO:	    printoption("RCVD", DO, c);	    dooption(c);	    SetIn3270();	    if (c == TELOPT_NAWS) {		sendnaws();	    } else if (c == TELOPT_LFLOW) {		localflow = 1;		setcommandmode();		setconnmode(0);	    }	    telrcv_state = TS_DATA;	    continue;	case TS_DONT:	    printoption("RCVD", DONT, c);	    dontoption(c);	    flushline = 1;	    setconnmode(0);	/* set new tty mode (maybe) */	    SetIn3270();	    telrcv_state = TS_DATA;	    continue;	case TS_SB:	    if (c == IAC) {		telrcv_state = TS_SE;	    } else {		SB_ACCUM(c);	    }	    continue;	case TS_SE:	    if (c != SE) {		if (c != IAC) {		    /*		     * This is an error.  We only expect to get		     * "IAC IAC" or "IAC SE".  Several things may		     * have happend.  An IAC was not doubled, the		     * IAC SE was left off, or another option got		     * inserted into the suboption are all possibilities.		     * If we assume that the IAC was not doubled,		     * and really the IAC SE was left off, we could		     * get into an infinate loop here.  So, instead,		     * we terminate the suboption, and process the		     * partial suboption if we can.		     */		    SB_ACCUM(IAC);		    SB_ACCUM(c);		    subpointer -= 2;		    SB_TERM();		    printoption("In SUBOPTION processing, RCVD", IAC, c);		    suboption();	/* handle sub-option */		    SetIn3270();		    telrcv_state = TS_IAC;		    goto process_iac;		}		SB_ACCUM(c);		telrcv_state = TS_SB;	    } else {		SB_ACCUM(IAC);		SB_ACCUM(SE);		subpointer -= 2;		SB_TERM();		suboption();	/* handle sub-option */		SetIn3270();		telrcv_state = TS_DATA;	    }	}    }    if (count)	ring_consumed(&netiring, count);    return returnValue||count;}

⌨️ 快捷键说明

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