From decwrl!elroy.jpl.nasa.gov!sdd.hp.com!cs.utexas.edu!uunet!allbery Wed May 16 10:13:47 PDT 1990 Article 1558 of comp.sources.misc: Path: decwrl!elroy.jpl.nasa.gov!sdd.hp.com!cs.utexas.edu!uunet!allbery From: wht%n4hgf@gatech.edu (Warren Tucker) Newsgroups: comp.sources.misc Subject: v12i078: ECU 2.80 part 25/29 Message-ID: <88381@uunet.UU.NET> Date: 12 May 90 02:04:37 GMT Sender: allbery@uunet.UU.NET Lines: 2280 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 12, Issue 78 Submitted-by: wht%n4hgf@gatech.edu (Warren Tucker) Archive-name: ecu2.80/part25 ---- Cut Here and unpack ---- #!/bin/sh # This is part 25 of ecu280 if touch 2>&1 | fgrep '[-amc]' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= ckermit/ckutio-orig.c ============== if test ! -d 'ckermit'; then echo "x - creating directory ckermit" mkdir 'ckermit' fi echo "x - extracting ckermit/ckutio-orig.c (Text)" sed 's/^X//' << 'SHAR_EOF' > ckermit/ckutio-orig.c && Xchar *ckxv = "Unix tty I/O, 4E(047), 27 Jan 88"; X X/* C K U T I O */ X X/* C-Kermit interrupt, terminal control & i/o functions for Unix systems */ X X/* X Author: Frank da Cruz (SY.FDC@CU20B), X Columbia University Center for Computing Activities, January 1985. X Copyright (C) 1985, 1988, Trustees of Columbia University in the City of New X York. Permission is granted to any individual or institution to use, copy, or X redistribute this software so long as it is not sold for profit, provided this X copyright notice is retained. X*/ X/* Includes for all Unixes (conditional includes come later) */ X X#include /* Types */ X X#include /* Directory */ X#include /* Character types */ X#ifdef NULL X#undef NULL X#endif /* NULL */ X#include /* Unix Standard i/o */ X#include /* Interrupts */ X X#ifndef ZILOG X#include /* Longjumps */ X#else X#include X#endif X X#include "ckcdeb.h" /* Typedefs, formats for debug() */ X X/* Maximum length for the name of a tty device */ X X#ifndef DEVNAMLEN X#define DEVNAMLEN 25 X#endif X X/* 4.1 BSD support added by Charles E. Brooks, EDN-VAX */ X/* Fortune 32:16 Pro:For 1.8 support mostly like 4.1, added by J-P Dumas */ X X#ifdef BSD4 X#define ANYBSD X#ifdef MAXNAMLEN X#define BSD42 X#ifdef aegis Xchar *ckxsys = " Apollo DOMAIN/IX 4.2 BSD"; X#else Xchar *ckxsys = " 4.2 BSD"; X#endif /* aegis */ X#else X#ifdef FT18 X#define BSD41 Xchar *ckxsys = " Fortune For:Pro 1.8"; X#else X#define BSD41 X#ifndef C70 Xchar *ckxsys = " 4.1 BSD"; X#endif /* not c70 */ X#endif /* ft18 */ X#endif /* maxnamlen */ X#endif /* bsd4 */ X X/* 2.9bsd support contributed by Bradley Smith, UCLA */ X#ifdef BSD29 X#define ANYBSD Xchar *ckxsys = " 2.9 BSD"; X#endif /* bsd29 */ X X/* X Version 7 UNIX support contributed by Gregg Wonderly, X Oklahoma State University: gregg@okstate.csnet X*/ X#ifdef V7 Xchar *ckxsys = " Version 7 UNIX (tm)"; X#endif /* v7 */ X X/* BBN C70 support from Frank Wancho, WANCHO@SIMTEL20 */ X#ifdef C70 Xchar *ckxsys = " BBN C/70"; X#endif /* c70 */ X X/* IBM 370 IX/370 support from Wayne Van Pelt, GE/CRD, Schenectedy, NY */ X#ifdef IX370 Xchar *ckxsys = " IBM IX/370"; X#endif /* ix370 */ X X/* Amdahl UTS 2.4 (v7 derivative) for IBM 370 series compatible mainframes */ X/* Contributed by Garard Gaye, Jean-Pierre Dumas, DUMAS@SUMEX-AIM. */ X#ifdef UTS24 Xchar *ckxsys = " Amdahl UTS 2.4"; X#endif /* uts24 */ X X/* Pro/Venix Version 1.x support from Columbia U. */ X#ifdef PROVX1 Xchar *ckxsys = " Pro-3xx Venix v1"; X#endif /* provx1 */ X X/* Tower support contributed by John Bray, Auburn, Alabama */ X#ifdef TOWER1 Xchar *ckxsys = " NCR Tower 1632, OS 1.02"; X#endif /* tower1 */ X X/* Sys III/V, Xenix, PC/IX support by Herm Fischer, Encino, CA */ X#ifdef UXIII X#ifdef XENIX Xchar *ckxsys = " Xenix/286"; X#else X#ifdef PCIX Xchar *ckxsys = " PC/IX"; X#else X#ifdef ISIII Xchar *ckxsys = " Interactive Systems Corp System III"; X#else X#ifdef hpux X/* HP 9000 Series changes contributed by Bill Coalson */ Xchar *ckxsys = " HP 9000 Series HP-UX"; X#else X#ifdef aegis X/* Apollo Aegis support from SAS Institute, Cary, NC */ Xchar *ckxsys = " Apollo DOMAIN/IX System V"; X#else X#ifdef ZILOG Xchar *ckxsys = " Zilog S8000 Zeus 3.21+"; X#else X#ifdef VXVE X/* Control Data Corp VX/VE 5.2.1 System V support by */ X/* S.O. Lidie, Lehigh University, LUSOL@LEHICDC1.BITNET */ Xchar *ckxsys = " CDC VX/VE 5.2.1 System V"; X#else Xchar *ckxsys = " AT&T System III/System V"; X#endif /* vxve */ X#endif /* zilog */ X#endif /* aegis */ X#endif /* hpux */ X#endif /* isiii */ X#endif /* pcix */ X#endif /* xenix */ X#endif /* uxiii */ X X/* Features... */ X X/* Do own buffering, using unbuffered read() calls... */ X#ifdef UXIII X#define MYREAD X#endif /* uxiii */ X X#ifdef BSD42 X#undef MYREAD X#include X#endif /* bsd42 */ X X X/* X Variables available to outside world: X X dftty -- Pointer to default tty name string, like "/dev/tty". X dfloc -- 0 if dftty is console, 1 if external line. X dfprty -- Default parity X dfflow -- Default flow control X ckxech -- Flag for who echoes console typein: X 1 - The program (system echo is turned off) X 0 - The system (or front end, or terminal). X functions that want to do their own echoing should check this flag X before doing so. X X flfnam -- Name of lock file, including its path, e.g., X "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77" X hasLock -- Flag set if this kermit established a uucp lock. X inbufc -- number of tty line rawmode unread characters X (system III/V unixes) X backgrd -- Flag indicating program executing in background ( & on X end of shell command). Used to ignore INT and QUIT signals. X X Functions for assigned communication line (either external or console tty): X X sysinit() -- System dependent program initialization X syscleanup() -- System dependent program shutdown X ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access. X ttclos() -- Close & reset the tty, releasing any access lock. X ttpkt(speed,flow) -- Put the tty in packet mode and set the speed. X ttvt(speed,flow) -- Put the tty in virtual terminal mode. X or in DIALING or CONNECTED modem control state. X ttinl(dest,max,timo) -- Timed read line from the tty. X ttinc(timo) -- Timed read character from tty. X myread() -- System 3 raw mode bulk buffer read, gives X -- subsequent chars one at a time and simulates X -- FIONREAD! X myunrd(c) -- Places c back in buffer to be read (one only) X ttchk() -- See how many characters in tty input buffer. X ttxin(n,buf) -- Read n characters from tty (untimed). X ttol(string,length) -- Write a string to the tty. X ttoc(c) -- Write a character to the tty. X ttflui() -- Flush tty input buffer. X X ttlock(ttname) -- Lock against uucp collisions (Sys III) X ttunlck() -- Unlock " " " X look4lk(ttname) -- Check if a lock file exists X*/ X X X/* XFunctions for console terminal: X X congm() -- Get console terminal modes. X concb(esc) -- Put the console in single-character wakeup mode with no echo. X conbin(esc) -- Put the console in binary (raw) mode. X conres() -- Restore the console to mode obtained by congm(). X conoc(c) -- Unbuffered output, one character to console. X conol(s) -- Unbuffered output, null-terminated string to the console. X conola(s) -- Unbuffered output, array of strings to the console. X conxo(n,s) -- Unbuffered output, n characters to the console. X conchk() -- Check if characters available at console (bsd 4.2). X Check if escape char (^\) typed at console (System III/V). X coninc(timo) -- Timed get a character from the console. X conint() -- Enable terminal interrupts on the console if not background. X connoi() -- Disable terminal interrupts on the console if not background. X XTime functions X X msleep(m) -- Millisecond sleep X ztime(&s) -- Return pointer to date/time string X rtimer() -- Reset timer X gtimer() -- Get elapsed time since last call to rtimer() X*/ X X X/* Conditional Includes */ X X#ifdef FT18 X#include /* File information */ X#endif /* ft18 */ X X/* Whether to #include ... */ X#ifndef PROVX1 X#ifndef aegis X#ifndef XENIX X#include /* File information */ X#endif /* xenix */ X#endif /* aegis */ X#endif /* provx1 */ X X#ifdef aegis X#ifdef BSD4 X#include X#include X#endif /* bsd4 */ X#endif /* aegis */ X X/* System III, System V */ X X#ifdef UXIII X#include X#include X#include /* directory reading for locking */ X#include /* error numbers for system returns */ X#endif /* uxiii */ X X#ifdef HPUX X#include X#endif X X/* Not Sys III/V */ X X#ifndef UXIII X#include /* Set/Get tty modes */ X#ifndef PROVX1 X#ifndef V7 X#ifndef BSD41 X#include /* Clock info (for break generation) */ X#endif /* not bsd41 */ X#endif /* not v7 */ X#endif /* not provx1 */ X#endif /* not uxiii */ X X#ifdef BSD41 X#include /* BSD 4.1 ... ceb */ X#endif /* bsd41 */ X X#ifdef BSD29 X#include /* BSD 2.9 (Vic Abell, Purdue) */ X#endif /* bsd29 */ X X#ifdef TOWER1 X#include /* Clock info for NCR Tower */ X#endif /* tower1 */ X X#ifdef aegis X#include "/sys/ins/base.ins.c" X#include "/sys/ins/error.ins.c" X#include "/sys/ins/ios.ins.c" X#include "/sys/ins/sio.ins.c" X#include "/sys/ins/pad.ins.c" X#include "/sys/ins/time.ins.c" X#include "/sys/ins/pfm.ins.c" X#include "/sys/ins/pgm.ins.c" X#include "/sys/ins/ec2.ins.c" X#include "/sys/ins/type_uids.ins.c" X#include X#undef TIOCEXCL X#undef FIONREAD X#endif X X/* The following two conditional #defines are catch-alls for those systems */ X/* that didn't have or couldn't find ... */ X X#ifndef FREAD X#define FREAD 0x01 X#endif X X#ifndef FWRITE X#define FWRITE 0x10 X#endif X X X/* Declarations */ X Xlong time(); /* All Unixes should have this... */ Xextern int errno; /* System call error code. */ X X/* Special stuff for V7 input buffer peeking */ X X#ifdef V7 Xint kmem[2] = { -1, -1}; Xchar *initrawq(), *qaddr[2]={0,0}; X#define CON 0 X#define TTY 1 X#endif /* v7 */ X X/* dftty is the device name of the default device for file transfer */ X/* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */ X X#ifdef PROVX1 X char *dftty = "/dev/com1.dout"; /* Only example so far of a system */ X int dfloc = 1; /* that goes in local mode by default */ X#else X char *dftty = CTTNAM; /* Remote by default, use normal */ X int dfloc = 0; /* controlling terminal name. */ X#endif /* provx1 */ X X int dfprty = 0; /* Default parity (0 = none) */ X int ttprty = 0; /* Parity in use. */ X int ttmdm = 0; /* Modem in use. */ X int dfflow = 1; /* Xon/Xoff flow control */ X int backgrd = 0; /* Assume in foreground (no '&' ) */ X Xint ckxech = 0; /* 0 if system normally echoes console characters, else 1 */ X X/* Declarations of variables global within this module */ X Xstatic long tcount; /* Elapsed time counter */ X Xstatic char *brnuls = "\0\0\0\0\0\0\0"; /* A string of nulls */ X Xstatic jmp_buf sjbuf, jjbuf; /* Longjump buffer */ Xstatic int lkf = 0, /* Line lock flag */ X conif = 0, /* Console interrupts on/off flag */ X cgmf = 0, /* Flag that console modes saved */ X xlocal = 0, /* Flag for tty local or remote */ X ttyfd = -1; /* TTY file descriptor */ Xstatic char escchr; /* Escape or attn character */ X X#ifdef BSD42 X static struct timeval tv; /* For getting time, from sys/time.h */ X static struct timezone tz; X#endif /* bsd42 */ X X#ifdef BSD29 X static long clock; /* For getting time from sys/time.h */ X static struct timeb ftp; /* And from sys/timeb.h */ X#endif /* bsd29 */ X X#ifdef BSD41 X static long clock; /* For getting time from sys/time.h */ X static struct timeb ftp; /* And from sys/timeb.h */ X#endif /* bsd41 */ X X#ifdef TOWER1 Xstatic long clock; /* For getting time from sys/time.h */ Xstatic struct timeb ftp; /* And from sys/timeb.h */ X#endif /* tower1 */ X X#ifdef V7 Xstatic long clock; X#endif /* v7 */ X X/* sgtty/termio information... */ X X#ifdef UXIII X static struct termio ttold = {0}; /* Init'd for word alignment, */ X static struct termio ttraw = {0}; /* which is important for some */ X static struct termio tttvt = {0}; /* systems, like Zilog... */ X static struct termio ccold = {0}; X static struct termio ccraw = {0}; X static struct termio cccbrk = {0}; X#else X static struct sgttyb /* sgtty info... */ X ttold, ttraw, tttvt, ttbuf, /* for communication line */ X ccold, ccraw, cccbrk; /* and for console */ X#endif /* uxiii */ X Xstatic char flfnam[80]; /* uucp lock file path name */ Xstatic int hasLock = 0; /* =1 if this kermit locked uucp */ Xstatic int inbufc = 0; /* stuff for efficient SIII raw line */ Xstatic int ungotn = -1; /* pushback to unread character */ Xstatic int conesc = 0; /* set to 1 if esc char (^\) typed */ X Xstatic int ttlock(); /* definition of ttlock subprocedure */ Xstatic int ttunlck(); /* and unlock subprocedure */ Xstatic char ttnmsv[DEVNAMLEN]; /* copy of open path for tthang */ X X X#ifdef aegis Xstatic status_$t st; /* error status return value */ Xstatic short concrp = 0; /* true if console is CRP pad */ X#define CONBUFSIZ 10 Xstatic char conbuf[CONBUFSIZ]; /* console readahead buffer */ Xstatic int conbufn = 0; /* # chars in readahead buffer */ Xstatic char *conbufp; /* next char in readahead buffer */ Xstatic uid_$t ttyuid; /* tty type uid */ Xstatic uid_$t conuid; /* stdout type uid */ X X/* APOLLO Aegis main() X * establish acl usage and cleanup handling X * this makes sure that CRP pads X * get restored to a usable mode X */ Xmain(argc,argv) int argc; char **argv; { X status_$t status; X pfm_$cleanup_rec dirty; X X int pid = getpid(); X X /* acl usage according to invoking environment */ X default_acl(USE_DEFENV); X X /* establish a cleanup continuation */ X status = pfm_$cleanup(dirty); X if (status.all != pfm_$cleanup_set) X { X /* only handle faults for the original process */ X if (pid == getpid() && status.all > pgm_$max_severity) X { /* blew up in main process */ X status_$t quo; X pfm_$cleanup_rec clean; X X /* restore the console in any case */ X conres(); X X /* attempt a clean exit */ X debug(F101, "cleanup fault status", "", status.all); X X /* doexit(), then send status to continuation */ X quo = pfm_$cleanup(clean); X if (quo.all == pfm_$cleanup_set) X doexit(pgm_$program_faulted); X else if (quo.all > pgm_$max_severity) X pfm_$signal(quo); /* blew up in doexit() */ X } X /* send to the original continuation */ X pfm_$signal(status); X /*NOTREACHED*/ X } X return(ckcmai(argc, argv)); X} X#endif /* aegis */ X X X/* S Y S I N I T -- System-dependent program initialization. */ X Xsysinit() { X X/* for now, nothing... */ X return(0); X} X X/* S Y S C L E A N U P -- System-dependent program cleanup. */ X Xsyscleanup() { X X/* for now, nothing... */ X return(0); X} X X X/* T T O P E N -- Open a tty for exclusive access. */ X X/* Returns 0 on success, -1 on failure. */ X/* X If called with lcl < 0, sets value of lcl as follows: X 0: the terminal named by ttname is the job's controlling terminal. X 1: the terminal named by ttname is not the job's controlling terminal. X But watch out: if a line is already open, or if requested line can't X be opened, then lcl remains (and is returned as) -1. X*/ Xttopen(ttname,lcl,modem) char *ttname; int *lcl, modem; { X X#ifdef UXIII X#ifndef CIE X char *ctermid(); /* Wish they all had this! */ X#endif /* not cie */ X#endif /* uxiii */ X X#ifdef CIE /* CIE Regulus doesn't... */ X#define ctermid(x) strcpy(x,"") X#endif X X char *x; extern char* ttyname(); X char cname[DEVNAMLEN+4]; X X if (ttyfd > -1) return(0); /* If already open, ignore this call */ X ttmdm = modem; /* Make this available to other fns */ X xlocal = *lcl; /* Make this available to other fns */ X#ifdef NEWUUCP X acucntrl("disable",ttname); /* Open getty on line (4.3BSD) */ X#endif /* newuucp */ X 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 /* uxiii */ X X if (ttyfd < 0) { /* If couldn't open, fail. */ X perror(ttname); X return(-1); X } X#ifdef aegis X /* Apollo C runtime claims that console pads are tty devices, which X * is reasonable, but they aren't any good for packet transfer. */ X ios_$inq_type_uid((short)ttyfd, ttyuid, st); X if (st.all != status_$ok) { X fprintf(stderr, "problem getting tty object type: "); X error_$print(st); X } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */ X close(ttyfd); ttyfd = -1; X errno = ENOTTY; perror(ttname); X return(-1); X } X#endif /* aegis */ X strncpy(ttnmsv,ttname,DEVNAMLEN); /* Open, keep copy of name locally. */ X X/* Caller wants us to figure out if line is controlling tty */ X X debug(F111,"ttopen ok",ttname,*lcl); X if (*lcl == -1) { X if (strcmp(ttname,CTTNAM) == 0) { /* "/dev/tty" always remote */ X debug(F110," Same as CTTNAM",ttname,0); X xlocal = 0; X } else if (isatty(0)) { /* Else, if stdin not redirected */ X x = ttyname(0); /* then compare its device name */ X strncpy(cname,x,DEVNAMLEN); /* (copy from internal static buf) */ X debug(F110," ttyname(0)",x,0); X x = ttyname(ttyfd); /* ...with real name of ttname. */ X xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1; X debug(F111," ttyname",x,xlocal); X } else { /* Else, if stdin redirected... */ X#ifdef UXIII X/* Sys III/V provides nice ctermid() function to get name of controlling tty */ X ctermid(cname); /* Get name of controlling terminal */ X debug(F110," ctermid",cname,0); X x = ttyname(ttyfd); /* Compare with name of comm line. */ X xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1; X debug(F111," ttyname",x,xlocal); X#else X/* Just assume local, so "set speed" and similar commands will work */ X/* If not really local, how could it work anyway?... */ X xlocal = 1; X debug(F101," redirected stdin","",xlocal); X#endif /* uxiii */ X } X } X X/* Now check if line is locked -- if so fail, else lock for ourselves */ X X lkf = 0; /* Check lock */ X if (xlocal > 0) { X if (ttlock(ttname) < 0) { X fprintf(stderr,"Exclusive access to %s denied\n",ttname); X close(ttyfd); ttyfd = -1; X debug(F110," Access denied by lock",ttname,0); X return(-1); /* Not if already locked */ X } else lkf = 1; X } X X/* Got the line, now set the desired value for local. */ X X if (*lcl < 0) *lcl = xlocal; X X/* Some special stuff for v7... */ X X#ifdef V7 X if (kmem[TTY] < 0) { /* If open, then skip this. */ X qaddr[TTY] = initrawq(ttyfd); /* Init the queue. */ X if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) { X fprintf(stderr, "Can't read /dev/kmem in ttopen.\n"); X perror("/dev/kmem"); X exit(1); X } X } X#endif /* v7 */ X X/* Request exclusive access on systems that allow it. */ X X#ifndef XENIX X/* Xenix exclusive access prevents open(close(...)) from working... */ X#ifdef TIOCEXCL X if (ioctl(ttyfd,TIOCEXCL, NULL) < 0) X fprintf(stderr,"Warning, problem getting exclusive access\n"); X#endif /* tiocexcl */ X#endif /* xenix */ X X/* Get tty device settings */ X X#ifndef UXIII X gtty(ttyfd,&ttold); /* Get sgtty info */ X#ifdef aegis X sio_$control((short)ttyfd, sio_$raw_nl, false, st); X if (xlocal) { /* ignore breaks from local line */ X sio_$control((short)ttyfd, sio_$int_enable, false, st); X sio_$control((short)ttyfd, sio_$quit_enable, false, st); X } X#endif /* aegis */ 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#ifdef aegis X sio_$control((short)ttyfd, sio_$raw_nl, false, st); X if (xlocal) { /* ignore breaks from local line */ X sio_$control((short)ttyfd, sio_$int_enable, false, st); X sio_$control((short)ttyfd, sio_$quit_enable, false, st); X } X#endif /* aegis */ X ioctl(ttyfd,TCGETA,&ttraw); X ioctl(ttyfd,TCGETA,&tttvt); X#endif /* not uxiii */ X X#ifdef VXVE X ttraw.c_line = 0; /* STTY line 0 for VX/VE */ X ioctl(ttyfd,TCSETA,&ttraw); X tttvt.c_line = 0; /* STTY line 0 for VX/VE */ X ioctl(ttyfd,TCSETA,&tttvt); X#endif /* vxve */ X X debug(F101,"ttopen, ttyfd","",ttyfd); X debug(F101," lcl","",*lcl); X debug(F111," lock file",flfnam,lkf); X return(0); X} X X X/* T T C L O S -- Close the TTY, releasing any lock. */ X Xttclos() { X if (ttyfd < 0) return(0); /* Wasn't open. */ X if (xlocal) { X if (tthang()) /* Hang up phone line */ X fprintf(stderr,"Warning, problem hanging up the phone\n"); X if (ttunlck()) /* Release uucp-style lock */ X fprintf(stderr,"Warning, problem releasing lock\n"); X } X ttres(); /* Reset modes. */ X/* Relinquish exclusive access if we might have had it... */ X#ifndef XENIX X#ifdef TIOCEXCL X#ifdef TIOCNXCL X if (ioctl(ttyfd, TIOCNXCL, NULL) < 0) X fprintf(stderr,"Warning, problem relinquishing exclusive access\n"); X#endif /* tiocnxcl */ X#endif /* tiocexcl */ X#endif /* not xenix */ X close(ttyfd); /* Close it. */ X#ifdef NEWUUCP X acucntrl("enable",flfnam); /* Close getty on line. */ X#endif /* newuucp */ X ttyfd = -1; /* Mark it as closed. */ X return(0); X} X X/* T T H A N G -- Hangup phone line */ X Xtthang() { X#ifdef UXIII X#ifdef HPUX X unsigned long dtr_down = 00000000000, X modem_rtn; 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 X#include 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 */ 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 */ 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 X#include 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 $TOUCH -am 0507233990 ckermit/ckutio-orig.c && chmod 0644 ckermit/ckutio-orig.c || echo "restore of ckermit/ckutio-orig.c failed" set `wc -c ckermit/ckutio-orig.c`;Wc_c=$1 if test "$Wc_c" != "62898"; then echo original size 62898, current size $Wc_c fi echo "End of part 25, continue with part 26" exit 0