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

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

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

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 04 of ecu3
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= ecuicmhelp.c ==============
echo 'x - extracting ecuicmhelp.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuicmhelp.c' &&
X/*+-------------------------------------------------------------------------
X	ecuicmhelp.c -- help for icmd commands
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	calculate_help_right_column()
X	display_help_screen()
X	display_help_stderr(cmd)
X	help_cmd_line_setup(prompt)
X	help_get_cmd()
X	icmd_help(narg,arg)
X	search_cmd_list_pcmd(cmd)
X	show_cmds()
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <curses.h>
X#define OMIT_TERMIO_REFERENCES
X#define STDIO_H_INCLUDED
X#include "ecu.h"
X#define NEED_P_CMD
X#include "ecucmd.h"
X#include "ecukey.h"
X#include "pc_scr.h"
X
X#include "stdio_lint.h"
X
X#define PDAT	"ecuhelp.data"
X
Xextern int rcvr_pid;
X
Xlong start_pos[TOKEN_QUAN];
Xint start_pos_has_been_read = 0;
Xchar help_filename[256] = "";
XFILE *fpdat;		/* help data file */
Xint help_right_column = 0;	/* right column for show_cmds */
Xint help_longest_cmd = 0;
Xint help_longest_descr = 0;
X
X/*+-------------------------------------------------------------------------
X	search_cmd_list_pcmd(cmd)
X--------------------------------------------------------------------------*/
XP_CMD *
Xsearch_cmd_list_pcmd(cmd)
Xregister char *cmd;
X{
Xregister P_CMD *cmd_list = icmd_cmds;
X
X	while(cmd_list->token != -1)
X	{
X		if(minunique(cmd_list->cmd,cmd,cmd_list->min))
X			break;
X		cmd_list++;
X	}
X	if(cmd_list->token == -1)
X		return((P_CMD *)0);
X	else
X		return(cmd_list);
X
X}	/* end of search_cmd_list_pcmd */
X
X/*+-------------------------------------------------------------------------
X	display_help_stderr(cmd)
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_help_stderr(cmd)
Xchar *cmd;
X{
Xregister itmp;
XP_CMD *pcmd;
Xchar buf[128];
X
X	if(! (pcmd = search_cmd_list_pcmd(cmd)))
X	{
X		ff(se,"'%s' is not a valid command\r\n",cmd);
X		return;
X	}
X
X	if(!start_pos[pcmd->token])
X	{
X		ff(se,"no help available for '%s'\r\n",cmd);
X		return;
X	}
X
X	fseek(fpdat,start_pos[pcmd->token],0);
X	ff(se,"\r\n");
X	while(fgets(buf,sizeof(buf),fpdat) != NULL)
X	{
X		itmp = strlen(buf);
X		buf[--itmp] = 0;
X		if(itmp == 0)
X			break;
X		ff(se,"%s\r\n",buf);
X	}
X
X}	/* end of display_help_stderr */
X
X/*+-------------------------------------------------------------------------
X	calculate_help_right_column()
X--------------------------------------------------------------------------*/
Xvoid
Xcalculate_help_right_column()
X{
Xregister itmp;
Xregister P_CMD *pcmd = icmd_cmds;
X
X	if(help_right_column)	/* already bee thru here? */
X		return;				/* ... seems so */
X
X	while(pcmd->token != -1)
X	{
X		if(!*pcmd->descr)
X		{
X			pcmd++;
X			continue;
X		}
X		itmp = strlen(pcmd->cmd);
X		if(itmp > help_longest_cmd)
X			help_longest_cmd = itmp;
X		itmp = strlen(pcmd->descr);
X		if(itmp > help_longest_descr)
X			help_longest_descr = itmp;
X		pcmd++;
X	}
X	help_right_column = 1 + help_longest_cmd + 2 + help_longest_descr + 3;
X
X}	/* end of calculate_help_right_column */
X
X/*+-------------------------------------------------------------------------
X	help_cmd_line_setup(prompt)
X--------------------------------------------------------------------------*/
Xvoid
Xhelp_cmd_line_setup(prompt)
Xchar *prompt;
X{
Xregister icol;
Xint y;
Xint x;
X
X	wmove(stdscr,LINES - 1,0);
X	wstandout(stdscr);
X	waddch(stdscr,' ');
X	waddch(stdscr,' ');
X	waddstr(stdscr,prompt);
X	getyx(stdscr,y,x);
X	for(icol = x; icol < COLS-1; icol++)
X		waddch(stdscr,' ');
X	wmove(stdscr,y,x);
X	wstandend(stdscr);
X	wrefresh(stdscr);
X}	/* end of help_cmd_line_setup */
X
X/*+-------------------------------------------------------------------------
X	char *help_get_cmd()
X--------------------------------------------------------------------------*/
Xchar *
Xhelp_get_cmd()
X{
Xregister y;
Xregister x;
Xstatic char cmd[15];
Xchar delim;
X
X	help_cmd_line_setup("Enter command name (ESC to quit):  ");
X	wstandout(stdscr);
X	getyx(stdscr,y,x);
X	wingets(stdscr,y,x,cmd,sizeof(cmd) - 1,&delim,0);
X	wstandend(stdscr);
X	if((delim == ESC) || (cmd[0] == 0))
X		return((char *)0);
X	else
X		return(cmd);
X}	/* end of help_get_cmd */
X
X/*+-------------------------------------------------------------------------
X	display_help_screen()
Xget user command section choice and display that group of commands
X--------------------------------------------------------------------------*/
Xint
Xdisplay_help_screen()
X{
Xregister itmp;
Xregister P_CMD *pcmd;
Xregister y = 1;
Xregister x = 0;
Xshort cmdclass;
Xchar s80[80];
Xchar **cpptr;
Xstatic char *list[] =
X{
X	"g   - general commands",
X	"c   - communications-related commands",
X	"t   - transfer-related commands",
X	"p   - procedure-related commands",
X    "Esc - exit help",
X	(char *)0
X};
Xstatic char keylist[] = {'g','c','t','p',ESC,0};
X
X
X	wclear(stdscr);
X	wmove(stdscr,0,0);
X	wstandout(stdscr);
X	waddstr(stdscr,"Interactive Command Help");
X	getyx(stdscr,y,x);
X	for(itmp = x; itmp < COLS-1; itmp++)
X		waddch(stdscr,' ');
X	wstandend(stdscr);
X
X	itmp = 6;
X	cpptr = list;
X	while(*cpptr)
X	{
X		wmove(stdscr,itmp++,4);
X		waddstr(stdscr,*cpptr++);
X	}
X	wmove(stdscr,19,4);
X	waddstr(stdscr,"---- press a key -------");
X	switch(winget_single(stdscr,"",keylist) & 0x7F)
X	{
X		case 'g': cmdclass = ccG; break;
X		case 'c': cmdclass = ccC; break;
X		case 't': cmdclass = ccT; break;
X		case 'p': cmdclass = ccP; break;
X		case ESC: return(1); /* <=================== */
X	}
X
X	pcmd = icmd_cmds;
X	y = 1;
X	x = 0;
X	wmove(stdscr,y,x);
X	wclrtobot(stdscr);
X	while(pcmd->token != -1)
X	{
X		if(!*pcmd->descr || (pcmd->cmdclass != cmdclass))
X		{
X			pcmd++;
X			continue;
X		}
X		wmove(stdscr,y,x);
X		strcpy(s80,pcmd->cmd);
X		pad_zstr_to_len(s80,help_longest_cmd + 2);
X		for(itmp = 0; itmp < pcmd->min; itmp++)
X			s80[itmp] = to_upper(s80[itmp]);
X		waddstr(stdscr,s80);
X
X		strcpy(s80,pcmd->descr);
X		pad_zstr_to_len(s80,help_longest_descr + 1);
X		waddstr(stdscr,s80);
X
X		if(!x)
X			waddch(stdscr,(unsigned)sVR);
X		y++;
X		if(y >= LINES - 2)
X		{
X			y = 1;
X			x = help_right_column;
X		}
X		pcmd++;
X	}
X	wmove(stdscr,LINES - 2,0);
X	wstandout(stdscr);
X	waddstr(stdscr,
X"Capitalized portion of listed command sufficient for command recognition");
X	getyx(stdscr,y,x);
X	for(itmp = x; itmp < COLS-1; itmp++)
X		waddch(stdscr,' ');
X	wstandend(stdscr);
X	return(0);
X
X}	/* end of display_help_screen */
X
X/*+-------------------------------------------------------------------------
X	show_cmds()
Xcommands with null descriptions are "undocumented"
X--------------------------------------------------------------------------*/
Xvoid
Xshow_cmds()
X{
Xregister char *cptr;
Xint rcvr_active = (rcvr_pid > 0) || (rcvr_pid == -2);
X
X	if(rcvr_active && (rcvr_pid != -2))
X		kill_rcvr_process(SIGUSR1);
X
X	calculate_help_right_column();
X	windows_start();
X	scrollok(stdscr,0);
X	if(!display_help_screen())
X	{
X		while(cptr = help_get_cmd())
X		{
X			wmove(stdscr,LINES - 1,0);
X			wclrtoeol(stdscr);
X			wrefresh(stdscr);
X			display_help_stderr(cptr);
X			ff(se,"\r\npress return:  ");
X			ttygetc(1);
X			if(display_help_screen())
X				break;
X		}
X	}
X	windows_end(stdscr);
X	redisplay_rcvr_screen();
X	if(rcvr_active)
X		start_rcvr_process(0);
X
X}	/* end of show_cmds */
X
X/*+-------------------------------------------------------------------------
X	icmd_help(narg,arg)
X--------------------------------------------------------------------------*/
Xvoid
Xicmd_help(narg,arg)
Xint narg;
Xchar **arg;
X{
Xregister char *cptr;
Xchar s128[128];
Xchar *getenv();
X
X	ff(se,"\r\n");
X	if(!help_filename[0])
X	{
X		if((cptr = getenv("ECUHELP")) == NULL)
X			sprintf(help_filename,"%s/%s",ECULIBDIR,PDAT);
X		else
X			strcpy(help_filename,cptr);
X	}
X
X	if((fpdat = fopen(help_filename,"r")) == NULL)
X	{
X		perror(help_filename); fputc('\r',se);
X		return;
X	}
X
X	if(!start_pos_has_been_read)
X	{
X		fread((char *)start_pos,sizeof(long),TOKEN_QUAN,fpdat);
X		start_pos_has_been_read = 1;
X	}
X
X	if(narg > 1)
X		display_help_stderr(arg[1]);
X	else
X		show_cmds();
X
X	fclose(fpdat);
X}	/* end of icmd_help */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224222990 'ecuicmhelp.c' &&
chmod 0644 ecuicmhelp.c ||
echo 'restore of ecuicmhelp.c failed'
Wc_c="`wc -c < 'ecuicmhelp.c'`"
test 7848 -eq "$Wc_c" ||
	echo 'ecuicmhelp.c: original size 7848, current size' "$Wc_c"
