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

📄 ecurcvr.c

📁 一个通讯程序源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* #define DEFENSIVE *//* #define ANSI_DEBUG */		/* debug ansi *//* #define ANSI_DEBUG_2 */		/* debug ansi intensive output *//* #define ANSI_DEBUG_3 */		/* debug ansi selected output *//* #define ANSI_DEBUG_NOBUF */	/* unbufferred logging *//* #define ANSI_DEBUG_LOGFILE	"/dev/tty2h" *//* #define DEBUG_CURSOR */#ifndef LIMIT_BELL#define LIMIT_BELL#endif/*+-------------------------------------------------------------------------	ecurcvr.c - rcvr process + ANSI filter + non-ANSI<->ANSI hoop jumping	wht@n4hgf.Mt-Park.GA.US  Defined functions:	accumulate_ansi_sequence(rchar)	ansi_CNL()	ansi_CPL()	ansi_CUB()	ansi_CUD()	ansi_CUF()	ansi_CUP()	ansi_CUU()	ansi_DCH()	ansi_DL()	ansi_DSR()	ansi_ECH()	ansi_ED()	ansi_EL()	ansi_HPA()	ansi_ICH()	ansi_IL()	ansi_SD()	ansi_SGR()	ansi_SU()	ansi_VPA()	is_ansi_terminator(rchar)	lgetc_rcvr()	process_ansi_sequence()	process_rcvd_char(rchar)	rcvd_ESC()	rcvr()	rcvr_log_open()	rcvrdisp(buf,buflen)	rcvrdisp_actual()	rcvrdisp_actual2()	redisplay_rcvr_screen()	saved_cursor_restore_cursor()	saved_cursor_save_cursor()	spaces(buf,buflen)	spaces_trap(code,buf,buflen)--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 *//*:09-06-1992-13:29-wht@n4hgf-add receiver process buffered screen write *//*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA *//*:05-29-1992-13:28-wht@n4hgf-no banner - phone numbers are security risk *//*:11-11-1991-14:25-wht@n4hgf-lzero_length_read_detected code *//*:11-11-1991-12:45-wht@n4hgf-add LIMIT_BELL code *//*:08-26-1991-16:39-wht@n4hgf2-SD was still hopelessly manic *//*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 *//*:07-05-1991-06:13-wht@n4hgf-SD was in baaaaadd shape *//*:01-09-1991-22:31-wht@n4hgf-ISC port *//*:12-26-1990-14:32-wht@n4hgf-use memset in spaces() *//*:12-21-1990-21:06-wht@n4hgf-CUF and CUB set non-ansi cursor incorrectly *//*:12-20-1990-16:27-wht@n4hgf-had SU and SD swapped *//*:11-30-1990-18:39-wht@n4hgf-non-ansi console rcvr appears to be working *//*:11-28-1990-14:13-wht@n4hgf-start non-ansi console support *//*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */#include "ecu.h"#include "ecukey.h"#include <sys/ipc.h>#include <sys/sem.h>extern int errno;extern char rcvr_log_file[];	/* if rcvr_log!= 0,log filename */extern int rcvr_log;			/* rcvr log active if != 0 */extern FILE *rcvr_log_fp;		/* rcvr log file */extern int rcvr_log_raw;		/* if true, log all, else filter ctl chrs */extern int rcvr_log_append;		/* if true, append, else scratch */extern int rcvr_log_flusheach;	/* if true, flush log on each char */extern int rcvr_log_gen_title;extern uint tcap_LINES;	/* terminal line quantity - see ecutcap.c */extern uint tcap_COLS;	/* terminal column quantity - see ecutcap.c */extern uint LINESxCOLS;static char esc = ESC;#define MAX_ANSI_LEN	30	/* generous */char ansibuf[MAX_ANSI_LEN];char *ansi;int ansilen = 0;int in_ansi_accumulation = 0;int saved_cursor_y;int saved_cursor_x;#define RCVR_RDQUAN		250char lgetc_buf[RCVR_RDQUAN];char *lgetc_ptr;extern int lgetc_count;uchar autorz_frame[] = { SUB, 'B', '0', '0' };#ifdef ANSI_DEBUGFILE *wfp = (FILE *)0;#endifuchar non_multiscreen_hi_map[128] = {/*80*/	'c','u','e','a','a','a','a','c', /* the main purpose of this ... *//*88*/	'e','e','e','i','i','i','a','a', /* ... is to map ruling ... *//*90*/	'e','e','a','a','a','o','u','u', /* ... characters, but as ...*//*98*/	'y','o','u','X','#','Y','P','f', /* ... a side effect, also map ... *//*A0*/	'a','i','o','u','n','n','a','o', /* ... others to reasonable, ... *//*A8*/	'?','-','-','%','%','|','<','>', /* ... near, amusing, or random ... *//*B0*/	'#','#','#','|','+','+','+','.', /* ... printing characters as well *//*B8*/	'.','+','|','.','\'','\'','\'','.',/*C0*/	'`','+','+','+','-','+','+','+',/*C8*/	'`','.','+','+','+','=','+','+',/*D0*/	'+','+','+','`','`','.','.','+',/*D8*/	'+','\'','.','#','_','|','|','-',/*E0*/	'a','b','F','T','E','o','u','t',/*E8*/	'I','0','O','o','o','o','e','n',/*F0*/	'=','+','>','<','f','j','%','=',/*F8*/	'o','.','.','V','n','2','*',' '};/* * if != 0, allow xmtr use of rcvrdisp_actual2() function to buffer, * if 0, flush buffer whenever the function is called */int rcvrdisp_actual2_xmtr_buffer = 0;/*+-------------------------------------------------------------------------	rcvrdisp_p() - lock rcvrdisp mechanism--------------------------------------------------------------------------*/#ifdef RCVRDISP_PVvoidrcvrdisp_p(){	register int retn;	struct sembuf sembuf;	sembuf.sem_num = 0;	sembuf.sem_op = -1;	sembuf.sem_flg = 0;	while(1)	{		if(((retn = semop(shm->rcvrdisp_semid,&sembuf,1)) >= 0) ||			(errno != EINTR))		{			break;		}	}	if((retn < 0) && (errno != EINVAL))	{		extern char lopen_err_str[];		strcpy(lopen_err_str,"rcvrdisp_p failed: SysV IPC error");		termecu(TERMECU_IPC_ERROR);	}}	/* end of rcvrdisp_p */#endif /*  RCVRDISP_PV *//*+-------------------------------------------------------------------------	rcvrdisp_v() - unlock rcvrdisp mechanism--------------------------------------------------------------------------*/#ifdef RCVRDISP_PVvoidrcvrdisp_v(){	register int retn;	struct sembuf sembuf;	sembuf.sem_num = 0;	sembuf.sem_op = 1;	sembuf.sem_flg = 0;	while(1)	{		if(((retn = semop(shm->rcvrdisp_semid,&sembuf,1)) >= 0) ||			(errno != EINTR))		{			break;		}	}	if((retn < 0) && (errno != EINVAL))	{		extern char lopen_err_str[];		strcpy(lopen_err_str,"rcvrdisp_v failed: SysV IPC error");		termecu(TERMECU_IPC_ERROR);	}}	/* end of rcvrdisp_v */#endif /*  RCVRDISP_PV *//*+-------------------------------------------------------------------------	rcvrdisp_actual() - actual write to screen--------------------------------------------------------------------------*/voidrcvrdisp_actual(){#ifdef RCVRDISP_PV	rcvrdisp_p();#endif /*  RCVRDISP_PV */	if(shm->rcvrdisp_count)		write(TTYOUT,shm->rcvrdisp_buffer,shm->rcvrdisp_count);	shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;	shm->rcvrdisp_count = 0;#ifdef RCVRDISP_PV	rcvrdisp_v();#endif /*  RCVRDISP_PV */}	/* end of rcvrdisp_actual *//*+-------------------------------------------------------------------------	rcvrdisp_actual2() - for tcap, flush only if not receiver--------------------------------------------------------------------------*/voidrcvrdisp_actual2(){	if(rcvrdisp_actual2_xmtr_buffer || (getpid() == rcvr_pid))		return;#ifdef RCVRDISP_PV	rcvrdisp_p();#endif /*  RCVRDISP_PV */	if(shm->rcvrdisp_count)		write(TTYOUT,shm->rcvrdisp_buffer,shm->rcvrdisp_count);	shm->rcvrdisp_ptr = shm->rcvrdisp_buffer;	shm->rcvrdisp_count = 0;#ifdef RCVRDISP_PV	rcvrdisp_v();#endif /*  RCVRDISP_PV */}	/* end of rcvrdisp_actual2 *//*+-------------------------------------------------------------------------	rcvrdisp(buf,buflen) - logical write to screen--------------------------------------------------------------------------*/voidrcvrdisp(buf,buflen)char *buf;int buflen;{	if((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))		rcvrdisp_actual();	if((buflen + shm->rcvrdisp_count) > sizeof(shm->rcvrdisp_buffer))	{		write(TTYOUT,buf,buflen);		return;	}#ifdef RCVRDISP_PV	rcvrdisp_p();#endif /*  RCVRDISP_PV */	memcpy(shm->rcvrdisp_ptr,buf,buflen);	shm->rcvrdisp_ptr += buflen;	shm->rcvrdisp_count += buflen;#ifdef RCVRDISP_PV	rcvrdisp_v();#endif /*  RCVRDISP_PV */}	/* end of rcvrdisp *//*+-------------------------------------------------------------------------	redisplay_rcvr_screen() - redisplay logical receiver screenAs of writing, this function is called only by the XMTR process--------------------------------------------------------------------------*/voidredisplay_rcvr_screen(){	register uint y;	extern int tty_not_char_special;	if(tty_not_char_special)		return;	setcolor(colors_current);	tcap_stand_end();	for(y = 0; y < tcap_LINES; y++)	{		tcap_cursor(y,0);		fwrite(&shm->screen[y][0],			((y != tcap_LINES - 1) ? tcap_COLS : tcap_COLS - 1),1,se);	}	tcap_eeol();	tcap_cursor(shm->cursor_y,shm->cursor_x);}	/* end of redisplay_rcvr_screen */#ifdef DEBUG_CURSORvoidspaces_trap(code,buf,buflen)int code;register uchar *buf;register uint buflen;{	char *xyz = (char *)0x90000000;	ff(se,"rcvr 'spaces trap' code %d: cursor x,y=%d,%d\r\n",		code,		shm->cursor_y,shm->cursor_x);	ff(se,"buf=%08lx len=%08lx offs=%08lx\r\n",buf,buflen,		(ulong)buf - (ulong)shm->screen);	*xyz = 0;	abort();}#endif/*+-------------------------------------------------------------------------	spaces(buf,buflen) - fill with spaces--------------------------------------------------------------------------*/voidspaces(buf,buflen)register uchar *buf;uint buflen;{#ifdef DEBUG_CURSOR	if((ulong)buf > (((ulong)shm->screen) + LINESxCOLS))		spaces_trap(1,buf,buflen);	if((ulong)buf < (ulong)shm->screen)		spaces_trap(2,buf,buflen);	if((ulong)(buf + buflen) > (((ulong)shm->screen) + LINESxCOLS))		spaces_trap(3,buf,buflen);	if((ulong)(buf + buflen) < (ulong)shm->screen)		spaces_trap(4,buf,buflen);#endif	if(!buflen)		return;#ifdef DEFENSIVE	if((ulong)buf < (ulong)shm->screen)		return;	if((ulong)(buf + buflen) > (((ulong)shm->screen) + LINESxCOLS))		return;#endif	memset(buf,SPACE,buflen);}	/* end of spaces *//*+-------------------------------------------------------------------------	lgetc_rcvr() - rcvr version of get char from line--------------------------------------------------------------------------*/intlgetc_rcvr(){	extern int errno;	if(!lgetc_count)	{		rcvrdisp_actual();		while(lgetc_count <= 0)		{			errno = 0;			if((lgetc_count =				read(shm->Liofd,lgetc_buf,RCVR_RDQUAN)) < 0)			{				if(errno == EINTR)	/* if signal interrupted, ... */					continue;		/* ... read again */				termecu(TERMECU_LINE_READ_ERROR);			}			if(!lgetc_count)			{				lzero_length_read_detected(); /* maybe terminate program ... */				continue;					/* ... but if not, read again */			}		}		shm->rcvd_chars += lgetc_count;		shm->rcvd_chars_this_connect += lgetc_count;		lgetc_ptr = lgetc_buf;	}	lgetc_count--;	if(shm->Lparity)		return(*lgetc_ptr++ & 0x7F);	else		return(*lgetc_ptr++);}	/* end of lgetc_rcvr *//*+-------------------------------------------------------------------------	ansi_SGR() - Set Graphics RenditionThe DOS ANSI world expects to be able to be able to chain 0,1 and3x,4x params together with semicolons.  Supported modifiers for non-ansi terminals  0       normal  1       bold  4       underscore  5       blink  7       reverse video--------------------------------------------------------------------------*/voidansi_SGR(){	register itmp;	register char *cptr;	char SGRstr[MAX_ANSI_LEN];	char *token;	char *str_token();	if(!tty_is_multiscreen)	{		ansibuf[ansilen - 1] = 0;	/* get rid of 'm' */		cptr = ansibuf + 1;			/* get rid of '[' */		if(!strlen(cptr))			goto SGR_0;		while(token = str_token(cptr,";"))		{			cptr = (char *)0;	/* further calls to str_token need NULL */			switch(atoi(token))			{				default:				case 0:		/* normal */SGR_0:					tcap_stand_end();					tcap_blink_off();					tcap_underscore_off();					tcap_bold_off();					break;				case 1:		/* bold */					tcap_bold_on();					break;				case 4:		/* underscore */					tcap_underscore_on();					break;				case 5:		/* blink */					tcap_blink_on();					break;				case 7:		/* reverse video */					tcap_stand_out();					break;			}		}		return;	}	if(ansilen <= 3)	/* 'ESC[<0-9>m' and 'ESC[m' - quickly handled */	{		rcvrdisp(&esc,1);		rcvrdisp(ansibuf,ansilen);		return;	}/* check XENIX 'ESC[<2,3,7>m' extensions */	switch(itmp = atoi(ansibuf + 1))	{		case 7: /* XENIX 'ESC[7;<0-15>;<0-15>m' set fore/background color */			itmp = atoi(ansibuf + 3);	/* second parameter */			if(itmp > 15)				/* not XENIX extension */				break;			/* fall through */		case 2:	/* XENIX 'ESC[2;<0-15>;<0-15>m' set fore/background color */		case 3:	/* XENIX 'ESC[3;<0-1>m' color only set/clear blink */			rcvrdisp(&esc,1);			rcvrdisp(ansibuf,ansilen);			return;		default:			break;	}/* not XENIX extension */	ansibuf[ansilen - 1] = 0;	/* get rid of 'm' */	cptr = ansibuf + 1;			/* get rid of '[' */	while(token = str_token(cptr,";"))	{		cptr = (char *)0;	/* further calls to str_token need NULL */		sprintf(SGRstr,"\033[%sm",token);		rcvrdisp(SGRstr,strlen(SGRstr));	}}	/* end of ansi_SGR *//*+-------------------------------------------------------------------------	ansi_CUP() - cursor position (also HVP horiz/vertical position)--------------------------------------------------------------------------*/voidansi_CUP(){	register uint param_count = 0;	char ansicopy[MAX_ANSI_LEN];	register char *cptr = ansicopy;	register char *token;	char *str_token();	strcpy(cptr,ansibuf + 1);	*(cptr + ansilen - 2) = 0;	while(token = str_token(cptr,";"))	{		cptr = (char *)0;	/* further calls to str_token need NULL */		switch(++param_count)		{			case 1:	shm->cursor_y = atoi(token) - 1; break;			case 2:	shm->cursor_x = atoi(token) - 1; break;		}	}	switch(param_count)	{		case 0:			shm->cursor_y = 0;

⌨️ 快捷键说明

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