[comp.sources.misc] v16i031: ECU async comm package rev 3.0, Part07/35

wht@n4hgf.uucp (Warren Tucker) (01/06/91)

Submitted-by: wht@n4hgf.uucp (Warren Tucker)
Posting-number: Volume 16, Issue 31
Archive-name: ecu3/part07

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 07 of ecu3
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= ecusetup.c ==============
echo 'x - extracting ecusetup.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecusetup.c' &&
X/*+-------------------------------------------------------------------------
X	ecusetup.c -- ecu visual "argv"
X	wht@n4hgf.Mt-Park.GA.US
X
X  0000000000111111111122222222223333333333444444444455555555556666
X  0123456789012345678901234567890123456789012345678901234567890123
X00.--[ ecu rev ]-------------------------------------------------.
X01|                                                              |
X02|  Name/phone number to call: ...................              |
X03|  ...................        ................................ |
X04|                                                              |
X05|  tty: /dev/tty.....   (opened)                               | 
X06|                                                              |
X07|  duplex: .  baud: .....  parity: . (data bits .)             |
X08|  Add NL to transmitted CR: .                                 |
X09|  Add NL to received CR:    .                                 |
X10|                                                              |
X11|                                                              |
X12|   TAB:next ^B:prev END:proceed ^D:phone dir  ESC:quit ecu    |
X13`--------------------------------------------------------------'
X
X  Defined functions:
X	setup_display_baud()
X	setup_display_name()
X	setup_display_screen(write_lits)
X	setup_display_single_char()
X	setup_display_tty()
X	setup_line_open()
X	setup_open_status()
X	setup_screen(argv_logical)
X	setw_bot_msg(msg)
X	setw_get_single(nondelim_list)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <curses.h>
X#include "patchlevel.h"
X
X#define STDIO_H_INCLUDED
X#define OMIT_TERMIO_REFERENCES
X#include "ecu.h"
X#include "ecukey.h"
X#include "ecuxkey.h"
X#include "pc_scr.h"
X
X#define END		XFend
X
X#define SETW_LINES	14
X#define SETW_COLS	64
X#define SETW_TLY	1
X#define SETW_TLX	((80 - SETW_COLS) / 2)
X
X#define NAME_Y		2
X#define NAME_X		30
X#define NAME_LEN	19
X#define NAME_LX		3
X
X#define TELNO_Y		3
X#define TELNO_X		3
X#define TELNO_LEN	19
X
X#define DESCR_Y		3
X#define DESCR_X		30
X#define DESCR_LEN	32
X
X#define TTY_Y		5
X#define TTY_X		16
X#define TTY_LEN		5
X#define TTY_LX		3
X
X#define TTYOPN_LY	5
X#define TTYOPN_LX	24
X
X#define DPX_Y		7
X#define DPX_X		11
X#define DPX_LX		3
X
X#define BAUD_Y		7
X#define BAUD_X		20
X#define BAUD_LEN	5
X#define BAUD_LX		14
X
X#define PAR_Y		7
X#define PAR_X		34
X#define PAR_LX		27
X
X#define DB_Y		7
X#define DB_X		48
X#define DB_LX		37
X#define DB_LX2		49
X
X#define XADDNL_Y	8
X#define XADDNL_X	29
X#define XADDNL_LX	3
X
X#define RADDNL_Y	9
X#define RADDNL_X	29
X#define RADDNL_LX	3
X
Xextern char *numeric_revision;	/* ecunumrev.c */
Xextern char *revision_modifier; /* ecunumrev.c */
Xextern int rcvr_pid;
Xextern int interrupt;
Xextern char errmsg[];
X
XWINDOW *setw;
X
X#define SETW_MSG_LEFTX 2
X#define SETW_MSG_MAXLEN	(SETW_COLS - SETW_MSG_LEFTX - 8)
X#define SETW_MSG_BOT_Y  (SETW_LINES - 1)
X#define SETW_MSG_ERR_Y  (SETW_LINES - 3)
X
X/*+-------------------------------------------------------------------------
X	setw_msg(msg,y,fillch)
X--------------------------------------------------------------------------*/
Xvoid
Xsetw_msg(msg,y,fillch,last_msglen)
Xchar *msg;
Xint y;
Xchar fillch;
Xint *last_msglen;
X{
Xregister itmp;
Xregister itmp2;
Xchar msg2[80];
X
X	if(!*last_msglen && !strlen(msg))
X		return;
X
X	wmove(setw,y,SETW_MSG_LEFTX);
X
X	if((itmp = strlen(msg)) == 0)
X	{
X		itmp2 = *last_msglen + 2;
X		for(itmp = 0; itmp < itmp2; itmp++)
X			waddch(setw,fillch & 0xFF);
X		*last_msglen = 0;
X	}
X	else
X	{
X		waddch(setw,' ');
X		if(itmp > SETW_MSG_MAXLEN)
X		{
X			strncpy(msg2,msg,SETW_MSG_MAXLEN);
X			msg2[SETW_MSG_MAXLEN + 1] = 0;
X			waddstr(setw,msg2);
X			itmp = strlen(msg2);
X		}
X		else
X		{
X			waddstr(setw,msg);
X			itmp = strlen(msg);
X		}
X		waddch(setw,' ');
X		if((itmp2 = *last_msglen - itmp) > 0)
X		{
X			while(itmp2--)
X				waddch(setw,fillch & 0xFF);
X		}
X		*last_msglen = itmp;		/* remember last message length */
X	}
X	wrefresh(setw);
X}	/* end of setw_msg */
X
X/*+-------------------------------------------------------------------------
X	setw_bot_msg(msg)
X--------------------------------------------------------------------------*/
Xvoid
Xsetw_bot_msg(msg)
Xchar *msg;
X{
Xstatic int last_msglen = 0;
X
X	setw_msg(msg,SETW_MSG_BOT_Y,sHR,&last_msglen);
X}	/* end of setw_bot_msg */
X
X/*+-------------------------------------------------------------------------
X	setw_err_msg(msg)
X--------------------------------------------------------------------------*/
Xvoid
Xsetw_err_msg(msg)
Xchar *msg;
X{
Xstatic int last_msglen = 0;
X
X	setw_msg(msg,SETW_MSG_ERR_Y,' ',&last_msglen);
X}	/* end of setw_err_msg */
X
X/*+-------------------------------------------------------------------------
X	setup_display_name()
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_display_name()
X{
X	clear_area(setw,NAME_Y,NAME_X,NAME_LEN);
X	waddstr(setw,shm->Llogical);
X
X	clear_area(setw,TELNO_Y,TELNO_X,TELNO_LEN);
X	clear_area(setw,DESCR_Y,DESCR_X,DESCR_LEN);
X	if(strcmp(shm->Llogical,shm->Ldescr))
X	{
X		waddstr(setw,shm->Ldescr);
X		wmove(setw,TELNO_Y,TELNO_X);
X		waddstr(setw,shm->Ltelno);
X	}
X
X}	/* end of setup_display_name */
X
X/*+-------------------------------------------------------------------------
X	setup_display_tty()
X000000000011111
X012345678901234
X/dev/ttyxxxxxx
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_display_tty()
X{
X	clear_area(setw,TTY_Y,TTY_X,TTY_LEN);
X	waddstr(setw,&shm->Lline[8]);
X}	/* end of setup_display_tty */
X
X/*+-------------------------------------------------------------------------
X	setup_display_single_char()
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_display_single_char()
X{
X	wmove(setw,DPX_Y,DPX_X);
X	waddch(setw,(shm->Lfull_duplex) ? 'F' : 'E');
X	wmove(setw,PAR_Y,PAR_X);
X	waddch(setw,(shm->Lparity) ? to_upper(shm->Lparity) : 'N');
X	wmove(setw,DB_Y,DB_X);
X	waddch(setw,(shm->Lparity) ? '7' : '8');
X	wmove(setw,XADDNL_Y,XADDNL_X);
X	waddch(setw,(shm->Ladd_nl_outgoing) ? 'Y' : 'N');
X	wmove(setw,RADDNL_Y,RADDNL_X);
X	waddch(setw,(shm->Ladd_nl_incoming) ? 'Y' : 'N');
X
X }	/* end of setup_display_single_char */
X
X/*+-------------------------------------------------------------------------
X	setup_display_baud()
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_display_baud()
X{
Xchar s8[8];
X	clear_area(setw,BAUD_Y,BAUD_X,BAUD_LEN);
X	sprintf(s8,"%u",shm->Lbaud);
X	waddstr(setw,s8);
X
X}	/* end of setup_display_baud */
X
X/*+-------------------------------------------------------------------------
X	setup_display_screen(write_lits)
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_display_screen(write_lits)
Xint write_lits;
X{
X	if(write_lits)
X	{
X		wmove(setw,NAME_Y,NAME_LX);
X		waddstr(setw,"Name/phone number to call:");
X		wmove(setw,TTY_Y,TTY_LX);
X		waddstr(setw,"tty: /dev/tty");
X		wmove(setw,DPX_Y,DPX_LX);
X		waddstr(setw,"duplex:");
X		wmove(setw,BAUD_Y,BAUD_LX);
X		waddstr(setw,"baud:");
X		wmove(setw,PAR_Y,PAR_LX);
X		waddstr(setw,"parity:");
X		wmove(setw,DB_Y,DB_LX);
X		waddstr(setw,"(data bits");
X		wmove(setw,DB_Y,DB_LX2);
X		waddch(setw,')');
X		wmove(setw,XADDNL_Y,XADDNL_LX);
X		waddstr(setw,"Add NL to transmitted CR:");
X		wmove(setw,RADDNL_Y,RADDNL_LX);
X		waddstr(setw,"Add NL to received CR:");
X		wmove(setw,SETW_LINES - 2,1);
X		wstandout(setw);
X		waddstr(setw,		/* kludge -- must change if setw width does */
X			"   TAB:next ^B:prev END:proceed ^D:phone dir  ESC:quit ecu    ");
X		wstandend(setw);
X	}
X	setup_display_name();
X	setup_display_tty();
X	setup_display_single_char();
X	setup_display_baud();
X	wrefresh(setw);
X}	/* end of setup_display_screen */
X
X/*+-------------------------------------------------------------------------
X	setup_open_status()
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_open_status()
X{
X	wmove(setw,TTYOPN_LY,TTYOPN_LX);
X	if(shm->Liofd >= 0)
X		waddstr(setw,"(opened)");
X	else
X		waddstr(setw,"        ");
X	wrefresh(setw);
X}	/* end of setup_open_status */
X
X/*+-------------------------------------------------------------------------
X	setup_line_open()
X--------------------------------------------------------------------------*/
Xsetup_line_open()
X{
Xregister itmp;
Xregister retries = 8;
Xchar *lopen_err_text();
Xchar *cptr;
Xchar msg[80];
X
X	while(itmp = lopen())
X	{
X		if(retries)
X		{
X			if(!(itmp == LOPEN_ENABLED_IN_USE) &&
X				!(itmp == LOPEN_DIALOUT_IN_USE))
X			{
X				retries = 1;
X				goto FAIL;
X			}
X			sprintf(msg,"%s - waiting %d sec",lopen_err_text(itmp),retries);
X			cptr = msg;
X		}
X		else
X		{
XFAIL:
X			cptr = lopen_err_text(itmp);
X			ring_bell();
X		}
X		setw_err_msg(cptr);
X		if(!retries--)
X			break;
X		nap(1000L);
X		setw_err_msg("");
X	}
X	setup_open_status();
X	return(itmp);
X
X}	/* end of setup_line_open */
X
X/*+-------------------------------------------------------------------------
X	setw_get_single(nondelim_list)
Xassumes cursor is already positioned
X--------------------------------------------------------------------------*/
Xint
Xsetw_get_single(nondelim_list)
Xregister char *nondelim_list;
X{
Xregister uint itmp;
Xstatic char setw_nondelim_list[] =
X{
X	CR,NL,CTL_B,CTL_D,TAB,ESC,CTL_L,CTL_R,END
X};
X
X	itmp = winget_single(setw,nondelim_list,setw_nondelim_list);
X	if( (itmp & 0xFF) == CR)
X		itmp = NL | 0x1000;
X	return(itmp);
X}	/* end of setw_get_single */
X
X/*+-------------------------------------------------------------------------
X	setup_screen(argv_logical)
X--------------------------------------------------------------------------*/
Xvoid
Xsetup_screen(argv_logical)
Xchar *argv_logical;
X{
Xregister itmp;
Xregister input_state = 0;
Xchar s64[64];
Xint done = 0;
Xuint baud;
Xuchar delim;	/* important to be unsigned to avoid sign extension */
XWINDOW *window_create();
Xstatic char use_input_delim[] = {TAB,NL,END,CTL_D};
X
X	windows_start();
X	sprintf(s64,"ecu %s.%02d%s",numeric_revision,PATCHLEVEL,revision_modifier);
X	setw = window_create(s64,-3,SETW_TLY,SETW_TLX,SETW_LINES,SETW_COLS);
X	setup_display_screen(1);
X
XREENTER_INPUT_LOOP:
X	while(!done)
X	{
X		wrefresh(setw);
X		switch(input_state)
X		{
X			case 0:
XCASE_0:
X				if(argv_logical)
X				{
X					itmp = 0;	/* 'ecu -' means dont dial */
X					if(strcmp(argv_logical,"-"))	/* if not "-" */
X					{
X						strncpy(s64,argv_logical,NAME_LEN + 1);
X						s64[NAME_LEN + 1] = 0;
X						itmp = strlen(s64);
X					}
X					delim = END;
X				}
X				else
X				{
X					setw_bot_msg(
X						"logical phone directory entry, phone number or empty");
X 					itmp = wingets(setw,NAME_Y,NAME_X,s64,NAME_LEN + 1,&delim,
X						(shm->Llogical[0] != 0));
X					setw_err_msg("");
X				}
X				if(strchr(use_input_delim,delim) && strlen(s64))
X				{
X					strcpy(shm->Llogical,s64);
X					if(shm->Llogical[0] && (lookup_logical_telno() == 0))
X					{
X						setw_err_msg(errmsg);
X						setup_display_screen(0);
X						ring_bell();
X						argv_logical = (char *)0;
X						goto CASE_0;
X					}
X					setup_display_screen(0);
X					break;
X				}
X				setup_display_name();
X				break;
X
X			case 1:
X				setw_bot_msg("comm line: i.e., 1a, 2a, 4a, 4b, 4c, 4d");
X				setup_display_tty();
X				strcpy(s64,&shm->Lline[8]);
X 				itmp = wingets(setw,TTY_Y,TTY_X,s64,TTY_LEN + 1,&delim,1);
X				setw_err_msg("");
X				if(strchr(use_input_delim,delim) && strlen(s64))
X					strcpy(&shm->Lline[8],s64);
X				setup_display_tty();
X				break;
X
X			case 2:
X				setw_bot_msg("duplex F:full H:half");
X				wmove(setw,DPX_Y,DPX_X);
X				wrefresh(setw);
X				delim = NL;
X				switch(itmp = setw_get_single("fh"))
X				{
X					case 0:
X					case 1:
X						shm->Lfull_duplex = itmp;
X						break;
X					default:
X						delim = itmp & 0xFF;
X						break;
X				}
X				break;
X
X			case 3:		/* baud */
X				setw_bot_msg(
X				"rates: 110,300,600,1200,2400,4800,9600,19200,38400");
XCASE_3:
X				sprintf(s64,"%u",shm->Lbaud);
X 				itmp = wingets(setw,BAUD_Y,BAUD_X,s64,BAUD_LEN + 1,&delim,1);
X				if(strchr(use_input_delim,delim) && strlen(s64))
X				{
X					if(valid_baud_rate(baud = atoi(s64)) < 0)
X					{
X						setup_display_baud();
X						ring_bell();
X						goto CASE_3;
X					}
X					shm->Lbaud = baud;
X				}
X				setup_display_baud();
X				break;
X
X			case 4:
X				setw_bot_msg("parity: N:none E:even O:odd");
X				wmove(setw,PAR_Y,PAR_X);
X				wrefresh(setw);
X				delim = NL;
X				switch(itmp = setw_get_single("neo"))
X				{
X					case 0:	shm->Lparity = 0;   break;
X					case 1: shm->Lparity = 'e'; break;
X					case 2: shm->Lparity = 'o'; break;
X					default:
X						delim = itmp & 0xFF;
X						break;
X				}
X				wmove(setw,DB_Y,DB_X);
X				waddch(setw,(shm->Lparity) ? '7' : '8');
X				break;
X
X			case 5:
X				setw_bot_msg("");
X				wmove(setw,XADDNL_Y,XADDNL_X);
X				wrefresh(setw);
X				delim = NL;
X				switch(itmp = setw_get_single("ny"))
X				{
X					case 0:
X					case 1: shm->Ladd_nl_outgoing = itmp; break;
X					default: delim = itmp & 0xFF;
X				}
X				break;
X
X			case 6:
X				setw_bot_msg("");
X				wmove(setw,RADDNL_Y,RADDNL_X);
X				wrefresh(setw);
X				delim = NL;
X				switch(itmp = setw_get_single("ny"))
X				{
X					case 0:
X					case 1: shm->Ladd_nl_incoming = itmp; break;
X					default: delim = itmp & 0xFF; break;
X				}
X				break;
X		}
X
X		if(argv_logical)
X			break;
X
X		switch(delim)
X		{
X			case CTL_B:
X				if(input_state)
X					input_state--;
X				else
X					input_state = 6;
X				break;
X
X			case TAB:
X			case NL:
X				input_state++;
X				input_state %= 7;
X				break;
X
X			case ESC:
X				if(shm->Liofd >= 0)
X					lclose();
X				setw_bot_msg("");
X				setup_open_status();
X				hangup(0);
X				break;
X
X			case CTL_L:
X			case CTL_R:
X				tcap_clear_screen();
X				touchwin(stdscr);
X				wrefresh(stdscr);
X				setup_display_screen(1);
X				touchwin(setw);
X				wrefresh(setw);
X				break;
X
X			case END:
X			case CTL_D:
X				done = 1;
X				break;
X		}
X	}
X
X	if(shm->Liofd < 0)
X	{
X		wmove(setw,TTY_Y,TTY_X);
X		wrefresh(setw);
X		if(setup_line_open())
X		{
X			done = 0;
X			input_state = 1;
X			argv_logical = (char *)0;
X			goto REENTER_INPUT_LOOP;
X		}
X	}
X
X	wmove(setw,SETW_LINES - 2,1);
X	wstandout(setw);
X	waddstr(setw,		/* kludge -- must change if setw width does */
X		"------- Press HOME then 'help' for further assistance --------");
X	wstandend(setw);
X	setw_bot_msg("");
X	windows_end(setw);
X	tcap_cursor(SETW_TLY + SETW_LINES + 2,0);
X	if(delim == CTL_D)
X	{
X		rcvr_pid = -2;
X		pde_list_manager();
X	}
X	else if(shm->Llogical[0])
X	{
X#ifdef AUTO_DIAL_PROC
X		if(find_procedure(shm->Llogical))
X		{
X		char *pargv[2];
X			pargv[0] = shm->Llogical;
X			pargv[1] = "!INITIAL";
X			rcvr_pid = 0;
X			do_proc(2,pargv);
X			interrupt = 0;
X			start_rcvr_process(1);
X		}
X		else
X		{
X			rcvr_pid = -2;
X			DCE_dial();
X		}
X#else
X	rcvr_pid = -2;
X	DCE_dial();
X#endif
X	}
X	else
X		start_rcvr_process(1);
X
X}	/* end of setup_screen */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223390 'ecusetup.c' &&
chmod 0644 ecusetup.c ||
echo 'restore of ecusetup.c failed'
Wc_c="`wc -c < 'ecusetup.c'`"
test 14649 -eq "$Wc_c" ||
	echo 'ecusetup.c: original size 14649, current size' "$Wc_c"