# ============= ecuicmhist.c ==============
echo 'x - extracting ecuicmhist.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuicmhist.c' &&
X/*+-------------------------------------------------------------------------
X	ecuicmhist.c - ECU interactive command history handler
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	icmd_history_add(icmd_buf)
X	icmd_history_manager(func,newicmd,icmdsize)
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 "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 1224222990 'ecuicmhist.c' &&
chmod 0644 ecuicmhist.c ||
echo 'restore of ecuicmhist.c failed'
Wc_c="`wc -c < 'ecuicmhist.c'`"
test 3336 -eq "$Wc_c" ||
	echo 'ecuicmhist.c: original size 3336, current size' "$Wc_c"
# ============= eculine.c ==============
echo 'x - extracting eculine.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'eculine.c' &&
X/*+-----------------------------------------------------------------------
X	eculine.c -- ECU line handler
X wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	lRTSCTS_control(flag)
X	lbreak()
X	lclear_xmtr_xoff()
X	lclose()
X	ldraino(inflush_flag)
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	process_xmtr_rcvd_char(rchar,echo)
X	set_xon_xoff_by_arg(arg)
X	valid_baud_rate(baud)
X	xon_status()
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 "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	/* with UNIX 3.2.0, nap doesn't work as
X							 * advertized; param MUST be > granularity
X							 * or nap will return immediately
X							 */
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		if(rchar == 0x0A)
X			pputs("\n");
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	ldraino(inflush_flag) - wait for output to drain
X
XIf inflush_flag is set, also flush input after output drains
X--------------------------------------------------------------------------*/
Xvoid
Xldraino(inflush_flag)
Xint inflush_flag;
X{
X	ioctl(shm->Liofd,(inflush_flag) ? TCSETAF : TCSETAW,(char *)&Ltermio);
X
X}	/* end of ldraino */
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	shm->Lxonxoff = Ltermio.c_iflag & (IXON|IXOFF);
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(strncmp(shm->Lline,"/dev/tty",8))
X		return(LOPEN_INVALID);
X	if(!strcmp(shm->Lline,"/dev/tty"))
X		return(LOPEN_INVALID);
X	if(shm->Lline[8] == 'p')
X		return(LOPEN_NOPTY);
X	if(isupper(shm->Lline[itmp - 1]))
X		shm->Lline[itmp - 1] = tolower(shm->Lline[itmp - 1]);
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 | shm->Lxonxoff);
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(500L);
X	shm->Liofd = open(shm->Lline,O_RDWR,0777);
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X	nap(300L);
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	shm->Lxonxoff = Ltermio.c_iflag & (IXON|IXOFF);
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	set_xon_xoff_by_arg(arg)
X--------------------------------------------------------------------------*/
Xint
Xset_xon_xoff_by_arg(arg)
Xchar *arg;
X{
X	if(ulcmpb(arg,"on") < 0)
X		shm->Lxonxoff = IXON | IXOFF;
X	else if(ulcmpb(arg,"off") < 0)
X		shm->Lxonxoff = 0;
X	else if(ulcmpb(arg,"out") < 0)
X		shm->Lxonxoff = IXON;
X	else if(ulcmpb(arg,"in") < 0)
X		shm->Lxonxoff = IXOFF;
X	else
X		return(-1);
X
X	Ltermio.c_iflag &= ~(IXON|IXOFF);
X	Ltermio.c_iflag |= shm->Lxonxoff;
X	ioctl(shm->Liofd,TCSETA,(char *)&Ltermio);
X	return(0);
X
X}	/* end of set_xon_xoff_by_arg */
X
X/*+-------------------------------------------------------------------------
X	xon_status()
X--------------------------------------------------------------------------*/
Xchar *
Xxon_status()
X{
X	switch(shm->Lxonxoff)
X	{
X		case 0            : return("off");
X		case IXON         : return("in off, out on");
X		case        IXOFF : return("in on, out off");
X		case IXON | IXOFF : return("on");
X	}
X	return("logic error");
X}	/* end of xon_status */
X
X/*+-------------------------------------------------------------------------
X	lopen_err_text(lerr)
X--------------------------------------------------------------------------*/
Xchar *
Xlopen_err_text(lerr)
Xint lerr;
X{
Xstatic char lerr_s80[80];
Xchar s32[32];
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:
X			sprintf(s32,"errno %d",errno);
X			sprintf(lerr_s80,"open error (%-.60s)",
X				(errno < sys_nerr) ? sys_errlist[errno] : s32);
X			return(lerr_s80);
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		case LOPEN_NOPTY: return("ptys not supported");
X	}
X	if(lerr > 0)
X		sprintf(lerr_s80,"pid %d using line",lerr);
X	else
X		sprintf(lerr_s80,"unknown line error %d",lerr);
X	return(lerr_s80);
X}	/* end of lopen_err_text */
X
X/* end of eculine.c */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1224223090 'eculine.c' &&
chmod 0644 eculine.c ||
echo 'restore of eculine.c failed'
Wc_c="`wc -c < 'eculine.c'`"
test 23928 -eq "$Wc_c" ||
	echo 'eculine.c: original size 23928, current size' "$Wc_c"
