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.