From pa.dec.com!decwrl!olivea!uunet!sparky!kent Sun Aug 11 15:42:08 PDT 1991
Article: 2573 of comp.sources.misc
Path: pa.dec.com!decwrl!olivea!uunet!sparky!kent
From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
Newsgroups: comp.sources.misc
Subject: v21i063:  ecu - ECU async comm package rev 3.10, Part11/37
Message-ID: <1991Aug4.015736.8778@sparky.IMD.Sterling.COM>
Date: 4 Aug 91 01:57:36 GMT
References: <csm-v21i053=ecu.215539@sparky.imd.sterling.com>
Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield)
Organization: Sterling Software, IMD
Lines: 2152
Approved: kent@sparky.imd.sterling.com
X-Md4-Signature: 964f9b34e7a52c35a7161ac0afaa8729

Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Posting-number: Volume 21, Issue 63
Archive-name: ecu/part11
Environment: SCO, XENIX, ISC
Supersedes: ecu3: Volume 16, Issue 25-59

---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is ecu310.11 (part 11 of ecu310)
# do not concatenate these parts, unpack them in order with /bin/sh
# file ecuutil.c continued
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 11; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping ecuutil.c'
else
echo 'x - continuing file ecuutil.c'
sed 's/^X//' << 'SHAR_EOF' >> 'ecuutil.c' &&
X	arg_token(parsestr,termchars)
X	ascii_name_to_hex(str3char)
X	ascii_to_hex(ascii)
X	build_arg_array(cmd,arg,arg_max_quan,narg_rtn)
X	build_str_array(str,arg,str_max_quan,nstr_rtn)
X	disp_line_termio(fd,text)
X	disp_stat(st)
X	disp_termio(ttt,text)
X	errno_text(errno)
X	find_shell_chars(command)
X	get_curr_dir(cdir,cdir_max)
X	get_home_dir(home_dir)
X	hex_to_ascii_name(char_val)
X	make_char_graphic(ch,incl_3char)
X	make_dirs(pathname)
X	make_ecu_subdir()
X	mem_cpy(dest,src,len);
X	mkdir(dpath,dmode)
X	mode_map(mode,mode_str)
X	pad_zstr_to_len(zstr,len)
X	perror_errmsg(str)
X	print_cwd(curdir,buf_size)
X	skip_ld_break(zstr)
X	str_token(parsestr,termchars)
X	yes_or_no(strarg)
X
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
X/*:04-16-1991-15:45-wht@n4hgf-gcc cannot use memmove */
X/*:03-18-1991-22:31-wht@n4hgf-ISC 2.2 has mkdir() */
X/*:02-03-1991-14:23-wht@n4hgf-hack workaround for get_home_dir under x286 */
X/*:01-25-1991-16:23-wht@n4hgf-source name wrong in headers */
X/*:12-26-1990-14:32-wht@n4hgf-use memmove or Duff's Device in mem_cpy() */
X/*:12-04-1990-00:58-wht@n4hgf-allow alternating between str/arg_token */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecu.h"
X#include "termecu.h"
X#include "ecufork.h"
X#include "ecukey.h"
X#include <pwd.h>
X
Xchar *getenv();
X
Xextern int errno;
Xextern int rcvr_pid;		/* ==0 if rcvr process, else pid of rcvr */
Xextern char curr_dir[CURR_DIRSIZ];
X
Xchar *str_token_static = (char *)0;
X
Xchar *ascii_ctlstr =
X"NULSOHSTXETXEOTENQACKBELBS HT NL VT FF CR SO SI DLEDC1DC2DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US SP ";
X
X/*+-------------------------------------------------------------------------
X	mem_cpy(dest,src,len) - memcpy() with non-destructive overlapping copy
X
X  use Duff's device for speed if memmove not available
X--------------------------------------------------------------------------*/
Xvoid
Xmem_cpy(dest,src,len)
Xregister char *dest;
Xregister char *src;
Xregister len;
X{
X#if defined(M_UNIX) && !defined(DUFF) /*  && !defined(__GNUC__) */
X	/*
X	 * memmove() clobbers regs that GCC wants to keep
X	 * unless you use at least some of -fcall-save-{ax,bx,cx,dx}
X	 */
X	memmove(dest,src,len);
X#else
X	/*
X	 * for systems without memmove or with compiler that cannot use it
X	 */
X
X	register itmp = (len + 7) / 8;
X	if(dest > src)
X	{
X		dest += len;
X		src += len;
X		switch(len % 8)
X		{
X		case 0:	do{	*--dest = *--src;
X		case 7:		*--dest = *--src;
X		case 6:		*--dest = *--src;
X		case 5:		*--dest = *--src;
X		case 4:		*--dest = *--src;
X		case 3:		*--dest = *--src;
X		case 2:		*--dest = *--src;
X		case 1:		*--dest = *--src;
X			 	}while(--itmp > 0);
X		}
X	}
X	else
X	{
X		switch(len % 8)
X		{
X		case 0:	do{	*dest++ = *src++;
X		case 7:		*dest++ = *src++;
X		case 6:		*dest++ = *src++;
X		case 5:		*dest++ = *src++;
X		case 4:		*dest++ = *src++;
X		case 3:		*dest++ = *src++;
X		case 2:		*dest++ = *src++;
X		case 1:		*dest++ = *src++;
X			 	}while(--itmp > 0);
X		}
X	}
X#endif
X}	/* end of mem_cpy */
X
X/*+-------------------------------------------------------------------------
X	errno_text(err_no)
X--------------------------------------------------------------------------*/
Xchar *
Xerrno_text(err_no)
Xint err_no;
X{
Xstatic char errant[16];
X
X	switch(err_no)
X	{
X		case 0: return("0");
X		case EPERM: return("EPERM");
X		case ENOENT: return("ENOENT");
X		case ESRCH: return("ESRCH");
X		case EINTR: return("EINTR");
X		case EIO: return("EIO");
X		case ENXIO: return("ENXIO");
X		case E2BIG: return("E2BIG");
X		case ENOEXEC: return("ENOEXEC");
X		case EBADF: return("EBADF");
X		case ECHILD: return("ECHILD");
X		case EAGAIN: return("EAGAIN");
X		case ENOMEM: return("ENOMEM");
X		case EACCES: return("EACCES");
X		case EFAULT: return("EFAULT");
X		case ENOTBLK: return("ENOTBLK");
X		case EBUSY: return("EBUSY");
X		case EEXIST: return("EEXIST");
X		case EXDEV: return("EXDEV");
X		case ENODEV: return("ENODEV");
X		case ENOTDIR: return("ENOTDIR");
X		case EISDIR: return("EISDIR");
X		case EINVAL: return("EINVAL");
X		case ENFILE: return("ENFILE");
X		case EMFILE: return("EMFILE");
X		case ENOTTY: return("ENOTTY");
X		case ETXTBSY: return("ETXTBSY");
X		case EFBIG: return("EFBIG");
X		case ENOSPC: return("ENOSPC");
X		case ESPIPE: return("ESPIPE");
X		case EROFS: return("EROFS");
X		case EMLINK: return("EMLINK");
X		case EPIPE: return("EPIPE");
X		case EDOM: return("EDOM");
X		case ERANGE: return("ERANGE");
X		default:
X			sprintf(errant,"E%04u",errno);
X			return(errant);
X	}
X
X}	/* end of errno_text */
X
X/*+-------------------------------------------------------------------------
X	skip_ld_break(zstr) - skip leading spaces and tabs
X--------------------------------------------------------------------------*/
Xchar *
Xskip_ld_break(zstr)
Xregister char *zstr;
X{
X	while(isspace(*zstr))
X		zstr++;
X	return(zstr);
X}	/* end of skip_ld_break */
X
X/*+-------------------------------------------------------------------------
X	strip_trail_break(zstr) - strip leading spaces and tabs
X--------------------------------------------------------------------------*/
Xvoid
Xstrip_trail_break(zstr)
Xchar *zstr;
X{
Xregister int itmp = strlen(zstr);
Xregister char *zptr = zstr + itmp - 1;
X
X	while(itmp && isspace(*zptr))
X	{
X		*zptr-- = 0;
X		itmp--;
X	}
X}	/* end of strip_trail_break */
X
X/*+-----------------------------------------------------------------------
X	pad_zstr_to_len(zstr,len)
X
X  pads with spaces to specified length, unless already longer than
X  len in which case the string is truncated to 'len' characters.
X------------------------------------------------------------------------*/
Xvoid
Xpad_zstr_to_len(zstr,len)
Xchar *zstr;
Xint len;
X{
Xregister izstr;
X
X	izstr = strlen(zstr);
X	if(izstr >= len)
X		zstr[len] = 0;
X	else
X	{
X		while(izstr < len)
X			zstr[izstr++] = 0x20;
X		zstr[izstr] = 0;
X	}
X}	/* end of pad_zstr_to_len */
X
X/*+-----------------------------------------------------------------------
X	arg_token(parsestr,termchars)
X
XGet next token from string parsestr ((char *)0 on 2nd, 3rd, etc.
Xcalls), where tokens are nonempty strings separated by runs of chars
Xfrom termchars.  Writes nulls into parsestr to end tokens.
Xtermchars need not remain constant from call to call.
X
XTreats multiple occurrences of a termchar as one delimiter (does not
Xallow null fields).
X------------------------------------------------------------------------*/
Xchar *
Xarg_token(parsestr,termchars)
Xchar *parsestr;
Xchar *termchars;
X{
Xregister char *parseptr;
Xchar *token;
X
X	if(!parsestr && !str_token_static)
X		return((char *)0);
X
X	if(parsestr)
X		parseptr = parsestr;
X	else
X       parseptr = str_token_static;
X
X	while(*parseptr)
X	{
X		if(!strchr(termchars,*parseptr))
X			break;
X		parseptr++;
X	}
X
X	if(!*parseptr)
X	{
X		str_token_static = (char *)0;
X		return((char *)0);
X	}
X
X	token = parseptr;
X	if(*token == '\'')
X	{
X		token++;
X		parseptr++;
X		while(*parseptr)
X		{
X			if(*parseptr == '\'')
X			{
X				str_token_static = parseptr + 1;
X				*parseptr = 0;
X				return(token);
X			}
X			parseptr++;
X		}
X		str_token_static = (char *)0;
X		return(token);
X	}
X	while(*parseptr)
X	{
X		if(strchr(termchars,*parseptr))
X		{
X			*parseptr = 0;
X			str_token_static = parseptr + 1;
X			while(*str_token_static)
X			{
X				if(!strchr(termchars,*str_token_static))
X					break;
X				str_token_static++;
X			}
X			return(token);
X		}
X		parseptr++;
X	}
X	str_token_static = (char *)0;
X	return(token);
X}	/* end of arg_token */
X
X/*+-------------------------------------------------------------------------
X	build_arg_array(cmd,arg,arg_max_quan,&narg)
X--------------------------------------------------------------------------*/
Xvoid
Xbuild_arg_array(cmd,arg,arg_max_quan,narg_rtn)
Xchar *cmd;
Xchar **arg;
Xint arg_max_quan;
Xint *narg_rtn;
X{
Xregister itmp;
Xregister narg;
X
X	str_token_static = (char *)0;
X	for(itmp = 0; itmp < arg_max_quan; itmp++)
X		arg[itmp] = (char *)0;
X	arg[0] = arg_token(cmd," \t\r\n");
X
X	for(narg = 1; narg < arg_max_quan; ++narg)
X	{
X		if(!(arg[narg] = arg_token((char *)0," \t\r\n"))) 
X			break;
X	}
X
X	*narg_rtn = narg;
X
X}	/* end of build_arg_array */
X
X/*+-----------------------------------------------------------------------
X	str_token(parsestr,termchars)
X
XGet next token from string parsestr ((char *)0 on 2nd, 3rd, etc.
Xcalls), where tokens are nonempty strings separated by runs of chars
Xfrom termchars.  Writes nulls into parsestr to end tokens.
Xtermchars need not remain constant from call to call.
X
XTreats each occurrence of a termchar as delimiter (allows null
Xfields).
X------------------------------------------------------------------------*/
Xchar *
Xstr_token(parsestr,termchars)
Xchar *parsestr;
Xchar *termchars;
X{
Xregister char *termptr;
Xregister char *parseptr;
Xchar *token;
X
X	if(!parsestr && !str_token_static)
X		return((char *)0);
X
X	if(parsestr)
X		parseptr = parsestr;
X	else
X       parseptr = str_token_static;
X
X	while(*parseptr)
X	{
X		for(termptr = termchars; *termptr != 0; termptr++)
X		{
X			if(*parseptr == *termptr)
X				goto FOUND_TERM;
X		}
X		if(!*termptr)
X			break;
X		parseptr++;
X	}
X
X	if(!*parseptr)
X	{
X		str_token_static = (char *)0;
X		return((char *)0);
X	}
X
XFOUND_TERM:
X	token = parseptr;
X	while(*parseptr)
X	{
X		for(termptr = termchars; *termptr;)
X		{
X			if(*parseptr == *termptr++)
X			{
X				str_token_static = parseptr + 1;
X				*parseptr = 0;
X				return(token);
X			}
X		}
X		parseptr++;
X	}
X	str_token_static = (char *)0;
X	return(token);
X}	/* end of str_token */
X
X/*+-------------------------------------------------------------------------
X	build_str_array(str,arg,str_max_quan,&narg)
X--------------------------------------------------------------------------*/
Xvoid
Xbuild_str_array(str,arg,str_max_quan,nstr_rtn)
Xchar *str;
Xchar **arg;
Xint str_max_quan;
Xint *nstr_rtn;
X{
Xregister itmp;
Xregister narg;
X
X
X	str_token_static = (char *)0;
X	for(itmp = 0; itmp < str_max_quan; itmp++)
X		arg[itmp] = (char *)0;
X	arg[0] = str_token(str," \t\r\n");
X
X	for(narg = 1; narg < str_max_quan; ++narg)
X	{
X		if(!(arg[narg] = str_token((char *)0," \t\r\n"))) 
X			break;
X	}
X
X	*nstr_rtn = narg;
X
X}	/* end of build_str_array */
X
X/*+-----------------------------------------------------------------------
X	make_char_graphic(character,incl_3char) - Make all chars "printable"
X
X  returns pointer to a static string containing printable version
X  of a character.  If control char, printed as "^A", etc.
X  if incl_3char set true, then space + ASCII assignment (e.g. "NUL") is
X  appended to the string for non-printable graphics
X------------------------------------------------------------------------*/
Xchar *make_char_graphic(ch,incl_3char)
Xregister char ch;
Xint incl_3char;
X{
Xstatic char gg[16];
X
X	ch &= 0x7F;
X	if((ch >= 0x20) && (ch < 0x7F))
X	{
X		gg[0] = ch; gg[1] = 0;
X	}
X	else
X	{
X		gg[0] = '^'; 
X		if(ch == 0x7F)
X		{
X			gg[1] = '?';
X			if(incl_3char)
X				strcpy(&gg[2]," DEL");
X			else
X				gg[2] = 0;
X		}
X		else
X		{
X			gg[1] = ch + 0x40;
X			if(incl_3char)
X			{
X				gg[2] = 0x20;
X				strncpy(&gg[3],ascii_ctlstr + (ch * 3),3);
X				gg[7] = 0;
X			}
X			else
X				gg[2] = 0;
X		}
X	}
X	return(gg);
X}	/* end of make_char_graphic */
X
X/*+-----------------------------------------------------------------------
X	mode_map(mode,mode_str)	build drwxrwxrwx string
X------------------------------------------------------------------------*/
Xchar *
Xmode_map(mode,mode_str)
Xunsigned short mode;
Xchar *mode_str;
X{
Xregister unsigned ftype = mode & S_IFMT;
Xregister char *rtn;
Xstatic char result[12];
X
X	rtn = (mode_str) ? mode_str : result;
X
X	/*          drwxrwxrwx */
X	/*          0123456789 */
X	strcpy(rtn,"----------");
X
X	switch(ftype)
X	{
X		case S_IFIFO:	*rtn = 'p'; break; /* FIFO (named pipe) */
X		case S_IFDIR:	*rtn = 'd'; break; /* directory */
X		case S_IFCHR:	*rtn = 'c'; break; /* character special */
X		case S_IFBLK:	*rtn = 'b'; break; /* block special */
X		case S_IFREG:	*rtn = '-'; break; /* regular */
X
X#if defined(BSD)
X		case S_IFLNK:	*rtn = 'l'; break; /* symbolic link */
X		case S_IFSOCK:	*rtn = 's'; break; /* socket */
X#endif
X
X#if defined (M_XENIX) || defined(M_UNIX)
X		case S_IFNAM:						/* name space entry */
X			if(mode & S_INSEM)				/* semaphore */
X			{
X				*rtn = 's';
X				break;
X			}
X			if(mode & S_INSHD)				/* shared memory */
X			{
X				*rtn = 'm';
X				break;
X			}
X#endif
X
X		default:		*rtn = '?'; break;	/* ??? */
X	}
X
X	if(mode & 000400) *(rtn + 1) = 'r';
X	if(mode & 000200) *(rtn + 2) = 'w';
X	if(mode & 000100) *(rtn + 3) = 'x';
X	if(mode & 004000) *(rtn + 3) = 's';
X	if(mode & 000040) *(rtn + 4) = 'r';
X	if(mode & 000020) *(rtn + 5) = 'w';
X	if(mode & 000010) *(rtn + 6) = 'x';
X	if(mode & 002000) *(rtn + 6) = 's';
X	if(mode & 000004) *(rtn + 7) = 'r';
X	if(mode & 000002) *(rtn + 8) = 'w';
X	if(mode & 000001) *(rtn + 9) = 'x';
X	if(mode & 001000) *(rtn + 9) = 't';
X
X	return(rtn);
X
X}	/* end of mode_map */
X
X/*+-----------------------------------------------------------------------
X	disp_termio(ttt)
X  display termio 'ttt' on stderr
X------------------------------------------------------------------------*/
Xvoid disp_termio(ttt,text)
Xstruct termio *ttt;
Xchar *text;
X{
Xregister flag;
Xregister i_cc;
Xregister char *cptr;
Xint dbits;
Xchar parity;
X
X	pprintf("---------> %s\n",text);
X
X	flag = ttt->c_iflag;
X	pprintf("iflag: %07o IGNBRK:%d  BRKINT:%d  IGNPAR:%d  PARMRK:%d  INPCK:%d  ISTRIP:%d\n",
X				flag,
X				(flag & IGNBRK) ? 1 : 0,
X				(flag & BRKINT) ? 1 : 0,
X				(flag & IGNPAR) ? 1 : 0,
X				(flag & PARMRK) ? 1 : 0,
X				(flag & INPCK ) ? 1 : 0,
X				(flag & ISTRIP) ? 1 : 0);
X	pprintf(
X"               INLCR:%d  IGNCR:%d  ICRNL:%d  IUCLC:%d  IXON:%d  IXANY:%d  IXOFF:%d\n",
X				(flag & INLCR ) ? 1 : 0,
X				(flag & IGNCR ) ? 1 : 0,
X				(flag & ICRNL ) ? 1 : 0,
X				(flag & IUCLC ) ? 1 : 0,
X				(flag & IXON  ) ? 1 : 0,
X				(flag & IXANY ) ? 1 : 0,
X				(flag & IXOFF ) ? 1 : 0);
X
X	flag = ttt->c_oflag;
X	pprintf("oflag: %07o OPOST:%d  OLCUC:%d  ONLCR:%d  OCRNL:%d  ONOCR:%d  ONLRET:%d  OFDEL:%d\n",
X				flag,
X				(flag & OPOST ) ? 1 : 0,
X				(flag & OLCUC ) ? 1 : 0,
X				(flag & ONLCR ) ? 1 : 0,
X				(flag & OCRNL ) ? 1 : 0,
X				(flag & ONOCR ) ? 1 : 0,
X				(flag & ONLRET) ? 1 : 0,
X				(flag & OFDEL ) ? 1 : 0);
X
X	flag = ttt->c_cflag;
X	pprintf("cflag: %07o ",ttt->c_cflag);
X	switch(flag & CBAUD)
X	{
X		case B0:	cptr = "HUP"; break;
X		case B50:	cptr = "50"; break;
X		case B75:	cptr = "75"; break;
X		case B110:	cptr = "110"; break;
X		case B134:	cptr = "134.5"; break;
X		case B150:	cptr = "150"; break;
X		case B200:	cptr = "200"; break;
X		case B300:	cptr = "300"; break;
X		case B600:	cptr = "600"; break;
X		case B1200:	cptr = "1200"; break;
X		case B1800:	cptr = "1800"; break;
X		case B2400:	cptr = "2400"; break;
X		case B4800:	cptr = "4800"; break;
X		case B9600:	cptr = "9600"; break;
X#if defined(B19200)
X		case B19200:cptr = "19200"; break;
X#endif
X#if defined(B38400)
X		case B38400:cptr = "38400"; break;
X#endif
X		default:	
X			switch(flag & CBAUD)
X			{
X				case EXTA:	cptr = "EXTA"; break;
X				case EXTB:	cptr = "EXTB"; break;
X				default:	cptr = "????"; break;
X			}
X	}
X	dbits = 5 + ((flag & CSIZE) >> 4);
X	parity = (flag & PARENB) ? ((flag & PARODD) ? 'O' : 'E') : 'N';
X	pprintf("%s-%d-%c-%d ",cptr,dbits,parity,(flag & CSTOPB) ? 2 : 1);
X	switch(flag & CS8)
X	{
X		case CS8: pputs("CS8 "); break;
X		case CS7: pputs("CS7 "); break;
X		case CS6: pputs("CS6 "); break;
X		case CS5: pputs("CS5 "); break;
X	}
X	pprintf("CREAD:%d  HUPCL:%d  CLOCAL:%d",
X				(flag & CREAD ) ? 1 : 0,
X				(flag & HUPCL ) ? 1 : 0,
X				(flag & CLOCAL) ? 1 : 0);
X#if defined(RTSFLOW)	/* only SCO */
X	pprintf(" RTSFLOW:%d  CTSFLOW:%d",
X				(flag & RTSFLOW ) ? 1 : 0,
X				(flag & CTSFLOW ) ? 1 : 0);
X#endif
X	pprintf("\n");
X
X	flag = ttt->c_lflag;
X	pprintf("lflag: %07o ISIG:%d  ICANON:%d  XCASE:%d  ECHO:%d  ECHOE:%d\n",
X				flag,
X				(flag & ISIG  ) ? 1 : 0,
X				(flag & ICANON) ? 1 : 0,
X				(flag & XCASE ) ? 1 : 0,
X				(flag & ECHO  ) ? 1 : 0,
X				(flag & ECHOE ) ? 1 : 0);
X	pprintf("            ECHOK:%d  ECHONL:%d  NOFLSH:%d",
X				(flag & ECHOK ) ? 1 : 0,
X				(flag & ECHONL) ? 1 : 0,
X				(flag & NOFLSH) ? 1 : 0);
X
X#if defined(XCLUDE)
X	pprintf("  XCLUDE:%d",(flag & XCLUDE) ? 1 : 0);
X#endif
X	pputs("\n");
X
X	pprintf("ctl chars: ");
X	for(i_cc = 0; i_cc < NCC; i_cc++)
X		pprintf("%02x   ",ttt->c_cc[i_cc]);
X	pprintf("  (hex)\n");
X	pprintf("           INTR QUIT ERAS KILL EOF  EOL  EOL2 SWTCH  VMIN-EOF VTIME-EOL\n");
X
X}	/* end of disp_termio */
X
X/*+-------------------------------------------------------------------------
X	disp_stat(st)
X--------------------------------------------------------------------------*/
Xvoid
Xdisp_stat(st)
Xstruct stat *st;
X{
Xchar mdmap[32];
X	mode_map(st->st_mode,mdmap);
X	pprintf("mode: %s ",mdmap);
X	pprintf("inode: %5u  dev: %3u rdev: %u,%u (0x%04x)\n",
X	    (uint)st->st_ino,(uint)st->st_dev,
X	    (ushort)st->st_rdev >> 8,(ushort)st->st_rdev & 0xFF,
X	    (ushort)st->st_rdev);
X
X}	/* end of disp_stat */
X
X/*+-----------------------------------------------------------------------
X	disp_line_termio(fd)
X
XGet current termio structure for file descriptor fd
Xand display on stderr
X------------------------------------------------------------------------*/
Xvoid
Xdisp_line_termio(fd,text)
Xint fd;		/* file descriptor */
Xchar *text;
X{
Xstruct termio fd_termio;
Xstruct stat fd_stat;
Xchar text2[128];
X
X	ioctl(fd,TCGETA,&fd_termio);
X	sprintf(text2,"fd: %d  %s",fd,text);
X	disp_termio(&fd_termio,text2);
X	fstat(fd,&fd_stat);
X	disp_stat(&fd_stat);
X
X}	/* end of disp_line_termio */
X
X/*+-----------------------------------------------------------------------
X	print_cwd(curdir) print and return current working directory
X------------------------------------------------------------------------*/
Xvoid print_cwd(curdir,buf_size)
Xchar *curdir;
Xint buf_size;
X{
X	ff(se,"%s\r\n",curr_dir);
X	strncpy(curdir,curr_dir,buf_size);
X}	/* end of print_cwd */
X
X/*+-----------------------------------------------------------------------
X	dummy_call() bypass optimizer (call from another module for noop)
X------------------------------------------------------------------------*/
Xvoid dummy_call() { ; }
X
X/*+-----------------------------------------------------------------------
X	ascii_name_to_hex(str3char)
X
X  return value of ascii ctl char name (e.g., "NUL") 0 - 0x1F
X  returns -1 if input not valid
X------------------------------------------------------------------------*/
Xascii_name_to_hex(str3char)
Xchar *str3char;
X{
Xregister char *cptr = ascii_ctlstr;
Xregister intval;
X
X	if(ulcmpb(str3char,"del") < 0)
X		return(127);
X
X	for(intval = 0; intval <= SPACE; intval++)
X	{
X		if(	(to_lower(*str3char) == to_lower(*cptr))				&&
X			(to_lower(*(str3char + 1)) == to_lower(*(cptr + 1)))	&&
X			((to_lower(*(str3char + 2)) == to_lower(*(cptr + 2)))	||
X			(*(cptr + 2) == ' ')))
X		{
X			return(intval);
X		}
X		cptr += 3;
X	}
X
X	return(-1);
X
X}	/* end of ascii_name_to_hex */
X
X/*+-------------------------------------------------------------------------
X	ascii_to_hex(ascii)
X--------------------------------------------------------------------------*/
Xascii_to_hex(ascii)
Xchar *ascii;
X{
Xint hexval;
X	if(strlen(ascii) == 1)
X		return(*ascii);
X	else if(!strncmp(ascii,"0x",2))
X	{
X		sscanf(ascii + 2,"%x",&hexval);
X		return(hexval & 0xFF);
X	}
X	else if(*ascii == '^')
X		return(*(ascii + 1) & 0x1F);
X	else
X		return(ascii_name_to_hex(ascii));
X}	/* end of ascii_to_hex */
X
X/*+-------------------------------------------------------------------------
X	hex_to_ascii_name(char_val)
X
X  Returns pointer to static string containing three character ASCII
X  name for control character followed by a null.
X--------------------------------------------------------------------------*/
Xchar *
Xhex_to_ascii_name(char_val)
Xchar char_val;
X{
Xstatic char ascii_name[4];
X
X	char_val &= 0x7F;
X
X	if(char_val == 0x7F)
X		strcpy(ascii_name,"DEL");
X	else if(char_val > SPACE)
X	{
X		ascii_name[0] = char_val;
X		ascii_name[1] = 0;
X	}
X	else
X	{
X		strncpy(ascii_name,ascii_ctlstr + (char_val * 3),3);
X		ascii_name[3] = 0;
X	}
X
X	return(ascii_name);
X
X}	/* end of hex_to_ascii_name */
X
X/*+-------------------------------------------------------------------------
X	get_curr_dir(cdir,cdir_max) - get current directory into 'cdir'
X--------------------------------------------------------------------------*/
Xint
Xget_curr_dir(cdir,cdir_max)
Xchar *cdir;
Xint cdir_max;
X{
X#if defined(BSD)
Xchar *getwd();
X	strcpy(cdir,".");
X	return((!getwd(cdir)) ? -1 : 0);
X#endif
X
X#if defined(M_XENIX) || defined(M_UNIX)
XFILE *popen();
XFILE *pipefp = popen("/bin/pwd","r");
Xint itmp;
X	strcpy(cdir,".");
X	if(!pipefp)
X		return(-1);
X	fgets(cdir,cdir_max,pipefp);
X	if((itmp = strlen(cdir)) && (*(cdir + itmp - 1) == 0x0A))
X		*(cdir + itmp - 1) = 0;
X	fclose(pipefp);
X	return(0);
X#endif
X
X}	/* end of get_curr_dir */
X
X/*+-----------------------------------------------------------------------
X	get_home_dir(home_dir):  leave plenty of room for result!
X------------------------------------------------------------------------*/
Xget_home_dir(home_dir)
Xchar *home_dir;
X{
Xstatic char home_directory[256] = "";
Xstruct passwd *pwent;
Xchar *cptr;
X
X	if(home_directory[0])
X	{
X		strcpy(home_dir,home_directory);
X		return(0);
X	}
X
X	if(cptr = getenv("HOME"))			/* x286 seems to blow up ... */
X	{									/* ... in pwent code ... hmmm */
X		strcpy(home_directory,cptr);
X		strcpy(home_dir,cptr);
X		return(0);
X	}
X
X	if(!(pwent = getpwuid(getuid())))
X	{
X		pperror("cannot get pwent for you!!");
X		termecu(TERMECU_PWENT_ERROR);
X	}
X	strcpy(home_directory,pwent->pw_dir);
X	strcpy(home_dir,pwent->pw_dir);
X	endpwent();
X	return(0);
X
X}	/* end of get_home_dir */
X
X/*+-------------------------------------------------------------------------
X	make_ecu_subdir()
Xmust be called early in execution before wierd tty states set, etc.
X--------------------------------------------------------------------------*/
Xvoid
Xmake_ecu_subdir()
X{
Xint itmp;
Xstruct stat fst;
Xchar s256[256];
X
X	get_home_dir(s256);
X	strcat(s256,"/.ecu");
X	if((!(itmp = stat(s256,&fst))) && ((fst.st_mode & S_IFMT) != S_IFDIR))
X	{
X		ff(se,"~/.ecu is not a directory. Rename the file and try again.\n\n");
X		exit(1);
X	}
X	if(itmp)		/* if stat failed, try to make the directory */
X	{
X		strcat(s256,"/.");
X		if(make_dirs(s256))
X		{
X			if(stat(s256,&fst))
X			{
X				ff(se,"cannot make ~/.ecu subdirectory.\n");
X				perror(s256);
X				exit(1);
X			}
X		}
X	}
X	chmod(s256,0700);
X}	/* end of make_ecu_subdir */
X
X/*+-------------------------------------------------------------------------
X	yes_or_no(strarg)
X  Returns 1 if first char is 'Y' or 'y'
X	or if strarg is numeric returns the numeric value
X	or if strarg is alpha == "on" returns 1
X  Returns 0 otherwise
X--------------------------------------------------------------------------*/
Xint
Xyes_or_no(strarg)
Xchar *strarg;
X{
X	if((strcmp(strarg,"on") == 0) || (to_lower(*strarg) == 'y'))
X		return(1);
X	else
X		return(atoi(strarg));
X}	/* end of yes_or_no */
X
X/*+-------------------------------------------------------------------------
X	find_shell_chars(command)
X--------------------------------------------------------------------------*/
Xint
Xfind_shell_chars(command)
Xchar *command;
X{
Xregister schar;
Xregister cchar;
Xregister char *scptr;
Xstatic char shell_chars[] = "\"~;*?'`{}[]$";
X
X	while(cchar = *command++)
X	{
X		scptr = shell_chars;
X		while(schar = *scptr++)
X			if(schar == cchar)
X				return(1);
X	}
X	return(0);
X}	/* end of find_shell_chars */
X
X/*+-------------------------------------------------------------------------
X	perror_errmsg(str)
X--------------------------------------------------------------------------*/
Xvoid
Xperror_errmsg(str)
Xchar *str;
X{
Xextern char errmsg[];
Xextern char *sys_errlist[];
Xextern int sys_nerr;
Xextern int errno;
X
X	if(errno > sys_nerr)
X		sprintf(errmsg,"%s: error %d",str,errno);
X	else
X		sprintf(errmsg,"%s: %s",str,sys_errlist[errno]);
X}	/* end of perror_errmsg */
X
X/*+-------------------------------------------------------------------------
X	cfree(p,num,size) - fix bug in XENIX -lmalloc
X--------------------------------------------------------------------------*/
X#if defined(M_XENIX) && defined(XENIX_MALLOC_LIB_BUG)
Xcfree(p,num,size)
Xchar *p;
Xint num;
Xint size;
X{
X	free(p);
X}	/* end of cfree */
X#endif
X
X#if defined(__GNUC__) && !defined(GCC140)
X/*+-------------------------------------------------------------------------
X	defeat_optimize_to_work_around_bug(would_be_optimized)
X
Xwork around for GCC 1.39 optimization bug (see ecufkey.c)
XThis bug was fixed in gcc 1.40
X--------------------------------------------------------------------------*/
Xvoid
Xdefeat_optimize_to_work_around_bug(would_be_optimized)
Xint *would_be_optimized;
X{
X	;	/* do absolutely nothing */
X}	/* end of defeat_optimize_to_work_around_bug */
X
X#endif /* __GNUC__ */
X/* end of ecuutil.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
echo 'File ecuutil.c is complete' &&
$TOUCH -am 0725125791 'ecuutil.c' &&
chmod 0644 ecuutil.c ||
echo 'restore of ecuutil.c failed'
Wc_c="`wc -c < 'ecuutil.c'`"
test 24595 -eq "$Wc_c" ||
	echo 'ecuutil.c: original size 24595, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ecuvmin.h ==============
if test -f 'ecuvmin.h' -a X"$1" != X"-c"; then
	echo 'x - skipping ecuvmin.h (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ecuvmin.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuvmin.h' &&
X/*+-------------------------------------------------------------------------
X	xenixvmin.h  --  set line default VMIN
X	wht@n4hgf.Mt-Park.GA.US
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#if defined(BUILDING_PROTOTYPES)	/* if building lint_args.h ... */
X#define XENIX_VMIN		2	/* ... include vmin handling routines */
X#else
X#define XENIX_VMIN		1	/* this is the real value for vmin */
X#endif
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125791 'ecuvmin.h' &&
chmod 0644 ecuvmin.h ||
echo 'restore of ecuvmin.h failed'
Wc_c="`wc -c < 'ecuvmin.h'`"
test 588 -eq "$Wc_c" ||
	echo 'ecuvmin.h: original size 588, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ecuwinutil.c ==============