# ============= eculock.c ==============
echo 'x - extracting eculock.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'eculock.c' &&
X#define HONEYDANBER /* means use ASCII pids in lock files */
X#if defined(SHARE_DEBUG)
X#define LOG_LOCKS
X#endif
X/*+-----------------------------------------------------------------------
X	eculock.c -- lock file management
X	wht@n4hgf.Mt-Park.GA.US
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/*: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 "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(getpid(),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(getpid(),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 1224223090 'eculock.c' &&
chmod 0644 eculock.c ||
echo 'restore of eculock.c failed'
Wc_c="`wc -c < 'eculock.c'`"
test 4250 -eq "$Wc_c" ||
	echo 'eculock.c: original size 4250, current size' "$Wc_c"
# ============= ecunumrev.c ==============
echo 'x - extracting ecunumrev.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecunumrev.c' &&
X/*+-----------------------------------------------------------------------
X	ecunumrev.c - revision numbers
X	wht@n4hgf.Mt-Park.GA.US
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#if defined(M_I286) && !defined(NO_SELECT)
X#define NO_SELECT
X#endif
X
X#ifdef WHT
Xchar *numeric_revision = "tw3.00";
X#else
X#ifdef SCO
Xchar *numeric_revision = "sco-3.00";
X#else
Xchar *numeric_revision = "unet-3.00";
X#endif
X#endif
X
X#if defined(M_UNIX)
Xchar *revision_modifier = "-386u wht@n4hgf";
X#else
X#if defined(M_I386)
X#if defined(NO_SELECT)
Xchar *revision_modifier = "-386n wht@n4hgf";
X#else
Xchar *revision_modifier = "-386s wht@n4hgf";
X#endif
X#else
Xchar *revision_modifier = "-286n wht@n4hgf";
X#endif
X#endif
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 1226041490 'ecunumrev.c' &&
chmod 0644 ecunumrev.c ||
echo 'restore of ecunumrev.c failed'
Wc_c="`wc -c < 'ecunumrev.c'`"
test 834 -eq "$Wc_c" ||
	echo 'ecunumrev.c: original size 834, current size' "$Wc_c"
true || echo 'restore of ecuphone.c failed'
echo End of part 4, continue with part 5
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.