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

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

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

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 12 of ecu3
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= hdbintf.c ==============
echo 'x - extracting hdbintf.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hdbintf.c' &&
X#if defined(SHARE_DEBUG)
X#define LOG_UNGETTY
X#define LOG_HDBDIAL
X#endif
X/*+-------------------------------------------------------------------------
X	hdbintf.c - HDB UUCP database and /etc/utmp interface routines
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	dialstr_translate(translate_list,to_translate)
X	enddlent()
X	enddvent()
X	getdlent()
X	getdlentname(name)
X	getdvbaud(baud)
X	getdvent()
X	getdvline(line)
X	hdb_dial(presult)
X	hdb_dial_error_text(errcode)
X	hdb_init()
X	ungetty_get_line()
X	ungetty_return_line()
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:10-16-1990-20:43-wht@n4hgf-add SHARE_DEBUG */
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 "esd.h"
X#include "var.h"
X#include "ecuhangup.h"
X#include "utmpstatus.h"
X#include "ecuungetty.h"
X#include "dvent.h"
X#include "dlent.h"
X#include "dialprog.h"
X#include <errno.h>
X#include <utmp.h>
X
Xchar *arg_token();
Xchar *skip_ld_break();
X
Xextern int errno;
Xextern char kbdintr;		/* current input INTR */
Xextern int interrupt;
Xextern ulong colors_current;
Xextern char *sys_errlist[];
Xextern int proc_level;
Xextern int proctrace;
X
Xint there_is_hdb_on_this_machine = 0;
XFILE *fpdv = NULL;
XFILE *fpdl = NULL;
Xchar *Devices_file = "/usr/lib/uucp/Devices";
Xchar *Dialers_file = "/usr/lib/uucp/Dialers";
Xchar *ungetty = (char *)0;
Xchar ungetty_executable[128];
Xchar ungetty_ttyname[64] = "";
X
X/*+-------------------------------------------------------------------------
X	ungetty_get_line()
X--------------------------------------------------------------------------*/
Xungetty_get_line()
X{
Xint itmp;
Xchar ungetty_log[80];
Xint ungetty_pid;
Xint (*original_sighdlr)();
Xint wait_status;
Xchar bamboozlement[20];
Xchar *bamboozle();
X
X	if(!there_is_hdb_on_this_machine)
X		return(LOPEN_ENABLED);
X
X	if(!ungetty)
X	{
X		sprintf(ungetty_executable,"%s/ecuungetty",ECULIBDIR);
X		ungetty = ungetty_executable;
X	}
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X	if(access(ungetty,1))
X	{
X		pperror(ungetty);
X		return(LOPEN_ENABLED);
X	}
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	if((ungetty_pid = smart_fork()) == 0)
X	{
X		execl(ungetty,"ungetty",shm->Lline,bamboozlement,(char *)0);
X		exit(-1);
X	}
X	while(((itmp = wait(&wait_status)) != ungetty_pid) && (itmp != -1))
X		;
X	signal(SIGCLD,original_sighdlr);
X	switch((wait_status >> 8) & 0xFF)
X	{
X		case UG_NOTENAB:	/* line acquired: not enabled */
X			ungetty_ttyname[0] = 0;
X			break;
X
X		case UG_ENAB:		/* line acquired: need ungetty -r when done */
X#if defined(LOG_UNGETTY)
X			sprintf(ungetty_log,"UNGETTY acquired %s",shm->Lline);
X			ecu_log_event(getpid(),ungetty_log);
X#endif
X			strcpy(ungetty_ttyname,shm->Lline);
X			break;
X
X		case UG_FAIL:		/* line in use */
X			ungetty_ttyname[0] = 0;
X			return(LOPEN_ENABLED_IN_USE);
X
X		default:
X#if defined(LOG_UNGETTY)
X			sprintf(ungetty_log,"UNGETTY status 0x%04x",wait_status);
X			ecu_log_event(getpid(),ungetty_log);
X#endif
X			ungetty_ttyname[0] = 0;
X			return(LOPEN_ENABLED);
X	}
X
X	return(0);
X
X}	/* end of ungetty_get_line */
X
X/*+-------------------------------------------------------------------------
X	ungetty_return_line()
X--------------------------------------------------------------------------*/
Xvoid
Xungetty_return_line()
X{
Xint ungetty_pid;
Xint itmp;
Xint (*original_sighdlr)();
Xint wait_status = 0xDEAD;
X#if defined(LOG_UNGETTY)
Xchar ungetty_log[80];
X#endif
Xchar bamboozlement[20];
Xchar *bamboozle();
X
X	if(!there_is_hdb_on_this_machine)
X		return;
X	if(!ungetty_ttyname[0])
X		return;
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X
X	/* call ungetty to see if we need to switch to dialin */
X	if(access(ungetty,1))
X	{
X		pperror(ungetty);
X		return;
X	}
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	if((ungetty_pid = smart_fork()) == 0)
X	{
X		execl(ungetty,"ungetty","-t",ungetty_ttyname,bamboozlement,(char *)0);
X		ecu_log_event(getpid(),"could not exec ecuungetty -t");
X		exit(-1);
X	}
X	while(((itmp = wait(&wait_status)) != ungetty_pid) &&
X			(itmp != -1) )
X		;
X	signal(SIGCLD,original_sighdlr);
X	switch((wait_status >> 8) & 0xFF)
X	{
X		case UG_RESTART:
X			break;
X
X		default:
X#if defined(LOG_UNGETTY)
X			sprintf(ungetty_log,"UNGETTY -t %s status %04x",
X				ungetty_ttyname,wait_status);
X			ecu_log_event(getpid(),ungetty_log);
X#endif
X			ungetty_ttyname[0] = 0;
X			return;
X	}
X
X	strcpy(bamboozlement,bamboozle(getpid()));
X
X	original_sighdlr = signal(SIGCLD,SIG_DFL);
X	if((ungetty_pid = smart_fork()) == 0)
X	{
X		execl(ungetty,"ungetty","-r",ungetty_ttyname,bamboozlement,(char *)0);
X		ecu_log_event(getpid(),"could not exec ecuungetty -r");
X		exit(-1);
X	}
X
X	while(((itmp = wait(&wait_status)) != ungetty_pid) &&
X			(itmp != -1))
X		;
X
X#if defined(LOG_UNGETTY)
X	if(wait_status)
X	{
X		sprintf(ungetty_log,"UNGETTY -r %s status 0x%04x",
X			ungetty_ttyname,wait_status);
X	}
X	else
X		sprintf(ungetty_log,"UNGETTY returned %s",ungetty_ttyname);
X	ecu_log_event(getpid(),ungetty_log);
X#endif
X
X	ungetty_ttyname[0] = 0;
X
X}	/* end of ungetty_return_line */
X
X/*+-------------------------------------------------------------------------
X	getdvent() - get first or next Devices entry (a la getpwent)
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvent()
X{
Xint itmp;
Xchar *cptr;
X#define MAX_DV_TOKENS 9
Xchar *tokens[MAX_DV_TOKENS];
Xstatic struct dvent dve;
Xstatic char dvstr[128];
Xchar *strchr();
X
X	if(!there_is_hdb_on_this_machine)
X		return((struct dvent *)0);
X
X	if(fpdv == NULL)
X	{
X		if((fpdv = fopen(Devices_file,"r")) == NULL)
X		{
X			pperror(Devices_file);
X			return((struct dvent *)0);
X		}
X	}
X
X	while(1)
X	{
X		if(fgets(dvstr,sizeof(dvstr),fpdv) == NULL)
X			return((struct dvent *)0);
X
X		if((dvstr[0] == '#') || (dvstr[0] == ' ') || (strlen(dvstr) == 1))
X			continue;
X
X		build_arg_array(dvstr,tokens,MAX_DV_TOKENS,&itmp);
X
X		if(itmp > 1)
X			break;
X	}
X
X	dve.type = tokens[0];
X	dve.line = tokens[1];
X	dve.dialer = tokens[2];
X	if(!strcmp(tokens[3],"Any"))
X	{
X		dve.low_baud = 1;
X		dve.high_baud = 100000L;
X	}
X	else
X	{
X		dve.low_baud = atoi(tokens[3]);
X		if(!(cptr = strchr(tokens[3],'-')))
X			dve.high_baud = dve.low_baud;
X		else
X			dve.high_baud = atoi(cptr + 1);
X	}
X	dve.dialprog = tokens[4];
X	return(&dve);
X
X}	/* end of getdvent */
X
X/*+-------------------------------------------------------------------------
X	getdvbaud(baud) - get Devices entry matching baud rate
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvbaud(baud)
Xuint baud;
X{
Xstruct dvent *dve;
X
X	while(1)
X	{
X		if((dve = getdvent()) == (struct dvent *)0)
X			return(dve);
X		if((dve->low_baud <= baud) && (baud <= dve->high_baud))
X			return(dve);
X	}
X	/*NOTREACHED*/
X
X}	/* end of getdvbaud */
X
X/*+-------------------------------------------------------------------------
X	getdvline(line) - get Devices entry matching line
Xcalling argument 'line's is string AFTER "/dev/tty"
X--------------------------------------------------------------------------*/
Xstruct dvent *
Xgetdvline(line)
Xchar *line;
X{
Xstruct dvent *dve;
X
X	while(1)
X	{
X		if((dve = getdvent()) == (struct dvent *)0)
X			return(dve);
X		if(!strcmp(dve->line + 3,line))
X			return(dve);
X	}
X	/*NOTREACHED*/
X
X}	/* end of getdvline */
X
X/*+-------------------------------------------------------------------------
X	enddvent()
X--------------------------------------------------------------------------*/
Xvoid
Xenddvent()
X{
X	if(fpdv != NULL)
X	{
X		fclose(fpdv);
X		fpdv = NULL;
X	}
X}	/* end of enddvent */
X
X/*+-------------------------------------------------------------------------
X	dialstr_translate(translate_list,to_translate) - translate dial strings
X--------------------------------------------------------------------------*/
Xvoid
Xdialstr_translate(translate_list,to_translate)
Xregister char *translate_list;
Xchar *to_translate;
X{
X	register char *cptr;
X
X	while(*translate_list && *(translate_list + 1))
X	{
X		for(cptr=to_translate; *cptr; cptr++)
X		{
X			if(*translate_list == *cptr)
X				*cptr = *(translate_list + 1);
X		}
X		translate_list += 2;
X	}
X}	/* end of dialstr_translate */
X
X/*+-------------------------------------------------------------------------
X	getdlent() - get first or next Dialers entry (a la getpwent)
X--------------------------------------------------------------------------*/
Xstruct dlent *
Xgetdlent()
X{
Xint itmp;
Xchar *cptr;
X#define MAX_DL_TOKENS 3
Xchar *tokens[MAX_DL_TOKENS];
Xstatic struct dlent dle;
Xstatic char dlstr[128];
Xchar *strchr();
X
X	if(!there_is_hdb_on_this_machine)
X		return((struct dlent *)0);
X
X	if(fpdl == NULL)
X	{
X		if((fpdl = fopen(Dialers_file,"r")) == NULL)
X		{
X			pperror(Dialers_file);
X			return((struct dlent *)0);
X		}
X	}
X
X	while(1)
X	{
X		if(fgets(dlstr,sizeof(dlstr),fpdl) == NULL)
X			return((struct dlent *)0);
X		if(((itmp = strlen(dlstr)) > 0) && (dlstr[itmp - 1] == '\n'))
X			dlstr[--itmp] = 0;
X		if((dlstr[0] == '#') || (dlstr[0] == ' ') || (!itmp))
X			continue;
X		for(itmp = 0; itmp < MAX_DL_TOKENS; itmp++)
X			tokens[itmp] = "";
X		if(tokens[0] = arg_token(dlstr," \t\r\n"))
X		{
X			if(tokens[1] = arg_token((char *)0," \t\r\n"))
X			{
X			extern char *str_token_static;
X				tokens[2] = skip_ld_break(str_token_static);
X			}
X		}
X		break;
X	}
X
X	dle.name = tokens[0];
X	dle.tlate = tokens[1];
X	dle.script = tokens[2];
X	return(&dle);
X
X}	/* end of getdlent */
X
X/*+-------------------------------------------------------------------------
X	enddlent()
X--------------------------------------------------------------------------*/
Xvoid
Xenddlent()
X{
X	if(fpdl != NULL)
X	{
X		fclose(fpdl);
X		fpdl = NULL;
X	}
X}	/* end of enddlent */
X
X/*+-------------------------------------------------------------------------
X	getdlentname(name) - get Dialers entry by name
X--------------------------------------------------------------------------*/
Xstruct dlent *
Xgetdlentname(name)
Xchar *name;
X{
Xregister struct dlent *tdle;
X
X	while(tdle = getdlent())
X	{
X		if(!strcmp(name,tdle->name))
X			break;
X	}
X	return(tdle);
X
X}	/* end of getdlentname */
X
X/*+-------------------------------------------------------------------------
X	hdb_dial_error(errcode)
X
Xalso sets iv[0] to dial command status
X--------------------------------------------------------------------------*/
Xchar *
Xhdb_dial_error_text(errcode)
Xint errcode;
X{
X
X	iv[0] = 1;
X	switch(errcode & 0x7F)
X	{
X		case RCE_INUSE:
X			return("!Line in use");
X		case RCE_SIG:
X			iv[0] = 2;
X			return("!Interrupted");
X		case RCE_ARGS:
X			return("!Invalid arguments");
X		case RCE_PHNO:
X			return("!Invalid phone number");
X		case RCE_SPEED:
X			return("!Bad baud rate");
X		case RCE_OPEN:
X			return("!Line open error");
X		case RCE_IOCTL:
X			return("!Ioctl error");
X		case RCE_TIMOUT:
X			iv[0] = 3;
X			return("!Modem Error");
X		case RCE_NOTONE:
X			return("NO DIAL TONE");
X		case RCE_BUSY:
X			return("BUSY");
X		case RCE_NOCARR:
X			return("NO CARRIER");
X		case RCE_ANSWER:
X			return("NO ANSWER");
X		default:
X			
X		case RCE_NULL:
X			return("unknown error\n");
X	}
X}	/* end of hdb_dial_error */
X
X/*+-------------------------------------------------------------------------
X	hdb_dial(presult) - dial with uucp dialer if we can
X
Xreturn 0 if connected
X       1 if dial failed
X       2 if interrupted
X       3 if modem error
X       4 if use ecu DCE dialer
X--------------------------------------------------------------------------*/
Xint
Xhdb_dial(presult)
Xchar **presult;
X{
Xint itmp;
Xint dial_pid;
Xint wait_status;
Xint old_ttymode = get_ttymode();
Xint (*original_sighdlr)();
Xstruct dvent *dve;
Xstruct dlent *dle = (struct dlent *)0;
Xchar baudstr[10];
Xchar dial_log[100];
Xchar stripped_num[64];
Xchar *sptr;
Xchar *dptr;
Xstatic char stat_s20[20];
Xulong colors_at_entry = colors_current;
Xextern char *make_char_graphic();
X#ifdef WHT	/* hack for immediate need ... make a real feature later */
XFILE *fp;
Xchar credit_file[128];
X#endif
X
X	if(!there_is_hdb_on_this_machine)
X		return(4);
X
X	strcpy(dial_log,shm->Lline + 8);
X	sptr = dial_log + strlen(dial_log) - 1;
X	*sptr = to_upper(*sptr);
X	dve = getdvline(dial_log);
X	enddvent();
X	if(!dve)
X	{
X		pputs("no Devices entry for line ... using ecu dialer\n");
X		return(4);
X	}
X
X	dial_log[0] = 0;
X	if(*dve->dialprog != '/')
X	{
X		dle = getdlentname(dve->dialprog);
X		enddlent();
X		if(!dle)
X		{
X			sprintf(dial_log,
X				"UUCPDIAL Devices entry %s: '%s' not found in Dialers",
X				shm->Lline + 5,dve->dialprog);
X		}
X	}
X	else if(access(dve->dialprog,1))
X	{
X		sprintf(dial_log,"UUCPDIAL Devices entry %s: (%s) %s",
X			shm->Lline + 5,dve->dialprog,sys_errlist[errno]);
X	}
X
X	if(dial_log[0])
X	{
X#if defined(LOG_HDBDIAL)
X		ecu_log_event(getpid(),dial_log);
X#endif
X		pputs(dial_log + 9);
X		pputs("\ntrying ecu dialer\n");
X		return(4);
X	}
X
X	sptr = shm->Ltelno;
X	dptr = stripped_num;
X	while(*sptr)
X	{
X		if(strchr("()-",*sptr))
X		{
X			sptr++;
X			continue;
X		}
X		*dptr++ = *sptr++;
X	}
X	*dptr = 0;
X
X#ifdef WHT	/* hack for immediate need ... make a real feature later */
X	if(*(dptr - 1) == '$')
X	{
X		*--dptr = 0;
X		get_home_dir(credit_file);
X		strcat(credit_file,"/.ecu/.credit");
X		chmod(credit_file,0400);	/* let's keep this one quiet */
X		if(fp = fopen(credit_file,"r"))
X		{
X			*dptr++ = ',';
X			*dptr++ = ',';
X			*dptr++ = ',';
X			*dptr++ = ',';
X			*dptr = 0;
X			fgets(dptr,30,fp);
X			fclose(fp);
X		}
X		if(!fp || !(*dptr))
X		{
X			pprintf("credit card error\n");
X			iv[0] = 1;
X			return(1);
X		}
X		*(dptr + strlen(dptr) - 1) = 0; /* kill NL */
X	}
X#endif /* WHT */
X
X	pprintf("Type %s to abort ... ",
X		(kbdintr == 0x7F) ? "DEL" : make_char_graphic(kbdintr,0));
X	ttymode(2);
X
X	if(!dle)
X	{
X		if(access(dve->dialprog,1))
X		{
X			pperror(ungetty);
X			pputs("trying ecu dialer\n");
X			return(4);
X		}
X		sprintf(baudstr,"%u",shm->Lbaud);
X		original_sighdlr = signal(SIGCLD,SIG_DFL);
X		if((dial_pid = smart_fork()) == 0)
X		{
X			signal(SIGINT,SIG_DFL);
X			execl(dve->dialprog,"ECUdial",shm->Lline,stripped_num,
X				baudstr,(char *)0);
X			exit(-1);
X		}
X
X		wait_status = (RC_FAIL | RCE_SIG) << 8;
X		while(((itmp = wait(&wait_status)) != dial_pid) && (itmp != -1))
X			;
X		signal(SIGCLD,original_sighdlr);
X		ttymode(old_ttymode);
X		ttyflush(1);
X
X		if(interrupt)
X		{
X			kill(dial_pid,9);
X			ltoggle_dtr();
X			interrupt = 0;	 /* in case of SIGINT by user */
X		}
X		lreset_ksr(); /* uucp dialers are nice guys, but lets use our termio */
X
X#if defined(LOG_HDBDIAL)
X		if(wait_status)
X		{
X			sprintf(dial_log,"UUCPDIAL %s %s 0x%04x",
X				dve->dialprog,stripped_num,wait_status);
X			ecu_log_event(getpid(),dial_log);
X		}
X#endif
X
X		/*
X		 * if system reports interrupt, fake dial-reported status
X		 */
X		if(wait_status & 0xFF)
X			wait_status = (RC_FAIL | RCE_SIG) << 8;
X
X		if(!wait_status)
X		{
X			sprintf(stat_s20,"CONNECT %u",shm->Lbaud);
X			*presult = stat_s20;	/* DCE_dial will report result code */
X			return(0);
X		}
X
X		if((wait_status & 0xFF00) == 0xFF00)
X		{
X			pputs("uucp dial failure (see ~/.ecu/log) ... trying ecu dialer\n");
X			return(4);
X		}
X		*presult = hdb_dial_error_text((wait_status >> 8) & 0xFF);
X		setcolor(colors_error);
X		pputs(*presult);
X		setcolor(colors_at_entry);
X		pputc('\n');
X		ltoggle_dtr();
X	}
X	else
X	{
X		extern int expresp_verbosity;
X		pprintf("using Dialers entry '%s'\n",dle->name);
X		expresp_verbosity = (proc_level & proctrace) ? 1 : 0;
X		if(execute_expresp(dle->script))
X		{
X			*presult = "DIALER SCRIPT FAILED";
X			setcolor(colors_error);
X			pputs(*presult);
X			setcolor(colors_at_entry);
X			pputc('\n');
X			iv[0] = 1;
X		}
X		else
X		{
X			extern char last_Speed_result[];
X			if(last_Speed_result[0])
X				*presult = last_Speed_result;
X			else
X			{
X				sprintf(stat_s20,"CONNECT %u",shm->Lbaud);
X				*presult = stat_s20;	/* DCE_dial will report result code */
X			}
X			setcolor(colors_at_entry);
X			iv[0] = 0;
X		}
X	}
X
X	return((int)iv[0]);
X
X}	/* end of hdb_dial */
X
X/*+-------------------------------------------------------------------------
X	hdb_init()
X--------------------------------------------------------------------------*/
Xvoid
Xhdb_init()
X{
X	there_is_hdb_on_this_machine = !access(Devices_file,4);
X
X}	/* end of hdb_init */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of hdbintf.c */
SHAR_EOF
$TOUCH -am 1224223990 'hdbintf.c' &&
chmod 0644 hdbintf.c ||
echo 'restore of hdbintf.c failed'
Wc_c="`wc -c < 'hdbintf.c'`"
test 15942 -eq "$Wc_c" ||
	echo 'hdbintf.c: original size 15942, current size' "$Wc_c"
