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

📄 telopt.c

📁 支持Telnet功能的Modem通讯程序
💻 C
字号:
#include <stdio.h>	/*stderr,(fprintf)*/#include <sys/time.h>	/*->ttybuf.h (timeval)*/#define TELCMDS /*to use strings defined in telnet.h*/#define TELOPTS#include <arpa/telnet.h>/*IAC,DO,DONT,...*/#include "defs.h"	/*->sockbuf.h (uchar,SOCKBUFR_SIZE,TTYBUFR_SIZE)*/#include "sockbuf.h"	/*->telopt.h (putSock1)*/#include "telopt.h"	/*TelOptReq,TelOptEnt*/#include "ttybuf.h"	/*(putTtyN)*/#include "atcmd.h"	/*atcmd*/#include "verbose.h"	/*VERB_TELOPT*//* telnet option negotiation module */static TelOptStates stTabMaster[] = {    /*[opt]		[local]		[remote]*/    { TELOPT_BINARY,	{TOR_BETTER},	{TOR_BETTER}	},/*0*/    { TELOPT_ECHO,	{TOR_MUSTNOT},	{TOR_BETTER}	},/*1*/    { TELOPT_SGA,	{TOR_BETTER},	{TOR_MUST}	},/*3*/    { TELOPT_TTYPE,	{TOR_NEUTRAL},	{TOR_MUSTNOT}	},/*24*/    { -1,		{TOR_MUSTNOT},	{TOR_MUSTNOT}	} /* default state */};TelOptStates *stTab[NTELOPTS]; /* telOptInit() makes it usable */static /*const*/ TelOptStates *defaultSt; /* used when unknown options come *//* must call before each telnet session begins */voidtelOptReset(void){    TelOptStates *tosp;    for (tosp = stTabMaster; tosp->opt >= 0; tosp++) {	tosp->local.state = 	tosp->remote.state = 0; /* all options are disabled initially */	tosp->local.pending = 	tosp->remote.pending = 0;    }    telOpt.binsend =    telOpt.binrecv =    telOpt.sgasend = 0;    telOpt.sentReqs = 0;}/* must call once before using this module */voidtelOptInit(void){    TelOptStates *tosp;    int i;    for (tosp = stTabMaster; tosp->opt >= 0; tosp++) ;    for (i = 0; i < NTELOPTS; i++) stTab[i] = tosp; /* default entry */    defaultSt = tosp;    for (tosp-- ; tosp >= stTabMaster; tosp--) {	stTab[tosp->opt] = tosp;    }    telOpt.stTab = stTab;}static const char *telcmdStr(int cmd){    static char str[16];#ifndef TELCMD_FIRST /*is this rule correct for all telnet.h?*/#define TELCMD_FIRST (256 - sizeof(telcmds)/sizeof(telcmds[0]))#endif    if (cmd >= TELCMD_FIRST) {	return telcmds[cmd - TELCMD_FIRST];    } else {	sprintf(str, "?(%d)", cmd);	return str;    }}static const char *teloptStr(int opt){    static char str[16];    if (opt < NTELOPTS) {	return telopts[opt];    } else {	sprintf(str, "?(%d)", opt);	return str;    }}voidtelOptPrintCmd(const char *str, int cmd){    verboseOut(VERB_TELOPT, "%s IAC %s\r\n", str, telcmdStr(cmd));}static voidprintCmdOpt(const char *str, int cmd, int opt){    verboseOut(VERB_TELOPT, "%s %s %s\r\n", str, telcmdStr(cmd), teloptStr(opt));}static voidsetReqs(void){    static TelOptReq tabP[]	= { TOR_BETTERNOT, TOR_BETTER, TOR_MUSTNOT, TOR_MUST };    static TelOptReq tabN[]	= { TOR_BETTER, TOR_BETTERNOT, TOR_MUST, TOR_MUSTNOT };    /* %Bn=m (binary mode control) */    stTab[TELOPT_BINARY]->local.req = tabP[atcmd.pb[1]];    stTab[TELOPT_BINARY]->remote.req = tabP[atcmd.pb[0]];    /* %Ln (linemode control) */    stTab[TELOPT_SGA]->remote.req = tabN[atcmd.pl];    stTab[TELOPT_ECHO]->remote.req = tabN[atcmd.pl];    /* %Tn (terminal-type response control) */    stTab[TELOPT_TTYPE]->local.req = atcmd.pt.wont? TOR_MUSTNOT : TOR_NEUTRAL;}/* tell the peer my option-state-to-be requests */voidtelOptSendReqs(void){    TelOptStates *tosp;    setReqs();    for (tosp = stTabMaster; tosp->opt >= 0; tosp++) {	switch (tosp->local.req) {	case TOR_MUSTNOT:	case TOR_BETTERNOT:	    if (tosp->local.state == 1) {		putOptCmd(WONT, tosp->opt);		printCmdOpt(">", WONT, tosp->opt);		tosp->local.pending = 1;	    }	    break;	case TOR_BETTER:	case TOR_MUST:	    if (tosp->local.state == 0) {		putOptCmd(WILL, tosp->opt);		printCmdOpt(">", WILL, tosp->opt);		tosp->local.pending = 1;	    }	    break;	default:;	}	    	switch (tosp->remote.req) {	case TOR_MUSTNOT:	case TOR_BETTERNOT:	    if (tosp->remote.state == 1) {		putOptCmd(DONT, tosp->opt);		printCmdOpt(">", DONT, tosp->opt);		tosp->remote.pending = 1;	    }	    break;	case TOR_BETTER:	case TOR_MUST:	    if (tosp->remote.state == 0) {		putOptCmd(DO, tosp->opt);		printCmdOpt(">", DO, tosp->opt);		tosp->remote.pending = 1;	    }	    break;	default:;	}	        }    telOpt.sentReqs = 1;}/* summarize option states into flags */static voidtelOptSummarize(void){    telOpt.binsend = stTab[TELOPT_BINARY]->local.state;    telOpt.binrecv = stTab[TELOPT_BINARY]->remote.state;    telOpt.sgasend = stTab[TELOPT_SGA]->remote.state;}/* telnet option request/response handling */inttelOptHandle(int cmd, int opt){    TelOptState *tostp;    TelOptStates *tosp;    int reqState;	/* cmd's requiring state */    int posiResCmd;	/* positive response command for cmd */    int negaResCmd;	/* negative response command for cmd */    TelOptReq mustNegate;	/* must negate if req is this */    TelOptReq betterNegate;	/* better negate if req is this */    TelOptReq betterAssert;	/* better assert if req is this */    TelOptReq mustAssert;	/* must assert if req is this */    printCmdOpt("<", cmd, opt);    tosp = (opt < NTELOPTS)? stTab[opt] : defaultSt;    switch (cmd) {    case WILL:	tostp = &tosp->remote;	reqState = 1;	mustNegate = TOR_MUSTNOT;	betterNegate = TOR_BETTERNOT;	betterAssert = TOR_BETTER;	mustAssert = TOR_MUST;	posiResCmd = DO;	negaResCmd = DONT;	break;    case WONT:	tostp = &tosp->remote;	reqState = 0;	mustNegate = TOR_MUST;	betterNegate = TOR_BETTER;	betterAssert = TOR_BETTERNOT;	mustAssert = TOR_MUSTNOT;	posiResCmd = DONT;	negaResCmd = DO;	break;    case DO:	tostp = &tosp->local;	reqState = 1;	mustNegate = TOR_MUSTNOT;	betterNegate = TOR_BETTERNOT;	betterAssert = TOR_BETTER;	mustAssert = TOR_MUST;	posiResCmd = WILL;	negaResCmd = WONT;	break;    case DONT:	tostp = &tosp->local;	reqState = 0;	mustNegate = TOR_MUST;	betterNegate = TOR_BETTER;	betterAssert = TOR_BETTERNOT;	mustAssert = TOR_MUSTNOT;	posiResCmd = WONT;	negaResCmd = WILL;	break;    default:	fprintf(stderr, "bug\r\n");	exit(1);    }    if (tostp->req == mustNegate || tostp->req == betterNegate) {	if (tostp->pending) {	    tostp->pending = 0;	    if (tostp->req == mustNegate)		return 1; /* requirment didn't meet */	    if (tostp->state == !reqState) { /* this may not happen */		tostp->state = reqState;		putOptCmd(posiResCmd, opt); /* positive response */		printCmdOpt(">", posiResCmd, opt);	    }	} else {	    putOptCmd(negaResCmd, opt); /* negative response */	    printCmdOpt(">", negaResCmd, opt);	}    } else /*if (tostp->req == betterAssert or mustAssert or TOR_NEUTRAL)*/ {	if (tostp->pending) {	    tostp->pending = 0;	    /* don't response because cmd is the response of my request */	} else {	    putOptCmd(posiResCmd, opt); /* positive response */	    printCmdOpt(">", posiResCmd, opt);	}	tostp->state = reqState; /* {en,dis}able option as requested */    }    telOptSummarize();    return 0;}/* send term-type subnego param */static voidttypeSBHandle(void){    putSock1(IAC);    putSock1(SB);    putSock1(TELOPT_TTYPE);    putSock1(TELQUAL_IS);    putSockN(atcmd.pt.str, atcmd.pt.len);    putSock1(IAC);    putSock1(SE);    verboseOut(VERB_TELOPT, "> SB %s IS %s SE\r\n",	     telopts[TELOPT_TTYPE], atcmd.pt.str);}/* telnet option subnegotiation request handling */inttelOptSBHandle(int opt){    verboseOut(VERB_TELOPT, "< SB %s SEND SE.\r\n", telopts[opt]);    switch (opt) {    case TELOPT_TTYPE:	ttypeSBHandle();	break;    default:	return 1;    }    return 0;}

⌨️ 快捷键说明

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