From decwrl!ucbvax!ucsd!swrinde!cs.utexas.edu!uunet!allbery Wed May 16 09:17:53 PDT 1990
Article 1537 of comp.sources.misc:
Path: decwrl!ucbvax!ucsd!swrinde!cs.utexas.edu!uunet!allbery
From: wht%n4hgf@gatech.edu (Warren Tucker)
Newsgroups: comp.sources.misc
Subject: v12i057: ECU 2.80 part 04/29
Message-ID: <88359@uunet.UU.NET>
Date: 12 May 90 01:56:14 GMT
Sender: allbery@uunet.UU.NET
Lines: 1385
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)

Posting-number: Volume 12, Issue 57
Submitted-by: wht%n4hgf@gatech.edu (Warren Tucker)
Archive-name: ecu2.80/part04

---- Cut Here and unpack ----
#!/bin/sh
# This is part 04 of ecu280
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= ecuicmhist.c ==============
echo "x - extracting ecuicmhist.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ecuicmhist.c &&
X/* CHK=0x3B8B */
X/*+-------------------------------------------------------------------------
X	ecuicmhist.c - ecu interactive command history handler
X	wht%n4hgf@gatech.edu
X
X  Defined functions:
X	icmd_history_add(icmd_buf)
X	icmd_history_manager(func,newicmd,icmdsize)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-07-1990-21:23-wht@n4hgf---- 2.80 --- */
X/*:04-19-1990-03:07-wht@n4hgf-GCC run found unused vars -- rm them */
X/*:04-17-1990-14:26-wht-creation */
X
X#include <curses.h>
X#include "pc_scr.h"
X
X#define STDIO_H_INCLUDED
X#define OMIT_TERMIO_REFERENCES
X#include "ecu.h"
X
X#include "ecukey.h"
X#include "ecuxkey.h"
X
Xchar *strdup();
X
X#ifdef WHT
X#define ICMDH_MAXCNT	100
X#else
X#define ICMDH_MAXCNT	50
X#endif
X#define ICMDH_MAXLEN	72
X
Xtypedef struct icmd_hist
X{
X	struct icmd_hist *prev;
X	struct icmd_hist *next;
X	uchar *icmd;
X} ICMDH;
X
XICMDH *icmdh_head = (ICMDH *)0;
XICMDH *icmdh_tail = (ICMDH *)0;
Xint icmdh_count = 0;
X
X/*+-------------------------------------------------------------------------
X	icmd_history_add(icmd_buf)
X--------------------------------------------------------------------------*/
Xvoid
Xicmd_history_add(icmd_buf)
Xchar *icmd_buf;
X{
XICMDH *icmdh = (ICMDH *)malloc(sizeof(ICMDH));
Xchar *strdup();
X
X	if(!icmdh)
X		return;
X	if(!(icmdh->icmd = strdup(icmd_buf)))
X	{
X		free((char *)icmdh);
X		return;
X	}
X	if(strlen(icmdh->icmd) > ICMDH_MAXLEN)
X		icmdh->icmd[ICMDH_MAXLEN] = 0;
X	if(icmdh_tail)
X	{
X		icmdh_tail->next = icmdh;
X		icmdh->prev = icmdh_tail;
X		icmdh->next = (ICMDH *)0;
X		icmdh_tail = icmdh;
X	}
X	else
X	{
X		icmdh->prev = (ICMDH *)0;
X		icmdh->next = (ICMDH *)0;
X		icmdh_head = icmdh;
X		icmdh_tail = icmdh;
X	}
X	if(++icmdh_count > ICMDH_MAXCNT)
X	{
X		icmdh = icmdh_head;
X		icmdh_head = icmdh->next;
X		icmdh_head->prev = (ICMDH *)0;
X		free(icmdh->icmd);
X		free((char *)icmdh);
X		icmdh_count--;
X	}
X		
X}	/* end of icmd_history_add */
X
X/*+-------------------------------------------------------------------------
X	icmd_history_manager(func,newicmd,icmdsize) - entered by Home Xkey
X
Xreturn new icmd string to execute
Xreturns 0 if ok to exce new cmd, else 1 if not
X(returns 0 if null or ESC, so caller can handle exit condition)
X--------------------------------------------------------------------------*/
Xint
Xicmd_history_manager(func,newicmd,icmdsize)
Xuchar func;
Xuchar *newicmd;
Xint icmdsize;
X{
Xregister itmp;
Xregister ICMDH *icmdh = icmdh_tail;
X
X	if((func != XFcurup) && (func != XFhome))
X	{
X		ring_bell();
X		return(1);
X	}
X
X	if(!icmdh)
X	{
X		ff(se,"no interactive commands saved\r\n");
X		return(1);
X	}
X	while(1)
X	{
X		strncpy(newicmd,icmdh->icmd,icmdsize - 1);
X		*(newicmd + icmdsize - 1) = 0;
X
X		ttygets(newicmd,icmdsize,4+2);
X		switch(*newicmd)
X		{
X		case ESC:
X		case 0:
X			return(0);
X		case XFhome:
X			icmdh = icmdh_head;
X			*newicmd = 0;
X			break;
X		case XFend:
X			icmdh = icmdh_tail;
X			*newicmd = 0;
X			break;
X		case XFpgup:
X		case XFpgdn:
X			ring_bell();
X			*newicmd = 0;
X			break;
X		case XFcurup:
X			if(icmdh->prev)
X				icmdh = icmdh->prev;
X			*newicmd = 0;
X			break;
X		case XFcurdn:
X			if(icmdh->next)
X				icmdh = icmdh->next;
X			*newicmd = 0;
X			break;
X		default:
X			return(0);
X		}
X
X		itmp = strlen(newicmd);
X		while(itmp--)
X			fputc(BS,se);
X		itmp = strlen(newicmd);
X		while(itmp--)
X			fputc(' ',se);
X		itmp = strlen(newicmd);
X		while(itmp--)
X			fputc(BS,se);
X	}
X}	/* end of icmd_history_manager */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of ecuicmhist.c */
SHAR_EOF
$TOUCH -am 0507233390 ecuicmhist.c &&
chmod 0644 ecuicmhist.c ||
echo "restore of ecuicmhist.c failed"
set `wc -c ecuicmhist.c`;Wc_c=$1
if test "$Wc_c" != "3438"; then
	echo original size 3438, current size $Wc_c