# ============= kbdtest.c ==============
echo 'x - extracting kbdtest.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'kbdtest.c' &&
X/*+-----------------------------------------------------------------------
X	kbdtest.c -- hack to test keyboard function key sequences
X    wht@n4hgf.Mt-Park.GA.US
X
X  compile with     cc -o kbdtest kbdtest.c
X  or just          cc kbdtest.c;a.out
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-21-1990-23:47-wht@n4hgf-liven up for release with ECU 3 */
X/*:04-07-1990-01:36-wht@tridom-bring out of the daaaaark ages a bit */
X/*:04-18-1988-13:44-wht-first edits -- oollldd program */
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <fcntl.h>
X#include <termio.h>
X#include <sys/types.h>
X#include <sys/errno.h>
X#include <sys/stat.h>
X#include <string.h>
X
X#define ff	fprintf
X#define se	stderr
X
X#define TTYIN   0
X#define TTYOUT  1
X#define TTYERR  2
X
Xstruct termio tv0;		/* for saving, changing TTY atributes */
Xstruct termio tv;		/* for saving, changing TTY atributes */
X
X/*+-----------------------------------------------------------------------
X	ttymode(arg) -- control user console (kbd/screen)
X
X  Where arg ==
X	0 restore attributes saved at start of execution
X	1 raw mode 
X
X------------------------------------------------------------------------*/
Xvoid ttymode(arg)
X{
X	char *mode_type;
X
X	switch(arg)
X	{
X		case 0:	
X			mode_type = "console to cooked mode\r\n";
X			break;
X		default: 
X			mode_type = "console to raw mode\r\n";
X			break;
X	}
X	(void)fprintf(stderr,mode_type);
X
X	if(arg)
X	{
X		(void)ioctl(TTYIN,TCGETA,&tv);
X		tv.c_iflag &= ~(INLCR | ICRNL | IGNCR | IXOFF | IUCLC | ISTRIP);
X		tv.c_oflag |= OPOST;
X		tv.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
X		tv.c_lflag &= ~(ICANON | ISIG | ECHO);
X		tv.c_cc[VEOF] = '\01';
X		tv.c_cc[VEOL] = '\0';
X		tv.c_cc[VMIN] = 1;
X		tv.c_cc[VTIME] = 1;
X		(void)ioctl(TTYIN,TCSETAW,&tv);
X	}
X	else
X		(void)ioctl(TTYIN,TCSETAW,&tv0);
X}
X
X
X/*+-----------------------------------------------------------------------
X	main()
X------------------------------------------------------------------------*/
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
Xunsigned char inchar;
X
X	setbuf(stdout,NULL);
X	setbuf(stderr,NULL);
X
X	ioctl(TTYIN,TCGETA,&tv0);		/* get original status */
X	ttymode(2);
X
X	fprintf(stderr,"press ^D (0x04) to terminate program\r\n");
X
X	while(read(TTYIN,&inchar,1) == 1)
X	{
X		printf("%02x %c\r\n",inchar,
X		    ((inchar >= 0x20) && (inchar < 0x7F)) ? inchar : '.');
X		if((inchar & 0x7F) == 4)
X		{
X			ttymode(0);
X			exit(0);
X		}
X	}
X	ttymode(0);
X	exit(1);
X
X}
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of kbdtest.c */
SHAR_EOF
$TOUCH -am 1224223990 'kbdtest.c' &&
chmod 0664 kbdtest.c ||
echo 'restore of kbdtest.c failed'
Wc_c="`wc -c < 'kbdtest.c'`"
test 2521 -eq "$Wc_c" ||
	echo 'kbdtest.c: original size 2521, current size' "$Wc_c"