# ============= ecushm.c ==============
echo 'x - extracting ecushm.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecushm.c' &&
X/*+-------------------------------------------------------------------------
X	ecushm.c - shared memory handler for ecu xmtr/rcvr comm
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	shm_done()
X	shm_init()
X	shmr_process_rcvr_SIGUSR2()
X	shmr_set_xmtr_bn_1()
X	shmx_connect()
X	shmx_make_rcvr_sleep(seconds)
X	shmx_process_xmtr_SIGUSR2()
X	shmx_rc_report(prcvd_chars,prcvd_chars_this_connect)
X	shmx_set_rcvr_ansi(mode)
X	shmx_set_rcvr_bn(bn_value)
X	shmx_set_rcvr_log(logfilename,append_flag,raw_flag)
X	shmx_set_rcvr_nl_control()
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include <sys/ipc.h>
X#include <sys/shm.h>
X
X/* xmtr to rcvr cmds */
X#define SHMX_MAKE_RCVR_SLEEP	1	/* sleep xi1=#seconds */
X#define	SHMX_SET_RCVR_BN		2	/* set want_bell_notify xi1=value */
X#define SHMX_SET_RCVR_LOG		3	/* log file manipulations
X									 * xi1=append, xi2=raw, xs1=name */
X/* rcvr to xmtr cmds */
X#define SHMR_SET_XMTR_BN1		1	/* set want_bell_notify to 1 */
X
Xextern int want_bell_notify;
Xextern int rcvr_pid;
Xextern int xmtr_pid;
Xextern char rcvr_log_file[];	/* if rcvr_log!= 0,log filename */
Xextern int rcvr_log;			/* rcvr log active if != 0 */
Xextern FILE *rcvr_log_fp;		/* rcvr log file */
Xextern int rcvr_log_raw;		/* if true, log all, else filter ctl chrs */
Xextern int rcvr_log_flusheach;
Xextern int rcvr_log_append;	/* if true, append, else scratch */
Xextern int rcvr_log_gen_title;
X
XECU_SDS FAR *shm;				/* shared segment pointer */
Xkey_t shm_key;
Xint shm_shmid;
X
X/*+-------------------------------------------------------------------------
X	shm_init()
X  Called by parent process (xmtr) to initialize environment
X--------------------------------------------------------------------------*/
Xshm_init()
X{
Xchar FAR *shmat();
Xuint save_LINESxCOLS;
Xextern uint LINESxCOLS;
X
X	shm_key = 0xEC000000L | getpid();
X
X	if((shm_shmid = shmget(shm_key,sizeof(ECU_SDS),IPC_CREAT | 0600)) < 0)
X	{
X		perror("shmget");
X		exit(11);
X	}
X
X	if(((char FAR *)shm = shmat(shm_shmid,(char FAR *)0,0)) == (char FAR *)-1)
X	{
X		perror("shmat");
X		exit(11);
X	}
X
X	shm->xcmd = 0;	/* signal from xmtr to rcvr SIGUSR2 */
X	shm->xi1 = 0;	/* parameters */
X	shm->xi2 = 0;
X	shm->xs1[0] = 0;
X	shm->rcmd = 0;	/* signal from rcvr to xmtr SIGUSR2 */
X	shm->ri1 = 0;	/* parameters */
X	shm->ri2 = 0;
X	shm->rs1[0] = 0;
X	shm->rcvd_chars = 0L;
X	shm->rcvd_chars_this_connect = 0L;
X
X	shm->cursor_y = 0;
X	shm->cursor_x = 0;
X	shm->friend_space[0] = 0;
X	save_LINESxCOLS = LINESxCOLS;
X	LINESxCOLS = sizeof(shm->screen);	/* avoid trap */
X	spaces((char *)shm->screen,sizeof(shm->screen));
X	LINESxCOLS = save_LINESxCOLS;
X
X	return(0);
X
X}	/* end of shm_init */
X
X/*+-------------------------------------------------------------------------
X	shm_done() -- finished with shm -- clean up
X--------------------------------------------------------------------------*/
Xvoid
Xshm_done()
X{
X	if(shmctl(shm_shmid,IPC_RMID,(struct shmid_ds *)0))
X		perror("shmctl IPC_RMID");
X}	/* end of shm_done */
X
X/*+-------------------------------------------------------------------------
X	shmx_rc_report(prcvr_chars,prcvr_chars_this_connect)
X xmtr calls to get rcvr stats
X--------------------------------------------------------------------------*/
Xshmx_rc_report(prcvd_chars,prcvd_chars_this_connect)
Xlong *prcvd_chars;
Xlong *prcvd_chars_this_connect;
X{
X	*prcvd_chars = shm->rcvd_chars;
X	*prcvd_chars_this_connect = shm->rcvd_chars_this_connect;
X}	/* end of shmx_rc_report */
X
X/*+-------------------------------------------------------------------------
X	shmx_connect() -- xmtr calls when modem connects
X--------------------------------------------------------------------------*/
Xvoid
Xshmx_connect()
X{
X	shm->rcvd_chars_this_connect = 0L;
X}	/* end of shmx_connect */
X
X/*+-------------------------------------------------------------------------
X	shmx_make_rcvr_sleep(seconds)
X--------------------------------------------------------------------------*/
Xvoid
Xshmx_make_rcvr_sleep(seconds)
Xint seconds;
X{
X	shm->xcmd = SHMX_MAKE_RCVR_SLEEP;
X	shm->xi1 = seconds;
X	kill_rcvr_process(SIGUSR2);
X
X}	/* end of shmx_make_rcvr_sleep */
X
X/*+-------------------------------------------------------------------------
X	shmx_set_rcvr_log(logfilename,append_flag,raw_flag,flush_each)
X
Xnull logfilename stops logging
Xappend_flag says whether to open for write or append
Xraw_flag says whether or not to filter non-printable chars or not
X(NL not filtered)
X--------------------------------------------------------------------------*/
Xvoid
Xshmx_set_rcvr_log(logfilename,append_flag,raw_flag,flush_each)
Xchar *logfilename;
Xint append_flag;
Xint raw_flag;
Xint flush_each;
X{
X	shm->xcmd = SHMX_SET_RCVR_LOG;
X	shm->xi1 = append_flag;
X	shm->xi2 = raw_flag;
X	shm->xi3 = flush_each;
X	strcpy(shm->xs1,logfilename);
X	kill_rcvr_process(SIGUSR2);
X}	/* end of shmx_set_rcvr_log */
X
X/*+-------------------------------------------------------------------------
X	shmx_set_rcvr_bn(bn_value)
X--------------------------------------------------------------------------*/
Xvoid
Xshmx_set_rcvr_bn(bn_value)
Xint bn_value;
X{
X	shm->xcmd = SHMX_SET_RCVR_BN;
X	shm->xi1 = bn_value;
X	kill_rcvr_process(SIGUSR2);
X
X}	/* end of shmx_set_rcvr_bn */
X
X/*+-------------------------------------------------------------------------
X	shmr_set_xmtr_bn_1()
X--------------------------------------------------------------------------*/
Xvoid
Xshmr_set_xmtr_bn_1()
X{
X	shm->rcmd = SHMR_SET_XMTR_BN1;
X	kill(xmtr_pid,SIGUSR2);
X
X}	/* end of shmr_set_xmtr_bn_1 */
X
X/*+-------------------------------------------------------------------------
X	shmx_process_xmtr_SIGUSR2()
X--------------------------------------------------------------------------*/
Xvoid
Xshmx_process_xmtr_SIGUSR2()
X{
Xregister rcmd;
Xregister ri1,ri2;
X
X	rcmd = shm->rcmd;
X	shm->rcmd = 0;
X	ri1 = shm->ri1;
X	ri2 = shm->ri2;
X
X	switch(rcmd)
X	{
X		case SHMR_SET_XMTR_BN1:
X			want_bell_notify = 1;
X			break;
X	}
X
X}	/* end of shmx_process_xmtr_SIGUSR2 */
X
X/*+-------------------------------------------------------------------------
X	shmr_process_rcvr_SIGUSR2()
X--------------------------------------------------------------------------*/
Xvoid
Xshmr_process_rcvr_SIGUSR2()
X{
Xregister xcmd;
Xregister xi1,xi2,xi3;
Xchar xs1[SHM_STRLEN];
X
X	xcmd = shm->xcmd;
X	shm->xcmd = 0;
X	xi1 = shm->xi1;
X	xi2 = shm->xi2;
X	xi3 = shm->xi3;
X	strcpy(xs1,shm->xs1);
X
X	switch(xcmd)
X	{
X		case SHMX_MAKE_RCVR_SLEEP:
X			sleep(xi1);
X			break;
X
X		case SHMX_SET_RCVR_BN:
X			want_bell_notify = xi1;
X			break;
X
X		case SHMX_SET_RCVR_LOG:
X			if(rcvr_log) 		/* if already logging */
X			{
X				if(!rcvr_log_raw)
X					putc('\n',rcvr_log_fp);
X				fclose(rcvr_log_fp);
X				rcvr_log = 0;
X			}
X			if(strlen(xs1) == 0)	/* if all we wanted was to stop log ... */
X				break;				/* ... then quit */
X			rcvr_log_gen_title = 1;
X			rcvr_log = 1;
X			rcvr_log_append = xi1;
X			rcvr_log_raw = xi2;
X			rcvr_log_flusheach = xi3;
X			strcpy(rcvr_log_file,xs1);
X			rcvr_log_open();
X			break;
X	}
X
X}	/* end of shmr_process_rcvr_SIGUSR2 */
X
X/* end of ecushm.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223390 'ecushm.c' &&
chmod 0644 ecushm.c ||
echo 'restore of ecushm.c failed'
Wc_c="`wc -c < 'ecushm.c'`"
test 7052 -eq "$Wc_c" ||
	echo 'ecushm.c: original size 7052, current size' "$Wc_c"
# ============= ecusighdl.c ==============
echo 'x - extracting ecusighdl.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecusighdl.c' &&
X/* #define RCVR_CLEAN_CORE_DUMP */
X/*+-----------------------------------------------------------------------
X	ecusighdl.c - xmtr/rcvr individual process signal handlers
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	child_signals()
X	hangup(sig)
X	kill_rcvr_process(sig)
X	rcvr_SIGHUP_handler()
X	rcvr_SIGINT_handler()
X	rcvr_SIGTERM_handler()
X	rcvr_SIGUSR1_handler()
X	rcvr_SIGUSR2_handler()
X	rcvr_common_signal_handler()
X	rcvr_death_handler(sig)
X	rcvr_signals()
X	start_rcvr_process(notify_flag)
X	xmtr_SIGHUP_handler(sig)
X	xmtr_SIGINT_handler()
X	xmtr_SIGTERM_handler(sig)
X	xmtr_SIGUSR2_handler()
X	xmtr_bsd4_SIGCHLD_handler()
X	xmtr_signals()
X	xmtr_SIGCLD_handler()
X
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-18-1990-20:02-wht@n4hgf-add rcvr_death_handler */
X/*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecufork.h"
X
Xextern int errno;
Xextern int rcvr_pid;
Xextern int xmtr_pid;
Xextern int windows_active;
Xextern int current_ttymode;
Xextern char lopen_err_str[];
Xextern int rcvr_log;
Xextern FILE *rcvr_log_fp;
Xextern char rcvr_log_file[];	/* if rcvr_log!= 0,log filename */
Xextern int rcvr_log_append;
X
Xint interrupt = 0;			/* interrupt indicator */
Xint proc_interrupt = 0;		/* procedure interrupt indicator */
Xint last_child_wait_status = 0;
Xint last_child_wait_pid = 0;
Xint xmtr_killed_rcvr = 0;
X
Xchar *signal_name_text();
X
Xvoid hangup();
Xvoid xmtr_signals();
X
Xvoid rcvr_SIGTERM_handler();
Xvoid rcvr_SIGINT_handler();
Xvoid rcvr_SIGUSR1_handler();
Xvoid rcvr_SIGUSR2_handler();
Xvoid rcvr_SIGHUP_handler();
Xvoid xmtr_SIGINT_handler();
Xvoid xmtr_SIGHUP_handler();
Xvoid xmtr_SIGTERM_handler();
Xvoid xmtr_SIGCLD_handler();
Xvoid rcvr_common_signal_handler();
Xvoid rcvr_death_handler();
X
X/*+-----------------------------------------------------------------------
X	start_rcvr_process(notify_flag)
X------------------------------------------------------------------------*/
Xstart_rcvr_process(notify_flag)
Xint notify_flag;
X{
Xchar s40[40];
Xextern ulong colors_current;
Xulong colors_at_entry = colors_current;
X
X	fflush(so);
X	fflush(se);
X
X	if(rcvr_pid > 0)			/* if process already active,just ... */
X		return(rcvr_pid);		/* ... return the process id */
X
X	if(rcvr_log && rcvr_log_file[0] && rcvr_log_fp)
X	{
X		fclose(rcvr_log_fp);
X		rcvr_log_fp = NULL;
X	}
X
X	xmtr_killed_rcvr = 0;
X	rcvr_pid = smart_fork();
X	if(rcvr_pid == 0)		/* if we are the (spawned) rcvr process */
X	{
X		if(notify_flag)
X		{
X			setcolor(colors_notify);
X			fputs("[interactive mode]",se);
X			setcolor(colors_at_entry);
X			fputs("\r\n",se);
X		}
X
X		rcvr();	/* run until killed */
X		/*NOTREACHED*/
X	}
X	else if(rcvr_pid > 0) 	/* we are the father (xmtr) process */
X	{
X#if defined(FORK_DEBUG)
X		sprintf(s40,"DEBUG rcvr pid %d",rcvr_pid);
X		ecu_log_event(getpid(),s40);		/* rcvr */
X#endif
X		if(rcvr_log)
X			rcvr_log_append = 1;	/* until next %log -s */
X		xmtr_signals();
X		return(rcvr_pid);
X	}
X	else
X	{
X		rcvr_pid = -1;		/* no receiver active */
X		ff(se,"\r\n\ncould not fork for receive\r\n");
X		hangup(HANGUP_NO_FORK_FOR_RCVR);
X		/*NOTREACHED*/
X	}
X}	/* end of start_rcvr_process */
X
X/*+-----------------------------------------------------------------------
X	kill_rcvr_process(sig) -- kill rcvr process with signal 'sig'
X------------------------------------------------------------------------*/
Xvoid
Xkill_rcvr_process(sig)
Xint sig;
X{
Xint wait_count = 70;
X
X	if(rcvr_pid > 0)		/* if we have forked a rcvr process */
X	{
X		xmtr_killed_rcvr = 1;
X		rcvr_log_fp = NULL;
X		xmtr_signals();
X		kill(rcvr_pid,sig);
X		if(sig != SIGUSR2)	/* rcvr does not die on SIGUSR2 */
X		{
X			errno = 0;
X			while(wait_count)
X			{
X				if(kill(rcvr_pid,0) && (errno == ESRCH))
X					break;
X				errno = 0;
X				nap(40L);
X				wait_count--;
X			}
X			if(!wait_count)
X			{
X				while(!kill(rcvr_pid,SIGKILL))
X				{
X					wait((int *)0);
X					nap(40L);
X				}
X			}
X			rcvr_pid = -1;
X			if(rcvr_log && rcvr_log_file[0])
X				rcvr_log_fp = fopen(rcvr_log_file,"a");
X		}
X	}
X
X}	/* end of kill_rcvr_process */
X
X/*+-------------------------------------------------------------------------
X	hangup_code_text(code)
X--------------------------------------------------------------------------*/
Xchar *
Xhangup_code_text(code)
Xint code;
X{
Xstatic char errant[16];
Xchar *signal_name_text();
X
X	if((code >= HANGUP_SIG1) && (code <= HANGUP_SIGN))
X		return(signal_name_text(code));
X
X	switch(code)
X	{
X		case HANGUP_LINE_READ_ERROR: return("line read error");
X		case HANGUP_XMTR_WRITE_ERROR: return("line write error");
X		case HANGUP_XMTR_LOGIC_ERROR: return("XMTR LOGIC ERROR");
X		case HANGUP_RCVR_LOGIC_ERROR: return("RCVR LOGIC ERROR");
X		case HANGUP_BSD4_IOCTL: return("BSD4 ioctl error");
X		case HANGUP_SHM_ABL: return("SHM ABL error");
X		case HANGUP_SHM_RTL: return("SHM RTL error");
X		case HANGUP_NO_FORK_FOR_RCVR: return("can't fork for RCVR");
X		case HANGUP_TTYIN_READ_ERROR: return("keyboard read error");
X		case HANGUP_LINE_OPEN_ERROR: return("line open error");
X		case HANGUP_PWENT_ERROR: return("password entry error");
X		case HANGUP_USAGE: return("usage");
X		case HANGUP_INIT_PROC_ERROR: return("error during initial procedure");
X		case HANGUP_CONFIG_ERROR: return("configuration error");
X		default:
X			sprintf(errant,"code %u?",code);
X			return(errant);
X	}
X
X}	/* end of hangup_code_text */
X
X/*+-----------------------------------------------------------------------
X	hangup(sig) -- terminate program (with comm line cleanup)
X
X  close comm line
X  return any ungetty'd line
X  return user's console to normal status
X  unlink shm name
X  terminate program
X  see ecuhangup.h
X------------------------------------------------------------------------*/
Xvoid
Xhangup(sig)
Xint sig;
X{
Xint isig;
Xint save_errno = errno;
Xextern char initial_procedure[];
X
X	if(xmtr_pid == getpid())		/* if we are xmtr */
X	{
X		for(isig = 1; isig < NSIG; isig++)
X			signal(isig,SIG_IGN);
X		kill_rcvr_process(SIGUSR1);
X		if(shm)
X		{
X			if(shm->Lmodem_off_hook)
X				DCE_hangup();
X			if(shm->Liofd != -1)
X				lclose();			/* close line */
X		}
X
X		/* make SURE we release any line acquired from getty */
X		ungetty_return_line();	/* lclose() calls this via unlock_tty(),
X								 * but ok to make sure
X								 */
X
X		if(windows_active)
X			windows_end_signal();
X		tcap_curbotleft();
X		tcap_eeod();
X		ttymode(0);			/* normal tty status */
X		shm_done();
X		if(sig > NSIG)
X		{
X		char s64[64];
X			setcolor(colors_error);
X			if(sig == HANGUP_INIT_PROC_ERROR)
X				pprintf("initial procedure '%s' failed\n",initial_procedure);
X			else if((sig > HANGUP_INIT_PROC_ERROR) &&
X					(sig <= HANGUP_INIT_PROC_ERROR + 32))
X			{
X				pprintf("procedure command: exit %d\n",
X					sig - HANGUP_INIT_PROC_ERROR);
X			}
X			else
X			{
X				sprintf(s64,"## XMTR %s, errno = %d",hangup_code_text(sig),
X					save_errno);
X				pputs(s64);
X				pputs("\n");
X				if(lopen_err_str[0])
X				{
X					pputs(lopen_err_str);
X					pputs("\n");
X				}
X				ecu_log_event(getpid(),s64);
X				errno = save_errno;
X				if(errno)
X					pperror("errno may not apply, but");
X			}
X		}
X		setcolor(colors_normal);
X	}
X	else							/* we are rcvr */
X	{
X		if(sig > NSIG)
X		{
X		char s64[64];
X			sprintf(s64,"## RCVR %s, errno = %d",hangup_code_text(sig),
X				save_errno);
X			setcolor(colors_error);
X			pputs(s64);
X			pputs("\n");
X			ecu_log_event(getpid(),s64);
X			errno = save_errno;
X			if(errno)
X				pperror("errno may not apply, but");
X		}
X		setcolor(colors_normal);
X		kill(xmtr_pid,SIGHUP);
X	}
X	exit(sig);
X	/*NOTREACHED*/
X
X}	/* end of hangup */
X
Xvoid
Xrcvr_common_signal_handler()
X{
Xextern int rcvr_log;
Xextern int rcvr_log_raw;
Xextern FILE *rcvr_log_fp;
X
X	if(rcvr_log)
X	{
X		if(!rcvr_log_raw)
X			fputs("\n",rcvr_log_fp);
X		fclose(rcvr_log_fp);
X	}
X
X	exit(0);
X}
Xvoid
Xrcvr_SIGTERM_handler()
X{
X	rcvr_common_signal_handler();
X}
Xvoid
Xrcvr_SIGINT_handler()
X{
X	signal(SIGINT,rcvr_SIGINT_handler);
X}
Xvoid
Xrcvr_SIGUSR1_handler()
X{
X	rcvr_common_signal_handler();
X}
Xvoid
Xrcvr_SIGUSR2_handler()
X{
X	signal(SIGUSR2,rcvr_SIGUSR2_handler);
X	shmr_process_rcvr_SIGUSR2();
X}
Xvoid
Xrcvr_SIGHUP_handler()
X{
X	rcvr_common_signal_handler();
X}
Xvoid
Xrcvr_death_handler(sig)
Xint sig;
X{
X	fprintf(stderr,"\r\nreceiver process caught signal %s\r\n",
X		signal_name_text(sig));
X	fprintf(stderr,"cursor y=%d x=%d\r\n",shm->cursor_y,shm->cursor_x);
X#ifdef SIGABRT
X	signal(SIGABRT,SIG_DFL);
X#else
X	signal(SIGIOT,SIG_IOT);
X#endif
X	abort();
X	_exit(-1);
X}
X/*+-------------------------------------------------------------------------
X	xmtr_SIGINT_handler()
X--------------------------------------------------------------------------*/
Xvoid
Xxmtr_SIGINT_handler()
X{
X	signal(SIGINT,xmtr_SIGINT_handler);
X	interrupt = 1;
X	proc_interrupt = 1;
X}	/* end of xmtr_SIGINT_handler */
X
Xvoid
Xxmtr_SIGHUP_handler(sig)
Xint sig;
X{
X	hangup(sig);
X}
Xvoid
Xxmtr_SIGTERM_handler(sig)
Xint sig;
X{
X	hangup(sig);
X}
X
Xvoid
Xxmtr_SIGUSR2_handler()
X{
X	signal(SIGUSR2,xmtr_SIGUSR2_handler);
X	shmx_process_xmtr_SIGUSR2();
X}
X
X/*+-------------------------------------------------------------------------
X	xmtr_SIGCLD_handler()
X--------------------------------------------------------------------------*/
Xvoid
Xxmtr_SIGCLD_handler()
X{
Xextern int xmtr_killed_rcvr;
X
XWAIT:
X	errno = 0;
X	if((last_child_wait_pid = wait(&last_child_wait_status)) < 0)
X	{
X		if(errno == EINTR)
X			goto WAIT;
X	}
X
X#if defined(FORK_DEBUG)
X	sprintf(s40,"DEBUG fork SIGCLD pid %d term %x",
X		last_child_wait_pid,last_child_wait_status);
X	ecu_log_event(getpid(),s40);		/* xmtr_SIGCLD_handler() */
X#endif
X
X	if((last_child_wait_pid  == rcvr_pid) && !xmtr_killed_rcvr)
X	{
X		fprintf(stderr,"\r\nECU receiver process died unexpectedly\r\n");
X		hangup(HANGUP_RCVR_LOGIC_ERROR);
X	}
X	signal(SIGCLD,xmtr_SIGCLD_handler);
X
X}	/* end of xmtr_SIGCLD_handler */
X
X/*+-------------------------------------------------------------------------
X	child_signals() - signal() calls for children processes
X--------------------------------------------------------------------------*/
Xvoid
Xchild_signals()
X{
X	signal(SIGHUP,SIG_DFL);
X	signal(SIGINT,SIG_DFL);
X	signal(SIGTERM,SIG_DFL);
X	signal(SIGQUIT,SIG_DFL);
X	signal(SIGUSR1,SIG_DFL);
X	signal(SIGUSR2,SIG_DFL);
X	signal(SIGCLD,SIG_DFL);
X
X}	/* end of child_signals */
X
X/*+-------------------------------------------------------------------------
X	xmtr_signals()
X--------------------------------------------------------------------------*/
Xvoid
Xxmtr_signals()
X{
X	signal(SIGHUP,xmtr_SIGHUP_handler);
X	signal(SIGQUIT,SIG_IGN);
X	signal(SIGINT,xmtr_SIGINT_handler);
X	signal(SIGTERM,xmtr_SIGTERM_handler);
X	signal(SIGCLD,xmtr_SIGCLD_handler);
X	signal(SIGUSR2,xmtr_SIGUSR2_handler);
X
X}	/* end of xmtr_signals */
X
X/*+-------------------------------------------------------------------------
X	rcvr_signals()
X--------------------------------------------------------------------------*/
Xvoid
Xrcvr_signals()
X{
X	signal(SIGHUP,rcvr_SIGHUP_handler);
X	signal(SIGQUIT,SIG_IGN);
X#ifdef RCVR_CLEAN_CORE_DUMP
X	signal(SIGILL,SIG_DFL);
X	signal(SIGTRAP,SIG_DFL);
X	signal(SIGIOT,SIG_DFL);
X	signal(SIGABRT,SIG_DFL);
X	signal(SIGEMT,SIG_DFL);
X	signal(SIGFPE,SIG_DFL);
X	signal(SIGBUS,SIG_DFL);
X	signal(SIGSEGV,SIG_DFL);
X#else
X#ifdef SIGILL
X	signal(SIGILL,rcvr_death_handler);
X#endif
X#ifdef SIGTRAP
X	signal(SIGTRAP,rcvr_death_handler);
X#endif
X#ifdef SIGIOT
X	signal(SIGIOT,rcvr_death_handler);
X#endif
X#ifdef SIGABRT
X	signal(SIGABRT,rcvr_death_handler);
X#endif
X#ifdef SIGEMT
X	signal(SIGEMT,rcvr_death_handler);
X#endif
X#ifdef SIGFPE
X	signal(SIGFPE,rcvr_death_handler);
X#endif
X#ifdef SIGBUS
X	signal(SIGBUS,rcvr_death_handler);
X#endif
X#ifdef SIGSEGV
X	signal(SIGSEGV,rcvr_death_handler);
X#endif
X#endif
X	signal(SIGTERM,rcvr_SIGTERM_handler);
X	signal(SIGINT,rcvr_SIGINT_handler);
X	signal(SIGUSR1,rcvr_SIGUSR1_handler);
X	signal(SIGUSR2,rcvr_SIGUSR2_handler);
X
X}	/* end of rcvr_signals */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223390 'ecusighdl.c' &&
chmod 0644 ecusighdl.c ||
echo 'restore of ecusighdl.c failed'
Wc_c="`wc -c < 'ecusighdl.c'`"
test 11775 -eq "$Wc_c" ||
	echo 'ecusighdl.c: original size 11775, current size' "$Wc_c"
