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

📄 expresp.c

📁 一个通讯程序源码
💻 C
字号:
/*+-------------------------------------------------------------------------	expresp.c - HDB expect/respond per SCO Devices file	wht@n4hgf.Mt-Park.GA.US Meaning of some of the escape characters: \p - pause (approximately 1/4-1/2 second delay) \d - delay (2 seconds) \D - phone number/token \T - phone number with Dialcodes and character translation \N - null byte \K - insert a BREAK \E - turn on echo checking (for slow devices) \e - turn off echo checking \r - carriage return \c - no new-line \n - send new-line \s - send space \nnn - send octal number \\ - send backslash \m### - sleep ### (decimal) milliseconds (non-standard) Speed - Hayes-specific "CONNECT"  handler  Defined functions:	execute_expresp(expresp_script)	expect(str)	pcmd_expresp(param)	respond(str)--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 *//*:09-04-1992-19:07-wht@n4hgf-new msec delay syntax + harden *//*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA *//*:12-16-1991-15:25-wht@n4hgf-allow for backslash in expect and respond *//*:10-09-1991-20:21-wht@n4hgf-bad llookfor echo argument *//*:08-01-1991-05:00-wht@n4hgf-\n sent CR not NL *//*:08-01-1991-04:31-wht@n4hgf-nap min of hzmsec if \m *//*:08-01-1991-04:22-wht@n4hgf-detect NULL expect string *//*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 *//*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug *//*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */#include "ecu.h"#include "ecuerror.h"#include "esd.h"#include "var.h"#include "proc.h"#define MAX_FIELDS	50	/* max fields in a chat script */#define MAX_EXPRESP	511	/* max length of a chat script */#define MAX_EXPECT	63	/* max length of expect string */#define DEFAULT_TIMEOUT_MSECS (45*1000L)#define ERDEBUG(verb,str,arg) if(expresp_verbosity >= verb) \	pprintf(str,arg)long atol();char *strip_phone_num();char *dialcodes_translate();extern int proctrace;int expresp_verbosity = 0;ulong expect_timeout_msecs = DEFAULT_TIMEOUT_MSECS;int expresp_echo_check = 0;char last_Speed_result[32];/*+-------------------------------------------------------------------------	expect(str) - expect (read) string from remotereturn code on failure, 0 on success--------------------------------------------------------------------------*/intexpect(str)char *str;{	int erc;	int itmp;	char op;	char s4[4];	char parsebuf[MAX_EXPECT + 1];	int remaining = MAX_EXPECT;	long atol();	register char *cptr;	register char *parsed = parsebuf;	int old_ttymode = get_ttymode();	if(!str)	{		ERDEBUG(2,"expect string NULL\n",0);		return(eExpectRespondFail);	}	if(old_ttymode != 2)		ttymode(2);	/*	 * ~?[]	 */	if((*str == '~') && *(str + 1) && (*(str + 2) == '['))	{		op = *(str + 1);		str += 3;		switch(op)		{			case 'm':	/* msec expect timeout */			case 't':	/*  sec expect timeout */				expect_timeout_msecs = atol(str);				if(op == 't')					expect_timeout_msecs *= 1000L;				ERDEBUG(2,"expect timeout = %lu msec\n",expect_timeout_msecs);				break;			default:				ERDEBUG(0,"\nexpect: invalid subop: ~%c[]\n",op);				break;		}		if(cptr = strchr(str,']'))			str = cptr + 1;		else		{			ERDEBUG(0,"\nexpect: missing ] after ~[%c\n",op);			erc = eExpectRespondFail;			goto DID_NOT_GET_EXPECTED;		}	}	ERDEBUG(2,"expect: <<%s>>\n",str);	if(!strlen(str) || !strcmp(str,"\"\""))		goto GOT_EXPECTED;	if(!strcmp(str,"Speed"))	{		LRWT lr;		long ms_start;		long ms_now;		struct timeb now_timeb;		ftime(&now_timeb);		ms_start = (now_timeb.time * 1000) + now_timeb.millitm;		do {			last_Speed_result[0] = 0;			lr.to1 = 90 * 100L;			lr.to2 = 120L;			/* allow interrupts + cooked read */			lr.raw_flag = 0x80;			lr.buffer = last_Speed_result;			lr.bufsize = sizeof(last_Speed_result);			lr.delim = "\n";			lr.echo_flag = !!expresp_verbosity;			lgets_timeout(&lr);			ftime(&now_timeb);			ms_now = (now_timeb.time * 1000) + now_timeb.millitm;		} while(!sigint && !lr.count && ((ms_now - ms_start) < 90*1000L));		if(sigint || strncmp(lr.buffer,"CONNECT",7))			goto DID_NOT_GET_EXPECTED;		else			goto GOT_EXPECTED;	}	cptr = str;	while(remaining && *cptr)	{		if(*cptr == '\\')		{			if(!*(++cptr))	/* if no character after escape, ... */			{				ERDEBUG(2," error: str ended with '\\'\n",0);				goto DID_NOT_GET_EXPECTED;			}			if(isdigit(*cptr))	/* handle \ooo */			{				strncpy(s4,cptr,3);				s4[3] = 0;				sscanf(s4,"%o",&itmp);				cptr += strspn(s4,"01234567");				*parsed++ = (char)itmp;				remaining--;				continue;			}			switch(*cptr)			{				case 'n':					*parsed++ = 0x0A;					remaining--;					break;				case 'r':					*parsed++ = 0x0D;					remaining--;					break;				case '\\':					*parsed++ = '\\';					remaining--;					break;				case '~':					*parsed++ = '~';					remaining--;					break;				case 's':					*parsed++ = ' ';					remaining--;					break;				default:					ERDEBUG(2," meaningless here: \\%c\n",*cptr);					break;			}			cptr++;		}		else		{			*parsed++ = *cptr++;			remaining--;		}	}	*parsed = 0;	if(!remaining)		ERDEBUG(1," expect string too long\n",0);	if(expresp_verbosity >= 3)		hex_dump(parsebuf,strlen(parsebuf),"expecting",1);	if(llookfor(parsebuf,expect_timeout_msecs,!!expresp_verbosity))	{GOT_EXPECTED:		ERDEBUG(2,"[EXPECT SUCCEEDED]\n",0);		erc = 0;		goto RESTORE_TTYMODE_AND_RETURN_ERC;	}DID_NOT_GET_EXPECTED:	ERDEBUG(2,"[EXPECT FAILED%s]\n",(sigint) ? " (interrupted)" : "");	if(sigint)	{		sigint = 0;		erc = eCONINT;	}	else		erc = eExpectRespondFail;	goto RESTORE_TTYMODE_AND_RETURN_ERC;RESTORE_TTYMODE_AND_RETURN_ERC:	if(old_ttymode != 2)		ttymode(old_ttymode);	return(erc);}	/* end of expect *//*+-------------------------------------------------------------------------	respond(str) - send to remotewe enable SIGINT processing in here and return if 'sigint'detected, but here, unlike many other places, we do *not* resetsigint (since we do not really "handle" it)--------------------------------------------------------------------------*/voidrespond(str)register char *str;{	int itmp;	long nap_msec;	char s4[4];	char *cptr;	char *phnum;	char op;	int send_no_cr = 0;	int old_ttymode = get_ttymode();	if(sigint)		return;	ttymode(2);	/* enable SIGINT/sigint */	ERDEBUG(2,"respond: <<%s>>\n",str);	while(*str)	{		if(*str == '\\')		{			if(isdigit(*++str))	/* handle \ooo */			{				strncpy(s4,str,3);				s4[3] = 0;				sscanf(s4,"%o",&itmp);				str += strspn(s4,"01234567") - 1; /* -1 because str++ later */				lputc((char)itmp);			}			else switch(*str)			{				case 'p':  /* pause (approximately 1/4-1/2 second delay) */					ldraino(0);	/* wait for output to drain */					if(Nap(400L) < 0)						goto RETURN;					break;				case 'M': /* CLOCAL on */				case 'm': /* CLOCAL off */					itmp = (*str == 'M');					lCLOCAL(itmp);					ERDEBUG(2,"CLOCAL set %s\n",(itmp) ? "ON" : "OFF");					break;				case 'd':  /* delay (2 seconds) */					ldraino(0);	/* wait for output to drain */					if(Nap(2000L) < 0)						goto RETURN;					break;				case 'D':  /* phone number/token */					cptr = strip_phone_num(shm->Ltelno);					if(expresp_echo_check)						lputs_paced(40,cptr);					else						lputs(cptr);					break;				case 'T':  /* phnum with Dialcodes and char translation */					phnum = strip_phone_num(shm->Ltelno);					cptr = dialcodes_translate(&phnum);					if(expresp_echo_check)					{						lputs_paced(40,cptr);						lputs_paced(40,phnum);					}					else					{						lputs(cptr);						lputs(phnum);					}					break;				case 'N':  /* null byte */					lputc(0);					break;				case 'K':  /* insert a BREAK */					lbreak();					break;				case 'E':  /* turn on echo checking (for slow devices) */					expresp_echo_check = 1;					break;				case 'e':  /* turn off echo checking */					expresp_echo_check = 0;					break;				case 'r':  /* carriage return */					lputc(0x0D);					break;				case 'c':  /* no new-line */					send_no_cr = 1;					break;				case 'n':  /* send new-line */					lputc(0x0A);					break;				case '\\':  /* send backslash */					lputc('\\');					break;				case '~':  /* send tilde */					lputc('~');					break;			}		}		else if((*str == '~') && *(str + 1) && (*(str + 2) == '['))		{			op = *(str + 1);			str += 3;			switch(op)			{				case 'n':	/* nap for milliseconds */					nap_msec = atol(str);					if(nap_msec < 0L)						nap_msec = 0;					if(nap_msec >= 500)						ERDEBUG(2,"nap for %lu msec\n",nap_msec);					Nap(nap_msec);					break;				default:					ERDEBUG(0,"\nrespond: invalid subop: ~%c[]\n",op);					break;			}			if(cptr = strchr(str,']'))				str = cptr + 1;			else			{				ERDEBUG(0,"\nrespond: missing ] after ~[%c\n",op);				goto RETURN;			}		}		else			lputc(*str);		if(expresp_echo_check)		{			ldraino(1);		/* wait for output to drain, then flush input */			Nap(40L);		/* fake it */		}		str++;	}	if(!send_no_cr)		lputc(0x0D);RETURN:	ttymode(old_ttymode);}	/* end of respond *//*+-------------------------------------------------------------------------	execute_expresp(expresp_script)return 0 on success, else error code--------------------------------------------------------------------------*/intexecute_expresp(expresp_script)char *expresp_script;{	char *fields[MAX_FIELDS + 1];	int ifields;	int nfields;	int erc;	char expresp_copy[MAX_EXPRESP + 1];	char *expect_this;	char *send_on_fail;#define EXPECT_STATE (!(ifields & 1))	/* even numbered fields are expect */	expresp_echo_check = 0;	last_Speed_result[0] = 0;	ERDEBUG(2,"[EXPECT/RESPOND INITIAL TIMEOUT %ld MSEC]\n",	    expect_timeout_msecs);	strncpy(expresp_copy,expresp_script,sizeof(expresp_copy));	build_arg_array(expresp_copy,fields,MAX_FIELDS,&nfields);	if(!nfields)	/* if no script, assume success */	{		ERDEBUG(2,"[EMPTY SCRIPT - EXPECT/RESPOND SUCCEEDED]\n",0);		return(0);	}	for(ifields = 0; ifields < nfields; ifields++)	{		if(sigint)			break;		if(EXPECT_STATE)		{			expect_this = fields[ifields];			while(1)	/* until break or return(error) */			{				if(send_on_fail = strchr(expect_this,'-'))					*send_on_fail++ = 0;				if(!(erc = expect(expect_this)))					break;				if((erc != eExpectRespondFail) || !send_on_fail)				{					ERDEBUG(2,"[EXPECT/RESPOND FAILED]\n",0);					return(eExpectRespondFail);				}				if(expect_this = strchr(send_on_fail,'-'))					*expect_this++ = 0;				if(sigint)					break;				respond(send_on_fail);			}		}		else			respond(fields[ifields]);	}	if(sigint)	{		sigint = 0;		ERDEBUG(2,"[CONSOLE INTERRUPT]\n",0);		return(eCONINT);	}	ERDEBUG(2,"[EXPECT/RESPOND SUCCEEDED]\n",0);	return(0);}	/* end of execute_expresp *//*+-------------------------------------------------------------------------	pcmd_expresp(param)expresp [-v[v...]] <exp-resp-str> [<timeout_msecs>]--------------------------------------------------------------------------*/intpcmd_expresp(param)ESD *param;{	int erc;	int itmp;	char *cptr;	ESD *tesd;	char switches[8];	if((tesd = esdalloc(MAX_EXPRESP + 1)) == (ESD *)0)		return(eNoMemory);	get_switches(param,switches,sizeof(switches));	if(erc = gstr(param,tesd,0))	{		esdfree(tesd);		return(erc);	}	expect_timeout_msecs = DEFAULT_TIMEOUT_MSECS;	expresp_verbosity = (!!strchr(switches,'v')) || proctrace;	if(expresp_verbosity)	{		cptr = switches;		itmp = 0;		while(*cptr)			itmp += (*cptr++ == 'v');		if(itmp > 1)			expresp_verbosity = itmp;	}	if(erc = gint(param,&expect_timeout_msecs))	{		/* if something there non-integer */		if(!end_of_cmd(param))		{			erc = eSyntaxError;			goto RETURN;		}	}	erc = execute_expresp(tesd->pb);RETURN:	esdfree(tesd);	iv[0] = !!erc;	if(proctrace)		pprintf("$i00 = %7ld (0x%08lx,0%lo)\n",iv[0],iv[0],iv[0]);	if(erc == eExpectRespondFail)		erc = 0;	return(erc);}	/* end of pcmd_expresp *//* vi: set tabstop=4 shiftwidth=4: *//* end of expresp.c */

⌨️ 快捷键说明

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