# ============= logevent.c ==============
echo 'x - extracting logevent.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'logevent.c' &&
X/*+-------------------------------------------------------------------------
X	logevent.c - log ecu event
X	wht@n4hgf.Mt-Park.GA.US
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
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 <stdio.h>
X#include <sys/locking.h>
X#include "stdio_lint.h"
X#include "lint_args.h"
X
X/*+-------------------------------------------------------------------------
X	ecu_log_event(pid,event_note)
X--------------------------------------------------------------------------*/
Xvoid
Xecu_log_event(pid,event_note)
Xint pid;
Xchar *event_note;
X{
Xchar tstr256[256];
XFILE *ecu_log_fp;
Xstatic char logname[128] = "";
X
X	if(!logname[0])
X	{
X		get_home_dir(tstr256);
X		strcat(tstr256,"/.ecu/log");
X	}
X	if((ecu_log_fp = fopen(tstr256,"a")) != NULL)
X	{
X		locking(fileno(ecu_log_fp),LK_LOCK,0L);
X		get_tod(2,tstr256);
X		tstr256[10] = '-';
X		fputs(tstr256,ecu_log_fp);
X		fprintf(ecu_log_fp,"-%05d-",pid);
X		fputs(event_note,ecu_log_fp);
X		fputs("\n",ecu_log_fp);
X		fflush(ecu_log_fp);
X		locking(fileno(ecu_log_fp),LK_UNLCK,0L);
X		fclose(ecu_log_fp);
X	}
X}	/* end of ecu_log_event */
X
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of logevent.c */
SHAR_EOF
$TOUCH -am 1224224090 'logevent.c' &&
chmod 0644 logevent.c ||
echo 'restore of logevent.c failed'
Wc_c="`wc -c < 'logevent.c'`"
test 1295 -eq "$Wc_c" ||
	echo 'logevent.c: original size 1295, current size' "$Wc_c"
