From pa.dec.com!decwrl!uunet!sparky!kent Sun Aug 11 15:48:59 PDT 1991
Article: 2590 of comp.sources.misc
Newsgroups: comp.sources.misc
Path: pa.dec.com!decwrl!uunet!sparky!kent
From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Subject:  v21i080:  ecu - ECU async comm package rev 3.10, Part28/37
Message-ID: <1991Aug5.211838.8098@sparky.IMD.Sterling.COM>
X-Md4-Signature: e117c15802bf0a745734474813daa96f
Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield)
Organization: Sterling Software, IMD
References: <csm-v21i053=ecu.215539@sparky.imd.sterling.com>
Date: Mon, 5 Aug 1991 21:18:38 GMT
Approved: kent@sparky.imd.sterling.com
Lines: 1485

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

---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is ecu310.28 (part 28 of ecu310)
# do not concatenate these parts, unpack them in order with /bin/sh
# file gendial/gendial.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" != 28; 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 gendial/gendial.c'
else
echo 'x - continuing file gendial/gendial.c'
sed 's/^X//' << 'SHAR_EOF' >> 'gendial/gendial.c' &&
X  display termio 'ttt' on se
X------------------------------------------------------------------------*/
Xvoid
Xdisplay_termio(ttt,text)
Xstruct termio *ttt;
Xchar *text;
X{
Xregister flag;
Xregister i_cc;
Xregister char *cptr;
Xint dbits;
Xchar parity;
X
X	ff(se,"----->> %s\n",text);
X
X	flag = ttt->c_iflag;
X	ff(se,
X"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	ff(se,
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	ff(se,
X"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	ff(se,"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		case EXTA:	cptr = "EXTA(19200?)"; break;
X		case EXTB:	cptr = "EXTB(38400?)"; break;
X		default:	cptr = "????"; break;
X	}
X	dbits = 5 + ((flag & CSIZE) >> 4);
X	parity = (flag & PARENB) ? ((flag & PARODD) ? 'O' : 'E') : 'N';
X	ff(se,"%s-%d-%c-%d ",cptr,dbits,parity,(flag & CSTOPB) ? 2 : 1);
X	switch(flag & CS8)
X	{
X		case CS8: fputs("CS8 ",se); break;
X		case CS7: fputs("CS7 ",se); break;
X		case CS6: fputs("CS6 ",se); break;
X		case CS5: fputs("CS5 ",se); break;
X	}
X	ff(se,"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)
X	ff(se," RTSFLOW:%d  CTSFLOW:%d",
X				(flag & RTSFLOW ) ? 1 : 0,
X				(flag & CTSFLOW ) ? 1 : 0);
X#endif
X	ff(se,"\n");
X
X	flag = ttt->c_lflag;
X	ff(se,"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	ff(se,"       ECHOK:%d  ECHONL:%d  NOFLSH:%d  XCLUDE:%d\n",
X				(flag & ECHOK ) ? 1 : 0,
X				(flag & ECHONL) ? 1 : 0,
X				(flag & NOFLSH) ? 1 : 0,
X				(flag & XCLUDE) ? 1 : 0);
X
X	ff(se,
X"           INTR QUIT ERAS KILL EOF  EOL  EOL2 SWTCH VMIN==EOF VTIME==EOL\n");
X	ff(se,"ctl chars: ");
X	for(i_cc = 0; i_cc < NCC; i_cc++)
X		ff(se,"%02x   ",ttt->c_cc[i_cc]);
X	ff(se,"  (hex)\n");
X
X}	/* end of display_termio */
X
X/*+-------------------------------------------------------------------------
X	open_dce() - open the dce_name (DCE)
Xplugs global 'fddce' and returns fd of open DCE line
X--------------------------------------------------------------------------*/
Xint
Xopen_dce()
X{
Xint fd1;
Xint fd2;
X
X	/*  open with O_NDELAY set or the open probably will hang */
X	if((fd1 = open(dce_name,O_RDWR | O_NDELAY)) < 0)
X	{
X		ff(se,"%s: Can't open device: %s\n",*gargv,dce_name);
X		myexit(RC_FAIL | RCE_OPEN | DialerExitCode);
X	}
X
X	ioctl(fd1,TCGETA,&dce_termio);
X	dce_termio.c_oflag = 0;
X	dce_termio.c_iflag = 0;
X	dce_termio.c_cflag &= ~(CBAUD | HUPCL);
X	dce_termio.c_cflag |= CLOCAL		|
X		((hangup_flag) ? HUPCL : 0)		|
X		((hangup_flag && DCE_hangup_CBAUD) ? DCE_hangup_CBAUD : hiCBAUD);
X	dce_termio.c_lflag &= ~ECHO;
X	dce_termio.c_cc[VMIN] = 1;
X	dce_termio.c_cc[VTIME] = 0;
X
X	if (Debug >= 10)
X		display_termio(&dce_termio,"setting line termio");
X
X	if(status = ioctl(fd1,TCSETA,&dce_termio))
X	{
X		DEBUG(1,"%s: ioctl error on %s",dce_name);
X		DEBUG(1,"%s",dce_name);
X		DEBUG(1," errno=%d\n",errno);
X		cleanup(RC_FAIL | RCE_IOCTL | DialerExitCode);
X	}
X
X	/* reopen line without O_NDELAY */
X	fd2 = fd1;
X	if((fd1 = open(dce_name,O_RDWR)) < 0)
X	{
X		ff(se,"%s: Can't open device w/o O_NDELAY: %s\n",*gargv,dce_name);
X		myexit(RC_FAIL | RCE_OPEN | DialerExitCode);
X	}
X	close(fd2);
X
X	ioctl(fd1,TCFLSH,2);		/* flush any residue in clists */
X	fddce = fd1;				/* save fd in global */
X	return(fd1);
X
X}	/* end of open_dce */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv)
X--------------------------------------------------------------------------*/
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
Xint itmp;
Xint unrecognized_switches = 0;
Xchar *cptr;
Xlong startsec;
Xextern int optind;
Xextern int opterr;
Xextern char *optarg;
X
X	setbuf(stderr,NULL);
X	setbuf(stdout,NULL);
X
X/* security considerations */
X	uid = getuid();
X	uid_uucp = get_uucp_uid();
X	secure = 0;
X	if(!strncmp(argv[0],"ECU",3))
X		ecu_calling = 1;
X
X	gargv = argv;
X	gargc = argc;
X
X	signal(SIGILL,dial_abort);
X	signal(SIGIOT,dial_abort);
X	signal(SIGEMT,dial_abort);
X	signal(SIGFPE,dial_abort);
X	signal(SIGBUS,dial_abort);
X	signal(SIGSEGV,dial_abort);
X	signal(SIGSYS,dial_abort);
X	signal(SIGTERM,dial_abort);
X	signal(SIGINT,dial_abort);
X
X	opterr = 0;	
X	while((itmp = getopt(argc,argv,"hx:")) != EOF)
X	{
X		switch(itmp)
X		{
X			case 'h':
X				hangup_flag++;
X				break;
X			case 'x':
X				Debug = atoi(optarg);
X				break;
X			case '?':	/* dialer-specific code may want to handle these */
X				unrecognized_switches++;
X				break;
X		}
X	}
X
X/* announce who we are and our arguments if debugging */
X	if(Debug > 1)
X	{
X		ff(se,"\ngeneric dialer %s (%s %s)\n",revision,
X			DCE_name,DCE_revision);
X		if(ecu_calling || !uid)
X		{
X			ff(se,"(args ");
X			for(itmp = 0; itmp < argc; itmp++)
X				ff(se,"%s ",argv[itmp]);
X			fputs(")\n",se);
X		}
X		if(Debug >= 8)
X			ff(se,"uid = %d  euid=%d\n",uid,geteuid());
X	}
X
X	chdir("/usr/spool/uucp");	/* in case of core dump */
X
X	/* give DCE-specific code a chance at the entire command line */
X	if(status = DCE_argv_hook(argc,argv,optind,unrecognized_switches))
X	{
X		DEBUG(1,"dialer failed: %s\n",RCE_text(status));
X		exit(status);
X	}
X
X/* check argument count */
X	if(hangup_flag)
X	{
X		if((argc - optind) != 2)
X			status++;
X	}
X	else if((argc - optind) != 3)
X		status++;
X
X/* die with usage if argument error */
X	if(status)
X	{
X		if(hangup_flag)
X			ff(se,"Usage: %s -h devicename speed\n",argv[0]);
X		else
X			ff(se,"Usage: %s devicename number speed\n",argv[0]);
X		myexit(RC_FAIL | RCE_ARGS);
X	}
X
X/* if called with "ttyxx" style ttyname, convert to "/dev/ttyxx" */
X	cptr = argv[optind++];
X	if(!strncmp(cptr,"tty",3))
X	{
X	char s32[32];
X		strcpy(s32,"/dev/");
X		strcat(s32,cptr);
X		dce_name = strdup(s32);
X	}
X	else
X		dce_name = cptr;
X
X/* save phone number */
X	if(!hangup_flag)
X		telno = argv[optind++];
X
X/* get baud rates (validated by DCE-dependent code) */
X	loCBAUD = hiCBAUD = DCE_baud_to_CBAUD(atoi(argv[optind]));
X	if(cptr = strchr(argv[optind],'-'))
X		hiCBAUD = DCE_baud_to_CBAUD(atoi(++cptr));
X
X	(void)open_dce();	/* open the line */
X
X/*   H A N G U P     R E Q U E S T   */
X	if(hangup_flag)
X	{
X		if(call_ungetty('t') != UG_RESTART)
X			cleanup(SUCCESS);
X		DCE_hangup();
X		cleanup((call_ungetty('r')) ? RC_FAIL : SUCCESS );
X	}
X
X/*   D I A L    R E Q U E S T    */
X
X	switch(call_ungetty('a'))
X	{
X		case UG_NOTENAB:	/* line acquired: not enabled */
X			status = SUCCESS;
X			break;
X		case UG_ENAB:		/* line acquired: need ungetty -r when done */
X			status = RC_ENABLED;
X			break;
X		case UG_FAIL:		/* could not acquire line */
X			myexit(RC_FAIL | RCE_INUSE);
X		case 255:
X			myexit(RC_FAIL | RCE_NULL);
X	}
X
X	/*
X	 * indicate we are dialing
X	 * record the time and, oh yeah, dial
X	 */
X	dialing = 1;
X	time(&startsec);
X	status = DCE_dial(telno);		/* if dial succeeded ... */
X	if(Debug >= 2)
X	{
X		ff(se,"connect %s after %ld seconds\n",
X			(status) ? "FAILED" : "succeeded",
X			time((long *)0) - startsec);
X	}
X
X	/*
X	 * success or not
X	 */
X	myexit(((status) ? RC_FAIL : 0) | status);
X}	/* end of main */
X
X/* end of gendial.c */
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
echo 'File gendial/gendial.c is complete' &&
$TOUCH -am 0725125891 'gendial/gendial.c' &&
chmod 0644 gendial/gendial.c ||
echo 'restore of gendial/gendial.c failed'
Wc_c="`wc -c < 'gendial/gendial.c'`"
test 26443 -eq "$Wc_c" ||
	echo 'gendial/gendial.c: original size 26443, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= gendial/template.c ==============