fi
# ============= eculine.c ==============
echo "x - extracting eculine.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > eculine.c &&
X/* CHK=0x60C4 */
X/*+-----------------------------------------------------------------------
X	eculine.c -- line related procedures
X wht%n4hgf@gatech.edu
X
X  Defined functions:
X	lbreak()
X	lclear_xmtr_xoff()
X	lclose()
X	lflush(flush_type)
X	lget_xon_xoff(ixon,ixoff)
X	lgetc_timeout(msec)
X	lgetc_xmtr()
X	lgets_timeout(lrwt)
X	llookfor(lookfor,msecs,echo_flag)
X	lnew_baud_rate(new_baud)
X	lopen()
X	lopen_err_text(lerr)
X	lputc(lchar)
X	lputc_paced(pace_msec,lchar)
X	lputs(string)
X	lputs_paced(pace_msec,string)
X	lquiet(msecs,echo_flag)
X	lrdchk_xmtr()
X	lreset_ksr()
X	lset_baud_rate(ioctl_flag)
X	lset_parity(ioctl_flag)
X	ltoggle_dtr()
X	lxon_xoff(flag)
X	valid_baud_rate(baud)
X	process_xmtr_rcvd_char(rchar,echo)
X
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-07-1990-21:23-wht@n4hgf---- 2.80 --- */
X/*:04-19-1990-03:07-wht@n4hgf-GCC run found unused vars -- rm them */
X/*:04-10-1990-17:34-wht@n4hgf-provisions for ecu xmtr logging when rcvr dead */
X/*:03-28-1990-04:58-wht@n4hgf-add to echo in process_xmtr_rcvd_char */
X/*:03-27-1990-15:18-wht@n4hgf-overhaul for/wait/SIGCLD handling */
X/*:03-26-1990-00:46-wht@n4hgf-if EACCES, suggest course of action to user */
X/*:03-25-1990-14:11-wht@n4hgf------ x2.70 ------- */
X/*:02-09-1990-16:05-wht-heuristic debug of RTS/CTS use */
X/*:12-21-1989-21:53-wht-RTS/CTS flow control */
X/*:12-04-1989-17:43-wht-lget_xon_xoff was returning wrong kind of data */
X/*:11-10-1989-21:49-wht-send xmtr-rcvd chars thru ansi filter */
X/*:11-04-1989-07:00-wht-keep ansi cursor position in shm */
X/*:10-25-1989-13:16-wht-notify rcvr on parity change */
X/*:07-03-1989-22:57-wht------ x2.00 ----- */
X/*:06-30-1989-00:32-wht-ltoggle_dtr no longer lopen/lclose, but open/close */
X/*:06-24-1989-16:53-wht-flush edits --- ecu 1.95 */
X
X#include "ecu.h"
X#include "ecukey.h"
X#include "ecuhangup.h"
X#if !defined(NO_SELECT)
X#include <sys/select.h>
X#endif
X
Xextern int rcvr_pid;
Xextern int errno;
Xextern int lgetc_count;
Xextern int vmin;
Xextern int interrupt;		/* SIGINT flag: see xmtr_SIGINT_handler */
X
Xchar lopen_err_str[64] = "";
X
X#define LPUTS_NAP_COUNT	20
X
X/*+-------------------------------------------------------------------------
X	process_xmtr_rcvd_char(rchar,echo) - feed xmtr-rcvd char to rcvr code
X
Xecho: 0 no echo
X      1 echo literally
X      2 "make printable"
X--------------------------------------------------------------------------*/
Xvoid
Xprocess_xmtr_rcvd_char(rchar,echo)
Xuint rchar;
Xregister int echo;
X{
Xextern int rcvr_log;
Xextern FILE *rcvr_log_fp;
Xextern char rcvr_log_file[];	/* if rcvr_log!= 0,log filename */
X
X	if(process_rcvd_char(rchar))
X		return;
X
X	if(echo == 1)
X	{
X		if(rchar == NL)
X			fputc(CR,se);
X		fputc(rchar,se);
X		if(rchar != CR)
X			plogc(rchar);
X	}
X	else if(echo == 2)
X	{
X	char *make_char_graphic();
X		pputs(make_char_graphic(rchar,0));
X	}
X
X}	/* end of process_xmtr_rcvd_char */
X
X/*+-------------------------------------------------------------------------
X	lgetc_xmtr() -- xmtr version of get char from line
Xalso called by rcvr code when lgetc_buf empty and vmin == 1
X--------------------------------------------------------------------------*/
Xuchar
Xlgetc_xmtr()
X{
Xint itmp;
Xextern int errno;
Xuchar char_rtnd;
X
XREAD_AGAIN:
X	if((itmp = read(shm->Liofd,&char_rtnd,1)) < 1)
X	{
X		if(!itmp)
X		{
X			pperror("lgetc_xmtr: zero length read\n");
X			hangup(HANGUP_LINE_READ_ERROR);
X		}
X		if(errno == EINTR)			/* if signal interrupted, ... */
X		{
X			if(interrupt)
X				return(0);
X			goto READ_AGAIN;
X		}
X		hangup(HANGUP_LINE_READ_ERROR);
X	}
X	shm->rcvd_chars++;
X	shm->rcvd_chars_this_connect++;
X	if(shm->Lparity)
X		char_rtnd &= 0x7F;
X	return(char_rtnd);
X
X}	/* end of lgetc_xmtr */
X
X/*+-------------------------------------------------------------------------
X	lrdchk_xmtr() -- rdchk(shm->Liofd) for xmtr
X--------------------------------------------------------------------------*/
Xint
Xlrdchk_xmtr()
X{
X	return(rdchk(shm->Liofd));
X}	/* end of lrdchk_xmtr */
X
X/*+-------------------------------------------------------------------------
X	char *lgets_timeout(LRWT *) - may be called by xmtr only
X
Xto1 and to2 are unsigned long values in milliseconds (not
Xcurrently supported well under BSD4); to1 is the time to wait
Xfor the first character, to2 the time to wait for subsequent
Xcharacters.
X
Xif raw_flag 0,     non-printables are stripped from beginning
X                   and end of received characters (i.e., modem
X                   response reads); NULs discarded, parity stripped
Xif raw_flag 1,     full raw read buffer returned
X
X0x80 in raw_flag indicates console interrupts should be enabled.
Xif interrupt thus detected, the procedure returns "!Interrupted"
Xwithout reseting variable 'interrupt'
X
Xbuffer is address to read chars into
X
Xbufsize is buffer max size (allowing room for terminating null)
Xwhich should be at least 2 if raw_size includes 0x80 bit,
Xelse at least 12 characters if 0x80 omitted.
X
Xcount is a int which, at return, receives the actual count read
X
X--------------------------------------------------------------------------*/
Xchar *
Xlgets_timeout(lrwt)
XLRWT *lrwt;
X{
X/**********************/
X#if defined(NO_SELECT)
X/**********************/
X
Xregister actual_count = 0;
Xregister char *cptr = lrwt->buffer;
Xregister echo_flag = lrwt->echo;
Xint max_count = lrwt->bufsize;
Xchar *rtn_val;
Xint timeout_counter;
Xint qc1;
Xint qc2;
Xint raw_mode = lrwt->raw_flag & 0x0F;
Xint check_sigint = (lrwt->raw_flag & 0x80);
Xint old_ttymode = get_ttymode();	/* save original tty mode */
Xint delim_len;
Xlong quantum;
Xlong ltmp;
Xlong nap(long);
X
X	delim_len = (lrwt->delim) ? strlen(lrwt->delim) : 0;
X
X	if((shm->Lbaud < 300) && lrwt->to2)
X		if(lrwt->to2 < 300L) lrwt->to2 = 300L;
X	else if((shm->Lbaud < 1200) && lrwt->to2)
X		if(lrwt->to2 < 200L) lrwt->to2 = 100L;
X
X/* shortest interval */
X	ltmp = (lrwt->to1 < lrwt->to2) ? lrwt->to1 : lrwt->to2;
X
X/* calculate wait quantum */
X	quantum = ltmp / 10L;				/* try for ten ticks */
X
X#if defined(M_I386)
X	if(quantum < 40L)
X		quantum = 40L;
X#else
X	if(quantum < 20L)
X		quantum = 20L;
X#endif
X	qc1 = lrwt->to1 / quantum;
X	if(!qc1) qc1 = 1L;
X	qc2 = lrwt->to2 / quantum;
X	if(!qc2) qc2 = 1L;
X
X/* perform the lrtw function using nap() and rdchk()
X   input: qc1 is first nap count (for first charcters) 
X          qc2 is 2nd nap count (for subsequent characters) 
X          quantum is the nap period in milliseconds
X          cptr is char* to receive read string
X          max_count is max number of characters incl null
X          lrwt->raw_flag as described above
X
X  output: lrwt->count is actual count of return result
X          lrwt->buffer is return read buffer
X*/
X	max_count--;				/* leave room for null */
X
X	if(check_sigint)
X		ttymode(2);				/* let console interrupt long timeouts */
X
X	timeout_counter = qc1;		/* first timeout */ 
X	*cptr = 0;					/* init result string */
X	while(timeout_counter--)
X	{
X		nap(quantum);
X
X		if(check_sigint && interrupt)
X			goto INTERRUPTED;
X
X		while(lrdchk_xmtr())
X		{
X			*cptr = lgetc_xmtr();
X
X			if(check_sigint && interrupt)
X				goto INTERRUPTED;
X
X			if(*cptr == 0)
X				continue;
X
X			process_xmtr_rcvd_char(*cptr,echo_flag);
X
X			if(!raw_mode && (*cptr == CR))
X					continue;
X
X			*++cptr = 0;
X			if(++actual_count == 1)
X			{
X				if(!lrwt->to2)
X					break;
X				timeout_counter = qc2;
X			}
X
X			if(--max_count == 0)
X				goto BOTTOM;
X
X			if(delim_len && (actual_count >= delim_len) &&
X					!strncmp(lrwt->delim,cptr - delim_len,delim_len))
X				goto BOTTOM;
X		}
X	}
X
X/******************************/
X#else /* other than NO_SELECT */
X/******************************/
X/* --- use select --- */
Xregister actual_count = 0;
Xregister char *cptr = lrwt->buffer;
Xregister max_count = lrwt->bufsize;
Xregister raw_mode = lrwt->raw_flag & 0x0F;
Xregister echo_flag = lrwt->echo;
Xint check_sigint = (lrwt->raw_flag & 0x80);
Xint old_ttymode = get_ttymode();	/* save original tty mode */
Xint fdmask;
Xint delim_len;
Xstruct timeval tval;
Xchar *rtn_val;
X
X	delim_len = (lrwt->delim) ? strlen(lrwt->delim) : 0;
X
X	if((shm->Lbaud < 300) && lrwt->to2)
X		if(lrwt->to2 < 300L) lrwt->to2 = 300L;
X	else if((shm->Lbaud < 1200) && lrwt->to2)
X		if(lrwt->to2 < 200L) lrwt->to2 = 100L;
X
X
X/* perform the lrtw function
X
X  output: lrwt->count is actual count of return result
X          lrwt->buffer is return read buffer
X*/
X	max_count--;				/* leave room for null */
X
X	if(check_sigint)
X		ttymode(2);				/* let console interrupt long timeouts */
X
X	*cptr = 0;					/* init result string */
X	while(1)
X	{
X		if(check_sigint && interrupt)
X			goto INTERRUPTED;
X
X		errno = 0;
X		fdmask = 1 << shm->Liofd;
X		if(actual_count)
X		{
X			tval.tv_sec = lrwt->to2 / 1000L;
X			tval.tv_usec = (lrwt->to2 % 1000L) * 1000L;
X		}
X		else
X		{
X			tval.tv_sec = lrwt->to1 / 1000L;
X			tval.tv_usec = (lrwt->to1 % 1000L) * 1000L;
X		}
X		if(select(32,&fdmask,(int *)0,(int *)0,&tval) != 1)
X		{
X			if(errno == EINTR)
X				continue;
X			break;
X		}
X
X		while(rdchk(shm->Liofd))
X		{
X			*cptr = lgetc_xmtr();
X
X			if(check_sigint && interrupt)
X				goto INTERRUPTED;
X
X			if(*cptr == 0)
X				continue;
X
X			process_xmtr_rcvd_char(*cptr,!!echo_flag);
X
X			if(!raw_mode && (*cptr == CR))
X					continue;
X
X			*++cptr = 0;
X			actual_count++;
X
X			if(--max_count == 0)
X				goto BOTTOM;
X
X			if(delim_len && (actual_count >= delim_len) &&
X					!strncmp(lrwt->delim,cptr - delim_len,delim_len))
X				goto BOTTOM;
X		}
X		if(!lrwt->to2)
X			break;
X	}
X
X#endif	/* NO_SELECT */
X
X/********* common post processing for select() / no select() ************/
XBOTTOM:
X	if(check_sigint)
X		ttymode(old_ttymode);
X	if(raw_mode)
X	{
X		lrwt->count = actual_count;
X		return(lrwt->buffer);
X	}
X	cptr = lrwt->buffer;
X	while(((*cptr > 0) && (*cptr < SPACE)) || (*cptr >= DEL))
X		cptr++;
X	rtn_val = cptr;
X	actual_count = 0;
X	while(((*cptr &= 0x7F) >= SPACE) && (*cptr < DEL))
X	{
X		cptr++;
X		actual_count++;
X	}
X	*cptr = 0;
X	strcpy(lrwt->buffer,rtn_val);
X	lrwt->count = actual_count;
X	return(lrwt->buffer);
X
XINTERRUPTED:
X	ttymode(old_ttymode);
X	strcpy(lrwt->buffer,"!Interrupted");
X	lrwt->count = strlen(lrwt->buffer);
X	return((char *)0);
X
X}	/* end of lgets_timeout */
X
X/*+-------------------------------------------------------------------------
X	lgetc_timeout(msec) - may be called by xmtr only
X
X reads one character from line unless msec passes with no receipt.
X return char if received, else -1 if timeout
X--------------------------------------------------------------------------*/
Xint
Xlgetc_timeout(msec)
Xlong msec;
X{
Xuchar rtn_char;
X#if defined(NO_SELECT)
Xlong nap();
Xlong count;
X
XAGAIN:
X	count = msec;
X	while(!lrdchk_xmtr())
X	{
X		if(interrupt)
X			return(-1);
X		if((count -= nap(20L)) <= 0)
X			return(-1);
X	}
X
X#else
X
Xint fdmask;
Xstruct timeval tval;
X
XAGAIN:
X	tval.tv_sec = msec / 1000L;
X	tval.tv_usec = (msec % 1000L) * 1000L;
X	fdmask = 1 << shm->Liofd;
X	if(select(32,&fdmask,(int *)0,(int *)0,&tval) < 1)
X		return(-1);
X	if(!lrdchk_xmtr())
X		return(-1);
X	if(interrupt)
X		return(-1);
X#endif
X
X	rtn_char = lgetc_xmtr();
X	if(!rtn_char)
X		goto AGAIN;
X	return(rtn_char);
X
X}	/* end of lgetc_timeout */
X
X/*+-------------------------------------------------------------------------
X	llookfor(lookfor,msecs,echo_flag)
Xreturn 1 if successful, else 0 if no match
Xecho_flag: 0 no echo
X           1 echo literally
X           2 "make printable"
X--------------------------------------------------------------------------*/
Xint
Xllookfor(lookfor,msecs,echo_flag)
Xchar *lookfor;
Xulong msecs;
Xint echo_flag;
X{
Xregister lookfor_len = strlen(lookfor);
Xregister lchar;
Xchar *lastfew = (char *)malloc(lookfor_len);
Xint success_flag = 0;
Xint old_ttymode = get_ttymode();
X
X	if(!lastfew)
X	{
X		pputs("memory exhausted\n");
X		return(0);
X	}
X
X	ttymode(2);
X
X	memset(lastfew,0,lookfor_len);
X	while((lchar = lgetc_timeout(msecs)) >= 0)
X	{
X		if(!lchar)		/* skip nulls */
X			continue;
X		process_xmtr_rcvd_char(lchar,echo_flag);
X		memcpy(lastfew,lastfew + 1,lookfor_len - 1);
X		*(lastfew + lookfor_len - 1) = lchar;
X		if(!strncmp(lastfew,lookfor,lookfor_len))
X		{
X			success_flag = 1;
X			break;
X		}
X	}
X	free(lastfew);
X	ttymode(old_ttymode);
X	return(success_flag);
X}	/* end of llookfor */
X
X/*+-------------------------------------------------------------------------
X	lquiet(msecs,echo_flag)
X--------------------------------------------------------------------------*/
Xvoid
Xlquiet(msecs,echo_flag)
Xulong msecs;
Xint echo_flag;
X{
Xregister lchar;
Xint old_ttymode = get_ttymode();
X
X	ttymode(2);
X	while((lchar = lgetc_timeout(msecs)) >= 0)
X	{
X		if(interrupt)	/* if interrupt, return */
X			break;
X		if(!lchar)		/* skip nulls */
X			continue;
X		process_xmtr_rcvd_char(lchar,!!echo_flag);
X	}
X	ttymode(old_ttymode);
X
X}	/* end of lquiet */
X
X/*+-------------------------------------------------------------------------
X	lflush(flush_type) -- flush line driver input &/or output buffers
X
X0 == input buffer
X1 == output buffer
X2 == both buffers
X--------------------------------------------------------------------------*/
Xvoid
Xlflush(flush_type)
Xint flush_type;
X{
X	lgetc_count = 0;
X	switch(flush_type)
X	{
X		case 0:
X			ioctl(TTYIN,TCFLSH,(char *)0); break;
X		case 1:
X			ioctl(TTYIN,TCFLSH,(char *)1); break;
X		case 2:
X			ioctl(TTYIN,TCFLSH,(char *)2); break;
X	}
X}	/* end of lflush */
X
X/*+-------------------------------------------------------------------------
X	lreset_ksr()
X
X  This procedure restores the termio for the
X  comm line to the values in Ltermio
X--------------------------------------------------------------------------*/
Xvoid
Xlreset_ksr()
X{
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X
X}	/* end of lreset_ksr */
X
X/*+-----------------------------------------------------------------------
X	lputc(lchar) -- write lchar to comm line
X------------------------------------------------------------------------*/
Xvoid
Xlputc(lchar)
Xchar lchar;
X{
X	while(write(shm->Liofd,&lchar,1) < 0)
X	{
X		if(errno == EINTR)
X			continue;
X		pperror("lputc write error");
X		hangup(HANGUP_XMTR_WRITE_ERROR);
X	}
X	shm->xmit_chars++;
X	shm->xmit_chars_this_connect++;
X}	/* end of lputc */
X
X/*+-----------------------------------------------------------------------
X	lputc_paced(pace_msec,lchar) -- write lchar to comm line
X  with time between each character 
X------------------------------------------------------------------------*/
Xvoid
Xlputc_paced(pace_msec,lchar)
Xregister pace_msec;
Xchar lchar;
X{
X
X	lputc(lchar);	
X	nap((long)(pace_msec ? pace_msec : LPUTS_NAP_COUNT));
X
X}	/* end of lputc_paced */
X
X/*+-----------------------------------------------------------------------
X	lputs(string) -- write string to comm line
X------------------------------------------------------------------------*/
Xvoid
Xlputs(string)
Xregister char *string;
X{
X	while(*string)
X		lputc(*string++);
X}
X
X/*+-----------------------------------------------------------------------
X	lputs_paced(pace_msec,string) -- write string to comm line
X  with time between each character 
X------------------------------------------------------------------------*/
Xvoid
Xlputs_paced(pace_msec,string)
Xregister pace_msec;
Xregister char *string;
X{
X	while(*string)
X		lputc_paced(pace_msec,*string++);
X
X}	/* end of lputs_paced */
X
X/*+-------------------------------------------------------------------------
X	valid_baud_rate(baud) -- returns (positive) baud rate selector
Xor -1 if invalid baud rate
X--------------------------------------------------------------------------*/
Xvalid_baud_rate(baud)
Xuint baud;
X{
X	switch(baud)
X	{
X		case 110: return(B110);
X		case 300: return(B300);
X		case 600: return(B600);
X		case 1200: return(B1200);
X		case 2400: return(B2400);
X		case 4800: return(B4800);
X		case 9600: return(B9600);
X		case 19200: return(EXTA);
X		case 38400: return(EXTB);
X		default: return(-1);
X	}
X
X}	/* end of valid_baud_rate */
X
X/*+-----------------------------------------------------------------------
X	lset_baud_rate(ioctl_flag)
X
X  If 'ioctl_flag' is set, then perform ioctl call
X  is executed after setting baud rate
X------------------------------------------------------------------------*/
Xlset_baud_rate(ioctl_flag)
Xint ioctl_flag;
X{
Xint baud_selector = valid_baud_rate(shm->Lbaud);
X
X	if(baud_selector == -1)
X		baud_selector = valid_baud_rate(shm->Lbaud = DEFAULT_BAUD_RATE);
X
X	Ltermio.c_cflag &= ~CBAUD;
X	Ltermio.c_cflag |= baud_selector;
X
X#if defined(HO_HUM)
X	if(ioctl_flag)
X#endif
X		 ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X	return(0);
X
X}	/* end of lset_baud_rate */
X
X/*+-------------------------------------------------------------------------
X	lRTSCTS_control(flag)
X--------------------------------------------------------------------------*/
Xvoid
XlRTSCTS_control(flag)
Xint flag;
X{
X	switch(flag)
X	{
X		case 0:
X			Ltermio.c_iflag |= (IXOFF);
X			Ltermio.c_cflag &= ~(RTSFLOW | CTSFLOW);
X			break;
X
X		case 1:
X			Ltermio.c_iflag &= ~(IXON | IXOFF | IXANY);
X			Ltermio.c_cflag |= (RTSFLOW | CTSFLOW);
X			break;
X
X		case 2:
X			Ltermio.c_iflag &= ~(IXON | IXOFF | IXANY);
X			Ltermio.c_cflag |= RTSFLOW;
X			Ltermio.c_cflag &= ~CTSFLOW;
X			break;
X
X		case 3:
X			Ltermio.c_iflag &= ~(IXON | IXOFF | IXANY);
X			Ltermio.c_cflag |= CTSFLOW;
X			Ltermio.c_cflag &= ~RTSFLOW;
X			break;
X	}
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X
X}	/* end of lRTSCTS_control */
X
X/*+-------------------------------------------------------------------------
X	lnew_baud_rate(new_baud)
X--------------------------------------------------------------------------*/
Xint
Xlnew_baud_rate(new_baud)
Xuint new_baud;
X{
X	if(valid_baud_rate(new_baud) < 0)
X		return(-1);
X	if(shm->Lbaud != new_baud)
X		shm->Lmodem_already_init = 0;
X	shm->Lbaud = new_baud;
X	lset_baud_rate(1);
X	return(0);
X}	/* end of lnew_baud_rate */
X
X/*+-----------------------------------------------------------------------
X	lset_parity(ioctl_flag)
X
X  If 'ioctl_flag' is set, then perform ioctl call
X  is executed after setting parity
X------------------------------------------------------------------------*/
Xvoid
Xlset_parity(ioctl_flag)
Xint ioctl_flag;
X{
X	Ltermio.c_cflag &= ~(CS8 | PARENB | PARODD);
X	switch(to_lower(shm->Lparity))
X	{
X		case 'e':
X			Ltermio.c_cflag |= CS7 | PARENB;
X			Ltermio.c_iflag |= ISTRIP;
X			break;
X		case 'o':
X			Ltermio.c_cflag |= CS7 | PARENB | PARODD;
X			Ltermio.c_iflag |= ISTRIP;
X			break;
X		default:
X			ff(se,"invalid parity: %c ... defaulting to no parity\r\n");
X		case 0:
X		case 'n':
X			Ltermio.c_cflag |= CS8;
X			Ltermio.c_iflag &= ~(ISTRIP);
X			shm->Lparity = 0;
X			break;
X	}			
X
X#if defined(HO_HUM)
X	if(ioctl_flag)
X#endif
X	{
X		ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X	}
X
X}	/* end of lset_parity */
X
X/*+-------------------------------------------------------------------------
X	lclear_xmtr_xoff()
X--------------------------------------------------------------------------*/
Xvoid
Xlclear_xmtr_xoff()
X{
X	ioctl(shm->Liofd,TCXONC,(char *)1); /* restart xmtr output */
X}	/* end of lclear_xmtr_xoff */
X
X/*+-------------------------------------------------------------------------
X	lbreak()
X--------------------------------------------------------------------------*/
Xvoid
Xlbreak()
X{
X	ioctl(shm->Liofd,TCSBRK,(char *)0);
X}	/* end of lbreak */
X
X/*+----------------------------------------------------------------------
X	lopen()
Xreturns negative LOPEN_ codes if failure else positive pid using line
Xelse 0 if successful open
X------------------------------------------------------------------------*/
Xint
Xlopen()
X{
Xregister itmp = strlen(shm->Lline);
Xstruct stat ttystat;
X
X	lopen_err_str[0] = 0;
X	if(shm->Liofd >= 0)
X		return(LOPEN_ALREADY);
X	if(isupper(shm->Lline[itmp - 1]))
X		shm->Lline[itmp - 1] = tolower(shm->Lline[itmp - 1]);
X	if(!strcmp(shm->Lline,"/dev/tty"))
X		return(LOPEN_INVALID);
X	if(itmp = lock_tty())		/* get lock file */
X		return(itmp);
X	if(stat(shm->Lline,&ttystat) < 0)
X		return(LOPEN_NODEV);
X	shm->Liofd = open(shm->Lline,O_RDWR,0777);
X	if(shm->Liofd < 0)
X	{
X		if(errno == EACCES)
X			sprintf(lopen_err_str,"open error - try chmod +rw %s",shm->Lline);
X		return(LOPEN_OPNFAIL);
X	}
X	else
X	{
X		ioctl(shm->Liofd,TCGETA,(char *) &Ltermio);
X		Ltermio.c_iflag = (IGNPAR | IGNBRK | IXOFF );
X		Ltermio.c_oflag = 0;
X		Ltermio.c_cflag |= (CLOCAL | CREAD | HUPCL);
X		Ltermio.c_lflag = 0;
X
X		Ltermio.c_cc[VMIN]   = 1;
X		Ltermio.c_cc[VTIME]  = 1;
X		lset_baud_rate(0);		/* do not perform ioctl */
X		lset_parity(1);			/* do perform ioctl */
X	}
X
X	lopen_err_str[0] = 0;
X	return(0);
X
X}	/* end of lopen */
X
X/*+-----------------------------------------------------------------------
X	lclose()
X------------------------------------------------------------------------*/
Xvoid
Xlclose()
X{
X	if(shm->Liofd < 0)
X		return;
X	unlock_tty();	/* kill lock file (writes to line; must go before close) */
X	close(shm->Liofd);
X	shm->Liofd = -1;
X
X}	/* end of lclose */
X
X/*+-------------------------------------------------------------------------
X	ltoggle_dtr()
X--------------------------------------------------------------------------*/
Xvoid
Xltoggle_dtr()
X{
X	close(shm->Liofd);
X	nap(300L);
X	shm->Liofd = open(shm->Lline,O_RDWR,0777);
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X	nap(600L);
X}	/* end of ltoggle_dtr */
X
X/*+-------------------------------------------------------------------------
X	lxon_xoff(flag)
XIXON specifies whether or not we respond to xon/xoff characters
XIXOFF specifies whether or not we generate XON/XOFF characters
X--------------------------------------------------------------------------*/
Xvoid
Xlxon_xoff(flag)
Xint flag;
X{
X	if(flag & IXON)
X		Ltermio.c_iflag |= IXON;
X	else
X		Ltermio.c_iflag &= ~IXON;
X
X	if(flag & IXOFF)
X		Ltermio.c_iflag |= IXOFF;
X	else
X		Ltermio.c_iflag &= ~IXOFF;
X
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X
X}	/* end of lxon_xoff */
X
X/*+-------------------------------------------------------------------------
X	lget_xon_xoff(ixon,ixoff)
X--------------------------------------------------------------------------*/
Xvoid
Xlget_xon_xoff(ixon,ixoff)
Xint *ixon;
Xint *ixoff;
X{
X	*ixon  = Ltermio.c_iflag & IXON;
X	*ixoff = Ltermio.c_iflag & IXOFF;
X}	/* end of lget_xon_xoff */
X
X/*+-------------------------------------------------------------------------
X	lopen_err_text(lerr)
X--------------------------------------------------------------------------*/
Xchar *
Xlopen_err_text(lerr)
Xint lerr;
X{
Xstatic char lerr_s40[40];
X
X	if(lopen_err_str[0])
X		return(lopen_err_str);
X
X	switch(lerr)
X	{
X		case LOPEN_INVALID: return("invalid line name");
X		case LOPEN_UNKPID: return("unknown pid is using line");
X		case LOPEN_LCKERR: return("error creating lock file");
X		case LOPEN_NODEV: return("line does not exist");
X		case LOPEN_ALREADY: return("line already open");
X		case LOPEN_OPNFAIL: return("line open error (chmod +rw ?)");
X		case LOPEN_ENABLED: return("line enabled for incoming login");
X		case LOPEN_ENABLED_IN_USE: return("line in use by incoming login");
X		case LOPEN_DIALOUT_IN_USE: return("line in use by another dial out");
X	}
X	if(lerr > 0)
X		sprintf(lerr_s40,"pid %d using line",lerr);
X	else
X		sprintf(lerr_s40,"unknown line error %d",lerr);
X	return(lerr_s40);
X}	/* end of lopen_err_text */
X
X/* end of eculine.c */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0507233390 eculine.c &&
chmod 0644 eculine.c ||
echo "restore of eculine.c failed"
set `wc -c eculine.c`;Wc_c=$1
if test "$Wc_c" != "22750"; then
	echo original size 22750, current size $Wc_c