# ============= ecutcap.c ==============
echo 'x - extracting ecutcap.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecutcap.c' &&
X/*+-------------------------------------------------------------------------
X	ecutcap.c -- termcap stuff
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	tcap_blink_off()
X	tcap_blink_on()
X	tcap_bold_off()
X	tcap_bold_on()
X	tcap_clear_screen()
X	tcap_curbotleft()
X	tcap_curleft(count)
X	tcap_cursor(y,x)
X	tcap_curright(count)
X	tcap_delete_chars(count)
X	tcap_delete_lines(count)
X	tcap_draw_box(y,x,height,width,title,title_x)
X	tcap_draw_box_primitive(y,x,height,width)
X	tcap_eeod()
X	tcap_eeol()
X	tcap_horiz_rule(count)
X	tcap_insert_lines(count)
X	tcap_putc_stderr(character)
X	tcap_init()
X	tcap_stand_end()
X	tcap_stand_out()
X	tcap_clear_area_char(count,clrch)
X	tcap_gets(buf,bufsize,delim,wait_for_key)
X	tcap_underscore_off()
X	tcap_underscore_on()
X	tcap_vbell()
X	tcap_vertical_rule(y,x,count)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:11-28-1990-14:52-wht@n4hgf-tcap support for non-ansi console */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "ecukey.h"
X#include "pc_scr.h"
X
Xuint tcap_LINES;
Xuint tcap_COLS;
X
Xstatic char *tc_blink_on = "";
Xstatic char *tc_blink_off = "";
Xstatic char *tc_bold_on = "";
Xstatic char *tc_bold_off = "";
Xstatic char *tc_clear = "";
Xstatic char *tc_curleft = "";
Xstatic char *tc_curright = "";
Xstatic char *tc_delchar = "";
Xstatic char *tc_delline = "";
Xstatic char *tc_eeod = "";
Xstatic char *tc_eeol = "";
Xstatic char *tc_inschar = "";
Xstatic char *tc_insline = "";
Xstatic char *tc_move = "";
Xstatic char *tc_standout = "";
Xstatic char *tc_standend = "";
Xstatic char *tc_underscore_on = "";
Xstatic char *tc_underscore_off = "";
Xstatic char *tc_vbell = "";
Xstatic char tc_strbuf[384];
Xstatic int tc_standout_width;
X
Xchar *tgetstr();
Xchar *tgoto();
Xchar *getenv();
X
Xvoid tcap_cursor();
Xvoid tcap_stand_out();
Xvoid tcap_stand_end();
X
X/*+-------------------------------------------------------------------------
X	tcap_init() - get termcap variables
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_init()
X{
Xchar termbuf[1024];
Xchar *cptr;
X
X	cptr = tc_strbuf;
X	if(tgetent(termbuf,getenv("TERM")) > 0)
X	{
X		tc_blink_on         = tgetstr("mb",&cptr);	/* "XENIX extension" */
X		tc_blink_off        = tgetstr("me",&cptr);	/* "XENIX extension" */
X		tc_clear            = tgetstr("cl",&cptr);
X		tc_curleft          = tgetstr("kl",&cptr);
X		tc_curright         = tgetstr("kr",&cptr);
X		tc_delchar          = tgetstr("dc",&cptr);
X		tc_delline          = tgetstr("dl",&cptr);
X		tc_eeod             = tgetstr("cd",&cptr);
X		tc_eeol             = tgetstr("ce",&cptr);
X		tc_inschar          = tgetstr("ic",&cptr);
X		tc_insline          = tgetstr("al",&cptr);
X		tc_move             = tgetstr("cm",&cptr);
X		tc_standout         = tgetstr("so",&cptr);
X		tc_standend         = tgetstr("se",&cptr);
X		tc_underscore_on    = tgetstr("us",&cptr);
X		tc_underscore_off   = tgetstr("ue",&cptr);
X		tc_vbell            = tgetstr("vb",&cptr);
X		tc_bold_on          = tc_standout;			/* for now */
X		tc_bold_off         = tc_standend;			/* for now */
X		if((tc_standout_width = tgetnum("sg")) < 0)
X			tc_standout_width = 0;
X		tcap_LINES = tgetnum("li");
X		tcap_COLS = tgetnum("co");
X	}
X
X}	/* end of tcap_init */
X
X/*+-------------------------------------------------------------------------
X	tcap_horiz_rule(count) - horizontal rule starting at current position
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_horiz_rule(count)
Xregister count;
X{
X	while(count--)
X		fputc(sHR,se);
X}	/* end of tcap_horiz_rule */
X
X/*+-------------------------------------------------------------------------
X	tcap_vertical_rule(y,x,count) - vertical rule starting at y,x
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_vertical_rule(y,x,count)
Xint y;
Xregister x;
Xregister count;
X{
X
X	while(count--)
X	{
X		tcap_cursor(y++,x);
X		fputc(sVR,se);
X	}
X		
X}	/* end of tcap_vertical_rule */
X
X/*+-------------------------------------------------------------------------
X	tcap_draw_box_primitive(y,x,height,width) - ruled box
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_draw_box_primitive(y,x,height,width)
Xregister y;
Xint x;
Xint height;
Xint width;
X{
Xregister i;
X
X	tcap_cursor(y,x);
X	fputc(sTL,se);
X	if((i = width - 2) > 0)
X		tcap_horiz_rule(i);
X	fputc(sTR,se);
X	if((i = height - 2) > 0)
X	{
X		tcap_vertical_rule(y + 1,x + width - 1,i);
X		tcap_vertical_rule(y + 1,x,i);
X	}
X	tcap_cursor(y + height - 1,x);
X	fputc(sBL,se);
X	if((i = width - 2) > 0)
X		tcap_horiz_rule(i);
X	fputc(sBR,se);
X
X}	/* end of tcap_draw_box_primitive */
X
X/*+-------------------------------------------------------------------------
X	tcap_draw_box(y,x,height,width,title,title_x)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_draw_box(y,x,height,width,title,title_x)
Xchar *title;
X{
Xregister stand = (title_x < 0);
X
X	if(stand)
X		title_x = -title_x;
X
X	tcap_draw_box_primitive(y,x,height,width);
X	tcap_cursor(y,x + title_x);
X	fputc('[',se);
X	if(stand)
X		tcap_stand_out();
X	fprintf(so," %s ",title);
X	if(stand)
X		tcap_stand_end();
X	fputc(']',se);
X
X}	/* end of tcap_draw_box */
X
X/*+-------------------------------------------------------------------------
X	tcap_putc_stderr(character) - utility rotuine for tputs
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_putc_stderr(character)
Xint character;
X{
X	fputc(character,se);
X}	/* end of tcap_putc_stderr */
X
X/*+-------------------------------------------------------------------------
X	tcap_cursor(y,x)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_cursor(y,x)
Xuint y;
Xuint x;
X{
X	if(y >= tcap_LINES)
X		y = tcap_LINES - 1;
X	if(x >= tcap_COLS)
X		x = tcap_COLS - 1;
X	tputs(tgoto(tc_move,x,y),1,tcap_putc_stderr);
X}	/* end of tcap_cursor */
X
X/*+-------------------------------------------------------------------------
X	tcap_curleft(count) - move cursor left
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_curleft(count)
Xregister count;
X{
X	while(count--)
X		fputs(tc_curleft,se);
X}	/* end of tcap_curleft */
X
X/*+-------------------------------------------------------------------------
X	tcap_curright(count) - move cursor right
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_curright(count)
Xregister count;
X{
X	while(count--)
X		fputs(tc_curright,se);
X}	/* end of tcap_curright */
X
X/*+-------------------------------------------------------------------------
X	tcap_curbotleft()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_curbotleft()
X{
X	tcap_cursor(tcap_LINES - 1,0);
X}	/* end of tcap_curbotleft */
X
X/*+-------------------------------------------------------------------------
X	tcap_insert_lines(count)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_insert_lines(count)
Xregister count;
X{
X	if(count && *tc_insline)
X	{
X		while(count--)
X			tputs(tc_insline,1,tcap_putc_stderr);
X	}
X}	/* end of tcap_insert_lines */
X
X/*+-------------------------------------------------------------------------
X	tcap_delete_lines(count)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_delete_lines(count)
Xregister count;
X{
X	if(count && *tc_delline)
X	{
X		while(count--)
X			tputs(tc_delline,1,tcap_putc_stderr);
X	}
X}	/* end of tcap_delete_lines */
X
X/*+-------------------------------------------------------------------------
X	tcap_insert_chars(count)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_insert_chars(count)
Xregister count;
X{
X	if(count && *tc_inschar)
X	{
X		while(count--)
X			tputs(tc_inschar,1,tcap_putc_stderr);
X	}
X}	/* end of tcap_insert_chars */
X
X/*+-------------------------------------------------------------------------
X	tcap_delete_chars(count)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_delete_chars(count)
Xregister count;
X{
X	if(count && *tc_delchar)
X	{
X		while(count--)
X			tputs(tc_delchar,1,tcap_putc_stderr);
X	}
X}	/* end of tcap_delete_chars */
X
X/*+-------------------------------------------------------------------------
X	tcap_vbell() - output visual bell
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_vbell()
X{
X	if(*tc_vbell)
X		tputs(tc_vbell,1,tcap_putc_stderr);
X}	/* end of tcap_vbell */
X
X/*+-------------------------------------------------------------------------
X	tcap_clear_screen()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_clear_screen()
X{
X	if(*tc_clear)
X		tputs(tc_clear,1,tcap_putc_stderr);
X}	/* end of tcap_clear_screen */
X
X/*+-------------------------------------------------------------------------
X	tcap_eeol() - erase to end of line
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_eeol()
X{
X	if(*tc_eeol)
X		tputs(tc_eeol,1,tcap_putc_stderr);
X}	/* end of tcap_eeol */
X
X/*+-------------------------------------------------------------------------
X	tcap_eeod() - erase to end of display
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_eeod()
X{
X	if(*tc_eeod)
X		tputs(tc_eeod,1,tcap_putc_stderr);
X}	/* end of tcap_eeod */
X
X/*+-------------------------------------------------------------------------
X	tcap_stand_out()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_stand_out()
X{
X	if(*tc_standout) /*  && (tc_standout_width == 0)) */
X		tputs(tc_standout,1,tcap_putc_stderr);
X}	/* end of tcap_stand_out */
X
X/*+-------------------------------------------------------------------------
X	tcap_stand_end()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_stand_end()
X{
X	if(*tc_standend) /* && (tc_standout_width == 0)) */
X		tputs(tc_standend,1,tcap_putc_stderr);
X}	/* end of tcap_stand_end */
X
X/*+-------------------------------------------------------------------------
X	tcap_bold_on()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_bold_on()
X{
X	if(*tc_bold_on)
X		tputs(tc_bold_on,1,tcap_putc_stderr);
X	else if(*tc_standout) /*  && (tc_standout_width == 0)) */
X		tputs(tc_standout,1,tcap_putc_stderr);
X}	/* end of tcap_bold_on */
X
X/*+-------------------------------------------------------------------------
X	tcap_bold_off()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_bold_off()
X{
X	if(*tc_bold_off)
X		tputs(tc_bold_off,1,tcap_putc_stderr);
X	else if(*tc_standend) /* && (tc_standout_width == 0)) */
X		tputs(tc_standend,1,tcap_putc_stderr);
X}	/* end of tcap_bold_off */
X
X/*+-------------------------------------------------------------------------
X	tcap_underscore_on()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_underscore_on()
X{
X	if(*tc_underscore_on)
X		tputs(tc_underscore_on,1,tcap_putc_stderr);
X	else if(*tc_standout) /*  && (tc_standout_width == 0)) */
X		tputs(tc_standout,1,tcap_putc_stderr);
X}	/* end of tcap_underscore_on */
X
X/*+-------------------------------------------------------------------------
X	tcap_underscore_off()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_underscore_off()
X{
X	if(*tc_underscore_off)
X		tputs(tc_underscore_off,1,tcap_putc_stderr);
X	else if(*tc_standend) /* && (tc_standout_width == 0)) */
X		tputs(tc_standend,1,tcap_putc_stderr);
X}	/* end of tcap_underscore_off */
X
X/*+-------------------------------------------------------------------------
X	tcap_blink_on()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_blink_on()
X{
X	if(*tc_blink_on)
X		tputs(tc_blink_on,1,tcap_putc_stderr);
X	else if(*tc_standout) /*  && (tc_standout_width == 0)) */
X		tputs(tc_standout,1,tcap_putc_stderr);
X}	/* end of tcap_blink_on */
X
X/*+-------------------------------------------------------------------------
X	tcap_blink_off()
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_blink_off()
X{
X	if(*tc_blink_off)
X		tputs(tc_blink_off,1,tcap_putc_stderr);
X	else if(*tc_standend) /* && (tc_standout_width == 0)) */
X		tputs(tc_standend,1,tcap_putc_stderr);
X}	/* end of tcap_blink_off */
X
X/*+-------------------------------------------------------------------------
X	tcap_clear_area_char(count,clrch)
X--------------------------------------------------------------------------*/
Xvoid
Xtcap_clear_area_char(count,clrch)
Xregister count;
Xregister clrch;
X{
Xregister itmp = count;
X	while(itmp--)
X		fputc(clrch,se);
X	itmp = count;
X	while(itmp--)
X		fputs(tc_curleft,se);
X
X}	/* end of tcap_clear_area_char */
X
X/*+-------------------------------------------------------------------------
X numchars = tcap_gets(buf,bufsize,&delim,wait_for_key)
X
XThis procedure reads a string and returns the number
Xof characters read.  -1 is returned if an abort is signaled by the
Xkeyboard user.
X--------------------------------------------------------------------------*/
Xint
Xtcap_gets(buf,bufsize,delim,wait_for_key)
Xchar *buf;
Xregister bufsize;	/* includes room for null..field is 1 less */
Xregister uchar *delim;
Xint wait_for_key;
X{
Xregister count;
Xregister itmp;
Xregister char *cptr = buf;
X
X	if(!wait_for_key)
X		tcap_clear_area_char(bufsize-1,'_');
X
X	count = 0;			/* no characters in string */
X	*cptr = 0;			/* start with null string */
X
X	while(1)
X	{
X		*delim = ttygetc(1);
X		if((*delim < 0x20) || (*delim >= 0x7F))
X		{
X			switch(*delim)
X			{
X				case CR:
X					*delim = NL;
X				case NL:
X					return(count);
X
X				case BS:
X					if(count)
X					{
X						count--;
X						*--cptr = 0;
X						fputc(0x08,se);
X						fputc('_',se);
X						fputs(tc_curleft,se);
X					}
X					continue;
X
X				case ESC:
X				case CTL_U:
X					itmp = count;
X					while(itmp--)
X					{
X						*--cptr = 0;
X						fputc(0x08,se);
X					}
X					itmp = count;
X					while(itmp--)
X						fputc('_',se);
X					itmp = count;
X					while(itmp--)
X						fputs(tc_curleft,se);
X					cptr = buf;
X					count = 0;
X					if(*delim == ESC)
X						return(-1);
X					continue;
X
X				default:
X					return(-1);
X			}	/* end of switch(*delim) */
X			/*NOTREACHED*/
X		}		/* end of if read delimiter */
X
X		if(count == bufsize-1)
X			continue;
X		if(wait_for_key)
X		{
X			tcap_clear_area_char(bufsize-1,'_');
X			wait_for_key = 0;
X		}
X		fputc(*delim,se);
X		*cptr++ = *delim;
X		*cptr = 0;
X		count++;
X	}	/* end of while can get character */
X					
X}	/* end of tcap_gets */
X
X
X/* end of ecutcap.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223490 'ecutcap.c' &&
chmod 0644 ecutcap.c ||
echo 'restore of ecutcap.c failed'
Wc_c="`wc -c < 'ecutcap.c'`"
test 14554 -eq "$Wc_c" ||
	echo 'ecutcap.c: original size 14554, current size' "$Wc_c"
true || echo 'restore of ecutime.c failed'
echo End of part 7, continue with part 8
exit 0
--------------------------------------------------------------------
Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.