if test -f 'ecuwinutil.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ecuwinutil.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ecuwinutil.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuwinutil.c' &&
X/*+-------------------------------------------------------------------------
X	ecuwinutil.c - curses window utilities
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	clear_area(win,y,x,len)
X	clear_area_char(win,y,x,len,fillchar)
X	winbox(win)
X	window_create(title,title_x,tly,tlx,lines,cols)
X	window_setup(win,title,title_x)
X	windows_end(last_win)
X	windows_end_signal()
X	windows_start()
X	winget_single(win,nondelim_list,delim_list)
X	wingets(win,y,x,buf,bufsize,delim,edit)
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "ecucurses.h"
X#include <errno.h>
X#include "ecukey.h"
X#include "ecuxkey.h"
X#include "termecu.h"
X#include "pc_scr.h"
X
X#if !defined(ushort)
X#define ushort unsigned short
X#endif
X#if !defined(uchar)
X#define uchar unsigned char
X#endif
X#if !defined(uint)
X#define uint unsigned int
X#endif
X#if !defined(ulong)
X#define ulong unsigned long
X#endif
X
X#ifdef WHT /* for testing */
Xextern int tty_is_ansi;
X#endif
Xextern int tty_is_multiscreen;
X
Xunsigned char sTL = at_TL;
Xunsigned char sTR = at_TR;
Xunsigned char sBL = at_BL;
Xunsigned char sBR = at_BR;
Xunsigned char sLT = at_LT;
Xunsigned char sRT = at_RT;
Xunsigned char sVR = at_VR;
Xunsigned char sHR = at_HR;
X
Xint windows_active = 0;
Xint ttymode_before_window_start;
X
X/*+-------------------------------------------------------------------------
X	clear_area_char(win,y,x,len,fillchar)
X--------------------------------------------------------------------------*/
Xvoid
Xclear_area_char(win,y,x,len,fillchar)
XWINDOW *win;
Xint y;
Xint x;
Xint len;
Xchar fillchar;
X{
X	wmove(win,y,x);
X	while(len-- > 0)
X		waddch(win,fillchar & 0xFF);
X	wmove(win,y,x);
X
X}	/* end of clear_area_char */
X
X/*+-------------------------------------------------------------------------
X	clear_area(win,y,x,len)
X--------------------------------------------------------------------------*/
Xvoid
Xclear_area(win,y,x,len)
XWINDOW *win;
Xint y;
Xint x;
Xint len;
X{
X	clear_area_char(win,y,x,len,' ');
X}	/* end of clear_area_char */
X
X/*+-------------------------------------------------------------------------
X	windows_start()
X--------------------------------------------------------------------------*/
Xvoid
Xwindows_start()
X{
Xextern int tty_not_char_special;
X
X	if(tty_not_char_special)
X	{
X		errno = ENOTTY;
X		fprintf(stderr,"curses features unavailable when stdin not tty\r\n");
X		termecu(TERMECU_CURSES_ERROR);
X	}
X
X	ttymode_before_window_start = get_ttymode();
X	ttymode(0);
X	if(!initscr())
X	{
X		fprintf(stderr,"curses init failure ... check terminal type\r\n");
X		termecu(TERMECU_CURSES_ERROR);
X	}
X	savetty(); raw(); noecho(); nonl(); clear();
X#if defined(M_TERMINFO)
X	typeahead(-1);
X#endif
X	windows_active = 1;
X
X	if(!tty_is_multiscreen)
X	{
X		sTL = vanilla_TL;
X		sTR = vanilla_TR;
X		sBL = vanilla_BL;
X		sBR = vanilla_BR;
X		sLT = vanilla_LT;
X		sRT = vanilla_RT;
X		sVR = vanilla_VR;
X		sHR = vanilla_HR;
X	}
X
X}	/* end of windows_start */
X
X/*+-------------------------------------------------------------------------
X	windows_end(last_win)
X--------------------------------------------------------------------------*/
Xvoid
Xwindows_end(last_win)
XWINDOW *last_win;
X{
X	if(last_win)
X		wrefresh(last_win);
X/*
X	resetty();
X*/
X	endwin();
X	tcap_cursor(LINES - 1,0);
X	ttymode(ttymode_before_window_start);
X	windows_active = 0;
X}	/* end of windows_end */
X
X/*+-------------------------------------------------------------------------
X	windows_end2()
X--------------------------------------------------------------------------*/
Xvoid
Xwindows_end2()
X{
X	endwin();
X	ttymode(ttymode_before_window_start);
X	windows_active = 0;
X}	/* end of windows_end2 */
X
X/*+-------------------------------------------------------------------------
X	windows_end_signal() -- called by termecu()
X--------------------------------------------------------------------------*/
Xvoid
Xwindows_end_signal()
X{
X	windows_end2();
X}	/* end of windows_end_signal */
X
X/*+-------------------------------------------------------------------------
X	winbox(win)
X--------------------------------------------------------------------------*/
Xvoid
Xwinbox(win)
XWINDOW *win;
X{
X
X	box(win,sVR,sHR);
X	wmove(win,0,0); waddch(win,(unsigned)sTL);
X	wmove(win,win->_maxy - 1,0); waddch(win,(unsigned)sBL);
X	wmove(win,win->_maxy - 1,win->_maxx - 1); waddch(win,(unsigned)sBR);
X	wmove(win,0,win->_maxx - 1); waddch(win,(unsigned)sTR);
X
X}	/* end of winbox */
X
X/*+-------------------------------------------------------------------------
X	window_setup(win,title,title_x)
X--------------------------------------------------------------------------*/
Xvoid
Xwindow_setup(win,title,title_x)
XWINDOW *win;
Xchar *title;
Xint title_x;
X{
Xregister stand = (title_x < 0);
X
X	if(stand)
X		title_x = -title_x;
X
X	touchwin(win);
X	scrollok(win,0);		/* do not scroll */
X	winbox(win);
X	wmove(win,0,title_x);
X	if(stand)
X		wstandout(win);
X	waddch(win,'[');
X	wprintw(win," %s ",title);
X	waddch(win,']');
X	if(stand)
X		wstandend(win);
X}	/* end of window_setup */
X
X/*+-------------------------------------------------------------------------
X	window_create(title,title_x,tly,tlx,lines,cols)
Xif title_x negative, make title "stand" out
X--------------------------------------------------------------------------*/
XWINDOW *
Xwindow_create(title,title_x,tly,tlx,lines,cols)
Xchar *title;
Xint title_x;
Xint tly;
Xint tlx;
Xint lines;
Xint cols;
X{
Xregister WINDOW *nwin = newwin(lines,cols,tly,tlx);
X	
X	if(nwin)
X		window_setup(nwin,title,title_x);
X	else
X	{
X		fprintf(stderr,"\r\ncurses error: cannot create new window\r\n");
X		termecu(TERMECU_CURSES_ERROR);
X	}
X	return(nwin);
X}	/* end of window_create */
X
X/*+-------------------------------------------------------------------------
X	wingets
X numchars = wingets(win,y,x,buf,bufsize,&delim,edit)
X
XThis procedure reads a string from win and returns the number
Xof characters read.
X
XIf edit is non-zero and pstrpos is not null, the inital string
Xposition is set by dereferencing the pointer.
X
XThe terminating delim is returned in 'delim'.
X
XIf pstrpos is not null, the ending string position is returned in
Xthe integer pointed to.
X
X-1 is returned if an ESCape is typed by the keyboard user,
Xotherwise the count of characters in the string.
X
XThe entired line must be contained on one line (no line wrap supported).
X--------------------------------------------------------------------------*/
Xint
Xwingets(win,y,x,buf,bufsize,delim,edit,pstrpos)
XWINDOW *win;
Xint y;
Xregister x;
Xregister char *buf;
Xint bufsize;	/* includes room for null..field is 1 less */
Xregister uchar *delim;
Xint edit;
Xint *pstrpos;
X{
Xregister count = 0;
Xregister pos = 0;
Xint insert_mode = 0;
Xint rtn_val = 0;
X
X	bufsize--;
X	clear_area_char(win,y,x,bufsize,'_');
X	if(edit)
X	{
X		waddstr(win,buf);
X		count = pos = strlen(buf);
X		if(pstrpos)
X		{
X			pos = *pstrpos;
X			if((pos < 0) || (pos > count))
X				pos = count;
X		}
X	}
X	else
X		*buf = 0;
X	wmove(win,y,x + pos);
X
X	while(1)
X	{
X		wrefresh(win);
X		*delim = ttygetc(1);
X		if((*delim < 0x20) || (*delim >= 0x7F))
X		{
X			switch(*delim)
X			{
X				case CRET:
X					*delim = NL;
X				case NL:
X					wrefresh(win);
X					rtn_val = count;
X					goto RETURN;
X
X				case BS:
X					if(count)
X					{
X						if(count == pos)
X						{
X							*(buf + --count) = 0;
X							wmove(win,y,x + count);
X							waddch(win,'_');
X							wmove(win,y,x + count);
X							pos--;
X						}
X						else
X						{
X							if(!pos)
X								continue;
X							mem_cpy(buf + pos - 1,buf + pos,count - pos);
X							*(buf + --count) = 0;
X							wmove(win,y,x + --pos);
X							waddstr(win,buf + pos);
X							waddch(win,'_');
X							wmove(win,y,x + pos);
X						}
X					}
X					continue;
X
X				case XFcurlf:
X					if(pos)
X						wmove(win,y,x + --pos);
X					continue;
X
X				case XFcurrt:
X					if(pos < count)
X						wmove(win,y,x + ++pos);
X					continue;
X
X				case XFins:
X					insert_mode = !insert_mode;
X					continue;
X
X				case ESC:
X					rtn_val = -1;
X					goto RETURN;
X
X				case CTL_U:
X					clear_area_char(win,y,x,bufsize,'_');
X					count = 0;
X					pos = 0;
X					*buf = 0;
X					continue;
X
X				default:
X					*(buf + count) = 0;
X					rtn_val = count;
X					goto RETURN;
X
X			}	/* end of switch(*delim) */
X			/*NOTREACHED*/
X		}		/* end of if read delimiter */
X
X		if(count == bufsize)
X		{
X			ring_bell();
X			continue;
X		}
X
X		if(insert_mode && (pos != count))
X		{
X			waddch(win,*delim);
X			waddstr(win,buf + pos);
X			mem_cpy(buf + pos + 1,buf + pos,count - pos);
X			*(buf + pos++) = *delim;
X			*(buf + ++count) = 0;
X			wmove(win,y,x + pos);
X		}
X		else
X		{
X			waddch(win,*delim);
X			*(buf + pos) = *delim;
X			if(pos == count)
X				*(buf + ++count) = 0;
X			pos++;
X		}
X	}	/* end of while can get character */
X
XRETURN:
X	if(pstrpos)
X		*pstrpos = pos;
X	return(rtn_val);
X
X}	/* end of wingets */
X
X/*+-------------------------------------------------------------------------
X	winget_single(win,nondelim_list,delim_list)
X
XThis procedure assumes cursor is positioned, repeats reading a non-echoing
Xcharacter from the keyboard until it matches a character in nondelim_list
Xor delim_list.  delim_list is expected to contain printable characters
Xand no upper-case characters.
X
XIf no match occurs, the bell is rung and the keyboard is read again.
X
XIf the input character matches a character in delim_list, the index (0-n)
Xof the character in delim_list is returned.  If a match occurs, an
Xupper-case version of the matching character is placed in the window.
X
XIf the input character matches a character in nondelim_list, the character
Xis returned or'ed with 0x1000
X
X--------------------------------------------------------------------------*/
Xint
Xwinget_single(win,nondelim_list,delim_list)
XWINDOW *win;
Xregister char *nondelim_list;
Xregister char *delim_list;
X{
Xregister itmp;
Xregister nlen = strlen(nondelim_list);
Xregister dlen = strlen(delim_list);
Xregister ichar;
X
X	wrefresh(win);
X
X	while(1)
X	{
X		ichar = to_lower(ttygetc(1));
X		for(itmp = 0; itmp < nlen; itmp++)
X		{
X			if(ichar == nondelim_list[itmp])
X			{
X				waddch(win,to_upper(ichar));
X				wrefresh(win);
X				return(itmp);
X			}
X		}
X		for(itmp = 0; itmp < dlen; itmp++)
X		{
X			if(ichar == delim_list[itmp])
X				return(ichar | 0x1000);
X		}
X		ring_bell();
X	}
X
X}	/* end of winget_single */
X
X/* end of ecuwinutil.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125791 'ecuwinutil.c' &&
chmod 0644 ecuwinutil.c ||
echo 'restore of ecuwinutil.c failed'
Wc_c="`wc -c < 'ecuwinutil.c'`"
test 10243 -eq "$Wc_c" ||
	echo 'ecuwinutil.c: original size 10243, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ecuxenix.c ==============
if test -f 'ecuxenix.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ecuxenix.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ecuxenix.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecuxenix.c' &&
X/*+-----------------------------------------------------------------
X	ecuxenix.c -- very machine/OS dependent functions
X	wht@n4hgf.Mt-Park.GA.US
X
X  Defined functions:
X	bell_alarm(xbell_type)
X	bell_notify(xbell_type)
X	kbd_escape(xkey)
X	morse_bell(xbell_type,count)
X	rename(from,to)
X	send_bell_fd(fd,count,nap_msec)
X	send_get_response(token,narg,arg)
X	set_bell_fd(fd,pitch,duration)
X	set_default_escape_prompt()
X	show_escape_prompt()
X	signal_name_text(sig)
X	xbell(type,count)
X	xbell_fd(fd,type,count)
X
X  This module is a grab bag for historical reasons.  Needs reorg.
X------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:57-wht@n4hgf-ECU release 3.10 */
X/*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
X/*:07-14-1991-18:18-wht@n4hgf-new ttygets functions */
X/*:06-29-1991-15:42-wht@n4hgf-if WHT and xterm, play with title bar */
X/*:06-04-1991-13:19-wht@n4hgf-WHT version always gets morse for bells */
X/*:05-07-1991-06:10-wht@n4hgf-subtle changes in send_and_get_response */
X/*:03-18-1991-22:31-wht@n4hgf-ISC 2.2 has rename() */
X/*:01-16-1991-23:54-wht@n4hgf-if WHT, bell_notify always available */
X/*:01-09-1991-22:31-wht@n4hgf-ISC port */
X/*:12-04-1990-03:55-wht@n4hgf-bell_notify only if on multiscreen */
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 "ecukey.h"
X#include "ecufkey.h"
X#include "ecuxkey.h"
X#include "ecutty.h"
X#include "ecufork.h"
X#include "esd.h"
X
X#if defined(MORSE)
X/* the space between # and include prevents make depend from seeing this */
X# include <local/morse_dvr.h>
X#endif
X
Xchar *get_ttyname();
X
Xextern char curr_dir[]; /* current working key defns */
Xextern KDE keyset_table[];
Xextern char keyset_name[];
Xextern int want_bell_notify;	/* want bell notify */
Xextern int rcvr_pid;
Xextern int sigint;
Xextern int tty_is_multiscreen;
X
XESD *icmd_prompt;		/* interactive command prompt */
Xint icmd_prompt_len;
X
X/*+-------------------------------------------------------------------------
X	show_escape_prompt()
Xreturns number of character positions written to screen
X--------------------------------------------------------------------------*/
Xshow_escape_prompt()
X{
Xchar prompt_last;
X
X	prompt_last = 'd';	/* dummy */
X	if(icmd_prompt->cb)
X		prompt_last = *(icmd_prompt->pb + icmd_prompt->cb - 1);
X
X	icmd_prompt_len = 0;
X	shmx_make_rcvr_sleep(1);
X	if(!(colors_current & 0xFFFF0000L) || !(colors_current & 0xFFFFL))
X		setcolor(colors_normal);
X	else
X		setcolor(colors_current);
X	tcap_stand_out();
X	if(icmd_prompt->cb)
X	{
X		ff(se," %s",icmd_prompt->pb);
X		icmd_prompt_len += icmd_prompt->cb + 1;
X	}
X	if(isalnum(prompt_last))
X	{
X		fputs(" %",se);
X		icmd_prompt_len += 2;
X	}
X	tcap_stand_end();
X	fputc(' ',se);
X	icmd_prompt_len++;
X	fflush(so);
X	return(icmd_prompt_len);
X
X}	/* end of show_escape_prompt */
X
X/*+-------------------------------------------------------------------------
X	set_default_escape_prompt()
X--------------------------------------------------------------------------*/
Xvoid
Xset_default_escape_prompt()
X{
Xregister char *cptr;
Xchar *getenv();
X
X	if((cptr = getenv("ECUPROMPT")) != (char *)0)
X	{
X		strncpy(icmd_prompt->pb,cptr,icmd_prompt->maxcb);
X		*(icmd_prompt->pb + icmd_prompt->maxcb - 1) = 0;
X		icmd_prompt->cb = strlen(icmd_prompt->pb);
X		esd_null_terminate(icmd_prompt);
X	}
X
X}	/* end of set_default_escape_prompt */
X
X/*+-------------------------------------------------------------------------
X	kbd_escape() -- xmtr got extended key -- process it
Xreturns(1)
X--------------------------------------------------------------------------*/
Xkbd_escape(xkey)
Xuchar xkey;
X{
Xregister itmp;
Xint ttygets_flags = TG_XDELIM;
Xuchar delim;
Xint strpos;
Xregister backspace_count;
Xregister KDE *tkde;
Xuchar icmd_buf[128];
X
X	if((xkey >= XF_ALTA) && (xkey <= XF_ALTZ))
X	{
X	char alt_key_proc_name[8];
X	char *arg = alt_key_proc_name;
X	int narg = 1;
X	int rcvr_alive = (rcvr_pid > 0);
X		sprintf(alt_key_proc_name,"alt_%c",xkey - XF_ALTA + 'a');
X		if(rcvr_alive)
X			kill_rcvr_process(SIGUSR1);
X		ttymode(2);
X		ttyflush(0);
X		if(do_proc(narg,&arg))
X			ring_bell();
X		sigint = 0;
X		proc_file_reset();
X		ttymode(1);
X		if(rcvr_alive)
X			start_rcvr_process(0);
X		return(1);
X	}
X
X	switch(xkey)
X	{
X		case XFhome:	 /* home key pressed ? */
X			icmd_buf[0] = 0;
X			backspace_count = show_escape_prompt();
X			strpos = 0;
X			icmd_buf[0] = 0;
XGET_ICMD:
X			ttygets(icmd_buf,sizeof(icmd_buf),ttygets_flags,&delim,&strpos);
X			switch(delim)
X			{
X				case XFhome:
X				case XFend:
X				case XFpgup:
X				case XFpgdn:
X				case XFcurup:
X				case XFcurdn:
X					if(icmd_history_manager(delim,icmd_buf,sizeof(icmd_buf)))
X					{
X						ring_bell();
X						ttygets_flags |= 4;
X						goto GET_ICMD;
X					}
X				case ESC:
X				case NL:
X					break;
X				default:
X					ring_bell();
X					ttygets_flags |= 4;
X					goto GET_ICMD;
X			}
X			if((delim == ESC) || !icmd_buf[0])
X			{
X				while(backspace_count--)
X					ff(se,"\b \b");
X				break;
X			}
X			if(icmd(icmd_buf))
X				termecu(TERMECU_OK);
X			break;
X
X		default:
X			if((itmp = xf_to_KDEt(xkey)) < 0)
X			{
X				ring_bell();
X				break;
X			}
X			tkde = &keyset_table[itmp];
X			if((itmp = tkde->count) > 0)
X			{
X			register char *cptr = tkde->str;
X				while(itmp--)
X					lputc(*cptr++);
X			}
X			else if(tkde->count < 0)
X			{
X				switch(tkde->count)
X				{
X					case KACT_LOCAL_SHELL:
X						fputs("\r\n",se);
X						tcap_stand_out();
X						ff(se," local shell in %s ",curr_dir);
X						tcap_stand_end();
X						ff(se,"\r\n");
X						shell("!");
X						break;
X					case KACT_REDISPLAY:
X						redisplay_rcvr_screen();
X				}
X			}
X			else
X				ring_bell();
X			break;
X	}
X	return(1);
X}	/* end of kbd_escape */
X
X/*+-------------------------------------------------------------------------
X	set_bell_fd(fd,pitch,duration)
XExample: 1B 5B 3D 34 30 30 30 3B 31 42 | .[=4000;1B
X--------------------------------------------------------------------------*/
Xvoid
Xset_bell_fd(fd,pitch,duration)
Xint fd;
Xint pitch;
Xint duration;
X{
X#if defined(M_SYSV)
Xchar bell_cmd[32];
X
X	if(!tty_is_multiscreen)
X		return;
X
X	sprintf(bell_cmd,"\033[=%d;%dB",pitch,duration);
X	write(fd,bell_cmd,strlen(bell_cmd));
X#endif
X}	/* end of set_bell_fd */
X
X/*+-------------------------------------------------------------------------
X	send_bell_fd(fd,count,nap_msec)
X--------------------------------------------------------------------------*/
Xvoid
Xsend_bell_fd(fd,count,nap_msec)
Xregister fd;
Xregister count;
Xregister nap_msec;
X{
Xstatic char bellch = 0x07;
X
X	if(count)
X	{
X		while(count--)
X		{
X			write(fd,&bellch,1);	
X			nap((long)nap_msec);
X		}
X	}
X}	/* end of send_bell_fd */
X
X/*+-------------------------------------------------------------------------
X	xbell_fd(fd,type,count)
X--------------------------------------------------------------------------*/
Xvoid
Xxbell_fd(fd,type,count)
Xregister fd;
Xregister type;
Xregister count;
X{
X#if defined(M_SYSV)
Xregister itmp;
X
X	if(!tty_is_multiscreen)
X	{
X		ring_bell();
X		return;
X	}
X
X	if(count)
X	{
X		while(count--)
X		{
X			switch(type)
X			{
X				case XBELL_DONE:		/* octaves */
X					set_bell_fd(fd,1000,1);
X					send_bell_fd(fd,1,100);
X					set_bell_fd(fd,2000,1);
X					send_bell_fd(fd,1,100);
X					set_bell_fd(fd,4000,1);
X					send_bell_fd(fd,1,100);
X					break;
X				case XBELL_ATTENTION:		/* morse .-.-.- ATTENTION */
X					for(itmp = 0; itmp < 3; itmp++)
X					{
X						set_bell_fd(fd,2000,1);
X						send_bell_fd(fd,1,140);
X						set_bell_fd(fd,2000,3);
X						send_bell_fd(fd,1,340);
X					}
X					break;
X				case XBELL_C:		/* morse -.-. C */
X					for(itmp = 0; itmp < 2; itmp++)
X					{
X						set_bell_fd(fd,2000,3);
X						send_bell_fd(fd,1,320);
X						set_bell_fd(fd,2000,1);
X						send_bell_fd(fd,1,120);
X					}
X					break;
X				case XBELL_3T:		/* 3 morse T's */
X					set_bell_fd(fd,2000,3);
X					send_bell_fd(fd,3,460);
X					break;
X				default:
X					set_bell_fd(fd,2000,4);
X					send_bell_fd(fd,1,100);
X					break;
X			}
X		}
X	}
X				
X	set_bell_fd(fd,4000,1);
X#endif	
X}	/* end of xbell_fd */
X
X/*+-------------------------------------------------------------------------
X	morse_bell(xbell_type,count)
X--------------------------------------------------------------------------*/
X#if defined(MORSE)
Xmorse_bell(xbell_type,count)
Xint xbell_type;
Xint count;
X{
Xregister morse_fd;
Xint morse_frequency = 800;
Xchar morse_char;
Xstatic int morse_ticks = 0;
X
X#if !defined(WHT)
X	if(!tty_is_multiscreen)
X	{
X		ring_bell();
X		return(0);
X	}
X#endif
X
X	if(!morse_ticks)
X		morse_ticks = hz / 25;
X
X	if((morse_fd = open("/dev/morse",O_WRONLY,0)) < 0)
X		return(-1);
X
X	ioctl(morse_fd,MORSE_SET_SPEED,&morse_ticks);
X	ioctl(morse_fd,MORSE_SET_FREQUENCY,&morse_frequency);
X	switch(xbell_type)
X	{
X		case XBELL_DONE:
X			morse_char = 'd';
X/*
X			morse_frequency = 400;
X			ioctl(morse_fd,MORSE_SET_FREQUENCY,&morse_frequency);
X*/
X			break;
X		case XBELL_ATTENTION:
X			morse_char = '.';
X			break;
X		case XBELL_C:
X			morse_char = 'c';
X			break;
X		case XBELL_3T:
X			morse_char = 'o';
X			break;
X		default:
X			morse_char = BT;
X			break;
X	}
X	while(count--)
X		write(morse_fd,&morse_char,1);
X	close(morse_fd);
X	return(0);
X}	/* end of morse_bell */
X#endif
X
X/*+-------------------------------------------------------------------------
X	xbell(type,count)
X--------------------------------------------------------------------------*/
Xvoid
Xxbell(type,count)
Xint type;
Xint count;
X{
X#if defined(WHT) && defined(MORSE)
X	if(morse_bell(type,count))
X		ring_bell();
X#else
X	if(!tty_is_multiscreen)
X	{
X		ring_bell();
X		return;
X	}
X
X#if defined(MORSE)
X	if(morse_bell(type,count))
X#endif
X		xbell_fd(1,type,count);
X#endif /* WHT && MORSE */
X
X}	/* end of xbell */
X
X/*+-------------------------------------------------------------------------
X	bell_alarm(xbell_type)
X  ring bell on multiscreens; if morse driver included, use it instead
X--------------------------------------------------------------------------*/
Xint
Xbell_alarm(xbell_type)
Xint xbell_type;
X{
Xregister notify_fd;
Xregister fork_pid;
Xstatic long notify_time = 0L;
Xchar *get_ttyname();
Xchar devname[64];
Xint devnum;
Xint ttnum;
Xlong time();
X
X#if defined(M_SYSV)
X#if !(defined(WHT) && defined(MORSE))
X	if(!tty_is_multiscreen)
X	{
X		ring_bell();
X		return(1);
X	}
X#endif
X
X	ttnum = atoi(get_ttyname() + 8);
X
X/* if happened less than 15 secs ago, forget it */
X	if((time((long *)0) - notify_time) < 15L)
X		return(0);
X
X	notify_time = time((long *)0);
X
X#if defined(MORSE)
X	if(morse_bell(xbell_type,1))
X	{
X#endif
X		if((fork_pid = smart_fork()) != 0)
X		{
X#if defined(FORK_DEBUG)
X			sprintf(devname,"DEBUG bell notify pid %d",fork_pid);
X			ecu_log_event(getpid(),devname);	/* bell notify */
X#endif
X			return(fork_pid > 0);
X		}
X
X		for(devnum = 1; devnum < 13; devnum++)
X		{
X			if(devnum == ttnum)		/* don't bell notify ecu's tty */
X				continue;
X			sprintf(devname,"/dev/tty%02d",devnum);
X			if((notify_fd = open(devname,O_WRONLY,0)) >= 0)
X			{
X				xbell_fd(notify_fd,xbell_type,1);
X				close(notify_fd);
X			}
X		}
X
X		_exit(0);		/* end of child tine (of the fork, naturally) */
X#if defined(MORSE)
X	}
X	/*NOTREACHED*/
X#endif
X#else /* not SCO (M_SYSV) */
X	ring_bell();
X#endif
X	return(1);
X}	/* end of bell_alarm */
X
X/*+-------------------------------------------------------------------------
X	bell_notify(xbell_type)
X--------------------------------------------------------------------------*/
Xvoid
Xbell_notify(xbell_type)
Xint xbell_type;
X{
X#if defined(M_SYSV)
X	if(
X#ifndef WHT
X		tty_is_multiscreen &&
X#endif
X			 want_bell_notify)
X	{
X		bell_alarm(xbell_type);
X	}
X#endif
X}	/* end of bell_notify */
X
X/*+-------------------------------------------------------------------------
X	signal_name_text(sig)
X--------------------------------------------------------------------------*/
Xchar *
Xsignal_name_text(sig)
Xint sig;
X{
Xregister char *cptr;
Xstatic char sigunknown[20];
X
X	sig &= 0x7F;
X	switch(sig)
X	{
X		case SIGHUP:	cptr = "SIGHUP"; break;
X		case SIGINT:	cptr = "SIGINT"; break;
X		case SIGQUIT:	cptr = "SIGQUIT"; break;
X		case SIGILL:	cptr = "SIGILL"; break;
X		case SIGTRAP:	cptr = "SIGTRAP"; break;
X#ifdef SIGABRT
X		case SIGABRT:	cptr = "SIGABRT"; break;
X#else
X		case SIGIOT:	cptr = "SIGIOT"; break;
X#endif
X		case SIGEMT:	cptr = "SIGEMT"; break;
X		case SIGFPE:	cptr = "SIGFPE"; break;
X		case SIGKILL:	cptr = "SIGKILL"; break;
X		case SIGBUS:	cptr = "SIGBUS"; break;
X		case SIGSEGV:	cptr = "SIGSEGV"; break;
X		case SIGSYS:	cptr = "SIGSYS"; break;
X		case SIGPIPE:	cptr = "SIGPIPE"; break;
X		case SIGALRM:	cptr = "SIGALRM"; break;
X		case SIGTERM:	cptr = "SIGTERM"; break;
X		case SIGUSR1:	cptr = "SIGUSR1"; break;
X		case SIGUSR2:	cptr = "SIGUSR2"; break;
X		case SIGCLD:	cptr = "SIGCLD"; break;
X		case SIGPWR:	cptr = "SIGPWR"; break;
X#if	defined(SIGSTOP)
X		case SIGSTOP:   cptr = "SIGSTOP"; break;
X#endif
X#if	defined(SIGTSOP)
X		case SIGTSTP:   cptr = "SIGTSTP"; break;
X#endif
X#if	defined(SIGCONT)
X		case SIGCONT:   cptr = "SIGCONT"; break;
X#endif
X#if	defined(SIGTTIN)
X		case SIGTTIN:   cptr = "SIGTTIN"; break;
X#endif
X#if	defined(SIGTTOU)
X		case SIGTTOU:   cptr = "SIGTTOU"; break;
X#endif
X		default:
X			sprintf(sigunknown,"SIGNAL %u",sig);
X			return(sigunknown);
X	}
X	return(cptr);
X
X}	/* end of signal_name_text */
X
X/*+-------------------------------------------------------------------------
X	rename(from,to)
X--------------------------------------------------------------------------*/
X#if !defined(M_UNIX) && !defined(BUILDING_LINT_ARGS)
Xrename(from,to)
Xchar *from;
Xchar *to;
X{
Xstruct stat ss;
Xint save_errno;
Xextern int errno;
X
X	if(!stat(to,&ss))	/* if to exists, flunk */
X	{
X		errno = EEXIST;	/* fake "file exists" error */
X		return(-1);
X	}
X
X	if(link(from,to))	/* if cannot link, flunk */
X		return(-1);
X
X	if(unlink(from))	/* if cannot unlink, flunk */
X	{
X		save_errno = errno;
X		unlink(to);
X		errno = save_errno;
X		return(-1);
X	}
X
X	return(0);
X
X}	/* end of rename */
X#endif
X
X/*+-------------------------------------------------------------------------
X	send_get_response(token,narg,arg) - send a string, get and log response
X--------------------------------------------------------------------------*/
SHAR_EOF
true || echo 'restore of ecuxenix.c failed'
fi
echo 'End of ecu310 part 11'
echo 'File ecuxenix.c is continued in part 12'
echo 12 > _shar_seq_.tmp
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.