fi
# ============= eculock.c ==============
echo "x - extracting eculock.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > eculock.c &&
X/* CHK=0xCAB7 */
X#define HONEYDANBER /* means use ASCII pids in lock files */
X#if defined(WHT)
X#define LOG_LOCKS
X#endif
X/*+-----------------------------------------------------------------------
X	eculock.c -- lock file management
X	wht%n4hgf@gatech.edu
X
X  Defined functions:
X	check_utmp()
X	create_lock_file(name)
X	lock_tty()
X	unlock_tty()
X
XLock files under XENIX are supposed to use the direct line name
X(lower-case last letter); we create only the lower-case case, but
Xcheck for both.
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-07-1990-21:23-wht@n4hgf---- 2.80 --- */
X/*+:EDITS:*/
X/*:04-19-1990-03:07-wht@n4hgf-GCC run found unused vars -- rm them */
X/*:03-26-1990-00:46-wht@n4hgf-if EACCES, suggest course of action to user */
X/*:03-25-1990-14:11-wht@n4hgf------ x2.70 ------- */
X/*:03-25-1990-14:05-wht@n4hgf-remove lock file BEFORE returning line to getty */
X/*:11-24-1989-20:21-wht-considerations for UNIX 3.2 utmp */
X/*:11-23-1989-03:11-wht-conditional compile for M_XENIX or M_UNIX */
X/*:11-19-1989-15:39-wht-log more stuff if WHT */
X/*:11-17-1989-23:08-wht-put checks back in for both lock files */
X/*:11-13-1989-16:38-wht-fix chmod problem with new code */
X/*:11-08-1989-17:53-wht-revamp old hacked cruddy strategy */
X/*:11-08-1989-14:51-wht-because they were not chmod 444 */
X/*:10-17-1989-02:58-wht-why is uucp clobbering my lock files ?? */
X/*:07-03-1989-22:57-wht------ x2.00 ----- */
X/*:06-30-1989-01:06-wht-ecuungetty interface SEEMS to be working now */
X/*:06-29-1989-00:42-wht-add ungetty handler */
X/*:06-24-1989-16:52-wht-flush edits --- ecu 1.95 */
X
X#include "ecu.h"
X#include "utmpstatus.h"
X
Xextern int errno;
Xextern char ungetty_ttyname[];
Xextern char lopen_err_str[];
X
X/*+-------------------------------------------------------------------------
X	check_utmp()
Xreturn 0 if line available, else LOPEN code
X--------------------------------------------------------------------------*/
Xint
Xcheck_utmp()
X{
Xregister utstatus;
Xregister status = 0;
X
X	switch(utstatus = utmp_status(shm->Lline))
X	{
X		case US_DIALOUT:	/* enabled for login, currently dialout */
X			status = LOPEN_DIALOUT_IN_USE;
X			break;
X		case US_LOGGEDIN:	/* enabled for login, in use */
X			status = LOPEN_ENABLED_IN_USE;
X			break;
X		case US_NOTFOUND:	/* not in utmp, or getty dead */
X			break;
X		case US_LOGIN:		/* enabled for login, idle */
X			status = ungetty_get_line();
X			break;
X	}
X
X#if defined(LOG_LOCKS)
X{ char s64[64];
X	sprintf(s64,"UTMPCHK %s st=%d ut=%d",shm->Lline,status,utstatus);
X	ecu_log_event(s64);
X}
X#endif
X
X	return(status);
X
X}	/* end of check_utmp */
X
X/*+-----------------------------------------------------------------------
X	void unlock_tty()
X------------------------------------------------------------------------*/
Xvoid
Xunlock_tty()
X{
X	if(LLCKname[0] == 0)
X	{
X		ungetty_return_line();
X		return;
X	}
X
X#ifdef M_UNIX
X	ungetty_return_line();
X	unlink(LLCKname);
X	LLCKname[0] = 0;
X#else
X	unlink(LLCKname);
X	LLCKname[0] = 0;
X	ungetty_return_line();
X#endif
X
X}	/* end of unlock_tty */
X
X/*+-------------------------------------------------------------------------
X	create_lock_file(name)
X--------------------------------------------------------------------------*/
Xint
Xcreate_lock_file(name)
Xchar *name;
X{
Xregister fd;
Xint pid = getpid();
Xchar LTMP_fname[64];
X#if defined(HONEYDANBER)
Xchar pid10str[12];
X
X	sprintf(pid10str,"%10d\n",getpid());
X#endif
X
X	errno = 0;
X	sprintf(LTMP_fname,"/usr/spool/uucp/LTMP.%05d",pid);
X	if((fd = creat(LTMP_fname,0444)) < 0)
X	{
X		if(errno == EACCES)
X			sprintf(lopen_err_str,
X#if defined(M_UNIX)
X			"lock error - try chmod 043777 /usr/spool/uucp"
X#else
X			"lock error - try chmod 0777 /usr/spool/uucp"
X#endif
X			);
X		unlink(LTMP_fname);
X		return(-1);
X	}
X#if defined(HONEYDANBER)
X	write(fd,pid10str,11);
X#else
X	write(fd,(char *)&pid,sizeof(int));
X#endif
X
X	chmod(LTMP_fname,0444);
X	close(fd);
X
X	fd = link(LTMP_fname,name);		/* use 'fd' for link return code */
X	unlink(LTMP_fname);
X	chmod(name,0444);
X
X#if defined(LOG_LOCKS)
X{ char s128[128];
X  extern char *errno_text();
X	sprintf(s128,"CRLOCK %s status=%d errno=%s",name,fd,errno_text(errno));
X	ecu_log_event(s128);
X}
X#endif
X
X	return(fd);
X}	/* end of create_lock_file */
X
X/*+-------------------------------------------------------------------------
X	lock_tty() - create lock files for tty name in 'shm->Lline'
X--------------------------------------------------------------------------*/
Xlock_tty()
X{
Xregister itmp;
X
X	if(itmp = make_lock_name(shm->Lline,LLCKname))
X		return(itmp);
X
X	if(itmp = check_utmp())
X		return(itmp);
X
X#if defined(GETTY_LOCKS_TTY)
X	if(!ungetty_ttyname[0])	/* if getty did not lock line */
X	{
X#endif
X		if(create_lock_file(LLCKname))
X		{
X			if(itmp = is_active_lock(LLCKname))
X			{
X				ungetty_return_line();
X				errno = EACCES; /* for hangup() */
X				return(itmp);
X			}
X			if(create_lock_file(LLCKname))
X			{
X				ungetty_return_line();
X				errno = EACCES; /* for hangup() */
X				return(LOPEN_LCKERR);
X			}
X		}
X#if defined(GETTY_LOCKS_TTY)
X	}
X#endif
X
X	return(0);
X}	/* end of lock_tty */
X
X/* end of eculock.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0507233390 eculock.c &&
chmod 0644 eculock.c ||
echo "restore of eculock.c failed"
set `wc -c eculock.c`;Wc_c=$1
if test "$Wc_c" != "5091"; then
	echo original size 5091, current size $Wc_c
fi
# ============= ecunumrev.c ==============
echo "x - extracting ecunumrev.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ecunumrev.c &&
X/* CHK=0x4B08 */
X/*+-----------------------------------------------------------------------
X	ecunumrev.c
X	wht%n4hgf@gatech.edu
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:05-07-1990-21:23-wht@n4hgf---- 2.80 --- */
X/*:04-19-1990-03:07-wht@n4hgf-GCC run found unused vars -- rm them */
X/*:03-25-1990-14:11-wht@n4hgf------ x2.70 ------- */
X/*:03-23-1990-20:10-wht@n4hgf-x2.70 */
X/*:11-03-1989-16:20-wht----- x2.20 ----- */
X/*:06-24-1989-16:53-wht-flush edits --- ecu 1.95 */
X
X#if defined(M_I286) && !defined(NO_SELECT)
X#define NO_SELECT
X#endif
X
X#ifdef WHT
Xchar *numeric_revision = "twx0.80";
X#else
X#ifdef SCO
Xchar *numeric_revision = "sco2.80";
X#else
Xchar *numeric_revision = "unet2.80";
X#endif
X#endif
X
X#if defined(M_UNIX)
Xchar *revision_modifier = "-386u";
X#else
X#if defined(M_I386)
X#if defined(NO_SELECT)
Xchar *revision_modifier = "-386n";
X#else
Xchar *revision_modifier = "-386s";
X#endif
X#else
Xchar *revision_modifier = "-286n";
X#endif
X#endif
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0509100190 ecunumrev.c &&
chmod 0644 ecunumrev.c ||
echo "restore of ecunumrev.c failed"
set `wc -c ecunumrev.c`;Wc_c=$1
if test "$Wc_c" != "1028"; then
	echo original size 1028, current size $Wc_c
fi
echo "End of part 4, continue with part 5"
exit 0