# ============= nonansikey.c ==============
echo 'x - extracting nonansikey.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'nonansikey.c' &&
X/*+-----------------------------------------------------------------
X	nonansikey.c - keyboard function key -> ECU internal
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	define_nonansi_key(bufptr)
X	map_nonansi_key(buf,buflen)
X	nonansi_key_init()
X	nonansi_key_read(name)
X
X------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-01-1990-12:51-wht@n4hgf-creation, borrowing from and using ecufkey.c */
X
X#include "ecu.h"
X#include "ecukey.h"
X#include "ecufkey.h"
X#include "ecuxkey.h"
X#include "ecufork.h"
X
Xchar *keyset_idstr();
X
Xextern int tty_not_char_special;
X
XKDE nonansi_key_table[KDE_COUNT];
Xchar nonansi_key_name[32] = "";
X
X/*+-------------------------------------------------------------------------
X	nonansi_key_init()
X--------------------------------------------------------------------------*/
Xvoid
Xnonansi_key_init()
X{
Xregister itmp;
Xregister KDE *tkde;
Xchar *make_char_graphic();
X
X	for(itmp = 0; itmp < KDE_COUNT; itmp++)
X	{
X		tkde = &nonansi_key_table[itmp];
X		tkde->logical[0] = 0;
X		tkde->count = 0;
X		tkde->KDEt = (uchar)itmp;
X	}
X
X	nonansi_key_name[0] = 0;
X
X}	/* end of nonansi_key_init */
X
X/*+-------------------------------------------------------------------------
X	define_nonansi_key(bufptr)
X
X  returns 0 good keydef
X         -1 if syntax error
X--------------------------------------------------------------------------*/
Xint
Xdefine_nonansi_key(bufptr)
Xregister char *bufptr;
X{
Xregister itmp;
Xregister token_number;
XKDE *tkde;
Xint KDEt;
Xint done = 0;
Xchar token_separator[2];
Xchar *token;
Xchar *arg_token();
Xchar *str_token();
Xchar *strip_ld_break();
X
X	token_number = 0;
X	strcpy(token_separator,":");
X	while(!done && (token = (token_number < 2) ? str_token(bufptr,":")
X	                                           : arg_token(bufptr," \t")))
X	{
X		bufptr = (char *)0;	/* further calls to arg_token need NULL */
X		token = skip_ld_break(token);
X		strip_trail_break(token);
X
X		switch(token_number)
X		{
X			case 0:		/* first field is key identifier */
X				if((KDEt = keyset_idnum(token)) < 0)
X				{
X					ff(se,"  %s is not a legal key identifier\r\n",token);
X					return(-1);
X				}
X				tkde = &nonansi_key_table[KDEt];
X				tkde->logical[0] = 0;
X				tkde->count = 0;
X				break;
X
X			case 1:		/* second field is logical key name */
X				if(*token == '#')
X					goto MISSING_LABEL;
X				strncpy(tkde->logical,token,sizeof(tkde->logical));
X				tkde->logical[sizeof(tkde->logical) - 1] = 0;
X				strcpy(token_separator," \t"); /* space is tok sep now */
X				break;
X
X			case 2:		/* third field is first token of sequence */
X				if(*token == '#')
X					goto MISSING_SEQUENCE;
X				if(((itmp = ascii_to_hex(token)) < 1) || (itmp >= SPACE))
X				{	/* make sure it is escape */
X					ff(se,
X"  %s: first char in sequence must be in the range 0x01 to 0x1F not '%s'\r\n",
X						keyset_idstr(KDEt),token);
X					return(-1);
X				}
X
X			default:	/* third and subsequent to define key */
X				if(*token == '#')
X					done = 1;
X				if(tkde->count == sizeof(tkde->str))
X				{
X					ff(se,"  %s: output count too long",
X						keyset_idstr(KDEt));
X					return(-1);
X				}
X				if((itmp = ascii_to_hex(token)) < 0)
X				{
X					ff(se,"  %s: '%s' invalid\r\n",
X						keyset_idstr(KDEt),token);
X					return(-1);
X				}
X				tkde->str[tkde->count] = itmp;
X				tkde->count++;
X				break;
X		}	/* end of switch(token_number) */
X
X		token_number++;
X
X	}		/* end while not end of record */
X
X	switch(token_number)
X	{
X		case 0:
X			ff(se,"define nonansi key logic error\r\n");
X			hangup(HANGUP_XMTR_LOGIC_ERROR);
X			break;
X		case 1:
XMISSING_LABEL:
X			ff(se,"%s: missing key label\r\n",keyset_idstr(KDEt));
X			break;
X		case 2:
XMISSING_SEQUENCE:
X			ff(se,"%s: missing char sequence\r\n",keyset_idstr(KDEt));
X			break;
X		default:
X			return(0);
X	}
X
X	return(-1);		/* error */
X
X}	/* end of define_nonansi_key */
X
X/*+-------------------------------------------------------------------------
X	nonansi_key_read(name) - read key-sequence-to-fkey map from nonansikeys
X--------------------------------------------------------------------------*/
Xvoid
Xnonansi_key_read(name)
Xchar *name;
X{
Xregister itmp;
Xregister char *cptr;
Xchar buf[128];
XFILE *fp_keys;
Xint errstat = 0;
Xstatic char ecukeys_name[128];
X
X	nonansi_key_init();	/* clear any previous key defns */
X
X	if(!ecukeys_name[0])
X	{
X		get_home_dir(ecukeys_name);
X		strcat(ecukeys_name,"/.ecu/nonansikeys");
X	}
X
X	if((fp_keys = fopen(ecukeys_name,"r")) == NULL)
X	{
X		ff(se,"%s not found; unable to proceed\r\n",ecukeys_name);
X		hangup(HANGUP_CONFIG_ERROR);
X	}
X
X/* find nonansi_key name */
X	errstat = 1;
X	while((itmp = kde_fgets(buf,sizeof(buf),fp_keys)) != KDEt_EOF)
X	{
X		if((itmp == KDEt_COMMENT) || (itmp == KDEt_ENTRY))
X			continue;
X		if(!strcmp(buf,name))
X		{
X			errstat = 0;		/* indicate success */
X			break;
X		}
X	}
X	if(errstat)
X	{
X		ff(se,"terminal type '%s' not found in %s; unable to proceed\r\n",
X			name,ecukeys_name);
X		hangup(HANGUP_CONFIG_ERROR);
X	}
X
X/* read past any other nonansi_key names matching this set */
X	errstat = 1;
X	while((itmp = kde_fgets(buf,sizeof(buf),fp_keys)) != KDEt_EOF)
X	{
X		if(itmp == KDEt_ENTRY)
X		{
X			errstat = 0;		/* indicate success */
X			break;
X		}
X	}
X	if(errstat)
X	{
X		ff(se,"terminal type '%s' has null entry in %s; unable to proceed\r\n",
X			name,ecukeys_name);
X		hangup(HANGUP_CONFIG_ERROR);
X	}
X
X/* we found the definition ... process it */
X	errstat = 0;
X	itmp = KDEt_ENTRY;
X	do {
X		if(itmp == KDEt_NAME)
X			break;
X		else if(itmp == KDEt_ENTRY)
X		{
X			if(define_nonansi_key(buf))
X				errstat = 1;
X		}
X	} while((itmp = kde_fgets(buf,sizeof(buf),fp_keys)) != KDEt_EOF);
X
X/* close up shop */
X	strncpy(nonansi_key_name,name,sizeof(nonansi_key_name));
X	nonansi_key_name[sizeof(nonansi_key_name) - 1] = 0;
X	fclose(fp_keys);
X
X	if(!nonansi_key_table[KDEk_HOME].count)
X	{
X		ff(se,"You MUST have a 'Home' key defined\r\n");
X		errstat = 2;
X	}
X	if(!nonansi_key_table[KDEk_END].count)
X	{
X		ff(se,"You MUST have a 'End' key defined\r\n");
X		errstat = 2;
X	}
X	if((errstat == 2) || (errstat && tty_not_char_special))
X		hangup(HANGUP_CONFIG_ERROR);
X
X	if(errstat)
X	{
X		ff(se,
X			"Warning: key definition syntax errors\r\nContinue anyway (y,n)? ");
X		if((itmp = ttygetc(0)) == 'Y' || (itmp == 'y'))
X		{
X			ff(se,"YES\r\n");
X			return;
X		}
X		ff(se,"NO\r\n");
X		hangup(HANGUP_CONFIG_ERROR);
X	}
X
X	/*NOTREACHED*/
X
X}	/* end of nonansi_key_read */
X
X/*+-------------------------------------------------------------------------
X	map_nonansi_key(buf,buflen) - map char sequence to KDEt code
X
Xreturn KDEt code or 255 if no match
X--------------------------------------------------------------------------*/
Xuchar
Xmap_nonansi_key(buf,buflen)
Xuchar *buf;
Xint buflen;
X{
Xregister ikde;
Xregister KDE *tkde;
X
X	if(!buflen)
X		return(255);
X
X	for(ikde = 0,tkde = nonansi_key_table; ikde < KDE_COUNT;
X		ikde++,tkde++)
X	{
X		if((tkde->count == buflen) && !memcmp(tkde->str,buf,buflen))
X		{
X			return(tkde->KDEt);
X		}
X	}
X	return(255);
X}	/* end of map_nonansi_key */
X
X/* end of nonansikey.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224224090 'nonansikey.c' &&
chmod 0644 nonansikey.c ||
echo 'restore of nonansikey.c failed'
Wc_c="`wc -c < 'nonansikey.c'`"
test 6955 -eq "$Wc_c" ||
	echo 'nonansikey.c: original size 6955, current size' "$Wc_c"
# ============= pcmd.c ==============
echo 'x - extracting pcmd.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'pcmd.c' &&
X/*+-------------------------------------------------------------------------
X	pcmd.c - ecu miscellaneous procedure commands
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	pcmd_baud(param)
X	pcmd_cd(param)
X	pcmd_clrx(param)
X	pcmd_dial(param)
X	pcmd_duplex(param)
X	pcmd_echo(param)
X	pcmd_exit(param)
X	pcmd_flush(param)
X	pcmd_hangup(param)
X	pcmd_hexdump(param)
X	pcmd_lbreak(param)
X	pcmd_lgets(param)
X	pcmd_logevent(param)
X	pcmd_lookfor(param)
X	pcmd_nap(param)
X	pcmd_parity(param)
X	pcmd_prompt(param)
X	pcmd_ptrace(param)
X	pcmd_rtscts(param)
X	pcmd_send(param)
X	pcmd_set(param)
X	pcmd_system(param)
X	pcmd_xon(param)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-26-1990-02:34-wht@n4hgf-add cmd_rtscts */
X/*:12-03-1990-04:59-wht@n4hgf-beef up pcmd_exit */
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 "ecuerror.h"
X#include "ecuhangup.h"
X#include "ecukey.h"
X#include "esd.h"
X#include "var.h"
X#include "proc.h"
X
Xchar *strchr();
X
Xextern int proctrace;
Xextern int rcvr_pid;
Xextern ulong colors_current;
Xextern char errmsg[];
X
X/*+-------------------------------------------------------------------------
X	pcmd_baud(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_baud(param)
XESD *param;
X{
Xlong new_baud;
Xint erc;
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	if(erc = gint(param,&new_baud))
X		return(erc);
X	if(!valid_baud_rate((uint)new_baud))
X	{
X		pprintf("invalid baud rate: %lu\n",new_baud);
X		return(eFATAL_ALREADY);
X	}
X	shm->Lbaud = (uint)new_baud;
X	lset_baud_rate(1);
X	if(proctrace)
X	{
X		pprintf("baud rate set to %u\n",shm->Lbaud);
X	}
X	return(0);
X
X}	/* end of pcmd_baud */
X
X/*+-------------------------------------------------------------------------
X	pcmd_cd(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_cd(param)
XESD *param;
X{
Xint erc;
XESD *tesd = make_esd(256);
Xextern char curr_dir[];		/* current working directory */
X
X	if(!tesd)
X		return(eNoMemory);
X	if(erc = gstr(param,tesd,0))
X		goto RETURN;
X	if(expand_dirname(tesd->pb,tesd->maxcb))
X	{
X		pprintf("%s\n",errmsg);
X		param->index = param->old_index;
X		erc = eFATAL_ALREADY;
X		goto RETURN;
X	}
X	if(chdir(tesd->pb) < 0)		/* now change to the new directory */
X	{
X		pperror(tesd->pb);		/* print error if we get one */
X		pputs("\n");
X		erc = eFATAL_ALREADY;
X		goto RETURN;
X	}
X	get_curr_dir(curr_dir,256);
X
XRETURN:
X	free_esd(tesd);
X	return(erc);
X}	/* end of pcmd_cd */
X
X/*+-------------------------------------------------------------------------
X	pcmd_clrx(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_clrx(param)
XESD *param;
X{
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	lclear_xmtr_xoff();
X	if(proctrace)
X		pputs("transmitter XOFF cleared\n");
X	return(0);
X}	/* end of pcmd_clrx */
X
X/*+-------------------------------------------------------------------------
X	pcmd_dial(param)
X
X  DCE_dial does the following:
X  sets I0 to 0==connect,
X             1==failed to connect,
X             2==interrupted,
X             3==modem error
X  sets S0 to modem result code
X--------------------------------------------------------------------------*/
Xint
Xpcmd_dial(param)
XESD *param;
X{
Xint erc;
XESD *tesd = (ESD *)0;
X
X	if(shm->Lmodem_off_hook)
X	{
X		pputs("Already off hook\n");
X		return(eFATAL_ALREADY);
X	}
X	if(!(tesd = make_esd(64)))
X		return(eNoMemory);
X	if(erc = gstr(param,tesd,0))
X	{
X		free_esd(tesd);
X		return(erc);
X	}
X	strcpy(shm->Llogical,tesd->pb);
X	lclear_xmtr_xoff();
X	if(lookup_logical_telno())
X		(void)DCE_dial();
X	else
X	{
X		pprintf("No such entry: %s\n",tesd->pb);
X		erc = eFATAL_ALREADY;
X	}
X
X	if(!erc && (shm->Liofd < 0))
X		erc = eNoLineAttached;
X
X	free_esd(tesd);
X
X	return(erc);
X}	/* end of pcmd_dial */
X
X/*+-------------------------------------------------------------------------
X	pcmd_duplex(param)
Xduplex [f | h]
Xduplex ['f' | 'h']
Xduplex <int>  0 == half, non-0 == full
X--------------------------------------------------------------------------*/
Xint
Xpcmd_duplex(param)
XESD *param;
X{
Xint erc;
Xint new_duplex;
XESD *tesd;
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	if(!(tesd = make_esd(64)))
X		return(eNoMemory);
X	erc = gstr(param,tesd,0);
X	new_duplex = to_lower((erc) ? param->pb[param->index] : *tesd->pb);
X	free_esd(tesd);
X	erc = 0;
X
X	switch(new_duplex)
X	{
X		case 'f':
X			shm->Lfull_duplex = 1;
X			break;
X		case 'h':
X			shm->Lfull_duplex = 0;
X			break;
X		default:
X			erc = eBadParameter;
X	}
X	if(proctrace && !erc)
X		pprintf("duplex set to %s\n",(shm->Lfull_duplex) ? "full" : "half");
X	return(erc);
X
X}	/* end of pcmd_duplex */
X
X/*+-------------------------------------------------------------------------
X	pcmd_echo(param)
Xecho [-n] <str>
X--------------------------------------------------------------------------*/
Xint
Xpcmd_echo(param)
XESD *param;
X{
Xint erc;
XESD *tesd;
Xchar switches[8];
X
X	if((tesd = make_esd(256)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X	if(erc = gstr(param,tesd,1))
X	{
X		free_esd(tesd);
X		return(erc);
X	}
X	pputs(tesd->pb);
X	if(!strchr(switches,'n'))	/* if no -n */
X		pputs("\n");
X	free_esd(tesd);
X	return(0);
X
X}	/* end of pcmd_echo */
X
X/*+-------------------------------------------------------------------------
X	pcmd_exit(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_exit(param)
XESD *param;
X{
Xlong int1;
Xulong colors_at_entry = colors_current;
X
X	if(!gint(param,&int1) && int1)
X	{
X		setcolor(colors_error);
X		pprintf("[procedure exiting ecu: user code %ld]\n",int1);
X		setcolor(colors_at_entry);
X		if((int1 += HANGUP_USER1 - 1) > HANGUP_USERN)
X		{
X			int1 = HANGUP_USERN;
X			ff(se,"user exit code too large, using %d\r\n",
X				HANGUP_USERN - HANGUP_USER1);
X		}
X		hangup((int)int1);
X	}
X	setcolor(colors_success);
X	pputs("[procedure exiting ecu: normal exit]\n");
X	setcolor(colors_at_entry);
X	hangup(0);
X}	/* end of pcmd_exit */
X
X/*+-------------------------------------------------------------------------
X	pcmd_lgets(param)
X
Xlgets [-er] <strvar> <int1> <int2> [<str>]
X
Xread string into string variable number <stvar>
Xwaiting <int1> 1/10th secs for first char,
Xwaiting <int2> 1/10th secs for subsequent chars,
Xoptionally terminating read upon detection of <str>
X-e echos to screen
X-r completely raw, else strip CRs & NLs from either end of string
X$i0 receives the length of the read
X<strvar> receives the string
X--------------------------------------------------------------------------*/
Xint
Xpcmd_lgets(param)
XESD *param;
X{
Xint erc;
Xlong int2;
Xlong int3;
XESD *tesd1 = (ESD *)0;
XESD *svptr;
XLRWT lr;
Xchar switches[8];
XESD *make_esd();
Xchar ctmp;
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	get_switches(param,switches,sizeof(switches));
X
X	skip_cmd_char(param,'$');
X	if(erc = get_cmd_char(param,&ctmp))
X		return(erc);
X	if(to_lower(ctmp) != 's')
X		return(eIllegalVarType);
X	if(erc = get_svptr(param,&svptr,1))
X		return(erc);
X
X	if(erc = gint(param,&int2))
X		return(erc);
X
X	if(erc = gint(param,&int3))
X		return(erc);
X
X	if((tesd1 = make_esd(64)) == (ESD *)0)
X		return(eNoMemory);
X	if(gstr(param,tesd1,1))	/* optional delimiter */
X	{
X		free_esd(tesd1);
X		tesd1 = (ESD *)0;
X	}	
X
X	zero_esd(svptr);
X
X	lr.to1 = int2 * 100L;
X	lr.to2 = int3 * 100L;
X	/* allow interrupts + raw read per -r */
X	lr.raw_flag = (strchr(switches,'r')) ? 0x81 : 0x80;
X	lr.buffer = svptr->pb;
X	lr.bufsize = svptr->maxcb;
X	lr.delim = (tesd1) ? tesd1->pb : (char *)0;
X	lr.echo = (strchr(switches,'e') != (char *)0);
X	(void)lgets_timeout(&lr);
X	if(tesd1)
X		free_esd(tesd1);
X
X	svptr->cb = lr.count;
X	null_terminate_esd(svptr);
X	iv[0] = (long)lr.count;
X	if(proctrace)
X		pprintf("lgets read %d chars\n",lr.count);
X	return(0);
X
X}	/* end of pcmd_lgets */
X
X/*+-------------------------------------------------------------------------
X	pcmd_flush(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_flush(param)
XESD *param;
X{
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	lflush(2);
X	if(proctrace)
X		pputs("line flushed\n");
X	return(0);
X}	/* end of pcmd_flush */
X
X/*+-------------------------------------------------------------------------
X	pcmd_hangup(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_hangup(param)
XESD *param;
X{
X	if(shm->Liofd < 0)
X	{
X		if(proctrace)
X			pputs("no line attached ... hangup ignored\n");
X		DCE_now_on_hook();
X		return(0);
X	}
X
X	if(proctrace)
X		pputs("hanging up ... ");
X	DCE_hangup();
X	if(proctrace)
X		pputs("line on hook\n");
X	return(0);
X}	/* end of pcmd_hangup */
X
X/*+-------------------------------------------------------------------------
X	pcmd_hexdump(param)
X
Xhexdump [-s] <str>
Xhexdump -t[s] <str1> <str>
X<str> buf to dump
X<str1> title (if -t)
X-s short (terse) dump
X--------------------------------------------------------------------------*/
Xint
Xpcmd_hexdump(param)
XESD *param;
X{
Xint erc;
XESD *title = (ESD *)0;
XESD *buf;
Xchar switches[8];
Xextern FILE *plog_fp;
X
X	if((buf = make_esd(256)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X	if(strchr(switches,'t'))	/* if -t */
X	{
X		if((title = make_esd(256)) == (ESD *)0)
X		{
X			erc = eNoMemory;
X			goto RETURN;
X		}
X		if(erc = gstr(param,title,0))
X			goto RETURN;
X	}
X
X	if(erc = gstr(param,buf,1))
X		goto RETURN;
X
X	hex_dump(buf->pb,buf->cb,(title) ? title->pb : "",
X		(strchr(switches,'s')) ? 1 : 0);
X
X	if(plog_fp)
X		hex_dump_fp(plog_fp,buf->pb,buf->cb,(title) ? title->pb : "",
X			(strchr(switches,'s')) ? 1 : 0);
X
XRETURN:
X	free_esd(buf);
X	if(title)
X		free_esd(title);
X	return(erc);
X
X}	/* end of pcmd_hexdump */
X
X/*+-------------------------------------------------------------------------
X	pcmd_lbreak(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_lbreak(param)
XESD *param;
X{
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	lbreak();
X	return(0);
X}	/* end of pcmd_lbreak */
X
X/*+-------------------------------------------------------------------------
X	pcmd_logevent(param)
X
Xlogevent 'cmd'
X--------------------------------------------------------------------------*/
Xint
Xpcmd_logevent(param)
XESD *param;
X{
Xint erc;
XESD *eventstr;
Xextern int last_child_wait_status;
Xchar switches[8];
X
X	if((eventstr = make_esd(256)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X/* a hack */
X	strcpy(eventstr->pb,"PROC ");
X	eventstr->pb += 5;
X	eventstr->maxcb -= 5;
X
X	if(erc = gstr(param,eventstr,0))
X	{
X		eventstr->pb -= 5;		/* be nice */
X		eventstr->maxcb += 5;	/* or surely this will haunt us one day */
X		free_esd(eventstr);
X		return(erc);
X	}
X
X/* rehack */
X	eventstr->pb -= 5;
X	eventstr->maxcb += 5;
X	eventstr->cb += 5;
X
X	ecu_log_event(getpid(),eventstr->pb);
X	free_esd(eventstr);
X	return(0);
X
X}	/* end of eventstr_logevent */
X
X/*+-------------------------------------------------------------------------
X	pcmd_lookfor(param)
X
Xlookfor [-e] [quiet | <str>] [<int>]
X
X-e echo to screen while looking
Xquiet means look for quiet
X<str> means look for string
X<int> number 1/10ths secs (default 5.0 second) for timeout
X
Xin case of lookfor <str>, $i0 plugged 1 if found, else 0
X--------------------------------------------------------------------------*/
Xint
Xpcmd_lookfor(param)
XESD *param;
X{
Xint erc;
Xchar switches[8];
Xchar *cptr = (char *)0;
XESD *tesd = (ESD *)0;
Xulong decisecs = 50; /* default wait is 5 seconds */
Xint echo_flag;
Xchar quiet[8];
Xlong start_secs;
Xlong time();
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	get_switches(param,switches,sizeof(switches));
X	echo_flag = (strchr(switches,'e') != (char *)0);
X
X	if(!get_alpha_zstr(param,quiet,sizeof(quiet)))
X	{
X		if(strcmp(quiet,"quiet"))
X			return(eSyntaxError);
X	} 
X	else
X	{
X		if((tesd = make_esd(64)) == (ESD *)0)
X			return(eNoMemory);
X		if(erc = gstr(param,tesd,0))
X			goto RETURN;
X		if(!tesd->cb)
X		{
X			pputs("lookfor null string\n");
X			erc = eFATAL_ALREADY;
X			goto RETURN;
X		}
X		cptr = tesd->pb;
X	}
X
X	if(erc = gint(param,&decisecs))
X	{
X		/* if something there non-integer */
X		if(!end_of_cmd(param))
X		{
X			erc = eSyntaxError;
X			goto RETURN;
X		}
X	}
X	erc = 0;
X
X	if(proctrace)
X		time(&start_secs);
X
X	if(cptr)
X	{
X		iv[0] = (long)llookfor(cptr,decisecs * 100L,echo_flag);
X		if(proctrace)
X			pprintf("llookfor set $i00 = %ld\n",iv[0]);
X	}
X	else
X		lquiet(decisecs * 100L,echo_flag);
X
X	if(proctrace)
X		pprintf("waited %ld secs\n",time((long *)0) - start_secs);
X
XRETURN:
X	if(tesd)
X		free_esd(tesd);
X	return(erc);
X
X}	/* end of pcmd_lookfor */
X
X/*+-------------------------------------------------------------------------
X	pcmd_nap(param)
Xnap [-m] <int>
X<int> number 1/10ths secs, except if -m, nap <int> milliseconds
X--------------------------------------------------------------------------*/
Xint
Xpcmd_nap(param)
XESD *param;
X{
Xint erc;
Xchar switches[8];
Xulong interval;
X
X	get_switches(param,switches,sizeof(switches));
X
X	if(erc = gint(param,&interval))
X		return(erc);
X	if(interval)
X	{
X		if(strchr(switches,'m'))
X			nap(interval);
X		else
X			nap(interval * 100L);
X	}
X	return(0);
X}	/* end of pcmd_nap */
X
X/*+-------------------------------------------------------------------------
X	pcmd_parity(param)
Xparity [e | o | n]
Xparity ['e' | 'o' | 'n']
X--------------------------------------------------------------------------*/
Xint
Xpcmd_parity(param)
XESD *param;
X{
Xint erc;
Xint new_parity = 0;
XESD *tesd;
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X	if(!(tesd = make_esd(64)))
X		return(eNoMemory);
X	erc = gstr(param,tesd,0);
X	new_parity = to_lower((erc) ? param->pb[param->index] : *tesd->pb);
X	if(!erc && !tesd->cb)
X		new_parity = 'n';
X	free_esd(tesd);
X
X	switch(new_parity)
X	{
X		case 'n':
X			new_parity = 0;
X		case 'e':
X		case 'o':
X			shm->Lparity = new_parity;
X			lset_parity(1);
X			break;
X		default:
X			erc = eBadParameter;
X	}
X	if(proctrace && !erc)
X		pprintf("parity set to %s\n",
X			(shm->Lparity) ? ((shm->Lparity == 'e') ? "even" : "odd")
X			               : "none");
X	return(erc);
X
X}	/* end of pcmd_parity */
X
X/*+-------------------------------------------------------------------------
X	pcmd_prompt(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_prompt(param)
XESD *param;
X{
Xextern ESD *icmd_prompt;
X
X	return(gstr(param,icmd_prompt,0));
X}	/* end of pcmd_prompt */
X
X/*+-------------------------------------------------------------------------
X	pcmd_ptrace(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_ptrace(param)
XESD *param;
X{
Xchar s8[8];
Xregister itmp;
X
X	if(get_alpha_zstr(param,s8,sizeof(s8)))
X		return(eSyntaxError);
X	itmp = strlen(s8);
X	while(itmp--)
X		s8[itmp] = to_lower(s8[itmp]);
X	if(!strcmp(s8,"on"))
X		proctrace = 1;
X	else if(!strcmp(s8,"off"))
X		proctrace = 0;
X	else
X		return(eSyntaxError);
X	return(0);
X}	/* end of pcmd_ptrace */
X
X/*+-------------------------------------------------------------------------
X	pcmd_rname(param) - set remote name
X--------------------------------------------------------------------------*/
Xint
Xpcmd_rname(param)
XESD *param;
X{
Xint erc;
XESD *rname;
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X	if(!shm->Lmodem_off_hook)
X	{
X		pputs("Not connected\n");
X		return(eFATAL_ALREADY);
X	}
X
X	if((rname = make_esd(sizeof(shm->Lrname) - 1)) == (ESD *)0)
X		return(eNoMemory);
X
X	if(!(erc = gstr(param,rname,0)))
X	{
X		strcpy(shm->Lrname,rname->pb);
X		if(proctrace)
X			pprintf("rname set to '%s'\n",rname->pb);
X	}
X	free_esd(rname);
X	return(erc);
X
X}	/* end of pcmd_rname */
X
X/*+-------------------------------------------------------------------------
X	pcmd_send(param)
Xsend [-n] <str>
X-n do not send trailing CR
X--------------------------------------------------------------------------*/
Xint
Xpcmd_send(param)
XESD *param;
X{
Xint erc;
XESD *buf;
Xchar switches[8];
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	if((buf = make_esd(256)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X	if(erc = gstr(param,buf,1))
X	{
X		free_esd(buf);
X		return(erc);
X	}
X
X	lputs(buf->pb);
X
X	if(!strchr(switches,'n'))
X		lputc(CR);
X
X	free_esd(buf);
X	return(erc);
X}	/* end of pcmd_send */
X
X/*+-------------------------------------------------------------------------
X	pcmd_set(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_set(param)
XESD *param;
X{
Xint erc;
Xint itmp;
Xulong varnum;
Xuint varmax;
Xchar vartype;
Xchar varstr[16];
Xint show_status;
Xlong *ivptr;
XESD *svptr;
Xchar *cptr;
Xchar *make_char_graphic();
X
X	if(erc = skip_cmd_break(param))
X		return(erc);
X
X	do {
X		/* $ is optional */
X		if((erc = skip_cmd_char(param,'$')) && (erc != eSyntaxError))
X			return(erc);
X		/* get variable type */
X		if(get_cmd_char(param,&vartype))
X			return(eSyntaxError);
X		/* validate variable type */
X		vartype = to_lower(vartype);
X		switch(vartype)
X		{
X			case 'i':
X				varmax = IVQUAN;
X				break;
X			case 's':
X				varmax = SVQUAN;
X				break;
X			default:
X				return(eIllegalVarType);
X		}
X
X		if(!get_numeric_value(param,&varnum))
X			goto TEST_VARNUM;
X		else if(*(param->pb + param->index) == '[')
X		{
X			if(erc = get_subscript(param,&varnum))
X				return(erc);
XTEST_VARNUM:
X			if((int)varnum >= varmax)
X				return(eIllegalVarNumber);
X			switch(vartype)
X			{
X				case 'i':
X					ivptr = &iv[(int)varnum];
X					break;
X				default:
X					svptr = sv[(int)varnum];
X			}
X		}
X		else if(get_alphanum_zstr(param,varstr,sizeof(varstr)))
X			return(eInvalidVarName);
X		else
X		{
X			varnum = 0x1000L;
X			switch(vartype)
X			{
X				case 'i':
X					erc = find_mkvi(varstr,&ivptr,1);
X					break;
X				default:
X					erc = find_mkvs(varstr,&svptr,1);
X			}
X			if(erc)
X				return(erc);
X		}
X			
X		show_status = 1;
X		if(!skip_cmd_char(param,'='))	/* assignment */
X		{
X			switch(vartype)
X			{
X				case 'i':
X					if(erc = gint(param,ivptr))
X						return(erc);
X					break;
X				default:
X					if(erc = gstr(param,svptr,1))
X						return(erc);
X					break;
X			}
X			if(!proctrace)
X				show_status = 0;
X		}
X		if(show_status)
X		{
X			switch(vartype)
X			{
X				case 'i':
X					if(varnum != 0x1000L)
X						pprintf("$i%02ld = %7ld (0x%08lx,0%lo)\n",varnum,
X							*ivptr,*ivptr,*ivptr);
X					else
X						pprintf("$i%s = %ld (0x%08lx,0%lo)\n",varstr,
X							*ivptr,*ivptr,*ivptr);
X					break;
X				default:
X					if(varnum != 0x1000L)
X						pprintf("$s%02ld = '",varnum);
X					else
X						pprintf("$s%s = '",varstr);
X					itmp = svptr->cb;
X					cptr = svptr->pb;
X					while(itmp--)
X						pputs(make_char_graphic(*cptr++,0));
X					pputs("'\n");
X					break;
X			}
X		}
X	} while(!skip_comma(param));
X
X	if(!end_of_cmd(param))
X		return(eSyntaxError);
X
X	return(0);
X}	/* end of pcmd_set */
X
X/*+-------------------------------------------------------------------------
X	pcmd_system(param)
X
Xsystem [-l] 'cmd'
X-l makes comm line stdin/stdout
X-s keeps all fds the same
X
Xreturns $i0 set to exit status of program or 0x100 if interrupted
X--------------------------------------------------------------------------*/
Xint
Xpcmd_system(param)
XESD *param;
X{
Xint erc;
XESD *cmd;
Xextern int last_child_wait_status;
Xchar switches[8];
X
X	if((cmd = make_esd(256)) == (ESD *)0)
X		return(eNoMemory);
X
X	get_switches(param,switches,sizeof(switches));
X
X/* a hack */
X	*cmd->pb++ = (strchr(switches,'s')) ? '>' : 
X		((strchr(switches,'l')) ? '$' : '!');
X
X	cmd->maxcb--;
X
X	if(erc = gstr(param,cmd,1))
X	{
X		cmd->pb--;		/* be nice */
X		cmd->maxcb++;	/* or surely this will haunt us one day */
X		free_esd(cmd);
X		return(erc);
X	}
X
X/* rehack */
X	cmd->pb--;
X	cmd->cb++;
X	cmd->maxcb++;
X
X	if(proctrace)
X	{
X		pputs(cmd->pb + 1);
X		pputs("\n");
X	}
X
X	last_child_wait_status = 0xFF00;
X	shell(cmd->pb);
X	iv[0] = (last_child_wait_status & 0xFF)
X			? 0x100L : (long)last_child_wait_status >> 8;
X	if(proctrace)
X		pprintf("$i0 = %ld, (%s)\n",iv[0],
X			(iv[0] == 0x100L) ? "interrupted" : "program exit status");
X
X	free_esd(cmd);
X	return(0);
X}	/* end of pcmd_system */
X
X/*+-------------------------------------------------------------------------
X	get_big_endian_16(ptr)
X--------------------------------------------------------------------------*/
Xushort
Xget_big_endian_16(ptr)
Xregister uchar *ptr;
X{
Xregister ushort uint16 = ((ushort)ptr[0] << 8) | ptr[1];
X 
X	return(uint16);
X 
X}	/* end of get_big_endian_16 */
X 
X/*+-------------------------------------------------------------------------
X	get_big_endian_32(ptr)
X--------------------------------------------------------------------------*/
Xulong
Xget_big_endian_32(ptr)
Xregister uchar *ptr;
X{
Xregister ulong uint32 = ((ulong)*ptr++) << 24;
X	uint32 |= ((ulong)*ptr++) << 16;
X	uint32 |= ((ulong)*ptr++) <<  8;
X	uint32 |=  (ulong)*ptr++;
X	return(uint32);
X 
X}	/* end of get_big_endian_32 */
X
X/*+-------------------------------------------------------------------------
X	pcmd_getf(param) - get friend memory
X
Xgetf -x <int-var-spec> <offset>
Xwhere: -x ==
X   -b byte
X   -w word (little-endian)
X   -W word (big-endian)
X   -l 32-bits (little-endian)
X   -L 32-bits (big-endian)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_getf(param)
XESD *param;
X{
Xint erc;
Xchar switches[8];
Xlong *piv;
Xlong offset;
Xint size;
Xint big_endian;
X
X	if(erc = get_switches(param,switches,sizeof(switches)))
X		return(erc);
X	if((strlen(switches) != 2) || !strchr("bwWlL",switches[1]))
X	{
X		pputs("invalid switch\n");
X		return(eFATAL_ALREADY);
X	}
X	size = to_lower(switches[1]);
X	big_endian = isupper(switches[1]);
X
X/*
X	if(!get_svptr(param,&psv))
X		return(eNotImplemented);
X	else
X*/
X	if(!strncmp(param->pb + param->index,"$i",2))
X		param->index += 2;
X	if(erc = get_ivptr(param,&piv,1))
X		return(erc);
X
X	if(erc = gint(param,&offset))
X		return(erc);
X
X	if(proctrace)
X		pprintf("getf %s offset=0x%lx",switches,offset);
X
X	switch(size)
X	{
X		case 'b':
X			if(offset > ((long)sizeof(shm->friend_space) - 1))
X				goto OFFSET_TOO_LARGE;
X			*piv = *(((uchar *)shm->friend_space) + (int)offset) & 0xFF;
X			break;
X		case 'w':
X			if(offset > ((long)sizeof(shm->friend_space) - 2))
X				goto OFFSET_TOO_LARGE;
X			if(big_endian)
X				*piv = get_big_endian_16((uchar *)shm->friend_space +
X						(int)offset);
X			else
X				*piv = *(((ushort *)shm->friend_space) + (int)offset) & 0xFFFF;
X			break;
X		case 'l':
X			if(offset > ((long)sizeof(shm->friend_space) - 4))
X				goto OFFSET_TOO_LARGE;
X			if(big_endian)
X			{
X				*piv = get_big_endian_32((uchar *)shm->friend_space +
X						(int)offset);
X			}
X			else
X				*piv = *((long *)((char *)shm->friend_space + (int)offset));
X			break;
X	}
X
X	if(proctrace)
X		pprintf(" value=%ld (%08lx)\n",*piv,*piv);
X	return(0);
X
XOFFSET_TOO_LARGE:
X	if(proctrace)
X		pputs("\n");
X	pprintf("offset 0x%02lx too large for -%c (0x%02x bytes available)\n",
X		offset,switches[1],sizeof(shm->friend_space));
X	return(eFATAL_ALREADY);
X
X}	/* end of pcmd_getf */
X
X/*+-------------------------------------------------------------------------
X	pcmd_putf(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_putf(param)
XESD *param;
X{
X	return(eNotImplemented);
X}	/* end of pcmd_putf */
X
X/*+-------------------------------------------------------------------------
X	pcmd_xon(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_xon(param)
XESD *param;
X{
Xint erc;
Xchar new_xonxoff[8];
Xchar *xon_status();
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	if(erc = get_alpha_zstr(param,new_xonxoff,sizeof(new_xonxoff)))
X		return(erc);
X
X	if(set_xon_xoff_by_arg(new_xonxoff))
X		return(eBadParameter);
X
X	if(proctrace)
X		pprintf("xon/xoff flow control set to %s\n",xon_status());
X
X	return(erc);
X
X}	/* end of pcmd_xon */
X
X/*+-------------------------------------------------------------------------
X	pcmd_rtscts(param)
X--------------------------------------------------------------------------*/
Xint
Xpcmd_rtscts(param)
XESD *param;
X{
Xint erc;
Xchar new_rtscts[8];
X
X	if(shm->Liofd < 0)
X		return(eNoLineAttached);
X
X	if(erc = get_alpha_zstr(param,new_rtscts,sizeof(new_rtscts)))
X		return(erc);
X
X	lRTSCTS_control(yes_or_no(new_rtscts));
X
X	if(proctrace)
X	{
X		pprintf("RTS %s CTS %s\n",
X			(Ltermio.c_cflag & RTSFLOW) ? "on" : "off",
X			(Ltermio.c_cflag & CTSFLOW) ? "on" : "off");
X	}
X
X	return(erc);
X
X}	/* end of pcmd_rtscts */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of pcmd.c */
SHAR_EOF
$TOUCH -am 1226023490 'pcmd.c' &&
chmod 0644 pcmd.c ||
echo 'restore of pcmd.c failed'
Wc_c="`wc -c < 'pcmd.c'`"
test 24203 -eq "$Wc_c" ||
	echo 'pcmd.c: original size 24203, current size' "$Wc_c"
true || echo 'restore of pcmdfile.c failed'
echo End of part 12, continue with part 13
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.