[alt.sources] ecu - SCO XENIX V/{2,3}86 Extended CU part 36/47

wht@tridom.uucp (Warren Tucker) (10/12/89)

---- Cut Here and unpack ----
#!/bin/sh
# this is part 36 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file ckermit/ckutio-orig.c continued
#
CurArch=36
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file ckermit/ckutio-orig.c"
sed 's/^X//' << 'SHAR_EOF' >> ckermit/ckutio-orig.c
X    	perror("Can't send BREAK");
X	return(-1);
X    }
X    return(0);
X#else
X#ifdef ANYBSD
X    n = FWRITE;				/* Flush output queue. */
X    ioctl(ttyfd,TIOCFLUSH,&n); 		/* Ignore any errors.. */
X    if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) {	/* Turn on BREAK */
X    	perror("Can't send BREAK");
X	return(-1);
X    }
X    x = msleep(275);			/* Sleep for so many milliseconds */
X    if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) {	/* Turn off BREAK */
X	perror("BREAK stuck!!!");
X	doexit(1);			/* Get out, closing the line. */
X					/*   with exit status = 1 */
X    }
X    return(x);
X#else
X#ifdef	V7
X    genbrk(ttyfd);			/* Simulate a BREAK */
X    return(x);
X#endif
X#endif
X#endif
X#endif
X#endif
X}
X
X
X/*  M S L E E P  --  Millisecond version of sleep().  */
X
X/*
X Intended only for small intervals.  For big ones, just use sleep().
X*/
X
Xmsleep(m) int m; {
X
X#ifdef aegis
X    time_$clock_t dur;
X
X    dur.c2.high16 = 0;
X    dur.c2.low32  = 250 * m; /* one millisecond = 250 four microsecond ticks */
X    time_$wait(time_$relative, dur, st);
X    return(0);
X#else 
X#ifdef PROVX1
X    if (m <= 0) return(0);
X    sleep(-((m * 60 + 500) / 1000));
X    return(0);
X#endif
X
X#ifdef ANYBSD
X    int t1, t3, t4;
X    if (m <= 0) return(0);
X#ifndef BSD42
X/* 2.9 and 4.1 BSD do it this way */
X    if (ftime(&ftp) < 0) return(-1);	/* Get current time. */
X    t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
X    while (1) {
X	ftime(&ftp);			/* new time */
X	t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
X	if (t3 > m) return(t3);
X    }
X#else
X/* 4.2 & above can do it with select()... */
X    if (gettimeofday(&tv, &tz) < 0) return(-1); /* Get current time. */
X    t1 = tv.tv_sec;			/* Seconds */
X
X    tv.tv_sec = 0;			/* Use select() */
X    tv.tv_usec = m * 1000;
X    return(select( 0, (int *)0, (int *)0, (int *)0, &tv) );
X#endif
X#endif
X
X/* The clock-tick business is a pain.  Wm. E. Davidsen suggested: */
X/*   #include <sys/param.h>      */
X/*   #define CLOCK_TICK 1000/HZ  */
X/* But I don't see the symbol HZ in this file on my VAX. */
X/* Maybe just for XENIX. */
X
X#ifdef UXIII
X#ifdef XENIX
X/* Actually, watch out.  It's 50 on the AT, 20 on older PCs... */
X#define CLOCK_TICK 50			/* millisecs per clock tick */
X#else
X#ifndef XENIX
X#define CLOCK_TICK 17			/* 1/60 sec */
X#endif
X#endif
X
X    extern long times();
X    long t1, t2, tarray[4];
X    int t3;
X
X/* In SCO Xenix 2.1.3 or later, you can use nap((long)m) to do this. */
X
X    if (m <= 0) return(0);
X    if ((t1 = times(tarray)) < 0) return(-1);
X    while (1) {
X	if ((t2 = times(tarray)) < 0) return(-1);
X	t3 = ((int)(t2 - t1)) * CLOCK_TICK;
X	if (t3 > m) return(t3);
X    }
X#endif
X
X#ifdef TOWER1
X    int t1, t3;
X    if (m <= 0) return(0);
X    if (ftime(&ftp) < 0) return(-1);		/* Get current time. */
X    t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
X    while (1) {
X	ftime(&ftp);				/* new time */
X	t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
X	if (t3 > m) return (t3);
X    }
X#endif
X#endif
X}
X
X
X/*  R T I M E R --  Reset elapsed time counter  */
X
Xrtimer() {
X    tcount = time( (long *) 0 );
X}
X
X
X/*  G T I M E R --  Get current value of elapsed time counter in seconds  */
X
Xgtimer() {
X    int x;
X    x = (int) (time( (long *) 0 ) - tcount);
X    rtimer();
X    return( (x < 0) ? 0 : x );
X}
X
X
X/*  Z T I M E  --  Return date/time string  */
X
Xztime(s) char **s; {
X
X#ifdef UXIII
X    extern long time();			/* Sys III/V way to do it */
X    char *ctime();
X    long clock_storage;
X
X    clock_storage = time( (long *) 0 );
X    *s = ctime( &clock_storage );
X#endif
X
X#ifdef PROVX1
X    int utime[2];			/* Venix way */
X    time(utime);
X    *s = ctime(utime);
X#endif
X
X#ifdef ANYBSD
X    char *asctime();			/* Berkeley way */
X    struct tm *localtime();
X    struct tm *tp;
X#ifdef BSD42
X    gettimeofday(&tv, &tz);		/* BSD 4.2 */
X    time(&tv.tv_sec);
X    tp = localtime(&tv.tv_sec);
X#else
X    time(&clock);			/* BSD 4.1, 2.9 ... ceb */
X    tp = localtime(&clock);
X#endif
X    *s = asctime(tp);
X#endif
X
X#ifdef TOWER1
X    char *asctime();			/* Tower way */
X    struct tm *localtime();
X    struct tm *tp;
X
X    time(&clock);
X    tp = localtime(&clock);
X    *s = asctime(tp);
X#endif
X#ifdef V7
X    char *asctime();			/* V7 way */
X    struct tm *localtime();
X    struct tm *tp;
X
X    time(&clock);
X    tp = localtime(&clock);
X    *s = asctime(tp);
X#endif
X}
X
X
X/*  C O N G M  --  Get console terminal modes.  */
X
X/*
X Saves current console mode, and establishes variables for switching between 
X current (presumably normal) mode and other modes.
X*/
X
Xcongm() {
X    if (!isatty(0)) return(0);		/* only for real ttys */
X#ifdef aegis
X    ios_$inq_type_uid(ios_$stdin, conuid, st);
X    if (st.all != status_$ok)
X    {  fprintf(stderr, "problem getting stdin objtype: "); error_$print(st); }
X    concrp = (conuid == mbx_$uid);
X    conbufn = 0;
X#endif
X#ifndef UXIII
X     gtty(0,&ccold);			/* Structure for restoring */
X     gtty(0,&cccbrk);			/* For setting CBREAK mode */
X     gtty(0,&ccraw);			/* For setting RAW mode */
X#else
X     ioctl(0,TCGETA,&ccold);
X     ioctl(0,TCGETA,&cccbrk);
X     ioctl(0,TCGETA,&ccraw);
X#endif
X#ifdef VXVE
X     cccbrk.c_line = 0			/* STTY line 0 for CDC VX/VE */
X     ioctl(0,TCSETA,&cccbrk;
X     ccraw.c_line = 0			/* STTY line 0 for CDC VX/VE */
X     ioctl(0,TCSETA,&ccraw;
X#endif /* vxve */
X     cgmf = 1;				/* Flag that we got them. */
X     return(0);
X}
X
X
X/*  C O N C B --  Put console in cbreak mode.  */
X
X/*  Returns 0 if ok, -1 if not  */
X
Xconcb(esc) char esc; {
X    int x;
X    if (!isatty(0)) return(0);		/* only for real ttys */
X    if (cgmf == 0) congm();		/* Get modes if necessary. */
X    escchr = esc;			/* Make this available to other fns */
X    ckxech = 1;				/* Program can echo characters */
X#ifdef aegis
X    conbufn = 0;
X    if (concrp) return(write(1, "\035\002", 2));
X    if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
X#endif
X#ifndef UXIII
X    cccbrk.sg_flags |= CBREAK;		/* Set to character wakeup, */
X    cccbrk.sg_flags &= ~ECHO;		/* no echo. */
X    x = stty(0,&cccbrk);
X#else
X    cccbrk.c_lflag &= ~(ICANON|ECHO);
X    cccbrk.c_cc[0] = 003;		/* interrupt char is control-c */
X    cccbrk.c_cc[1] = escchr;		/* escape during packet modes */
X    cccbrk.c_cc[4] = 1;
X#ifdef ZILOG
X    cccbrk.c_cc[5] = 0;
X#else
X    cccbrk.c_cc[5] = 1;
X#endif /* zilog */
X    x = ioctl(0,TCSETAW,&cccbrk);  	/* set new modes . */
X#endif
X
X#ifndef aegis
X    if (x > -1) setbuf(stdout,NULL);	/* Make console unbuffered. */
X#endif
X#ifdef	V7
X    if (kmem[CON] < 0) {
X	qaddr[CON] = initrawq(0);
X	if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
X	    fprintf(stderr, "Can't read /dev/kmem in concb.\n");
X	    perror("/dev/kmem");
X	    exit(1);
X	}
X    }
X#endif
X    return(x);
X}
X
X
X/*  C O N B I N  --  Put console in binary mode  */
X
X/*  Returns 0 if ok, -1 if not  */
X
Xconbin(esc) char esc; {
X    if (!isatty(0)) return(0);		/* only for real ttys */
X    if (cgmf == 0) congm();		/* Get modes if necessary. */
X    escchr = esc;			/* Make this available to other fns */
X    ckxech = 1;				/* Program can echo characters */
X#ifdef aegis
X    conbufn = 0; if (concrp) return(write(1, "\035\002", 2));
X    if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
X#endif
X#ifndef UXIII
X    ccraw.sg_flags |= (RAW|TANDEM);   	/* Set rawmode, XON/XOFF */
X    ccraw.sg_flags &= ~(ECHO|CRMOD);  	/* Set char wakeup, no echo */
X    return(stty(0,&ccraw));
X#else
X    ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
X    ccraw.c_iflag |= (BRKINT|IGNPAR);
X    ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
X			|INPCK|ISTRIP);
X    ccraw.c_oflag &= ~OPOST;
X
X/*** Kermit used to put the console in 8-bit raw mode, but some users have
X *** pointed out that this should not be done, since some sites actually
X *** use terminals with parity settings on their Unix systems, and if we
X *** override the current settings and stop doing parity, then their terminals
X *** will display blotches for characters whose parity is wrong.  Therefore,
X *** the following two lines are commented out (Larry Afrin, Clemson U):
X ***
X ***   ccraw.c_cflag &= ~(PARENB|CSIZE);
X ***   ccraw.c_cflag |= (CS8|CREAD);
X ***
X *** Sys III/V sites that have trouble with this can restore these lines.
X ***/
X    ccraw.c_cc[4] = 1;
X    ccraw.c_cc[5] = 1;
X    return(ioctl(0,TCSETAW,&ccraw) );  	/* set new modes . */
X#endif
X}
X
X
X/*  C O N R E S  --  Restore the console terminal  */
X
Xconres() {
X    if (cgmf == 0) return(0);		/* Don't do anything if modes */
X    if (!isatty(0)) return(0);		/* only for real ttys */
X#ifndef UXIII				/* except for sIII, */
X    sleep(1);				/*  not known! */
X#endif					/*   (sIII does wait in ioctls) */
X    ckxech = 0;				/* System should echo chars */
X#ifdef aegis
X    conbufn = 0; if (concrp) return(write(1, "\035\001", 2));
X    if (conuid == input_pad_$uid) {pad_$cooked(ios_$stdin, st); return(0);}
X#endif
X#ifndef UXIII
X    return(stty(0,&ccold));		/* Restore controlling tty */
X#else
X    return(ioctl(0,TCSETAW,&ccold));
X#endif
X}
X
X
X/*  C O N O C  --  Output a character to the console terminal  */
X
Xconoc(c) char c; {
X    write(1,&c,1);
X}
X
X/*  C O N X O  --  Write x characters to the console terminal  */
X
Xconxo(x,s) char *s; int x; {
X    write(1,s,x);
X}
X
X/*  C O N O L  --  Write a line to the console terminal  */
X
Xconol(s) char *s; {
X    int len;
X    len = strlen(s);
X    write(1,s,len);
X}
X
X/*  C O N O L A  --  Write an array of lines to the console terminal */
X
Xconola(s) char *s[]; {
X    int i;
X    for (i=0 ; *s[i] ; i++) conol(s[i]);
X}
X
X/*  C O N O L L  --  Output a string followed by CRLF  */
X
Xconoll(s) char *s; {
X    conol(s);
X    write(1,"\r\n",2);
X}
X
X
X/*  C O N C H K  --  Return how many characters available at console  */
X
Xconchk() {
X    int x; long n;
X
X#ifdef PROVX1
X    x = ioctl(0, TIOCQCNT, &ttbuf);
X    n = ttbuf.sg_ispeed & 0377;
X    return((x < 0) ? 0 : n);
X#else
X#ifdef aegis
X    if (conbufn > 0) return(conbufn);	/* use old count if nonzero */
X
X    /* read in more characters */
X    conbufn = ios_$get(ios_$stdin,
X	      ios_$cond_opt, conbuf, (long)sizeof(conbuf), st);
X    if (st.all != status_$ok) conbufn = 0;
X    conbufp = conbuf;
X    return(conbufn);
X#else
X#ifdef V7
X    lseek(kmem[CON], (long) qaddr[CON], 0);
X    x = read(kmem[CON], &n, sizeof(int));
X    return((x == sizeof(int))? n: 0);
X#else
X#ifdef UXIII
X    if (conesc) {			/* Escape typed */
X	conesc = 0;
X	signal(SIGQUIT,esctrp);		/* Restore escape */
X	return(1);
X    }
X    return(0);
X#else
X#ifdef C70
X    if (conesc) {			/* Escape typed */
X	conesc = 0;
X	signal(SIGQUIT,esctrp);		/* Restore escape */
X	return(1);
X    }
X    return(0);
X#else
X#ifdef FIONREAD
X    x = ioctl(0, FIONREAD, &n);		/* BSD and maybe some others */
X    return((x < 0) ? 0 : n);
X#else
X    return(0);				/* Others can't do. */
X#endif
X#endif
X#endif
X#endif
X#endif
X#endif
X}
X
X
X/*  C O N I N C  --  Get a character from the console  */
X
Xconinc(timo) int timo; {
X    int n = 0; char ch;
X#ifdef aegis
X    fflush(stdout);
X    if (conchk() > 0)
X    {  --conbufn; return(*conbufp++ & 0377); }
X#endif
X    if (timo <= 0 ) {			/* untimed */
X	n = read(0, &ch, 1);		/* Read a character. */
X	ch &= 0377;
X	if (n > 0) return(ch); 		/* Return the char if read */
X	else 
X#ifdef UXIII
X#ifndef CIE				/* CIE Regulus has no such symbol */
X	    if (n < 0 && errno == EINTR) /* if read was interrupted by QUIT */
X		return(escchr);		 /* user entered escape character */
X	    else		    /* couldnt be ^c, sigint never returns */
X#endif
X#endif
X		return(-1);  		/* Return the char, or -1. */
X	}
X    signal(SIGALRM,timerh);		/* Timed read, so set up timer */
X    alarm(timo);
X    if (setjmp(sjbuf)) n = -2;
X    else {
X	n = read(0, &ch, 1);
X	ch &= 0377;
X    }
X    alarm(0);				/* Stop timing, we got our character */
X    signal(SIGALRM,SIG_DFL);
X    if (n > 0) return(ch);
X    else
X#ifdef UXIII
X#ifndef CIE				/* CIE Regulus has no such symbol */
X        if (n == -1 && errno == EINTR)  /* If read interrupted by QUIT, */
X	    return(escchr);		/* user entered escape character, */
X        else		    		/* can't be ^c, sigint never returns */
X#endif
X#endif
X	return(-1);
X}
X
X
X#ifdef ATT7300
X#include <sys/phone.h>
X#include <dial.h>
X#define ATT7300 4			/* REH */
XCALL tcfig;
Xstruct termio ctermio = {0};
Xstruct updata ph;
Xstatic int att7300 = 0;			/* REH */
X
X/*  A T T D I A L  --  Dial up the remote system */
X
X/* Purpose: to open and dial a number on the internal modem available on the 
X * ATT7300 UNIX PC.  Richard E. Hill, Dickinson, TX.
X */
X
Xattdial(ttname,speed,telnbr) char *ttname,*telnbr; int speed; {
X    int err;
X
X    if (ttyfd > 0) {
X	ioctl(ttyfd,TCGETA,&ctermio);	/* save current settings */
X	err=ttclos();			/* close port */
X    } else ioctl(0,TCGETA,&ctermio);	/* get standard settings */
X
X/* Open line, check availability & data mode, turn on speaker, close port. */
X
X    ttyfd = open (ttname,O_RDWR | O_NDELAY);
X    if (err=ioctl(ttyfd,PIOCOFFHOOK,&ph)) {
X	printf("Phone line for %s not available:%d %d %d\n",
X	       ttname,ttyfd,err,errno);
X	close(ttyfd);
X	ttyfd = -1;
X	return(-1);
X    }
X    ioctl(ttyfd,PIOCGETP,&ph);     /* set phone parameters   */
X    if (ph.c_lineparam & VOICE) {
X	printf("Phone line %s not in data mode. Switch to data & redial\n",
X	       ttname);
X	ioctl(ttyfd,PIOCDISC,&ph);
X	close(ttyfd);
X	ttyfd = -1;
X	  return(-1);
X    }
X    ph.c_feedback |= (SPEAKERON | RINGON | NORMSPK);
X    ioctl(ttyfd,PIOCSETP,&ph);		/* set phone parameters   */
X    ioctl(ttyfd,PIOCDISC,&ph);		/* release phone resources for dial */
X    close(ttyfd);
X/*
X	fprintf(stderr,"Phone line status. line_par:%o dialtone_wait:%o \
Xline_status:%o feedback:%o\n",
X        ph.c_lineparam, ph.c_waitdialtone, ph.c_linestatus,ph.c_feedback);
X*/
X
X/*  Close line so that it can be reopened using system routine "dial". */
X/*  Set terminal configuration parameters. */
X
X    ctermio.c_iflag |= (BRKINT|IGNPAR|IXON|IXOFF);
X    ctermio.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP| IXANY);
X    ctermio.c_oflag &= ~OPOST;
X    ctermio.c_cflag = (B1200 | CS8 | CREAD | CLOCAL | HUPCL);
X    ctermio.c_lflag &= ~(ICANON|ECHO);
X    ctermio.c_cc[4] = 1;
X    ctermio.c_cc[5] = 0;
X    tcfig.attr = &ctermio;
X    tcfig.baud = speed <= 1200 ? speed : 1200;
X    tcfig.speed = speed <= 300 ? 300 : 1200;
X    tcfig.line = ttname;
X    tcfig.telno = telnbr;
X    tcfig.modem = 0;
X    fprintf (stderr,"dialing:%s on line:%s at %d baud, speed:%d\n",
X	     tcfig.telno,tcfig.line,tcfig.baud,tcfig.speed);
X    if ((ttyfd = dial(tcfig)) > 0) {
X	att7300 = 1;
X/*
X	ioctl(ttyfd,TCGETA,&ctermio);
X	fprintf(stderr,"after dial:iflag:%o, oflag:%o, cflag:%o, lflag:%o,\
X	line:%o\n", ctermio.c_iflag,ctermio.c_oflag,ctermio.c_cflag,
X	ctermio.c_lflag, ctermio.c_line);
X*/
X	return(0);
X    }
X    printf("Sorry, connection not made. Error status: %d\n",ttyfd);
X    return(-2);
X}
X#endif /* ATT7300 */
X
SHAR_EOF
echo "File ckermit/ckutio-orig.c is complete"
chmod 0644 ckermit/ckutio-orig.c || echo "restore of ckermit/ckutio-orig.c fails"
echo "x - extracting ckermit/ckutio.diff (Text)"
sed 's/^X//' << 'SHAR_EOF' > ckermit/ckutio.diff &&
Xdiff ckutio.c ckutio-orig.c
X------------------------------ cut here -------------------------------
X1c1
X< /* CHK=0xDA43 */
X---
X> /* CHK=0x2848 */
X3,5d2
X< /*+:EDITS:*/
X< /*:06-16-1988-19:26-wht-modified for ecu - ECU_MODS is keyword */
X< #define ECU_MODS
X357,360d353
X< #ifdef ECU_MODS
X< static int ecu_calling = 0;
X< #endif
X< 
X528,529c521
X< /****** b e f o r e ****************************************************/
X< #ifndef ECU_MODS
X---
X> 
X536,568d527
X< #endif /* ECU_MODS */
X< /****** a f t e r ******************************************************/
X< #ifdef ECU_MODS
X< 	if(isdigit(*ttname))
X< 	{
X< 		xlocal = *lcl = 1;	/* force local if fd passed to program */
X< 		debug(F111,"ttopen numeric ttname, new local",ttname,xlocal);
X< 		ttyfd = atoi(ttname);
X< 		debug(F101,"ttyfd passed as numeric=","",ttyfd);
X< 		ecu_calling = 1;
X< /* Get tty device settings */
X< #ifndef UXIII
X< 		gtty(ttyfd,&ttold);			/* Get sgtty info */
X< 		gtty(ttyfd,&ttraw);			/* And a copy of it for packets*/
X< 		gtty(ttyfd,&tttvt);			/* And one for virtual tty service */
X< #else
X< 		ioctl(ttyfd,TCGETA,&ttold);		/* Same deal for Sys III, Sys V */
X< 		ioctl(ttyfd,TCGETA,&ttraw);
X< 		ioctl(ttyfd,TCGETA,&tttvt);
X< #endif /* not uxiii */
X< 		return(0);
X< 	}
X< 	else
X< 	{
X< #ifdef UXIII
X<     /* if modem connection, don't wait for carrier */
X<     ttyfd = open(ttname,O_RDWR | (modem ? O_NDELAY : 0) );
X< #else
X<     ttyfd = open(ttname,2);		/* Try to open for read/write */
X< #endif
X< 	}
X< #endif /* ECU_MODS */
X< /***********************************************************************/
X570d528
X< 
X703,711d660
X< 
X< #ifdef ECU_MODS
X< 	if(ecu_calling)
X< 	{
X< 		debug(F101,"ttclos disabled for ecu","",0);
X< 		return(0);
X< 	}
X< #endif
X< 
X748,755d696
X< 
X< #ifdef ECU_MODS
X< 	if(ecu_calling)
X< 	{
X< 		debug(F101,"tthang disabled for ecu","",0);
X< 		return(0);
X< 	}
X< #endif
SHAR_EOF
chmod 0644 ckermit/ckutio.diff || echo "restore of ckermit/ckutio.diff fails"
echo "x - extracting doc/_basic.txt (Text)"
sed 's/^X//' << 'SHAR_EOF' > doc/_basic.txt &&
X.*s 1 "Basic Organization"
X
XECU forks to run as two separate
Xprocesses, a transmitter (XMTR) and a receiver (RCVR).
XThe two processes
Xcommunicate via signals and a System V shared memory segment.
XXMTR controls RCVR and terminates it under certain circumstances,
Xcalled here auxiliary operations.  After an auxiliary operation
Xcompletes, XMTR forks again to recreate RCVR.
X
X.*s 2 "Transmitter Process (XMTR)"
X
XXMTR
Xaccepts user input from the computer keyboard; input is recognized
Xas belonging to one of two types: 1) transmit data and 2)
XECU commands.  Keyboard input
Xis passed to the serial line driver until an ECU command
Xis detected.  Commands are prefixed with a "hot key"
Xwhich causes ECU to accept keyboard data up to the next ENTER
Xkey as command text.  After a command has been processed,
Xkeyed data is again routed to the serial line.
X
X.*s 3 "Keyboard Interface"
X
XThe keyboard driver is set into the raw mode.
XXMTR reads characters one at a time from the driver.
XNormally, characters read from the keyboard are passed directly to
Xthe serial line driver.  The
XASCII ESC ("escape") character is handled as a special case.
XWhen a function key is pressed, the keyboard driver presents
Xto XMTR an ESC character,
Xfollowed by two more characters describing which function key has
Xbeen pressed.
XPressing the ESC key also causes XMTR to see an ESC character,
Xbut with no subsequent function key "suffix".
X
XWhen an ESC character is read, XMTR delays transmission of the
Xcharacter to the line for a short period to determine whether
Xthe ESC key has been pressed or a function key has been pressed.
XIf no "suffix" is detected, the ESC is passed to the line, having
Xsuffered an insignificant delay given human typing speeds.
X
XIf a function key "suffix" is detected, the function key type
Xis decoded.  A HOME key indicates an ECU command follows.  Any
Xother function key is passed to the function key mapping feature
X(described later).
X
X.*s 3 "ECU Command Assembly"
X
XAfter a HOME function key has been pressed, XMTR presents a
Xreverse video
Xprompt on the display, indicating its readiness to accept a command.
XDuring input,
Xthe command may be edited using the same control keys specified
Xwith stty(C).  Command input is aborted by pressing ESC.
XWhen a command string has been assembled, it is passed to the
Xcommand processor, which breaks the command arguments into a
Xtoken array similar to the argc/argv array.  When the command
Xhandler returns, XMTR returns to its normal mode of copying
Xkeyboard data to the serial line.
X
X.*s 3 "Function Key Mapping"
X
XFunction keys other than HOME are available to be mapped
Xto transmit short keystroke sequences on a connection by
Xconnection basis.  Under control of the dialing command ("Dial"
Xdescribed below)  or the function key control command ("FK"),
Xpredefined function key maps may be loaded.
X
XFunction keys which may be mapped are F1 through F12,
XPgUp, PgDn, End, Ins, Del, the unshifted keypad '5' key and
Xthe cursor control keys.
X
X.*s 3 "Auxiliary Operation Control"
X
XCertain commands cause ECU to perform what is called an
Xauxiliary operation, requiring temporary termination of the
XRCVR process.  There are two types of auxiliary operations:
X1) internal command execution and 2) external program execution.
X
XCertain internal commands require tight control over the serial line.
XFor instance, the Dial command requires transmitting modem command
Xstrings and receiving modem response codes.  Such procedures
Xare best accomplished by single-process control of the line.
XExternal program execution is of two kinds, file transfer invocation
Xand local shell/command execution.
X
XThe RCVR process is terminated in any of these cases either to
Xavoid the RCVR swallowing characters intended for other
Xtargets (the modem handler in XMTR or the file transfer protocol)
Xor to avoid having remote data interspersed with the output of
Xlocal programs.
X
X.*s 2 "Receiver Process (RCVR)"
X
XThe receiver process reads the incoming serial data stream and
Xpasses it to the user terminal driver through a filter which
Xscans for events such as the occurrence of ASCII BEL (bell)
Xcharacters or terminal control sequences.  RCVR also handles
Xthe session logging function.
X
X.*s 3 "ANSI Filter"
X
XSince the term "ANSI"
Xis used to describe many variations on the ANSI X3.64 recommendations
Xfor terminal control (read "IBM pseudo-ANSI"),
Xthe ECU receiver process has an "ANSI filter" which attempts to
Xtranslate ANSI-like control sequences to sequences acceptable
Xto the XENIX display driver.  The filter can be enabled or disabled
Xby user command.
X
X.*s 3 "Session Logging"
X
XWhen directed by the user, the RCVR process logs incoming serial
Xdata to a file named on the log command line.  The default operation
Xis to filter unprintable characters (other than TAB and NL) from the
Xlog, but raw logging is available with a command option.  In a like
Xmanner, the default is for appending to an existing file, but a
Xcommand option may specify scratching any previous contents.
X
XLog files receive header lines each time the file is
Xopened, stating the logical system name, the telephone number
Xand the date/time.
X
SHAR_EOF
chmod 0644 doc/_basic.txt || echo "restore of doc/_basic.txt fails"
echo "x - extracting doc/_end.txt (Text)"
sed 's/^X//' << 'SHAR_EOF' > doc/_end.txt &&
X
X.br
X.nr si 0n
X.af % i
X.ls 1
X.TC 1 1 3
SHAR_EOF
chmod 0644 doc/_end.txt || echo "restore of doc/_end.txt fails"
echo "x - extracting doc/_features.txt (Text)"
sed 's/^X//' << 'SHAR_EOF' > doc/_features.txt &&
X.*s 1 "Features"
X
X.*s 2 "Dialing Directory"
X
XECU provides an on-line editable dialing directory.  Remote
Xsystems are defined as records using alphanumeric identifiers
Xas keys.  Other record fields include telephone number, baud
Xrate, parity and textual description.
X
X.*s 2 "Online Command Dictionary"
X
XThe ECU help command presents a display of interactive commands.  The user
Xis then prompted to enter a command name for further, Unix-style
X"usage" information.
X
X.*s 2 "Multiscreen Event Alarm"
X
XBy using the "BN" (bell notify) interactive command, an audible alert is
Xsent to all multiscreens when an ASCII BEL (bell) is received
Xor when a file transfer completes.  An additional option
Xcauses an alert when ANY data is received from
Xthe line.  This makes it simple to
Xdo work on other multiscreen consoles and
Xbe alerted when attention to
Xthe communications session is required.
X
XFor instance, the Berkeley 4.x Unix utility "talk" rings the bell
Xwhen another user wishes an interactive chat mode.  BSD 
X"biff" rings the bell when incoming mail is received.
XScripts or commands at remote sites can be configured to ring the
Xbell as in:
X.DS I
Xmake foo bar; bell; make more_stuff; bell;
X.DE
Xto call attention to the ECU user when work is being done
Xon other multiscreen consoles.
X
X.*s 2 "Function Key Mapping"
X
XAll function keys with the exception of the HOME and keypad unshifted
X5 key can be programmed to emit selected strings.
XFor instance, when communicating with a Stratus computer,
Xa function key map might be constructed as follows:
X.DS L
X F1  F1     F2  F2         HOME ecu cmd     PGUP  dispform
X F3  F3     F4  F4         END  enter       PGDN  cancel
X F5  F5     F6  F6         INS  local shell CUR5  Screen dump
X F7  status F8  no status
X F9         F10 redisp     CUR^ ^           CUR>  >
X F11        F12            CUR< <           CURv  v
X.DE
X
X
X.*s 2 "Built-in Modem Dialer"
X
XThe built-in ECU dialer supports modems which use the 
X.B
XHayes-style AT command set or most variants
X.R
X.B thereof .
XIt is used when HoneyDanBer UUCP is not installed
Xor when there is no entry in the /usr/lib/uucp/Devices file for the
Xselected outgoing line.
X
XFor more information,
Xsee the later section titled "HoneyDanBer UUCP Interface".
X
XThe built-in dialer uses files in the /usr/lib/ecu directory which
Xcontains modem initialization information.
XModem initialization filenames are made from concatenating the
Xtty name with ".mi".  For instance, tty1a's initialization
Xfile is named "tty1a.mi".
X
XCommands for initializing the modem and for dialing may be specified
Xin a very flexible manner.  Separate init and dial strings  for each
Xlegal baud rate, a single pair of strings for all baud rates
Xor a combination may be specified.
X.DF L
X.hl
X.ce 1
XSample Modem Initialization Files
X
X#+-----------------------------------------------------------
X#  tty1a.mi - Microcom AX/9624c
X#  Copyright 1989 Warren H. Tucker, III. All Rights Reserved
X#------------------------------------------------------------
X#+:EDITS:
X#:06-17-1989-22:02-wht-creation
Xinit_>2400:ATS11=47X4S0=0S7=30\Q1\X1\N3   # baud rates > 2400
Xinit_default:ATS11=47X4S0=0S7=30\Q0\X0\N0 # other baud rates
Xdial_default:ATDT
X
X
X#+-----------------------------------------------------------
X#  tty2d.mi - USR Courier 2400
X#  Copyright 1989 Warren H. Tucker, III. All Rights Reserved
X#------------------------------------------------------------
X#+:EDITS:
X#:06-17-1989-22:02-wht-creation
Xinit_default:ATS11=47 X4 S0=0 S7=32
Xdial_default:ATDT
X
X.DE
X
X.*s 2 "File Transfer"
X
XECU supports numerous file transfer protocols:
Xas of this writing, XMODEM, XMODEM/CRC,
XXMODEM-1K, YMODEM/CRC Batch, ZMODEM/CRC-16, ZMODEM/CRC-32,
Xand Kermit are supported.
XAlthough a seamless interface is provided to the user,
Xtransfer is facilitated by executing external programs.
X
XXMODEM, YMODEM and ZMODEM transfers are supported by
Xpublic domain programs by Chuck Forsberg that have
Xbeen significantly modified to keep transfer statistics
Xpresent dynamic status
Xdisplays similar to the following:
X
X
X.DS L
X
X    .-- ecusz 2.02 -- dir: /u1/bin ----------------------------.
X    |  ZMODEM/CRC32  Data xfer rate ~=    234 chars/sec        |
X    |  File   1 of   1: less                                   |
X    |  File position:     50356 length:    50356  -rwxr-xr-x   |
X    |  Sending 50356 bytes  total time ~=  3:51                |
X    |  tx: hdr ZFIN  00000000      rx: hdr ZFIN  00000000      |
X    |  Comm I/O: rx      176  tx    52404 bytes                |
X    |  Baud rate:  2400 BINARY blklen:  1024 comm mode: NORMAL |
X    |  Time started: session: 18:41:51  this file: 18:41:53    |
X    |                elapsed: 00:03:41    current: 18:45:33    |
X    |  Error counts: this file:     0  total:      0           |
X    |  Total file bytes transferred: 50356                     |
X    |  End of file                                             |
X    |  Remote: CRC32 y  duplex y  continuous stream y          |
X    `----------------------------------------------------------'
X
X.DE
X
X.*s 2 "Procedures (Scripts)"
X
XA powerful, language-style procedure language is incorporated
Xinto ECU.  The lnaguage is described in later sections.
X
X.*s 2 "Initial (Startup) Procedure"
X
XAn
X.B
Xinitial procedure
X.R
Xmay be be specified to ECU either to initialize an interactive
Xsession or to execute an entirely unattended or "batch"
Xcommunication session.
X
X
X.*s 2 "Home Directory Files"
X
XECU control files reside in the .ecu subdirectory of
Xeach user's home directory.  For example, in home directory /usr/wht:
X.DS I
X/usr/wht/.ecu/dir     CD interactive command history file
X/usr/wht/.ecu/keys    function key mapping
X/usr/wht/.ecu/log     connect, file transfer history
X/usr/wht/.ecu/phone   dialing directory
X.DE
X
XThe .ecu directory also contains ECU procedure files
SHAR_EOF
echo "End of part 36"
echo "File doc/_features.txt is continued in part 37"
echo "37" > s2_seq_.tmp
exit 0
-- 
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation       ...!gatech!emory!tridom!wht 
Ker-au'-lo-phon.  An 8-foot partial flue-stop, having metal pipes
surmounted by adjustable rings, and with a hole bored near the top
of each pipe, producing a soft and "reedy" tone.