if test -f 'gendial/template.c' -a X"$1" != X"-c"; then
	echo 'x - skipping gendial/template.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting gendial/template.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gendial/template.c' &&
X/*+-------------------------------------------------------------------------
X	template.c - DCE-specific portion of generic SCO UUCP dialer
X	wht@n4hgf.Mt-Park.GA.US
X
X Necessary DCE switch setting or other configuration:
X   Switch foo off: enable onhook upon loss of DTR
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include "dialer.h"
X
X/*
X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
X *                    sees the transition; this value may be changed
X *                    as necessary before each call to ltoggleDTR(),
X * but, generally, a constant value will do.
X */
Xlong DCE_DTR_low_msec = 500;
X
X/*
X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
X *                     DCE may be expected to be ready to be commanded
X */
Xlong DCE_DTR_high_msec = 500;
X
X/*
X * DCE_write_pase_msec - milliseconds to pause between each character
X *                       sent to the DCE (zero if streaming I/O is
X *                       permitted); this value may be changed as
X * necessary before each call to lwrite(), but, generally, a constant
X * value will do.  Note that this value is used to feed a value to nap(),
X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
X * and .050 seconds on XENIX/86.
X */
Xlong DCE_write_pace_msec = 20;
X
X/*
X * DCE_name     - short name for DCE
X * DCE_revision - revision number for this module
X */
Xchar *DCE_name = "Frobozz 9600";
Xchar *DCE_revision = "1.10";
X
X/*
X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
X *                    and readying it for dial in access
X *                    (BXXX mask); use a value of zero if the speed
X *                    specified by the invoker is to be used.
X * This value is useful for DCEs such as the early Hayes 2400
X * which are so unfortunately compatible with their 1200 predecessor
X * that they refuse to answer at 2400 baud unless you last spoke to
X * them at that rate. For such bad boys, use B2400 below.
X */
Xint DCE_hangup_CBAUD = 0;
X/* int DCE_hangup_CBAUD = B2400; */
X
X/*
X * DCE_results - a table of DCE response strings and a token
X *               code for each; when you call lread() or lread_ignore(),
X *               if the read routine detects one of the strings,
X * the appropriate code is returned.  If no string matches, then
X * lread()/lread_ignore examines the DCE result string for a
X * numeric value; if one is found, the numeric value or'd with
X * 0x4000 is returned (in this way, e.g., you can read "modem
X * S registers."  If nothing agrees with this search, lread()
X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
X * This module is the only consumer  of the codes, although they
X * are decoded by gendial.c's _lread()
X */
X#define rfConnect		0x00400000
X
X#define rOk				0
X#define rNoCarrier		1
X#define rError			2
X#define rNoDialTone		3
X#define rBusy			4
X#define rNoAnswer		5
X#define rRring			6
X#define rConnect300		(7 | rfConnect)
X#define rConnect1200	(8 | rfConnect)
X#define rConnect2400	(9 | rfConnect)
X
XDCE_RESULT DCE_results[] =
X{
X	{ "OK",						rOk,			},
X	{ "NO CARRIER",				rNoCarrier,		},
X	{ "ERROR",					rError			},
X	{ "NO DIALTONE",			rNoDialTone,	},
X	{ "BUSY",					rBusy			},
X	{ "NO ANSWER",				rNoAnswer		},
X	{ "CONNECT",				rConnect300		},
X	{ "CONNECT 1200",			rConnect120		},
X	{ "CONNECT 2400",			rConnect2400	},
X	{ (char *)0,				-1				}		/* end table */
X};
X
X/*+-------------------------------------------------------------------------
X	DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
X
X  DCE dependent function must validate baud rates supported by DCE
X  returns baud rate in struct termio c_cflag fashion
X  or terminates program with error
X--------------------------------------------------------------------------*/
Xint
XDCE_baud_to_CBAUD(baud)
Xunsigned int baud;
X{
X	switch(baud)
X	{
X		case 50:   return(B50);		/* delete the ones you dont handle */
X		case 75:   return(B75);
X		case 110:  return(B110);
X		case 134:  return(B134);
X		case 150:  return(B150);
X		case 300:  return(B300);
X		case 1200: return(B1200);
X		case 2400: return(B2400);
X		case 4800: return(B4800);
X		case 9600: return(B9600);
X
X#if defined(B19200)
X		case 19200: return(B19200);
X#else
X#ifdef EXTA
X		case 19200: return(EXTA);
X#endif
X#endif
X
X#if defined(B38400)
X		case 38400: return(B38400);
X#else
X#ifdef EXTB
X		case 38400: return(EXTB);
X#endif
X#endif
X
X	}
X	myexit(RC_FAIL | RCE_SPEED);
X}	/* end of DCE_baud_to_CBAUD */
X
X/*+-------------------------------------------------------------------------
X	DCE_hangup() - issue hangup command to DCE
X
XThis function should do whatever is necessary to ensure
X1) any active connection is terminated
X2) the DCE is ready to receive an incoming call if DTR is asserted
X3) the DCE will not accept an incoming call if DTR is false
X
XThe function should return when done.
X
XAny necessary switch setting or other configuration necessary for this
Xfunction to succeed should be documented at the top of the module.
X--------------------------------------------------------------------------*/
Xvoid
XDCE_hangup()
X{
X	DEBUG(3,"--> reseting %s\n",DCE_name);
X
X}	/* end of DCE_hangup */
X
X/*+-------------------------------------------------------------------------
X	DCE_dial(telno) - dial a remote DCE
X
XThis function should connect to the remote DCE and use any success
Xindication to modify the tty baud rate if necessary before returning.
X
XUpon successful connection, return 0.
X
XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
XRCE_XXX value from dialer.h.
X
Xlwrite() is used to write to the DCE.
X
Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
Xfrom calling lread() will result automatically in the proper error
Xtermination of the program.  Read timeouts from calling lread_ignore()
Xreturn -1; you handle the execption here.
X
XAny necessary coding of phone numbers, switch settings or other
Xconfiguration necessary for this function to succeed should be
Xdocumented at the top of the module.
X--------------------------------------------------------------------------*/
Xint
XDCE_dial(telno)
Xchar *telno;
X{
Xchar cmd[80];
X
X/* preliminary setup */
X
X/* if root, let him see number, otherwise just say "remote system" */
X	DEBUG(1,"DIALING %s\n", (uid) ? "remote system" : telno);
X
X/* indicate non-root should not see DTE->DCE traffic */
X	secure = 1;
X
X/* issue the actual dialing command */
X
X/* indicate non-root can see DTE->DCE traffic */
X	secure = 0;
X
X	return(0);		/* succeeded */
X
X}	/* end of DCE_dial */
X
X/**********************************************************
X*  You probably do not need to modify the code below here *
X**********************************************************/
X
X/*+-------------------------------------------------------------------------
X	DCE_abort(sig) - dial attempt aborted
X
X sig =  0 if non-signal abort (read timeout, most likely)
X     != 0 if non-SIGALRM signal caught
X
X extern int dialing set  1 if dialing request was active,
X                    else 0 if hangup request was active
X
XThis is a chance for the DCE-specific code to do anything it
Xneeds to cl,ean up after a failure.  Note that if a dialing
Xcall fails, it is the responsibility of the higher-level
Xprogram calling the dialer to call it again with a hangup request, so
Xthis function is usually a no-op.
X--------------------------------------------------------------------------*/
Xvoid
XDCE_abort(sig)
Xint sig;
X{
X	DEBUG(10,"DCE_abort(%d);\n",sig);
X}	/* end of DCE_abort */
X
X/*+-------------------------------------------------------------------------
X	DCE_exit(exitcode) - "last chance for gas" in this incarnation
X
XThe independent portion of the dialer program calls this routine in
Xlieu of exit() in every case except one (see DCE_argv_hook() below).
XNormally, this function just passes it's argument to exit(), but
Xany necessary post-processing can be done.  The function must,
Xhowever, eventually call exit(exitcode);
X--------------------------------------------------------------------------*/
Xvoid
XDCE_exit(exitcode)
Xint exitcode;
X{
X	DEBUG(10,"DCE_exit(%d);\n",exitcode);
X	exit(exitcode);
X}	/* end of DCE_exit */
X
X/*+-------------------------------------------------------------------------
X	DCE_argv_hook(argc,argv,optind,unrecognized_switches)
X
XThis hook gives DCE-specific code a chance to look over the entire
Xcommand line, such as for -z Telebit processing.
X
Xargc andf argv are the same values passed to main(),
X
Xoptind is the value of optind at the end of normal getopt processing.
X
Xunrecognized_switches is the count of switches not handled by main().
XSpecifically, -h and -x are standard switches.
X
XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
Xany unrecognized switches, otherwise zero.  If you keep your nose clean
Xthough, you can do anything you need to do here and exit the program.
X
XNote: only simple switches (with no argument) may be used with this
Xfacility if the functrion is to return,' since main()'s getopt() will
Xstop processing switches if it runs into an unrecognized switch with an
Xargument.
X
XIf the function returns a non-zero value, then the value will be passed
XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
Xof the format expected by dialer program callers, with RC_FAIL set as a
Xminimum.
X--------------------------------------------------------------------------*/
Xint
XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
Xint argc;
Xchar **argv;
Xint optind;
Xint unrecognized_switches;
X{
X	if(unrecognized_switches)
X		return(RC_FAIL | RCE_ARGS);
X	return(0);
X}	/* end of DCE_argv_hook */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
$TOUCH -am 0725125891 'gendial/template.c' &&
chmod 0644 gendial/template.c ||
echo 'restore of gendial/template.c failed'
Wc_c="`wc -c < 'gendial/template.c'`"
test 9776 -eq "$Wc_c" ||
	echo 'gendial/template.c: original size 9776, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/Makefile ==============
