ecu - SCO XENIX V/{2,3}86 Extended CU part 35/47
Warren Tucker
wht at tridom.uucp
Thu Oct 12 05:11:23 AEST 1989
---- 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.
More information about the Alt.sources
mailing list