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

📄 atcmd.c

📁 支持Telnet功能的Modem通讯程序
💻 C
字号:
#include <stdio.h>	/*stderr,(sscanf,sprintf)*/#include <string.h>	/*(strncpy)*/#include <stdlib.h>	/*(getenv)*/#include <sys/time.h>	/*->ttybuf.h (timeval)*/#include <arpa/telnet.h>/*TELOPT_xxx*/#include "defs.h"	/*->atcmd.h (uchar)*/#include "atcmd.h"	/*atcmd*/#include "sock.h"	/*sockIsAlive*/#include "ttybuf.h"	/*(putTty1)*/#include "telopt.h"	/*telOpt*/#include "cmdlex.h"	/*(cmdLex)*/#include "cmdarg.h"	/*cmdarg*/#include "verbose.h"	/*VERB_MISC*/#ifdef BINMODE_AS_DEFAULT# define BINCMD "%B0=1%B1=1"#else# define BINCMD#endif#define INITSTR "AT" \	"S2=43"		/* escape char = '+' */ \	"S3=13"		/* CR */ \	"S4=10"		/* LF */ \	"S5=8"		/* BS */ \	"S7=20"		/* timelimit for non-blocking connect */ \	"S12=50"	/* escape sequence guard time */ \	BINCMD		/* binary mode */ \	"%T1"		/* terminal-type = $TERM */ \	"&W"		/* write to NVRAM */voidatcmdInit(void){    Cmdstat s;    /*memset(atcmd, 0, sizeof(atcmd));*/    if (cmdLex(INITSTR) != CMDST_OK	|| ( (s = cmdLex(getenv("MODEMU"))) != CMDST_OK && s != CMDST_NOAT )	|| ( (s = cmdLex(cmdarg.atcmd)) != CMDST_OK && s != CMDST_NOAT )	) {	fprintf(stderr, "Error in initialization commands.\r\n");	CHAR_CR = '\r'; /* force normal settings */	CHAR_LF = '\n';    }}/* LIT(A) -> "10" */#define LIT_(s) #s#define LIT(s) LIT_(s)/* D *//* dial command */voidatcmdD(const char *s, AtdAType at, AtdPType pt){    /*fprintf(stderr,"<%s>,%d,%d\r\n",s,at,pt);*/    if (*s == '"') s++;    /* "%[^:\"]:%[^\"]" */    sscanf(s, "%" LIT(ADDR_MAX) "[^:\"]:%" LIT(PORT_MAX) "[^\"]",	   atcmd.d.addr.str, atcmd.d.port.str);    atcmd.d.addr.type = at;    atcmd.d.port.type = pt;    /*fprintf(stderr,"<%s>:<%s>\r\n",atcmd.d.addr.str, atcmd.d.port.str);*/}/* "x0" or "x" -> 0, "x1" -> 1, ... */static intgetNumArg(const char *s){#define isdigit(c) ('0' <= (c) && (c) <= '9')    for ( ; *s != '\0'; s++) if (isdigit(*s)) return atoi(s);    return 0;}/* fake command *//* ("x1","012") -> 0, ("y3","012") -> 1 (just a range check) */intatcmdFake(const char *s, const char *vals){    int i;    i = getNumArg(s) + '0';    for (; *vals != '\0'; vals++) if (i == *vals) return 0;    return 1;}/* Hn *//* n: 0(disconnect) */intatcmdH(const char *s){    if (getNumArg(s) != 0) return 1;    if (sockIsAlive()) {	sockClose();	verboseOut(VERB_MISC, "Connection closed with ATH.\r\n");    }    return 0;}/* In *//* n: 4(show current settings), 5(show '&W'ed settings) or *//*    6(show telnet option states) */static voidprPercent(Atcmd *atcmdp){    char buf[64];    sprintf(buf, "%c%c%%B0=%d  %%B1=%d  %%D%d  %%L%d  %%R%d",	    CHAR_CR, CHAR_LF,	    atcmdp->pb[0], atcmdp->pb[1], atcmdp->pd, atcmdp->pl, atcmdp->pr);    putTtyN(buf, strlen(buf));    if (atcmdp->pt.wont) {	putTtyStr("  %T0");    } else {	sprintf(buf, "  %%T=\"%s\"", atcmdp->pt.str);	putTtyN(buf, strlen(buf));    }    sprintf(buf, "  %%V%d", atcmdp->pv);    putTtyN(buf, strlen(buf));}static voidprSreg(uchar *s){    int i;    char buf[8];    for (i = 0; i <= SREG_MAX; i++,s++) {	if (i % 8 == 0) {	    putTty1(CHAR_CR); putTty1(CHAR_LF);	} else putTtyStr("  ");	sprintf(buf, "S%02d=%03d", i, *s);	putTtyN(buf, 7);    }}static voidprOption(void){    static char *onoff[]={"off", "on "};    char buf[64];    putTty1(CHAR_CR); putTty1(CHAR_LF);    putTtyStr("MODEMU telnet option states:");    putTty1(CHAR_CR); putTty1(CHAR_LF);    putTty1(CHAR_CR); putTty1(CHAR_LF);    putTtyStr(   "OPTION  LOCAL  REMOTE");    sprintf(buf, "Binary   %s    %s",	    onoff[telOpt.stTab[TELOPT_BINARY]->local.state],	    onoff[telOpt.stTab[TELOPT_BINARY]->remote.state]);    putTty1(CHAR_CR); putTty1(CHAR_LF); putTtyN(buf, strlen(buf));    sprintf(buf, "Echo     %s    %s",	    onoff[telOpt.stTab[TELOPT_ECHO]->local.state],	    onoff[telOpt.stTab[TELOPT_ECHO]->remote.state]);    putTty1(CHAR_CR); putTty1(CHAR_LF); putTtyN(buf, strlen(buf));    sprintf(buf, "SGA      %s    %s",	    onoff[telOpt.stTab[TELOPT_SGA]->local.state],	    onoff[telOpt.stTab[TELOPT_SGA]->remote.state]);    putTty1(CHAR_CR); putTty1(CHAR_LF); putTtyN(buf, strlen(buf));    sprintf(buf, "TType    %s    %s",	    onoff[telOpt.stTab[TELOPT_TTYPE]->local.state],	    onoff[telOpt.stTab[TELOPT_TTYPE]->remote.state]);    putTty1(CHAR_CR); putTty1(CHAR_LF); putTtyN(buf, strlen(buf));    putTty1(CHAR_CR); putTty1(CHAR_LF);}static voidprVersion(void){    putTty1(CHAR_CR); putTty1(CHAR_LF);    putTtyStr("modemu version " LIT(VERSION_MAJOR) "." LIT(VERSION_MINOR));    putTty1(CHAR_CR); putTty1(CHAR_LF);}intatcmdI(const char *s){    int idx;    idx = getNumArg(s);    switch (idx) {    case 4:	putTty1(CHAR_CR); putTty1(CHAR_LF);	putTtyStr("MODEMU current settings:");	putTty1(CHAR_CR); putTty1(CHAR_LF);	prPercent(&atcmd);	prSreg(atcmd.s);	putTty1(CHAR_CR); putTty1(CHAR_LF);	break;    case 5:	putTty1(CHAR_CR); putTty1(CHAR_LF);	putTtyStr("MODEMU '&W'ed settings:");	putTty1(CHAR_CR); putTty1(CHAR_LF);	prPercent(&atcmdNV);	prSreg(atcmdNV.s);	putTty1(CHAR_CR); putTty1(CHAR_LF);	break;    case 6:	prOption();	break;    case 7:	prVersion();	break;    default:	return 1;    }    return 0;}/* Sn? *//* n: S register number */intatcmdSQuery(const char *s){    int idx;    char buf[4];    idx = getNumArg(s);    if (idx > SREG_MAX) return 1;    putTty1(CHAR_CR); putTty1(CHAR_LF);    sprintf(buf, "%03u", atcmd.s[idx]);    putTtyN(buf, 3);    putTty1(CHAR_CR); putTty1(CHAR_LF); /*at least Courier does*/    return 0;}/* "1=2" -> (1,2), "1=" -> (1,0), "=2" -> (0,2), "=" -> (0,0) */static voidgetNumArg2(const char *s, int *n1p, int *n2p){    char *s2;    *n1p = strtol(s, &s2, 10);    *n2p = strtol(s2+1, NULL, 10);}/* Sn=m *//* n: S register number *//* m: value 0-255 */intatcmdSSet(const char *s){    int idx, val;    getNumArg2(s+1, &idx, &val);    if (idx > SREG_MAX || val > 255) return 1;    atcmd.s[idx] = val;    return 0;}/* Z *//* recover &Wed settings and disconnect */voidatcmdZ(void){    atcmd = atcmdNV;    if (sockIsAlive()) {	sockClose();	verboseOut(VERB_MISC, "Connection closed with ATZ.\r\n");    }}/* &W *//* save current settings */voidatcmdAW(void){    atcmdNV = atcmd;}/* %Bn=m *//* n: 0(local) or 1(remote) *//* m: 0(better non-binary), 1(better binary), *//*    2(must non-binary) or 3(must binary) */intatcmdPB(const char *s){    int idx, val;    getNumArg2(s+2, &idx, &val);    if (idx > 1 || val > 3) return 1;    atcmd.pb[idx] = val;    telOpt.sentReqs = 0; /* renegotiate when returning online */    return 0;}/* %Dn *//* n: 0(enable dial canceling) or 1(disable dial canceling) */intatcmdPD(const char *s){    int i;    i = getNumArg(s);    if (i > 1) return 1;    atcmd.pd = i;    return 0;}/* %Ln *//* n: 0(better char mode), 1(better line mode), *//*    2(must char mode) or 3(must line mode) */intatcmdPL(const char *s){    int i;    i = getNumArg(s);    if (i > 3) return 1;    atcmd.pl = i;    telOpt.sentReqs = 0; /* renegotiate when returning online */    return 0;}/* %Q *//* quit modemu */voidatcmdPQ(void){    sockShutdown(); /* may discard unsent chars in kernel,		       or do ATH before quitting */    exit(0);}/* %Rn *//* n: 0(cooked?? mode) or 1(raw mode: 8bit thru, no IAC handling) *//* overrides %B and %L settings */intatcmdPR(const char *s){    int i;    i = getNumArg(s);    if (i > 1) return 1;    atcmd.pr = i;    return 0;}/* %Tn *//* n: 0(dont support telnet term-type option) or *//*    1(send $TERM for term-type option request) */intatcmdPT(const char *s){    int i;    i = getNumArg(s);    switch (i) {    case 0:	atcmd.pt.wont = 1;	break;    case 1:	strncpy(atcmd.pt.str, getenv("TERM"), PT_MAX);	atcmd.pt.len = strlen(atcmd.pt.str);	atcmd.pt.wont = 0;	break;    default:	return 1;    }    return 0;}/* %T="xxxx" *//* send xxxx for term-type option request */intatcmdPTSet(const char *s){    sscanf(s+4, "%" LIT(PT_MAX) "[^\"]", atcmd.pt.str);    /*strncpy(atcmd.pt.str, s+3, PT_MAX);*/    atcmd.pt.len = strlen(atcmd.pt.str);    /*telOpt.sentReqs = 0; renegotiation will be of no effect*/    atcmd.pt.wont = 0;    return 0;}/* %Vn *//* n: 0-255 *//*    bit0: output misc info to make up for less descriptive ATX0 indication *//*    bit1: output telnet option negotioation */intatcmdPV(const char *s){    int i;    i = getNumArg(s);    if (i > 255) return 1;    atcmd.pv = i;    return 0;}

⌨️ 快捷键说明

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