if test ! -d 'fasi'; then
    echo 'x - creating directory fasi'
    mkdir 'fasi'
fi
if test -f 'fasi/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/Makefile (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/Makefile' &&
X# FAS 2.08/FASI 1.00 Makefile for SCO UNIX SYS V/386
X#+:EDITS:
X#:01-17-1991-01:38-wht@n4hgf-adapt FAS 2.08 SCO make file
X
XSHELL = /bin/sh
XINCLLOC = /usr/include/local
XLKDRVRDIR = /etc/conf/pack.d/fas
XLKSCONFDIR = /etc/conf/sdevice.d
XLKNCONFDIR = /etc/conf/node.d
XLKICONFDIR = /etc/conf/init.d
XLKKCONFDIR = /etc/conf/kconfig.d
XDRVRNAME = Driver.o
XCONFNAME = fas
X
XCC = rcc
XCFLAGS = -O -DINKERNEL -DSCO -DNEED_PUT_GETCHAR -DFASI
X
XOBJS = fas.o
X
Xfas.o: 	fas.c $(INCLLOC)/fas.h $(INCLLOC)/digi-pc8.h Makefile
X
XDriver.o: fas.o
X	rm -rf Driver.o
X	ln fas.o Driver.o
X
Xinstall: Driver.o
X	sh -v idfasi
X
Xinstall2: install
X	cd /etc/conf/cf.d;./link_unix
X
Xspace.c:
X	@echo "You must copy the proper space-xxxxx file to \`space.c'"
X	@false
X	
Xs_$(CONFNAME):
X	@echo "You must copy the proper s_$(CONFNAME)-xxxxx file to \`s_$(CONFNAME)'"
X	@false
X		
Xn_$(CONFNAME):
X	@echo "You must copy the proper n_$(CONFNAME)-xxxxx file to \`n_$(CONFNAME)'"
X	@false
X		
Xi_$(CONFNAME):
X	@echo "You must copy the proper i_$(CONFNAME)-xxxxx file to \`i_$(CONFNAME)'"
X	@false
X		
X$(INCLLOC)/fas.h: fas.h
X	-mkdir $(INCLLOC) >/dev/null 2>&1
X	cp fas.h $(INCLLOC)/fas.h
X
X$(INCLLOC)/digi-pc8.h: digi-pc8.h
X	-mkdir $(INCLLOC) >/dev/null 2>&1
X	cp digi-pc8.h $(INCLLOC)/digi-pc8.h
X
Xclean:
X	rm -f fas.o Driver.o
X
Xclobber: clean
X
SHAR_EOF
$TOUCH -am 0709190991 'fasi/Makefile' &&
chmod 0644 fasi/Makefile ||
echo 'restore of fasi/Makefile failed'
Wc_c="`wc -c < 'fasi/Makefile'`"
test 1279 -eq "$Wc_c" ||
	echo 'fasi/Makefile: original size 1279, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/Master ==============
