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

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

---- Cut Here and unpack ----
#!/bin/sh
# this is part 35 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file ckermit/ckutio-orig.c continued
#
CurArch=35
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#else
X    unsigned short ttc_save;
X#endif /* hpux */
X#endif /* uxiii */
X
X    if (ttyfd < 0) return(0);		/* Not open. */
X#ifdef aegis
X    sio_$control((short)ttyfd, sio_$dtr, false, st);	/* DTR down */
X    msleep(500);					/* pause */
X    sio_$control((short)ttyfd, sio_$dtr, true,  st);	/* DTR up */
X#else
X#ifdef ANYBSD
X    ioctl(ttyfd,TIOCCDTR,0);		/* Clear DTR */
X    msleep(500);			/* Let things settle */
X    ioctl(ttyfd,TIOCSDTR,0);		/* Restore DTR */
X#endif /* anybsd */
X#ifdef UXIII
X#ifdef HPUX   /* Hewlett Packard way of modem control  */
X    if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0) return(-1); /* lower DTR */
X    msleep(500);
X    if (ioctl(ttyfd,MCGETA,&modem_rtn) < 0) return(-1); /* get line status */
X    if ((modem_rtn & MDCD) != 0) return(-1);        /* check if DCD is low */
X    modem_rtn = MRTS | MDTR;                        /* bits for RTS & DTR  */
X    if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) return(-1);    /*  set lines  */
X#else
X    ttc_save = ttraw.c_cflag;
X    ttraw.c_cflag &= ~CBAUD;		/* swa: set baud rate to 0 to hangup */
X    if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* do it */
X    msleep(100);			/* let things settle */
X    ttraw.c_cflag = ttc_save;
X
X/* NOTE - The following #ifndef...#endif can be removed for SCO Xenix 2.1.3 */
X/* or later, but must keep for earlier versions, which can't do close/open. */
X
X#ifndef XENIX		/* xenix cannot do close/open when carrier drops */
X				/* following corrects a PC/IX defficiency */
X    ttc_save = fcntl(ttyfd,F_GETFL,0);
X    close(ttyfd);		/* close/reopen file descriptor */
X    if ((ttyfd = open(ttnmsv, ttc_save)) < 0) return(-1);
X#endif /* not xenix */
X    if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* un-do it */
X#endif /* uxiii */
X#endif /* hpux  */
X#endif /* aegis */
X    return (0);
X}
X
X
X/*  T T R E S  --  Restore terminal to "normal" mode.  */
X
Xttres() {				/* Restore the tty to normal. */
X    int x;
X
X    if (ttyfd < 0) return(-1);		/* Not open. */
X#ifndef UXIII				/* except for sIII, */
X    sleep(1);				/* Wait for pending i/o to finish. */
X#endif	/* uxiii */			/*   (sIII does wait in ioctls) */
X
X#ifdef UXIII
X    if (ioctl(ttyfd,TCSETAW,&ttold) < 0) return(-1); /* restore termio stuff */
X    if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
X      return(-1);
X#else /* not uxiii */
X#ifdef FIONBIO
X    x = 0;
X    x = ioctl(ttyfd,FIONBIO,&x);
X    if (x < 0) {
X	perror("ttres ioctl");
X	debug(F101,"ttres ioctl","",x);
X    }
X#else /* not fionbio */
X#ifdef FNDELAY
X    x = (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & ~FNDELAY) == -1);
X    debug(F101,"ttres fcntl","",x);
X    if (x < 0) perror("fcntl");
X#endif /* fndelay */
X#endif /* fionbio */
X    x = stty(ttyfd,&ttold);		/* Restore sgtty stuff */
X    debug(F101,"ttres stty","",x);
X    if (x < 0) perror("stty");
X#endif /* uxiii */
X    return(x);
X}
X
X
X/* Exclusive uucp file locking control */
X/*
X by H. Fischer, creative non-Bell coding !
X copyright rights for lock modules assigned to Columbia University
X*/
Xstatic char *
Xxxlast(s,c) char *s; char c; {		/* Equivalent to strrchr() */
X    int i;
X    for (i = strlen(s); i > 0; i--)
X    	if ( s[i-1] == c ) return( s + (i - 1) );
X    return(NULL);    
X}
Xstatic
Xlook4lk(ttname) char *ttname; {
X    extern char *strcat(), *strcpy();
X    char *device, *devname;
X    char lockfil[50];			/* Max length for lock file name */
X
X#ifdef ISIII
X    char *lockdir = "/etc/locks";
X#else
X#ifdef ATT3BX
X    char *lockdir = "/usr/spool/locks";
X#else
X#ifdef NEWUUCP
X    char *lockdir = "/usr/spool/uucp/LCK";
X#else
X    char *lockdir = "/usr/spool/uucp";
X#endif /* newuucp */
X#endif /* att3bx */
X#endif /* isiii */
X
X    device = ( (devname=xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
X
X#ifdef ISIII
X    (void) strcpy( lockfil, device );
X#else
X    strcat( strcpy( lockfil, "LCK.." ), device );
X#endif /* isiii */
X
X    if (access( lockdir, 04 ) < 0) {	/* read access denied on lock dir */
X	fprintf(stderr,"Warning, read access to lock directory denied\n");
X	return( 1 );			/* cannot check or set lock file */
X    }
X	
X    strcat(strcat(strcpy(flfnam,lockdir),"/"), lockfil);
X    debug(F110,"look4lk",flfnam,0);
X
X    if ( ! access( flfnam, 00 ) ) {	/* print out lock file entry */
X	char lckcmd[40] ;
X	strcat( strcpy(lckcmd, "ls -l ") , flfnam);
X	system(lckcmd);
X	if (access(flfnam,02) == 0)
X	    printf("(You may type \"! rm %s\" to remove this file)\n",flfnam);
X	return( -1 );
X    }
X    if ( access( lockdir, 02 ) < 0 ) {	/* lock file cannot be written */
X	fprintf(stderr,"Warning, write access to lock directory denied\n");
X	return( 1 );
X    }
X    return( 0 );			/* okay to go ahead and lock */
X}
X
X
X/*  T T L O C K  */
X
Xstatic
Xttlock(ttfd) char *ttfd; {		/* lock uucp if possible */
X#ifndef aegis
X#ifdef ATT3BX
X    FILE *lck_fild;
X#endif /* att3bx */
X    int lck_fil, l4l;
X    int pid_buf = getpid();		/* pid to save in lock file */
X	
X    hasLock = 0;			/* not locked yet */
X    l4l = look4lk(ttfd);
X    if (l4l < 0) return (-1);		/* already locked */
X    if (l4l == 1) return (0);		/* can't read/write lock directory */
X    lck_fil = creat(flfnam, 0444);	/* create lock file ... */
X    if (lck_fil < 0) return (-1);	/* create of lockfile failed */
X		/* creat leaves file handle open for writing -- hf */
X#ifdef ATT3BX
X    fprintf((lck_fild = fdopen(lck_fil, "w")), "%10d\n", pid_buf);
X    fflush(lck_fild);
X#else
X    write (lck_fil, &pid_buf, sizeof(pid_buf) ); /* uucp expects int in file */
X#endif /* att3bx */
X    close (lck_fil);
X    hasLock = 1;			/* now is locked */
X#endif /* not aegis */
X    return(0);
X}
X
X/*  T T U N L O C K  */
X
Xstatic
Xttunlck() {				/* kill uucp lock if possible */
X    if (hasLock) return( unlink( flfnam ) );
X    return(0);
X}
X
X/* New-style (4.3BSD) UUCP line direction control (Stan Barber, Rice U) */
X
X#ifdef NEWUUCP
Xacucntrl(flag,ttname) char *flag, *ttname; {
X    char x[DEVNAMLEN+32], *device, *devname;
X
X    if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
X        return;				/* just return. */
X    device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
X    if (strncmp(device,"LCK..",4) == 0) device += 5;
X    sprintf(x,"/usr/lib/uucp/acucntrl %s %s",flag,device);
X    debug(F000,"called ",x,0);
X    system(x);
X}
X#endif /* newuucp */
X
X
X/*  T T P K T  --  Condition the communication line for packets. */
X/*		or for modem dialing */
X
X#define DIALING	4		/* flags (via flow) for modem handling */
X#define CONNECT 5
X
X/*  If called with speed > -1, also set the speed.  */
X
X/*  Returns 0 on success, -1 on failure.  */
X
Xttpkt(speed,flow,parity) int speed, flow, parity; {
X    int s, x;
X
X    if (ttyfd < 0) return(-1);		/* Not open. */
X    ttprty = parity;			/* Let other tt functions see this. */
X    debug(F101,"ttpkt setting ttprty","",ttprty);
X    s = ttsspd(speed);			/* Check the speed */
X
X#ifndef UXIII
X    if (flow == 1) ttraw.sg_flags |= TANDEM; /* Use XON/XOFF if selected */
X    if (flow == 0) ttraw.sg_flags &= ~TANDEM;
X    ttraw.sg_flags |= RAW;		/* Go into raw mode */
X    ttraw.sg_flags &= ~(ECHO|CRMOD);	/* Use CR for break character */
X#ifdef TOWER1
X    ttraw.sg_flags &= ~ANYP; 		/* Must tell Tower no parity */
X#endif /* tower1 */
X    if (s > -1) ttraw.sg_ispeed = ttraw.sg_ospeed = s; /* Do the speed */
X    if (stty(ttyfd,&ttraw) < 0) return(-1);	/* Set the new modes. */
X
X#ifdef MYREAD
X#ifdef BSD4
X/* Try to make reads nonblocking */
X#ifdef aegis
X    return(0);
X#endif /* aegis */
X#ifdef FIONBIO
X    x = 1;
X    if (ioctl(ttyfd,FIONBIO,&x) < 0) {
X	perror("ttpkt ioctl");
X	return(-1);
X    }
X#else /* fionbio */
X#ifdef FNDELAY
X    if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) | FNDELAY) == -1) {
X	return(-1);
X    }
X#endif /* fndelay */
X#endif /* bsd4 */
X    ttflui();				/* Flush any pending input */
X    return(0);
X#endif /* bsd4 */
X#else  /* myread */
X    ttflui();				/* Flush any pending input */
X    return(0);
X#endif /* myread */
X#endif /* not uxiii */
X
X#ifdef UXIII
X    if (flow == 1) ttraw.c_iflag |= (IXON|IXOFF);
X    if (flow == 0) ttraw.c_iflag &= ~(IXON|IXOFF);
X
X    if (flow == DIALING)  ttraw.c_cflag |= CLOCAL|HUPCL;
X    if (flow == CONNECT)  ttraw.c_cflag &= ~CLOCAL;
X
X    ttraw.c_lflag &= ~(ICANON|ECHO);
X    ttraw.c_lflag |= ISIG;		/* do check for interrupt */
X    ttraw.c_iflag |= (BRKINT|IGNPAR);
X    ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
X    ttraw.c_oflag &= ~OPOST;
X    ttraw.c_cflag &= ~(CSIZE|PARENB);
X    ttraw.c_cflag |= (CS8|CREAD);
X#ifdef IX370
X    ttraw.c_cc[4] = 48;	 /* So Series/1 doesn't interrupt on every char */
X    ttraw.c_cc[5] = 1;
X#else
X#ifdef VXVE
X    ttraw.c_cc[4] = 1;   /* [VMIN]  for CDC VX/VE */
X    ttraw.c_cc[5] = 0;   /* [VTIME] for CDC VX/VE */
X#else
X#ifdef MYREAD
X    ttraw.c_cc[4] = 200; /* return max of this many characters */
X    ttraw.c_cc[5] = 1;   /* or when this many secs/10 expire w/no input */
X#else
X    ttraw.c_cc[4] = 1;   /* [VMIN]  Maybe should be bigger for all Sys V? */
X    ttraw.c_cc[5] = 0;   /* [VTIME] Should be set high enough to ignore */
X					/* intercharacter spacing? */
X    /* But then we have to distinguish between Sys III and Sys V.. */
X#endif
X#endif
X#endif
X    if (s > -1) {			/* set speed */
X        ttraw.c_cflag &= ~CBAUD;
X	ttraw.c_cflag |= s;
X    }
X    if (ioctl(ttyfd,TCSETAW,&ttraw) < 0) return(-1);  /* set new modes . */
X    if (flow == DIALING) {
X#ifndef aegis
X	if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
X		return(-1);
X#endif /* not aegis */
X	close( open(ttnmsv,2) );	/* magic to force mode change!!! */
X    }
X    ttflui();
X    return(0);
X#endif /* uxiii */
X}
X
X
X/*  T T V T -- Condition communication line for use as virtual terminal  */
X
Xttvt(speed,flow) int speed, flow; {
X    int s;
X    if (ttyfd < 0) return(-1);		/* Not open. */
X
X    s = ttsspd(speed);			/* Check the speed */
X
X#ifndef UXIII
X    if (flow == 1) tttvt.sg_flags |= TANDEM; /* XON/XOFF if selected */
X    if (flow == 0) tttvt.sg_flags &= ~TANDEM;
X    tttvt.sg_flags |= RAW;		/* Raw mode */
X#ifdef TOWER1
X    tttvt.sg_flags &= ~(ECHO|ANYP);	/* No echo or system III ??? parity */
X#else
X    tttvt.sg_flags &= ~ECHO;		/* No echo */
X#endif
X    if (s > -1) tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */
X    if (stty(ttyfd,&tttvt) < 0) return(-1);
X
X#ifdef MYREAD
X#ifdef BSD4
X/* Make reads nonblocking */
X#ifdef aegis
X	return(0);
X#endif
X	if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) | FNDELAY) == -1)
X	    return(-1);
X	else return(0);
X#endif /* bsd4 */
X#endif /* myread */
X
X#else /* uxiii */
X    if (flow == 1) tttvt.c_iflag |= (IXON|IXOFF);
X    if (flow == 0) tttvt.c_iflag &= ~(IXON|IXOFF);
X
X    if (flow == DIALING)  tttvt.c_cflag |= CLOCAL|HUPCL;
X    if (flow == CONNECT)  tttvt.c_cflag &= ~CLOCAL;
X
X    tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
X    tttvt.c_iflag |= (IGNBRK|IGNPAR);
X    tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|BRKINT|INPCK|ISTRIP|IXANY);
X    tttvt.c_oflag &= ~OPOST;
X    tttvt.c_cflag &= ~(CSIZE|PARENB);
X    tttvt.c_cflag |= (CS8|CREAD);
X    tttvt.c_cc[4] = 1;
X    tttvt.c_cc[5] = 0;
X
X    if (s > -1) {			/* set speed */
X	tttvt.c_cflag &= ~CBAUD;
X	tttvt.c_cflag |= s;
X    }
X    if (ioctl(ttyfd,TCSETAW,&tttvt) < 0) return(-1);  /* set new modes . */
X
X    if (flow == DIALING) {
X#ifndef aegis
X	if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
X		return(-1);
X#endif
X	close( open(ttnmsv,2) );	/* magic to force mode change!!! */
X	}
X#endif
X    return(0);
X}
X
X
X/*  T T S S P D  --  Return the internal baud rate code for 'speed'.  */
X
Xttsspd(speed) {
X    int s, spdok;
X
X    if (speed < 0) return(-1);
X	spdok = 1;			/* Assume arg ok */
X	switch (speed) {
X	    case 0:    s = B0;    break;	/* Just the common ones. */
X	    case 110:  s = B110;  break;	/* The others from ttydev.h */
X	    case 150:  s = B150;  break;	/* could also be included if */
X	    case 300:  s = B300;  break;	/* necessary... */
X	    case 600:  s = B600;  break;
X	    case 1200: s = B1200; break;
X	    case 1800: s = B1800; break;
X	    case 2400: s = B2400; break;
X	    case 4800: s = B4800; break;
X	    case 9600: s = B9600; break;
X#ifdef PLEXUS
X	    case 19200: s = EXTA; break;
X#endif
X#ifdef aegis
X	    case 19200: s = EXTA; break;
X#endif
X	    default:
X	    	spdok = 0;
X		fprintf(stderr,"Unsupported line speed - %d\n",speed);
X		fprintf(stderr,"Current speed not changed\n");
X		break;
X	}    
X	if (spdok) return(s); else return(-1);
X }
X
X
X/*  T T F L U I  --  Flush tty input buffer */
X
Xttflui() {
X
X#ifndef UXIII
X    long n;
X#endif
X    if (ttyfd < 0) return(-1);		/* Not open. */
X
X    ungotn = -1;			/* Initialize myread() stuff */
X    inbufc = 0;
X
X#ifdef aegis
X    sio_$control((short)ttyfd, sio_$flush_in, true, st);
X    if (st.all != status_$ok)
X    {  fprintf(stderr, "flush failed: "); error_$print(st); }
X    else {	/* sometimes the flush doesn't work */
X	for (;;)
X	{   char buf[256];
X	    /* eat all the characters that shouldn't be available */
X	    (void)ios_$get((short)ttyfd, ios_$cond_opt, buf, 256L, st);
X	    if (st.all == ios_$get_conditional_failed) break;
X	    fprintf(stderr, "flush failed(2): "); error_$print(st);
X	}
X    }
X#else
X#ifdef UXIII
X#ifndef VXVE
X    if (ioctl(ttyfd,TCFLSH,0) < 0) perror("flush failed");
X#endif /* vxve */
X#else
X#ifdef TIOCFLUSH
X#ifdef ANYBSD
X    n = FREAD;				/* Specify read queue */
X    if (ioctl(ttyfd,TIOCFLUSH,&n) < 0) perror("flush failed");
X#else
X    if (ioctl(ttyfd,TIOCFLUSH,0) < 0) perror("flush failed");
X#endif
X#endif
X#endif
X#endif
X    return(0);
X}
X
X
X/* Interrupt Functions */
X
X
X/* Timeout handler for communication line input functions */
X
Xtimerh() {
X    longjmp(sjbuf,1);
X}
X
X 
X/* Set up terminal interrupts on console terminal */
X
X#ifdef UXIII
Xesctrp() {				/* trap console escapes (^\) */
X    conesc = 1;
X    signal(SIGQUIT,SIG_IGN);		/* ignore until trapped */
X}
X#endif
X
X#ifdef V7
Xesctrp() {				/* trap console escapes (^\) */
X    conesc = 1;
X    signal(SIGQUIT,SIG_IGN);		/* ignore until trapped */
X}
X#endif
X
X#ifdef C70
Xesctrp() {				/* trap console escapes (^\) */
X    conesc = 1;
X    signal(SIGQUIT,SIG_IGN);		/* ignore until trapped */
X}
X#endif
X
X/*  C O N I N T  --  Console Interrupt setter  */
X
Xconint(f) int (*f)(); {			/* Set an interrupt trap. */
X    int x, y;
X#ifdef SIGTSTP
X    int stptrap();			/* Suspend trap */
X#endif
X
X/* Check for background operation, even if not running on real tty, so that */
X/* background flag can be set correctly. */
X
X#ifdef BSD4
X    int mypgrp;				/* In BSD, we can check whether */
X    int ctpgrp;				/* this process's group is the */
X					/* same as the controlling */
X    mypgrp = getpgrp(0);		/* terminal's process group. */
X    ioctl (1, TIOCGPGRP, &ctpgrp);
X    x = (mypgrp != ctpgrp);		/* If they differ, then background. */
X    debug(F101,"conint process group test","",x);
X#else
X    x = (signal(SIGINT,SIG_IGN) == SIG_IGN);
X    debug(F101,"conint signal test","",x);
X#endif
X    y = isatty(0);
X    debug(F101,"conint isatty test","",y);
X#ifdef BSD29
X/* For some reason the signal() test doesn't work under 2.9 BSD... */
X    backgrd = !y;
X#else
X    backgrd = (x || !y);
X#endif
X    debug(F101,"conint backgrd","",backgrd);
X
X    signal(SIGHUP,f);			/* Ensure lockfile cleared on hangup */
X    signal(SIGTERM,f);			/* or soft kill. */
X
X/* check if invoked in background -- if so signals set to be ignored */
X
X    if (backgrd) {			/* In background, ignore signals */
X#ifdef SIGTSTP
X	signal(SIGTSTP,SIG_IGN);	/* Keyboard stop */
X#endif
X	signal(SIGQUIT,SIG_IGN);	/* Keyboard quit */
X	signal(SIGINT,SIG_IGN);		/* Keyboard interrupt */
X    } else {
X	signal(SIGINT,f);		/* Catch terminal interrupt */
X#ifdef SIGTSTP
X	signal(SIGTSTP,stptrap);	/* Keyboard stop */
X#endif
X#ifdef UXIII
X        signal(SIGQUIT,esctrp);		/* Quit signal, Sys III/V. */
X	if (conesc) conesc = 0;		/* Clear out pending escapes */
X#else
X#ifdef V7
X        signal(SIGQUIT,esctrp);		/* V7 like Sys III/V */
X	if (conesc) conesc = 0;
X#else
X#ifdef aegis
X        signal(SIGQUIT,f);		/* Apollo, catch it like others. */
X#else
X        signal(SIGQUIT,SIG_IGN);	/* Others, ignore like 4D & earlier. */
X#endif
X#endif
X#endif
X	conif = 1;			/* Flag console interrupts on. */
X    }
X    return;
X}
X
X
X/*  C O N N O I  --  Reset console terminal interrupts */
X
Xconnoi() {				/* Console-no-interrupts */
X
X#ifdef SIGTSTP
X    signal(SIGTSTP,SIG_DFL);
X#endif
X    signal(SIGINT,SIG_DFL);
X    signal(SIGHUP,SIG_DFL);
X    signal(SIGQUIT,SIG_DFL);
X    signal(SIGTERM,SIG_DFL);
X    conif = 0;				/* Flag interrupt trapping off */
X}
X
X
X/*  myread() -- For use by systems that can do nonblocking read() calls  */
X/*
X Returns:
X  -1  if no characters available, timer expired
X  -2  upon error (such as disconnect),
X  otherwise value of character (0 or greater)
X*/
Xmyread() {
X    static int inbuf_item;
X    static CHAR inbuf[257];
X    CHAR readit;
X
X    if (ungotn >= 0) {
X	readit = ungotn;
X	ungotn = -1;
X    } else {
X        if (inbufc > 0) {
X	    readit = inbuf[++inbuf_item];
X        } else {
X#ifdef aegis
X    /* myread() returns -1 when no input is available.  All the users of */
X    /* myread() explicitly loop until it returns a character or error. */
X    /* The Apollo code waits for input to be available. */
X
X    /* read in characters */
X	    inbufc = ios_$get((short)ttyfd, ios_$cond_opt, inbuf, 256L, st);
X	    errno = EIO;
X	    if (st.all == ios_$get_conditional_failed) /* get at least one */
X		inbufc = ios_$get((short)ttyfd, 0, inbuf, 1L, st);
X	    if (st.all == ios_$end_of_file) inbufc = 0;
X	    else if (st.all != status_$ok)
X	    {   inbufc = -1; errno = EIO; }
X#else
X            inbufc = read(ttyfd,inbuf,256);
X	    if (inbufc > 0) {
X		inbuf[inbufc] = '\0';
X		debug(F101,"myread read","",inbufc);
X	    }
X#endif /* aegis */
X	    if (inbufc == 0) {
X		if (ttmdm) {
X		    debug(F101,"myread read=0, ttmdm","",ttmdm);
X		    errno = 9999;	/* magic number for no carrier */
X		    return(-2);		/* end of file has no errno */
X		} else return(-1);	/* in sys 5 means no data available */
X	    }
X	    if (inbufc < 0) {		/* Real error */
X#ifdef EWOULDBLOCK
X		if (errno == EWOULDBLOCK) return(-1); else return(-2);
X#else
X		return(-2);
X#endif /* ewouldblock */
X    	    }
X	    readit = inbuf[inbuf_item = 0];
X	}
X        inbufc--;	
X    }
X    return(((int) readit) & 255);
X}
X
Xmyunrd(ch) CHAR ch; {			/* push back up to one character */
X    ungotn = ch;
X}
X
X
X/*  I N I T R A W Q  --  Set up to read /DEV/KMEM for character count.  */
X
X#ifdef	V7
X/*
X Used in Version 7 to simulate Berkeley's FIONREAD ioctl call.  This
X eliminates blocking on a read, because we can read /dev/kmem to get the
X number of characters available for raw input.  If your system can't
X or you won't let it read /dev/kmem (the world that is) then you must
X figure out a different way to do the counting of characters available,
X or else replace this by a dummy function that always returns 0.
X*/
X/*
X * Call this routine as: initrawq(tty)
X * where tty is the file descriptor of a terminal.  It will return
X * (as a char *) the kernel-mode memory address of the rawq character
X * count, which may then be read.  It has the side-effect of flushing
X * input on the terminal.
X */
X/*
X * John Mackin, Physiology Dept., University of Sydney (Australia)
X * ...!decvax!mulga!physiol.su.oz!john
X *
X * Permission is hereby granted to do anything with this code, as
X * long as this comment is retained unmodified and no commercial
X * advantage is gained.
X */
X#include <a.out.h>
X#include <sys/proc.h>
X
Xchar *initrawq(tty) int tty; {
X#ifdef UTS24
X    return(0);
X#else
X#ifdef BSD29
X    return(0);
X#else
X    long lseek();
X    static struct nlist nl[] = {
X	{PROCNAME},
X	{NPROCNAME},
X	{""}
X    };
X    static struct proc *pp;
X    char *malloc(), *qaddr, *p, c;
X    int m, pid, me;
X    NPTYPE xproc;			/* Its type is defined in makefile. */
X    int catch();
X
X    me = getpid();
X    if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
X    nlist(BOOTNAME, nl);
X    if (nl[0].n_type == 0) err("proc array");
X 
X    if (nl[1].n_type == 0) err("nproc");
X
X
X    lseek(m, (long)(nl[1].n_value), 0);
X    read (m, &xproc, sizeof(xproc));
X    signal(SIGALRM, catch);
X    if ((pid = fork()) == 0) {
X	while(1)
X	    read(tty, &c, 1);
X    }
X    alarm(2);
X 
X    if(setjmp(jjbuf) == 0) {
X	while(1)
X	    read(tty, &c, 1);
X    }
X    signal(SIGALRM, SIG_DFL);
X
X#ifdef DIRECT
X    pp = (struct proc *) nl[0].n_value;
X#else
X    if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
X    if (read(m, &pp, sizeof(pp)) != sizeof(pp))  err("no read of proc ptr");
X#endif
X    lseek(m, (long)(nl[1].n_value), 0);
X    read(m, &xproc, sizeof(xproc));
X
X    if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
X    if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
X    if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
X    	err("read proc table");
X    for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
X	if (pp -> p_pid == (short) pid) goto iout;
X    }
X    err("no such proc");
X 
Xiout:
X    close(m);
X    qaddr = (char *)(pp -> p_wchan);
X    free (p);
X    kill(pid, SIGKILL);
X    wait((int *)0);		/* Destroy the ZOMBIEs! */
X    return (qaddr);
X#endif
X#endif
X}
X
X
X/*  More V7-support functions...  */
X
Xstatic
Xerr(s) char *s; {
X    char buf[200];
X
X    sprintf(buf, "fatal error in initrawq: %s", s);
X    perror(buf);
X    doexit(1);
X}
X
Xstatic
Xcatch() {
X    longjmp(jjbuf, -1);
X}
X
X
X/*  G E N B R K  --  Simulate a modem break.  */
X
X#define	BSPEED	B150
X
Xgenbrk(fn) int fn; {
X    struct sgttyb ttbuf;
X    int ret, sospeed;
X
X    ret = ioctl(fn, TIOCGETP, &ttbuf);
X    sospeed = ttbuf.sg_ospeed;
X    ttbuf.sg_ospeed = BSPEED;
X    ret = ioctl(fn, TIOCSETP, &ttbuf);
X    ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", 8);
X    ttbuf.sg_ospeed = sospeed;
X    ret = ioctl(fn, TIOCSETP, &ttbuf);
X    ret = write(fn, "@", 1);
X    return;
X}
X#endif
X
X
X/*  T T C H K  --  Tell how many characters are waiting in tty input buffer  */
X
Xttchk() {
X    int x; long n;
X#ifdef FIONREAD
X    x = ioctl(ttyfd, FIONREAD, &n);	/* Berkeley and maybe some others */
X    debug(F101,"ttchk","",n);
X    return((x < 0) ? 0 : n);
X#else
X#ifdef	V7
X    lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */
X    x = read(kmem[TTY], &n, sizeof(int));
X    return((x == sizeof(int))? n: 0);
X#else
X#ifdef UXIII
X    return(inbufc + (ungotn >= 0) );	/* Sys III, Sys V */
X#else
X#ifdef PROVX1
X    x = ioctl(ttyfd, TIOCQCNT, &ttbuf);	/* Pro/3xx Venix V.1 */
X    n = ttbuf.sg_ispeed & 0377;
X    return((x < 0) ? 0 : n);
X#else
X#ifdef aegis
X    return(inbufc + (ungotn >= 0) );	/* Apollo Aegis */
X#else
X#ifdef C70
X    return(inbufc + (ungotn >= 0) );	/* etc... */
X#else
X    return(0);
X#endif
X#endif
X#endif
X#endif
X#endif
X#endif
X}
X
X
X/*  T T X I N  --  Get n characters from tty input buffer  */
X
X/*  Returns number of characters actually gotten, or -1 on failure  */
X
X/*  Intended for use only when it is known that n characters are actually */
X/*  Available in the input buffer.  */
X
Xttxin(n,buf) int n; char *buf; {
X    int x;
X
X#ifdef MYREAD
X    for( x = 0; (x > -1) && (x < n); buf[x++] = myread() );
X#else
X    debug(F101,"ttxin: n","",n);
X    x = read(ttyfd,buf,n);
X    debug(F101," x","",x);
X#endif
X    if (x > 0) buf[x] = '\0';
X    if (x < 0) x = -1;
X    return(x);
X}
X
X
X/*  T T O L  --  Similar to "ttinl", but for writing.  */
X
Xttol(s,n) int n; char *s; {
X    int x;
X    if (ttyfd < 0) return(-1);		/* Not open. */
X    x = write(ttyfd,s,n);
X    debug(F111,"ttol",s,n);
X    if (x < 0) debug(F101,"ttol failed","",x);
X    return(x);
X}
X
X
X/*  T T O C  --  Output a character to the communication line  */
X
Xttoc(c) char c; {
X    if (ttyfd < 0) return(-1);		/* Not open. */
X    return(write(ttyfd,&c,1));
X}
X
X
X/*  T T I N L  --  Read a record (up to break character) from comm line.  */
X/*
X  If no break character encountered within "max", return "max" characters,
X  with disposition of any remaining characters undefined.  Otherwise, return
X  the characters that were read, including the break character, in "dest" and
X  the number of characters read as the value of the function, or 0 upon end of
X  file, or -1 if an error occurred.  Times out & returns error if not completed
X  within "timo" seconds.
X*/
X#define CTRLC '\03'
Xttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol; {
X    int x = 0, ccn = 0, c, i, j, m, n;	/* local variables */
X
X    if (ttyfd < 0) return(-1);		/* Not open. */
X
X    m = (ttprty) ? 0177 : 0377;		/* Parity stripping mask. */
X    *dest = '\0';			/* Clear destination buffer */
X    if (timo) signal(SIGALRM,timerh);	/* Enable timer interrupt */
X    alarm(timo);			/* Set it. */
X    if (setjmp(sjbuf)) {		/* Timer went off? */
X        x = -1;
X    } else {
X	i = 0;				/* Next char to process */
X	j = 0;				/* Buffer position */
X        while (1) {
X            if ((n = ttchk()) > 0) {	/* See how many chars have arrived */
X                if (n > (max - j)) n = max - j;
X                if ((n = ttxin(n,dest+i)) < 0) { /* Get them all at once */
X		    x = -1;
X		    break;
X		}
X	    } else {			/* Or else... */
X		n = 1;			/* just wait for a char */
X		if ((c = ttinc(0)) == -1) {
X		    x = -1;
X		    break;
X		}
X                dest[i] = c;		/* Got one. */
X	    }
X	    j = i + n;			/* Remember next buffer position. */
X	    if (j >= max) {
X		debug(F101,"ttinl buffer overflow","",j);
X		x = -1;
X		break;
X	    }
X	    for (i; i < j; i++) {	/* Go thru all chars we just got */
X		dest[i] &= m;		/* Strip any parity */
X	        if (dest[i] == eol) {	/* Got eol? */
X		  dest[++i] = '\0';	/* Yes, tie off string, */
X		  alarm(0);		/* turn off timers, etc, */
X		  if (timo) signal(SIGALRM,SIG_DFL); /* and return length. */
X		  return(i);
X	      } else if ((dest[i] & 0177) == CTRLC) { /* Check for ^C^C */
X		  if (++ccn > 1) {	/* If we got 2 in a row, clean up */
X		     alarm(0);		/* and exit. */
X		     signal(SIGALRM,SIG_DFL);
X		     fprintf(stderr,"^C...");
X		     ttres();
X		     fprintf(stderr,"\n");
X		     return(-2);
X		  }
X	      } else ccn = 0;	/* Not ^C, so reset ^C counter, */
X	  }
X	}
X    }
X    debug(F100,"ttinl timout","",0);	/* Get here on timeout. */
X    debug(F111," with",dest,i);
X    alarm(0);				/* Turn off timer */
X    signal(SIGALRM,SIG_DFL);		/* and interrupt, */
X    return(x);				/* and return error code. */
X}
X
X
X/*  T T I N C --  Read a character from the communication line  */
X
Xttinc(timo) int timo; {
X    int m, n = 0;
X    CHAR ch = 0;
X
X    m = (ttprty) ? 0177 : 0377;		/* Parity stripping mask. */
X    if (ttyfd < 0) return(-1);		/* Not open. */
X    if (timo <= 0) {			/* Untimed. */
X#ifdef MYREAD
X    	/* comm line failure returns -1 thru myread, so no &= 0377 */
X    	while ((n = myread()) == -1) ;	/* Wait for a character... */
X	if (n == -2) n++;
X	return( (n < 0) ? -1 : n & m );
X#else
X	while ((n = read(ttyfd,&ch,1)) == 0) ; /* Wait for a character. */
X	return( (n < 0) ? -1 : (ch & 0377) );
X#endif
X    }
X    signal(SIGALRM,timerh);		/* Timed, set up timer. */
X    alarm(timo);
X    if (setjmp(sjbuf)) {
X	n = -1;
X    } else {
X#ifdef MYREAD
X    	while ((n = myread()) == -1) ;	/* If managing own buffer... */
X	if (n == -2) {
X	    n++;
X	} else {
X	    ch = n;
X	    n = 1;	
X	}
X#else
X    	n = read(ttyfd,&ch,1);		/* Otherwise call the system. */
X#endif
X    }
X    alarm(0);				/* Turn off timer, */
X    signal(SIGALRM,SIG_DFL);		/* and interrupt. */
X    return( (n < 0) ? -1 : (ch & m) );  /* Return char or -1. */
X}
X
X
X/*  T T S N D B  --  Send a BREAK signal  */
X
Xttsndb() {
X    int x; long n; char spd;
X
X    if (ttyfd < 0) return(-1);		/* Not open. */
X
X#ifdef PROVX1
X    gtty(ttyfd,&ttbuf);			/* Get current tty flags */
X    spd = ttbuf.sg_ospeed;		/* Save speed */
X    ttbuf.sg_ospeed = B50;		/* Change to 50 baud */
X    stty(ttyfd,&ttbuf);			/*  ... */
X    write(ttyfd,brnuls,3);		/* Send 3 nulls */
X    ttbuf.sg_ospeed = spd;		/* Restore speed */
X    stty(ttyfd,&ttbuf);			/*  ... */
X    return(0);
X#else
X#ifdef aegis
X    sio_$control((short)ttyfd, sio_$send_break, 250, st);
X    return(0);
X#else
X#ifdef UXIII
X    if (ioctl(ttyfd,TCSBRK,(char *)0) < 0) {	/* Send a BREAK */
SHAR_EOF
echo "End of part 35"
echo "File ckermit/ckutio-orig.c is continued in part 36"
echo "36" > 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.