if test -f 'fasi/Master' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/Master (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/Master (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/Master' &&
Xfas	Iocrwi	iHct	fas	0	0	1	16	-1
SHAR_EOF
$TOUCH -am 0429171591 'fasi/Master' &&
chmod 0644 fasi/Master ||
echo 'restore of fasi/Master failed'
Wc_c="`wc -c < 'fasi/Master'`"
test 32 -eq "$Wc_c" ||
	echo 'fasi/Master: original size 32, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/Node ==============
if test -f 'fasi/Node' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/Node (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/Node (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/Node' &&
Xfas	tty1a	c	80
Xfas	tty1A	c	208
Xfas	tty2a	c	81
Xfas	tty2b	c	82
Xfas	tty2c	c	83
Xfas	tty2d	c	84
Xfas	tty2e	c	85
Xfas	tty2f	c	86
Xfas	tty2g	c	87
Xfas	tty2h	c	88
Xfas	tty2A	c	209
Xfas	tty2B	c	210
Xfas	tty2C	c	211
Xfas	tty2D	c	212
Xfas	tty2E	c	213
Xfas	tty2F	c	214
Xfas	tty2G	c	215
Xfas	tty2H	c	216
SHAR_EOF
$TOUCH -am 0429171591 'fasi/Node' &&
chmod 0644 fasi/Node ||
echo 'restore of fasi/Node failed'
Wc_c="`wc -c < 'fasi/Node'`"
test 279 -eq "$Wc_c" ||
	echo 'fasi/Node: original size 279, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/PATCHLEVEL ==============
if test -f 'fasi/PATCHLEVEL' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/PATCHLEVEL (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/PATCHLEVEL (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/PATCHLEVEL' &&
Xrelease 2.08 patchlevel b2 fasi x1.03
SHAR_EOF
$TOUCH -am 0429171591 'fasi/PATCHLEVEL' &&
chmod 0644 fasi/PATCHLEVEL ||
echo 'restore of fasi/PATCHLEVEL failed'
Wc_c="`wc -c < 'fasi/PATCHLEVEL'`"
test 38 -eq "$Wc_c" ||
	echo 'fasi/PATCHLEVEL: original size 38, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/README ==============
if test -f 'fasi/README' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/README (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/README' &&
XThis is the original README from FAS 2.08 for reference only.
XRead README.FASI. DO NOT CONTACT UWE DOERING REGARDING THIS HACKED VERSION
X                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
X
XREADME file for the FAS Final Async Solution driver
X---------------------------------------------------
X
XWhat is this package:
X
X     This is an async driver for 286/386 based unix systems that adds
X     several features that are not supported by vendors drivers.
X     It supports
X
X        1.  the NS16550A and i82510 UART chips in full FIFO mode.
X        2.  modem sharing for input and output.
X        3.  shared interrupts.
X        4.  multiplexed UART registers (HUB-6 card etc.).
X        5.  full and half duplex hardware flow control.
X        6.  VP/ix, the ISC DOS emulator.
X
X
X     FAS was successfully tested under the following operating systems:
X
X     Microport UNIX SYSV 3.0
X     ISC 386/ix 2.0.2 & 2.2
X     ESIX Rev. C & D
X     Bell Tech/Intel UNIX 3.2
X     SCO UNIX 386
X     SCO XENIX 386 2.3.2
X     SCO XENIX 286 2.3.2
X
X     This driver should work with most of the UNIX SYS V/386 3.X ports
X     currently available. You can have both this and the original
X     vendor driver in the same kernel (if you really like to, but I
X     wouldn't know why). Each driver controls its own separate set of
X     serial ports. The only restriction here is that any int vector must
X     not be used by more than one of the drivers. The kernel config
X     program will complain otherwise.
X
X------------------------------------------------------------------------
X     
XHow it works:
X
X     DIALIN/DIALOUT ON THE SAME PORT
X     -------------------------------
X
X     This driver supports shared line usage by having two logical
X     devices sharing one physical line. Each logical device has its
X     own name. For example for the first line the names are ttyF00
X     (minor device 0) and ttyFM00 (minor device 192). The ttyF00
X     is used for cu, kermit, and other programs that want to dial
X     out. It ignores the modem signals and just goes to it. The
X     ttyFM00 line is strictly for getty. When getty calls open on
X     ttyFM00 the driver hangs the open until the modem asserts the
X     carrier detect signal and then lets the open complete. If cu
X     opens ttyF00 while getty is waiting for the open to complete
X     the device is given to cu and the getty open must wait for cu
X     to finish and then will again wait for the carrier. If cu
X     tries to open the ttyF00 line while getty has ttyFM00 open cu
X     will get an error. If getty tries to open ttyFM00 while cu has
X     ttyF00 open the getty open will just hang and wait for cu to
X     close the line and then wait for the carrier. To put it simply
X     you should put up a getty on ttyFM00 with a -t 60 and use ttyF00
X     for cu and uucico.
X
X     In the example above ttyF00 had a minor device number of 0 and
X     ttyFM00 one of 192. But there are several other possible minor
X     device numbers for each port.
X
X     The higher bits of the minor device number control the operating
X     mode of the device. The port can't be opened by two or more
X     different minor devices at the same time.
X
X     Minor device numbers are built according to the following
X     description:
X
X        Bitmap:   m m f f x x x x
X
X           `m m' are the mode bits as follows:
X
X            0 0   The carrier signal is totally ignored. With carrier high->low
X                  *no* SIGHUP signal is generated. The device does *not* block
X                  on open if there is no carrier.
X            0 1   After an initial open, the carrier signal is ignored.
X                  Although, carrier high->low generates a SIGHUP signal. From
X                  thereon the device is carrier controlled until the last
X                  process has closed the device. An ioctl call with a TCSETA*
X                  command resets the device to ignore carrier again until the
X                  next carrier high->low. The device does *not* block on open
X                  if there is no carrier.
X            1 0   The device is carrier controlled. It blocks on open if
X                  there is no carrier.
X            1 1   Same as mode `1 0', but a parallel non-blocking open
X                  is possible while waiting for carrier.
X
X           `f f' are the hardware flow control bits as follows:
X
X            0 0   The RTSFLOW/CTSFLOW termio(7) flags (if available) enable
X                  half duplex hardware flow control (for output direction,
X                  only) according to SCO's specifications. If these flags
X                  are not available no hardware flow control is used by
X                  this device.
X            0 1   The device uses full duplex hardware flow control (for
X                  input and output direction).
X            1 0   The device uses half duplex hardware flow control (for
X                  output direction, only).
X            1 1   Same as mode `1 0', but additionally the output buffer
X                  state is signaled to the connected device.
X
X                  Refer to the `space.c' file to determine which port
X                  signals are actually used for that purpose.
X
X           `x x x x'
X                  This is the physical port number. This driver supports
X                  up to 16 ports. If you need more, you should use an
X                  intelligent serial card because more than 16 devices
X                  will eat up to much CPU time with this dumb-port approach.
X
X     - Note: If a device is carrier controlled, this implies the generation
X             of a SIGHUP signal with every carrier high->low. This is of
X             course only true if the CLOCAL flag is *not* set.
X
X             On my own system I prefer a minor device number of `0101xxxx'
X             (80 + device #) for the non-blocking tty node and `1101xxxx'
X             (208 + device #) for the blocking tty node. This gives me
X             the SIGHUP signal on carrier loss and full duplex hardware
X             flow control with both logical devices. Dialout while a dialin
X             open is waiting for the carrier is also possible with this
X             setup.
X
X
X     WHICH SERIAL CARDS ARE SUPPORTED ?
X     ----------------------------------
X
X     The driver supports and has been tested on many serial async
X     dumb port cards. It supports most combinations of shared
X     interrupts. The current driver supports NS16450, NS16550A,
X     um82450 and i82510. 8250 chips are not supported due to various
X     bugs and speed problems in these parts. They have no place in any
X     286/386 or other high performance system. Replace them with one of
X     the supported chips. They are pin-to-pin compatible.
X     
X     Take a look at the various samples of space-xxxx for details
X     of how to set up for various devices.
X
X     At boot time you will see a status message on the screen with
X     symbols that show the init state of each port. The symbols
X     are as follows:
X
X        -     not defined in the fas_port array
X        >     int vector greater than limit
X        ?     can't initialize port
X        1-6   error during test phase indicated by number
X        *     port is initialized (NS16450)
X        +     port is initialized and has FIFOs forced off
X        f     port is initialized and has FIFOs (i82510)
X        F     port is initialized and has FIFOs (NS16550)
X
X     This is convenient to check whether you have entered the proper port
X     base addresses in `space.c'.
X
X
X     WHICH CARD WILL SUPPORT SHARED INTERRUPTS ?
X     -------------------------------------------
X
X     Many multi-port cards have jumpers or dip switches that let you
X     assign more than one port to the same interrupt (IRQ) line. This alone
X     is _no_ guaranty that they really support shared interrupts! These
X     cards may be designed for the DOS world where you may want two or more
X     serial ports but don't need to run them concurrently, that is, no more
X     than one of those ports assigned to the same IRQ line is allowed to be
X     in use at a time. For DOS this is sufficient as DOS is no multitasking
X     operating system. For UNIX this won't work because in the worst case
X     all serial ports may be in use at the same time.
X
X     The basic problem is that the PC (and AT) I/O bus can't handle shared
X     interrupts itself. This is due to a brain-dead hardware design. Therefor,
X     there must be some special logic on the serial card to provide shared
X     interrupts. And those cards are quite rare (and usually more expensive).
X
X     Therefor, you have the choice to give every port on the card its own
X     IRQ line or to buy a multi-port card that really has shared interrupts.
X     But in the latter case you better ask your vendor twice to make shure
X     that it has this functionality because from the card's manuals it often
X     isn't obvious which type of card it is. One well-known shared interrupts
X     card is the AST 4-port card. There are many compatible clones available
X     that are usually much cheaper than the original. You can even buy
X     AST compatible 8-port cards where two AST 4-port blocks are on the
X     same board.
X
X
X     A WORD ABOUT CHARACTER LOSSES
X     -----------------------------
X
X     If you've experienced character losses with your vendor async
X     driver at high baud rates you shouldn't blame the vendor for
X     that. The real reason for this problem lies in the ancient port
X     devices used in most 286/386 systems: The 8250 (not supported by
X     FAS) and the NS16450.
X
X     They have only one receiver character buffer. This implies that
X     the operating system must read a character from this buffer before
X     the next one arrives from the port's shift register. For the old
X     IBM PC with DOS this was sufficient. But for UNIX and with baud
X     rates up to 38400 this is simply a joke.
X
X     UNIX is not a real-time operating system. That means that it's
X     kernel isn't optimized for fast interrupt responses. With the
X     proper hardware this is no problem. But because the vendors have
X     to adapt UNIX to the standard hardware found in 286/386 systems they
X     also have to cope with the NS16450 ports which are in there simply
X     to be compatible with IBM PCs, XTs and ATs.
X
X     It is impossible to make it work at high baud rates without a
X     major redesign of the AT&T supplied UNIX kernel. But then it
X     wouldn't be UNIX SYSV any more.
X
X     Luckily, there is a pin-to-pin replacement available from
X     National Semiconductors: The NS16550A.
X
X     This device has separate 16 character FIFOs for the receiver and
X     the transmitter. With these FIFOs the interrupt latency of the
X     kernel can be quiet high without losing any characters.
X     Additionally, because with most interrupts many characters are
X     processed at once the system is loaded much less.
X
X     As you see, the necessary hardware is available. Therefor, if you
X     have to blame the UNIX vendor then blame him for not telling you
X     that you should buy some NS16550A and/or for not supplying you
X     with a serial driver that supports these port devices.
X
X     But as you have the FAS driver now and if you use the NS16550A
X     devices you shouldn't have this kind of trouble any more. This is
X     the philosophy behind the driver's name `Final Async Solution'.
X
X     Enjoy!
X
X     PS: If for some reason you can't get the NS16550A chips you
X         could use the i82510 chips from Intel. Although they are
X         much less efficient they are still better than the NS16450.
X
X     PPS: Some kernel functions may disable interrupts long enough
X          that even the input FIFO can't prevent character loss.
X          One culprit is the disk cache flush function. If you
X          configure your kernel with too many cache buffers (NBUF
X          parameter for AT&T derived UNIX) you may still lose
X          characters (at least at 38400 bps).
X
X          An other candidate is VP/ix, or rather the kernel functions
X          to support VP/ix. This may also lead to lost characters
X          at very high input speed.
X
X
X     HARDWARE FLOW CONTROL
X     ---------------------
X
X     FAS supports both full and half duplex hardware flow control, using
X     the RS232C RTS/CTS control lines (by default).
X
X     Full duplex flow control is a method to control character flow in
X     both input and output directions while in half duplex flow control
X     mode only the output direction is controlled.
X
X     You can select between full and half duplex flow control via the
X     minor device number of the device. In full duplex mode the RTS line
X     controls the input direction and the CTS line is responsible for the
X     output direction. In half duplex mode RTS tells the connected device
X     whether there is data in the output buffer (optional), and the CTS
X     line has the same function as in full duplex mode.
X
X     Full duplex mode:
X
X          As long as the FAS input buffer hasn't reached a certain
X          threshold the RTS line is set high to signal the connected
X          device that it may send characters. If the input buffer level
X          rises beyond this threshold RTS will go low and the device
X          is supposed to stop sending characters. As soon as there is
X          sufficient space in the input buffer RTS will go high again
X          and the character flow may continue.
X
X          The CTS line works the other way round. If the connected device
X          sets CTS to high the FAS character output is enabled. If CTS is
X          low, the output is stopped. There is a special feature for the
X          CTS part of the handshake. CTS is only looked at if the DSR
X          line is high. If DSR is low or not connected hardware output
X          handshake is disabled, that is, FAS sends characters
X          regardless of the state of CTS.
X
X          This has two advantages. At first, if you switch off a serial
X          device connected to an FAS port with hardware flow control
X          CTS will go low and therefor the output gets blocked. If at
X          this time there are still characters in the output buffer the
X          last process closing this port can't terminate until the
X          buffer has drained.
X
X          But as DSR will also go low if you switch off the device
X          this blocking of the output will be prevented. In short:
X          Hardware output handshake is only used if the connected
X          device sets DSR high, that is, the device is switched on
X          and is ready. So make sure that you keep this in mind when
X          you make serial cables and when you configure your serial
X          devices. DSR must be on if you want CTS handshake.
X
X          The other advantage of this CTS/DSR mechanismn is that you
X          can still connect dumb serial devices to an FAS hardware
X          handshake port using a minimal 3-wire cable. As an unconnected
X          DSR line is automatically low hardware output handshake is
X          disabled, which is just what you wanted in this case.
X
X     Half duplex mode:
X
X          There are actually three half duplex modes selected by
X          the minor device number:
X
X          First mode:
X             If the RTSFLOW termio(7) flag is set _and_ the CLOCAL
X             flag is _not_ set the RTS line is used to signal the
X             connected device that there is data in the output buffer.
X             As long as there is output data to come the RTS line stays
X             high. If the output buffer has drained RTS drops to low
X             until there is more data to be sent to the connected device.
X
X             If the CTSFLOW termio(7) flag is set _and_ the CLOCAL
X             flag is _not_ set the CTS line used to control the output
X             character flow. This works as in full duplex mode.
X
X          Second mode:
X             This mode overrides the RTSFLOW/CTSFLOW flags and works
X             as if the CTSFLOW flag is set permanently. The CLOCAL flag
X             doesn't affect this mode.
X
X          Third mode:
X             This mode overrides the RTSFLOW/CTSFLOW flags and works
X             as if both the RTSFLOW and CTSFLOW flags are set permanently.
X             The CLOCAL flag doesn't affect this mode.
X
X
X     CABLING
X     -------
X
X     Don't leave unused input lines (CTS, DCD, DSR, RING) open! Due
X     to crosstalking from other lines these input lines might change
X     their logic level rapidly, resulting in excessive modem status
X     interrupts that could bring your machine down to its knees.
X     Therefor you should connect any unused input line to GND (pin 7
X     on the D-Sub 25 RS232C connector).
X
X     To prevent the machine from locking up in a case like described
X     above the port causing the modem status interrupts will be shut
X     down for 30 seconds after the last close on that port. Any attempt
X     to use an open(), read(), write() or ioctl() call to this port
X     during the time until the last close and then 30 seconds from
X     there will result in an ENXIO error.
X
X     The port shutdown will be indicated on the system console by a
X     warning message containing the unit number of the offending port.
X
X     But even if this protection mechanismn isn't triggered on your
X     computer you might have this problem. This is usually indicated
X     by a bad system performance during high speed serial data transfers.
X     Use your system's performance measurement tools to check the
X     number of modem interrupts. If it is unusual high, or even
X     higher than the number of transmit/receive interrupts, you
X     certainly have a problem with your cabling. Of course, another
X     reason could be a bad port chip.
X
X     ATTENTION: If you want to connect two UNIX systems (both using
X     FAS) via a null modem cable, and if you want to run a getty
X     on both ends you need to modify the `space.c' file to prevent
X     both gettys talking to each other, wasting valuable CPU time.
X     Remove the `EI_DTR' (or `EI_RTS', depending on your setup) macro
X     for the desired port from the initializer part of the `fas_modem'
X     array. This will cause DTR (or RTS) to be asserted only on
X     dialout. Therefor, the getty at the other end will become alive
X     only if a dialout is in progress.
X
X
X     VP/ix SUPPORT
X     -------------
X
X     FAS allows DOS programs running under VP/ix to access serial
X     ports. You simply need to modify your personal VP/ix configuration
X     file (`vpix.cnf') to tell the DOS emulator which FAS devices to
X     use for COM1 (or COM1MOUSE) and COM2. Note that VP/ix opens
X     these devices at startup time, so you better make sure that
X     the desired devices aren't used by other processes when you
X     start VP/ix as VP/ix wants to use them exclusively.
X
X     There are some special features with the handling of the RTS and
X     DTR lines you should know about. If your DOS program asserts
X     the DTR line this will actually cause action on the modem
X     enable line you configured in `space.c'. Likewise, RTS asserts
X     the half duplex hardware handshake line configured in `space.c'.
X
X     If the used FAS device has full duplex hardware handshake enabled,
X     asserting RTS from DOS actually stops the character flow from FAS
X     to VP/ix. This prevents input buffers of interrupt driven DOS
X     programs from overflowing. FAS, on the other hand, uses its hardware
X     handshake to prevent an overflow of its own input buffer. Therefor
X     you can use DOS telecommunication programs even at high baud rates
X     without losing characters, provided your DOS programs are
X     configured to use full duplex RTS/CTS flow control.
X
X     All this virtual handling has the advantage that the DOS program
X     doesn't need to know certain details about your actual port setup.
X     Reading the modem status register, on the other hand, doesn't cause
X     any translation of the register value.
X
X     To enable VP/ix support, you have to uncomment the `HAVE_VPIX'
X     define in `fas.h'.
X
X
X     DEVICE LOCKUPS
X     --------------
X
X     There are certain conditions under which a device can lock up,
X     that is, at least one process that uses this device waits for
X     a tty I/O related event that obviously doesn't occure.
X
X     The most common case is that there are still characters in the
X     output buffer, but the output is disabled for some reason. Then
X     the last process that closes the tty device hangs in the close()
X     function until the output buffer has drained.
X
X     Tty output may be stopped by the software (XON/XOFF) or hardware
X     (RTS/CTS, by default) flow control. In this case something
X     seems to be wrong with the cabling or the connected device.
X     Please check this first out before you blame FAS. Sometimes
X     it helps to switch the device off and on a few times to unblock
X     the tty output.
X
X     Another reason could be a lost transmitter interrupt. This usually
X     indicates a hardware problem in your computer which should be fixed
X     as soon as possible. Otherwise, you can't run this system unattended
X     because it is too unreliable.
X
X     In the cases described above the last resort is entering `kill -9 <pid>'
X     once or twice. This should unblock and terminate the hanging process.
X
X     And there is a rare case which has to do with the number of available
X     CLISTs in the UNIX kernel. The CLIST output and input buffers are
X     256 bytes each (by default). If for some reason the output of a
X     tty device is stopped but a process continues to send data one
X     character at a time this uses up one CLIST for every charcacter.
X     If the number of CLISTs in the kernel is less than 256 all CLISTs
X     will be busy eventually.
X
X     The dangerous part here is that the pool of CLISTs is used by all
X     tty devices. Therefor, if one single tty device manages to eat up
X     all available CLISTs all tty in- and output comes to a halt. If this
X     happens you can't access your machine any more, not even from the
X     operator console. Although, the system is still alive internally.
X
X     Unfortunately, many UNIX vendors have put a dangerously low number-of-
X     CLISTs parameter into their kernel tune files. You should increase
X     it to a value that makes it impossible that one device alone can
X     occupy all CLISTs (it's the NCLIST parameter under AT&T derived
X     UNIX SysVr3.x). A value of 400 should be sufficient.
X
X------------------------------------------------------------------------
X
XWhat's in this package:
X
X     README         This file.
X
X     INSTALLATION   A description about how to install the driver
X                    on your system.
X
X     PATCHLEVEL     Just a reference file for future updates.
X
X     RELEASENOTES   Notes about the present FAS releases.
X                    
X     fas.h          The header file for the driver.
X
X     fas.c          The driver itself.
X
X     space-xxxxx    These are samples of what `space.c' must look
X                    like.  You can either copy one of these to
X                    `space.c' or use it as a template to create your
X                    own `space.c'.
X
X          space-c1-2     For com1 and com2.
X
X          space-c1-3     For com1, com2 and com3.
X
X          space-ast4     For the AST 4-port card.
X
X          space-hub6     For the Bell Tech HUB-6 card.
X
X     config-xxxxx   This is for uPort SYS V/386 only.
X                    Kernel configuaration file.  You should pick the one
X                    that matches your configuration and copy it to `config'.
X
X          config-c1-2    For com1 and com2.
X
X          config-c1-3    For com1, com2 and com3.
X
X          config-ast4    For the AST 4-port card.
X
X          config-hub6    For the Bell Tech HUB-6 card.
X
X     s_fas-xxxxx    This is for ISC 386/ix, ESIX, Bell Tech/Intel UNIX 3.2
X                    and SCO UNIX 386.
X                    Kernel configuration file.  You should pick the one
X                    that matches your configuration and copy it to `s_fas'.
X
X          s_fas-c1-2     For com1 and com2.
X
X          s_fas-c1-3     For com1, com2 and com3.
X
X          s_fas-ast4     For the AST 4-port card.
X
X          s_fas-hub6     For the Bell Tech HUB-6 card.
X
X     n_fas-xxxxx    This is for ISC 386/ix, ESIX, Bell Tech/Intel UNIX 3.2
X                    and SCO UNIX 386.
X                    Tty device nodes file.  You should pick the one
X                    that matches your configuration and copy it to `n_fas'.
X
X          n_fas-c1-2     For com1 and com2.
X
X          n_fas-c1-3     For com1, com2 and com3.
X
X          n_fas-ast4     For the AST 4-port card.
X
X          n_fas-hub6     For the Bell Tech HUB-6 card.
X
X     i_fas-xxxxx    This is for ISC 386/ix, ESIX, Bell Tech/Intel UNIX 3.2
X                    and SCO UNIX 386.
X                    Inittab getty lines file.  You should pick the one
X                    that matches your configuration and copy it to `i_fas'.
X
X          i_fas-c1-2     For com1 and com2.
X
X          i_fas-c1-3     For com1, com2 and com3.
X
X          i_fas-ast4     For the AST 4-port card.
X
X          i_fas-hub6     For the Bell Tech HUB-6 card.
X
X     Makefile.uPort A makefile for uPort SYS V/386 systems. This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X     Makefile.ISC   A makefile for ISC 386/ix systems.  This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X     Makefile.ESIX  A makefile for ESIX systems.  This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X     Makefile.BELL  A makefile for Bell Tech/Intel UNIX 3.2 systems.  This
X                    is generic and should work for all configurations of
X                    lines and interrupts.
X
X     Makefile.SCO   A makefile for SCO UNIX 386 systems.  This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X     Makefile.X386  A makefile for SCO Xenix 386 systems.  This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X     Makefile.X286  A makefile for SCO Xenix 286 systems.  This is generic
X                    and should work for all configurations of lines
X                    and interrupts.
X
X------------------------------------------------------------------------
X
XWhat you will need to use this package:
X
X     You will need one of the above mentioned UNIX systems with the
X     kernel link kit and the software development package.
X
X------------------------------------------------------------------------
X
XThe original asy replacement driver for Microport UNIX/386 (FAS' predecessor)
Xwas developed by
X
XJim Murray              INET            jjm%jjmhome@m2c.m2c.org
X2 Mohawk Circle         UUCP            harvard!m2c!jjmhome!jjm
XWestboro Mass 01581     
XUSA                                     voice (508) 366-2813
X
XCredits to him for releasing this great driver to the Usenet community.
XBut if you have problems with FAS please don't contact him because he
Xwasn't involved in the developement of FAS.
X
XFAS was developed by [BUT DON'T BOTHER HIM ABOUT FAS/i]
X
XUwe Doering             INET : gemini@geminix.in-berlin.de
XBillstedter Pfad 17 b   UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
X1000 Berlin 20
XGermany
X
X------------------------------------------------------------------------------
XFor FAS/i inquiries:
X   Warren Tucker wht@n4hgf.GA.US, emory!n4hgf!wht
X
X    ^    ^    ^    ^    ^    ^    ^    ^    ^    ^
XSend your questions and bug reports to this address.
SHAR_EOF
$TOUCH -am 0709233391 'fasi/README' &&
chmod 0644 fasi/README ||
echo 'restore of fasi/README failed'
Wc_c="`wc -c < 'fasi/README'`"
test 27697 -eq "$Wc_c" ||
	echo 'fasi/README: original size 27697, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/README.FASI ==============
if test -f 'fasi/README.FASI' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/README.FASI (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/README.FASI (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/README.FASI' &&
XFAS/i is a special-purpose, unsupported version of FAS 2.08 for
Xthose who need to have non-portable, but extended access to their tty driver.
SHAR_EOF
true || echo 'restore of fasi/README.FASI failed'
fi
echo 'End of ecu310 part 28'
echo 'File fasi/README.FASI is continued in part 29'
echo 29 > _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.


