Annotation of 43BSDReno/contrib/kermit/ckutio.c, revision 1.1

1.1     ! root        1: char *ckxv = "Unix tty I/O, 4C(037), 31 Jul 85";
        !             2: 
        !             3: /*  C K U T I O  */
        !             4: 
        !             5: /* C-Kermit interrupt, terminal control & i/o functions for Unix systems */
        !             6: 
        !             7: /*
        !             8:  Author: Frank da Cruz (SY.FDC@CU20B),
        !             9:  Columbia University Center for Computing Activities, January 1985.
        !            10:  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
        !            11:  Permission is granted to any individual or institution to use, copy, or
        !            12:  redistribute this software so long as it is not sold for profit, provided this
        !            13:  copyright notice is retained. 
        !            14: */
        !            15: /* Includes for all Unixes (conditional includes come later) */
        !            16: 
        !            17: #include <sys/types.h>                 /* Types */
        !            18: #include <sys/dir.h>                   /* Directory */
        !            19: #include <sys/param.h>         
        !            20: #include <ctype.h>                     /* Character types */
        !            21: #include <stdio.h>                     /* Unix Standard i/o */
        !            22: #include <signal.h>                    /* Interrupts */
        !            23: #include <setjmp.h>                    /* Longjumps */
        !            24: #include "ckcdeb.h"                    /* Typedefs, formats for debug() */
        !            25: 
        !            26: /* Maximum length for the name of a tty device */
        !            27: 
        !            28: #ifndef DEVNAMLEN
        !            29: #define DEVNAMLEN 25
        !            30: #endif
        !            31: 
        !            32: /* 4.1 BSD support added by Charles E. Brooks, EDN-VAX */
        !            33: /* Fortune 16:32 For:Pro 1.7 support mostly like 4.1, added by J-P Dumas */
        !            34: 
        !            35: #ifdef BSD4
        !            36: #define ANYBSD
        !            37: #undef DIRSIZ
        !            38: #define DIRSIZ (sizeof(struct direct))
        !            39: #ifdef MAXNAMLEN
        !            40: #define BSD42
        !            41: char *ckxsys = " 4.2 BSD";
        !            42: #else
        !            43: #ifdef FT17
        !            44: #define BSD41
        !            45: char *ckxsys = " For:Pro Fortune 1.7";
        !            46: #else
        !            47: #define BSD41
        !            48: #ifndef C70
        !            49: char *ckxsys = " 4.1 BSD";
        !            50: #endif
        !            51: #endif
        !            52: #endif
        !            53: #endif
        !            54: 
        !            55: /* 2.9bsd support contributed by Bradley Smith, UCLA */
        !            56: #ifdef BSD29
        !            57: #define ANYBSD
        !            58: char *ckxsys = " 2.9 BSD";
        !            59: #endif
        !            60: 
        !            61: /*
        !            62:  Version 7 UNIX support contributed by Gregg Wonderly,
        !            63:  Oklahoma State University:  [email protected]
        !            64: */
        !            65: #ifdef V7
        !            66: char *ckxsys = " Version 7 UNIX (tm)";
        !            67: #endif V7
        !            68: 
        !            69: /* BBN C70 support from Frank Wancho, WANCHO@SIMTEL20 */
        !            70: #ifdef C70
        !            71: char *ckxsys = " BBN C/70";
        !            72: #endif
        !            73: 
        !            74: /* Amdahl UTS 2.4 (v7 derivative) for IBM 370 series compatible mainframes */
        !            75: /* Contributed by Garard Gaye, Jean-Pierre Dumas, DUMAS@SUMEX-AIM. */
        !            76: #ifdef UTS24
        !            77: char *ckxsys = " Amdahl UTS 2.4";
        !            78: #endif
        !            79: 
        !            80: /* Pro/Venix Version 1.x support from Columbia U. */
        !            81: #ifdef PROVX1
        !            82: char *ckxsys = " Pro-3xx Venix v1";
        !            83: #endif
        !            84: 
        !            85: /* Tower support contributed by John Bray, Auburn, Alabama */
        !            86: #ifdef TOWER1
        !            87: char *ckxsys = " NCR Tower 1632, OS 1.02";
        !            88: #endif
        !            89: 
        !            90: /* Sys III/V, Xenix, PC/IX support by Herm Fischer, Encino, CA */
        !            91: #ifdef UXIII
        !            92: #ifdef XENIX
        !            93: char *ckxsys = " Xenix/286";
        !            94: #else
        !            95: #ifdef PCIX
        !            96: char *ckxsys = " PC/IX";
        !            97: #else
        !            98: #ifdef ISIII
        !            99: char *ckxsys = " Interactive Systems Corp System III";
        !           100: #else
        !           101: char *ckxsys = " AT&T System III/System V";
        !           102: #endif
        !           103: #endif
        !           104: #endif
        !           105: #endif
        !           106: 
        !           107: /* Features... */
        !           108: 
        !           109: /* Do own buffering, using unbuffered read() calls... */
        !           110: #ifdef UXIII
        !           111: #define MYREAD
        !           112: #endif
        !           113: 
        !           114: #ifdef BSD42
        !           115: #define MYREAD
        !           116: #endif
        !           117: 
        !           118: /*
        !           119:  Note - KERLD is the Berkeley Unix Berknet line driver, modified to pass
        !           120:  through all 8  bits, and to allow an arbitrary break character to be set.
        !           121:  Don't define this symbol unless you have made this modification to your
        !           122:  4.2BSD kernel!
        !           123: */
        !           124: #ifdef BSD4
        !           125: /* #define KERLD */  /* <-- note, commented out */
        !           126: #endif
        !           127: 
        !           128: /*
        !           129:  Variables available to outside world:
        !           130: 
        !           131:    dftty  -- Pointer to default tty name string, like "/dev/tty".
        !           132:    dfloc  -- 0 if dftty is console, 1 if external line.
        !           133:    dfprty -- Default parity
        !           134:    dfflow -- Default flow control
        !           135:    ckxech -- Flag for who echoes console typein:
        !           136:      1 - The program (system echo is turned off)
        !           137:      0 - The system (or front end, or terminal).
        !           138:    functions that want to do their own echoing should check this flag
        !           139:    before doing so.
        !           140: 
        !           141:    flfnam -- Name of lock file, including its path, e.g.,
        !           142:                "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
        !           143:    hasLock -- Flag set if this kermit established a uucp lock.
        !           144:    inbufc -- number of tty line rawmode unread characters 
        !           145:                (system III/V unixes)
        !           146:    backgrd -- Flag indicating program executing in background ( & on 
        !           147:                end of shell command). Used to ignore INT and QUIT signals.
        !           148: 
        !           149:  Functions for assigned communication line (either external or console tty):
        !           150: 
        !           151:    sysinit()               -- System dependent program initialization
        !           152:    ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access.
        !           153:    ttclos()                -- Close & reset the tty, releasing any access lock.
        !           154:    ttpkt(speed,flow)       -- Put the tty in packet mode and set the speed.
        !           155:    ttvt(speed,flow)        -- Put the tty in virtual terminal mode.
        !           156:                                or in DIALING or CONNECTED modem control state.
        !           157:    ttinl(dest,max,timo)    -- Timed read line from the tty.
        !           158:    ttinc(timo)             -- Timed read character from tty.
        !           159:    myread()               -- System 3 raw mode bulk buffer read, gives
        !           160:                           --   subsequent chars one at a time and simulates
        !           161:                           --   FIONREAD!
        !           162:    myunrd(c)              -- Places c back in buffer to be read (one only)
        !           163:    ttchk()                 -- See how many characters in tty input buffer.
        !           164:    ttxin(n,buf)            -- Read n characters from tty (untimed).
        !           165:    ttol(string,length)     -- Write a string to the tty.
        !           166:    ttoc(c)                 -- Write a character to the tty.
        !           167:    ttflui()                -- Flush tty input buffer.
        !           168: 
        !           169:    ttlock(ttname)         -- Lock against uucp collisions (Sys III)
        !           170:    ttunlck()              -- Unlock "       "     "
        !           171:    look4lk(ttname)        -- Check if a lock file exists
        !           172: */
        !           173: 
        !           174: /*
        !           175: Functions for console terminal:
        !           176: 
        !           177:    congm()   -- Get console terminal modes.
        !           178:    concb(esc) -- Put the console in single-character wakeup mode with no echo.
        !           179:    conbin(esc) -- Put the console in binary (raw) mode.
        !           180:    conres()  -- Restore the console to mode obtained by congm().
        !           181:    conoc(c)  -- Unbuffered output, one character to console.
        !           182:    conol(s)  -- Unbuffered output, null-terminated string to the console.
        !           183:    conola(s) -- Unbuffered output, array of strings to the console.
        !           184:    conxo(n,s) -- Unbuffered output, n characters to the console.
        !           185:    conchk()  -- Check if characters available at console (bsd 4.2).
        !           186:                Check if escape char (^\) typed at console (System III/V).
        !           187:    coninc(timo)  -- Timed get a character from the console.
        !           188:    conint()  -- Enable terminal interrupts on the console if not background.
        !           189:    connoi()  -- Disable terminal interrupts on the console if not background.
        !           190: 
        !           191: Time functions
        !           192: 
        !           193:    msleep(m) -- Millisecond sleep
        !           194:    ztime(&s) -- Return pointer to date/time string
        !           195:    rtimer() --  Reset timer
        !           196:    gtimer()  -- Get elapsed time since last call to rtimer()
        !           197: */
        !           198: 
        !           199: /* Conditional Includes */
        !           200: 
        !           201: #ifdef FT17
        !           202: #include <sys/file.h>                  /* File information */
        !           203: #endif
        !           204: 
        !           205: #ifndef PROVX1
        !           206: #include <sys/file.h>                  /* File information */
        !           207: #endif
        !           208: 
        !           209: /* System III, System V */
        !           210: 
        !           211: #ifdef UXIII
        !           212: #include <termio.h>
        !           213: #include <sys/ioctl.h>
        !           214: #include <fcntl.h>                     /* directory reading for locking */
        !           215: #include <errno.h>                     /* error numbers for system returns */
        !           216: #endif
        !           217: 
        !           218: /* Not Sys III/V */
        !           219: 
        !           220: #ifndef UXIII
        !           221: #include <sgtty.h>                     /* Set/Get tty modes */
        !           222: #ifndef PROVX1
        !           223: #ifndef V7
        !           224: #ifndef BSD41
        !           225: #include <sys/time.h>                  /* Clock info (for break generation) */
        !           226: #endif
        !           227: #endif
        !           228: #endif
        !           229: #endif
        !           230: 
        !           231: #ifdef BSD41
        !           232: #include <sys/timeb.h>                 /* BSD 4.1 ... ceb */
        !           233: #endif
        !           234: 
        !           235: #ifdef TOWER1
        !           236: #include <sys/timeb.h>                 /* Clock info for NCR Tower */
        !           237: #endif
        !           238: 
        !           239: /* Declarations */
        !           240: 
        !           241: long time();                           /* All Unixes should have this... */
        !           242: extern int errno;                      /* System call error return */
        !           243: 
        !           244: /* Special stuff for V7 input buffer peeking */
        !           245: 
        !           246: #ifdef V7
        !           247: int kmem[2] = { -1, -1};
        !           248: char *initrawq(), *qaddr[2]={0,0};
        !           249: #define CON 0
        !           250: #define TTY 1
        !           251: #endif
        !           252: 
        !           253: /* dftty is the device name of the default device for file transfer */
        !           254: /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
        !           255: 
        !           256: #ifdef PROVX1
        !           257:     char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
        !           258:     int dfloc = 1;                 /* that goes in local mode by default */
        !           259: #else
        !           260:     char *dftty = CTTNAM;              /* Remote by default, use normal */
        !           261:     int dfloc = 0;                     /* controlling terminal name. */
        !           262: #endif
        !           263: 
        !           264:     int dfprty = 0;                    /* Parity (0 = none) */
        !           265:     int dfflow = 1;                    /* Xon/Xoff flow control */
        !           266:     int backgrd = 0;                   /* Assume in foreground (no '&' ) */
        !           267: 
        !           268: int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
        !           269: 
        !           270: /* Declarations of variables global within this module */
        !           271: 
        !           272: static long tcount;                    /* Elapsed time counter */
        !           273: 
        !           274: static char *brnuls = "\0\0\0\0\0\0\0"; /* A string of nulls */
        !           275: 
        !           276: static jmp_buf sjbuf, jjbuf;           /* Longjump buffer */
        !           277: static int lkf = 0,                    /* Line lock flag */
        !           278:     conif = 0,                         /* Console interrupts on/off flag */
        !           279:     cgmf = 0,                          /* Flag that console modes saved */
        !           280:     xlocal = 0,                                /* Flag for tty local or remote */
        !           281:     ttyfd = -1;                                /* TTY file descriptor */
        !           282: static char escchr;                    /* Escape or attn character */
        !           283: 
        !           284: /* Special line discipline, 4.2bsd only, and only with kernel mods... */
        !           285: #ifdef KERLD
        !           286:     static int kerld = 1;              /* Special Kermit line discipline... */
        !           287:     struct tchars oldc, newc;          /* Special characters */
        !           288:     int ld = NETLDISC;                 /* Really a hack to "Berknet" l.d. */
        !           289:     int oldld;                         /* Old discipline */
        !           290: #else
        !           291:     static int kerld = 0;              /* Not selected, no special l.d. */
        !           292: #endif
        !           293: 
        !           294: #ifdef BSD42
        !           295:     static struct timeval tv;          /* For getting time, from sys/time.h */
        !           296:     static struct timezone tz;
        !           297: #endif
        !           298: 
        !           299: #ifdef BSD29
        !           300:     static struct timeval tv;          /* For getting time, from sys/time.h */
        !           301:     static struct timezone tz;         /* Same as 4.2 */
        !           302: #endif
        !           303: 
        !           304: #ifdef BSD41
        !           305:     static long clock;                 /* For getting time from sys/time.h */
        !           306:     static struct timeb ftp;           /* And from sys/timeb.h */
        !           307: #endif
        !           308: 
        !           309: #ifdef TOWER1
        !           310: static long clock;                     /* For getting time from sys/time.h */
        !           311: static struct timeb ftp;               /* And from sys/timeb.h */
        !           312: #endif
        !           313: 
        !           314: #ifdef V7
        !           315: static long clock;
        !           316: #endif
        !           317: 
        !           318: #ifdef UXIII
        !           319:   static struct termio                         /* sgtty info... */
        !           320:     ttold, ttraw, tttvt,               /* for communication line */
        !           321:     ccold, ccraw, cccbrk;              /* and for console */
        !           322: #else
        !           323:   static struct sgttyb                         /* sgtty info... */
        !           324:     ttold, ttraw, tttvt, ttbuf,                /* for communication line */
        !           325:     ccold, ccraw, cccbrk;              /* and for console */
        !           326: #endif
        !           327: 
        !           328: static char flfnam[80];                        /* uucp lock file path name */
        !           329: static int hasLock = 0;                        /* =1 if this kermit locked uucp */
        !           330: static int inbufc = 0;                 /* stuff for efficient SIII raw line */
        !           331: static int ungotn = -1;                        /* pushback to unread character */
        !           332: static int conesc = 0;                 /* set to 1 if esc char (^\) typed */
        !           333: 
        !           334: static int ttlock();                   /* definition of ttlock subprocedure */
        !           335: static int ttunlck();                  /* and unlock subprocedure */
        !           336: static char ttnmsv[DEVNAMLEN];         /* copy of open path for tthang */
        !           337: 
        !           338: /*  S Y S I N I T  --  System-dependent program initialization.  */
        !           339: 
        !           340: sysinit() {
        !           341: 
        !           342: /* for now, nothing... */
        !           343: 
        !           344: }
        !           345: 
        !           346: /*  T T O P E N  --  Open a tty for exclusive access.  */
        !           347: 
        !           348: /*  Returns 0 on success, -1 on failure.  */
        !           349: /*
        !           350:   If called with lcl < 0, sets value of lcl as follows:
        !           351:   0: the terminal named by ttname is the job's controlling terminal.
        !           352:   1: the terminal named by ttname is not the job's controlling terminal.
        !           353:   But watch out: if a line is already open, or if requested line can't
        !           354:   be opened, then lcl remains (and is returned as) -1.
        !           355: */
        !           356: ttopen(ttname,lcl,modem) char *ttname; int *lcl, modem; {
        !           357: 
        !           358: #ifdef UXIII
        !           359:     char *ctermid();                   /* Wish they all had this! */
        !           360: #endif
        !           361:     char *x; extern char* ttyname();
        !           362:     char cname[DEVNAMLEN];
        !           363: 
        !           364:     if (ttyfd > -1) return(0);         /* If already open, ignore this call */
        !           365:     xlocal = *lcl;                     /* Make this available to other fns */
        !           366: 
        !           367: #ifndef UXIII
        !           368:     ttyfd = open(ttname,2);            /* Try to open for read/write */
        !           369: #else
        !           370:     /* if modem connection, don't wait for carrier */
        !           371:     ttyfd = open(ttname,O_RDWR | (modem ? O_NDELAY : 0) );
        !           372: #endif
        !           373: 
        !           374:     if (ttyfd < 0) {                   /* If couldn't open, fail. */
        !           375:        return(-1);
        !           376:     }
        !           377:     strncpy(ttnmsv,ttname,DEVNAMLEN);  /* Open, keep copy of name locally. */
        !           378: 
        !           379: /* Caller wants us to figure out if line is controlling tty */
        !           380: 
        !           381:     debug(F111,"ttopen",ttname,*lcl);
        !           382:     if (*lcl == -1) {
        !           383:        if (strcmp(ttname,CTTNAM) == 0) {   /* "/dev/tty" always remote */
        !           384:            debug(F110," Same as CTTNAM",ttname,0);
        !           385:            xlocal = 0;
        !           386:        } else if (isatty(0)) {         /* Else, if stdin not redirected */
        !           387:            x = ttyname(0);             /* then compare its device name */
        !           388:            strncpy(cname,x,DEVNAMLEN); /* (copy from internal static buf) */
        !           389:            debug(F110," ttyname(0)",x,0);
        !           390:            x = ttyname(ttyfd);         /* ...with real name of ttname. */
        !           391:            xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1;
        !           392:            debug(F111," ttyname",x,xlocal);
        !           393:        } else {                        /* Else, if stdin redirected... */
        !           394: #ifdef UXIII
        !           395: /* Sys III/V provides nice ctermid() function to get name of controlling tty */
        !           396:            ctermid(cname);             /* Get name of controlling terminal */
        !           397:            debug(F110," ctermid",cname,0);
        !           398:            x = ttyname(ttyfd);         /* Compare with name of comm line. */
        !           399:            xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1;
        !           400:            debug(F111," ttyname",x,xlocal);
        !           401: #else
        !           402: /* Just assume local, so "set speed" and similar commands will work */
        !           403: /* If not really local, how could it work anyway?... */
        !           404:            xlocal = 1;
        !           405:            debug(F101," redirected stdin","",xlocal);
        !           406: #endif
        !           407:         }
        !           408:     }    
        !           409: 
        !           410: /* Now check if line is locked -- if so fail, else lock for ourselves */
        !           411: 
        !           412:     lkf = 0;                           /* Check lock */
        !           413:     if (xlocal > 0) {
        !           414:        if (ttlock(ttname) < 0) {
        !           415:            fprintf(stderr,"Exclusive access to %s denied\n",ttname);
        !           416:            close(ttyfd); ttyfd = -1;
        !           417:            debug(F110," Access denied by lock",ttname,0);
        !           418:            return(-1);                 /* Not if already locked */
        !           419:        } else lkf = 1;
        !           420:     }
        !           421: 
        !           422: /* Got the line, now set the desired value for local. */
        !           423: 
        !           424:     if (*lcl < 0) *lcl = xlocal;
        !           425: 
        !           426: /* Some special stuff for v7... */
        !           427: 
        !           428: #ifdef V7
        !           429:        if (kmem[TTY] < 0) {    /*  If open, then skip this.  */
        !           430:                qaddr[TTY] = initrawq(ttyfd);   /* Init the queue. */
        !           431:                if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
        !           432:                        fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
        !           433:                        perror("/dev/kmem");
        !           434:                        exit(1);
        !           435:                }
        !           436:        }
        !           437: #endif V7
        !           438: 
        !           439: /* Request exclusive access on systems that allow it. */
        !           440: 
        !           441: #ifndef XENIX
        !           442: /* Xenix exclusive access prevents open(close(...)) from working... */
        !           443: #ifdef TIOCEXCL
        !           444:        if (ioctl(ttyfd,TIOCEXCL, NULL) < 0)
        !           445:            fprintf(stderr,"Warning, problem getting exclusive access\n");
        !           446: #endif
        !           447: #endif
        !           448: 
        !           449: /* Get tty device settings */
        !           450: 
        !           451: #ifndef UXIII
        !           452:     gtty(ttyfd,&ttold);                        /* Get sgtty info */
        !           453:     gtty(ttyfd,&ttraw);                        /* And a copy of it for packets*/
        !           454:     gtty(ttyfd,&tttvt);                        /* And one for virtual tty service */
        !           455: #else
        !           456:     ioctl(ttyfd,TCGETA,&ttold);                /* Same deal for Sys III, Sys V */
        !           457:     ioctl(ttyfd,TCGETA,&ttraw);
        !           458:     ioctl(ttyfd,TCGETA,&tttvt);
        !           459: #endif
        !           460:     debug(F101,"ttopen, ttyfd","",ttyfd);
        !           461:     debug(F101," lcl","",*lcl);
        !           462:     debug(F111," lock file",flfnam,lkf);
        !           463:     return(0);
        !           464: }
        !           465: 
        !           466: /*  T T C L O S  --  Close the TTY, releasing any lock.  */
        !           467: 
        !           468: ttclos() {
        !           469:     if (ttyfd < 0) return(0);          /* Wasn't open. */
        !           470:     if (xlocal) {
        !           471:        if (tthang())                   /* Hang up phone line */
        !           472:            fprintf(stderr,"Warning, problem hanging up the phone\n");
        !           473:        if (ttunlck())                  /* Release uucp-style lock */
        !           474:            fprintf(stderr,"Warning, problem releasing lock\n");
        !           475:     }
        !           476:     ttres();                           /* Reset modes. */
        !           477: /* Relinquish exclusive access if we might have had it... */
        !           478: #ifndef XENIX
        !           479: #ifdef TIOCEXCL
        !           480: #ifdef TIOCNXCL
        !           481:     if (ioctl(ttyfd, TIOCNXCL, NULL) < 0)
        !           482:        fprintf(stderr,"Warning, problem relinquishing exclusive access\n");
        !           483: #endif
        !           484: #endif
        !           485: #endif
        !           486:     close(ttyfd);                      /* Close it. */
        !           487:     ttyfd = -1;                                /* Mark it as closed. */
        !           488:     return(0);
        !           489: }
        !           490: 
        !           491: /*  T T H A N G -- Hangup phone line */
        !           492: 
        !           493: tthang() {
        !           494: #ifdef UXIII
        !           495:     unsigned short ttc_save;
        !           496: #endif
        !           497: 
        !           498:     if (ttyfd < 0) return(0);          /* Not open. */
        !           499: #ifdef ANYBSD
        !           500:     ioctl(ttyfd,TIOCCDTR,0);           /* Clear DTR */
        !           501:     msleep(500);                       /* Let things settle */
        !           502:     ioctl(ttyfd,TIOCSDTR,0);           /* Restore DTR */
        !           503: #endif
        !           504: #ifdef UXIII
        !           505:     ttc_save = ttraw.c_cflag;
        !           506:     ttraw.c_cflag &= ~CBAUD;           /* swa: set baud rate to 0 to hangup */
        !           507:     if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* do it */
        !           508:     msleep(100);                       /* let things settle */
        !           509:     ttraw.c_cflag = ttc_save;
        !           510: #ifndef XENIX          /* xenix cannot do close/open when carrier drops */
        !           511:                                /* following corrects a PC/IX defficiency */
        !           512:     ttc_save = fcntl(ttyfd,F_GETFL,0);
        !           513:     close(ttyfd);              /* close/reopen file descriptor */
        !           514:     if ((ttyfd = open(ttnmsv, ttc_save)) < 0) return(-1);
        !           515: #endif
        !           516:     if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* un-do it */
        !           517: #endif
        !           518:     return (0);
        !           519: }
        !           520: 
        !           521: 
        !           522: /*  T T R E S  --  Restore terminal to "normal" mode.  */
        !           523: 
        !           524: ttres() {                              /* Restore the tty to normal. */
        !           525:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           526: #ifndef UXIII                          /* except for sIII, */
        !           527:     sleep(1);                          /* Wait for pending i/o to finish. */
        !           528: #endif                                 /*   (sIII does wait in ioctls) */
        !           529: #ifdef KERLD
        !           530:     if (kerld) ioctl(ttyfd,TIOCSETD,&oldld); /* Restore old line discipline. */
        !           531: #endif
        !           532: #ifdef UXIII
        !           533:     if (ioctl(ttyfd,TCSETAW,&ttold) < 0) return(-1); /* restore termio stuff */
        !           534: #else
        !           535:     if (stty(ttyfd,&ttold) < 0) return(-1); /* Restore sgtty stuff */
        !           536: #endif
        !           537: #ifdef KERLD
        !           538:     if (kerld) ioctl(ttyfd,TIOCSETC,&oldc); /* Restore old special chars. */
        !           539: #endif
        !           540: 
        !           541:     return(0);
        !           542: }
        !           543: 
        !           544: /* Exclusive uucp file locking control */
        !           545: /*
        !           546:  by H. Fischer, creative non-Bell coding !
        !           547:  copyright rights for lock modules assigned to Columbia University
        !           548: */
        !           549: static char *
        !           550: xxlast(s,c) char *s; char c; {         /* Equivalent to strrchr() */
        !           551:     int i;
        !           552:     for (i = strlen(s); i > 0; i--)
        !           553:        if ( s[i-1] == c ) return( s + (i - 1) );
        !           554:     return(NULL);          
        !           555: }
        !           556: static
        !           557: look4lk(ttname) char *ttname; {
        !           558:     extern char *strcat(), *strcpy();
        !           559:     char *device, *devname;
        !           560:     char lockfil[DIRSIZ+1];
        !           561: 
        !           562: #ifdef ISIII
        !           563:     char *lockdir = "/etc/locks";
        !           564: #else
        !           565: #ifdef ATT3BX
        !           566:     char *lockdir = "/usr/spool/locks";
        !           567: #else
        !           568:     char *lockdir = "/usr/spool/uucp";
        !           569: #endif
        !           570: #endif
        !           571: 
        !           572:     device = ( (devname=xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
        !           573: 
        !           574: #ifdef ISIII
        !           575:     (void) strcpy( lockfil, device );
        !           576: #else
        !           577:     strcat( strcpy( lockfil, "LCK.." ), device );
        !           578: #endif
        !           579: 
        !           580:     if (access( lockdir, 04 ) < 0) {   /* read access denied on lock dir */
        !           581:        fprintf(stderr,"Warning, read access to lock directory denied\n");
        !           582:        return( 1 );                    /* cannot check or set lock file */
        !           583:     }
        !           584:        
        !           585:     strcat(strcat(strcpy(flfnam,lockdir),"/"), lockfil);
        !           586:     debug(F110,"look4lk",flfnam,0);
        !           587: 
        !           588:     if ( ! access( flfnam, 00 ) ) {    /* print out lock file entry */
        !           589:        char lckcmd[40] ;
        !           590:        strcat( strcpy(lckcmd, "ls -l ") , flfnam);
        !           591:        system(lckcmd);
        !           592:        if (access(flfnam,02) == 0)
        !           593:            printf("(You may type \"! rm %s\" to remove this file)\n",flfnam);
        !           594:        return( -1 );
        !           595:     }
        !           596:     if ( access( lockdir, 02 ) < 0 ) { /* lock file cannot be written */
        !           597:        fprintf(stderr,"Warning, write access to lock directory denied\n");
        !           598:        return( 1 );
        !           599:     }
        !           600:     return( 0 );                       /* okay to go ahead and lock */
        !           601: }
        !           602: 
        !           603: /*  T T L O C K  */
        !           604: 
        !           605: 
        !           606: static
        !           607: ttlock(ttyfd) char *ttyfd; {           /* lock uucp if possible */
        !           608: #ifdef ATT3BX
        !           609:     FILE *lck_fild;
        !           610: #endif
        !           611:     int lck_fil, l4l;
        !           612:     int pid_buf = getpid();            /* pid to save in lock file */
        !           613:        
        !           614:     hasLock = 0;                       /* not locked yet */
        !           615:     l4l = look4lk(ttyfd);
        !           616:     if (l4l < 0) return (-1);          /* already locked */
        !           617:     if (l4l == 1) return (0);          /* can't read/write lock directory */
        !           618:     lck_fil = creat(flfnam, 0444);     /* create lock file ... */
        !           619:     if (lck_fil < 0) return (-1);      /* create of lockfile failed */
        !           620:                /* creat leaves file handle open for writing -- hf */
        !           621: #ifdef ATT3BX
        !           622:     fprintf((lck_fild = fdopen(lck_fil, "w")), "%10d\n", pid_buf);
        !           623:     fflush(lck_fild);
        !           624: #else
        !           625:     write (lck_fil, &pid_buf, sizeof(pid_buf) ); /* uucp expects int in file */
        !           626: #endif
        !           627:     close (lck_fil);
        !           628:     hasLock = 1;                       /* now is locked */
        !           629:     return(0);
        !           630: }
        !           631: 
        !           632: /*  T T U N L O C K  */
        !           633: 
        !           634: static
        !           635: ttunlck() {                            /* kill uucp lock if possible */
        !           636:     if (hasLock) return( unlink( flfnam ) );
        !           637: }
        !           638: 
        !           639: /*  T T P K T  --  Condition the communication line for packets. */
        !           640: /*             or for modem dialing */
        !           641: 
        !           642: #define DIALING        4               /* flags (via flow) for modem handling */
        !           643: #define CONNECT 5
        !           644: 
        !           645: /*  If called with speed > -1, also set the speed.  */
        !           646: 
        !           647: /*  Returns 0 on success, -1 on failure.  */
        !           648: 
        !           649: ttpkt(speed,flow) int speed, flow; {
        !           650:     int s;
        !           651:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           652: 
        !           653: #ifdef KERLD
        !           654: /* Note, KERLD ignores the TANDEM, ECHO, and CRMOD bits */
        !           655:     if (kerld) {
        !           656:        ioctl(ttyfd,TIOCGETD,&oldld);   /* Get line discipline */
        !           657:        ioctl(ttyfd,TIOCGETC,&oldc);    /* Get special chars */
        !           658:        newc = oldc;                    /* Copy special chars */
        !           659:        newc.t_brkc = '\r';             /* Set CR to be break character */
        !           660:        if(ioctl(ttyfd,TIOCSETC,&newc) < 0) return(-1);
        !           661:     }
        !           662: #endif
        !           663: 
        !           664:     s = ttsspd(speed);                 /* Check the speed */
        !           665: 
        !           666: #ifndef UXIII
        !           667:     if (flow == 1) ttraw.sg_flags |= TANDEM; /* Use XON/XOFF if selected */
        !           668:     if (flow == 0) ttraw.sg_flags &= ~TANDEM;
        !           669:     ttraw.sg_flags |= RAW;             /* Go into raw mode */
        !           670:     ttraw.sg_flags &= ~(ECHO|CRMOD);   /* Use CR for break character */
        !           671: #ifdef TOWER1
        !           672:     ttraw.sg_flags &= ~ANYP;           /* Must tell Tower no parityr */
        !           673: #endif
        !           674:     if (s > -1) ttraw.sg_ispeed = ttraw.sg_ospeed = s; /* Do the speed */
        !           675:     if (stty(ttyfd,&ttraw) < 0) return(-1);    /* Set the new modes. */
        !           676: 
        !           677: #ifdef MYREAD
        !           678: #ifdef BSD4
        !           679: /* Try to make reads nonblocking */
        !           680:     if (kerld == 0) {
        !           681:        if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & FNDELAY) == -1)
        !           682:            return(-1);
        !           683:        else return(0);
        !           684:     }
        !           685: #endif
        !           686: #endif
        !           687: #endif
        !           688: 
        !           689: #ifdef UXIII
        !           690:     if (flow == 1) ttraw.c_iflag |= (IXON|IXOFF);
        !           691:     if (flow == 0) ttraw.c_iflag &= ~(IXON|IXOFF);
        !           692: 
        !           693:     if (flow == DIALING)  ttraw.c_cflag |= CLOCAL|HUPCL;
        !           694:     if (flow == CONNECT)  ttraw.c_cflag &= ~CLOCAL;
        !           695: 
        !           696:     ttraw.c_lflag &= ~(ICANON|ECHO);
        !           697:     ttraw.c_lflag |= ISIG;             /* do check for interrupt */
        !           698:     ttraw.c_iflag |= (BRKINT|IGNPAR);
        !           699:     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
        !           700:     ttraw.c_oflag &= ~OPOST;
        !           701:     ttraw.c_cflag &= ~(CSIZE|PARENB);
        !           702:     ttraw.c_cflag |= (CS8|CREAD);
        !           703:     ttraw.c_cc[4] = 1;
        !           704:     ttraw.c_cc[5] = 0;
        !           705: 
        !           706:     if (s > -1) ttraw.c_cflag &= ~CBAUD, ttraw.c_cflag |= s; /* set speed */
        !           707: 
        !           708:     if (ioctl(ttyfd,TCSETAW,&ttraw) < 0) return(-1);  /* set new modes . */
        !           709:     if (flow == DIALING) {
        !           710:        if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
        !           711:                return(-1);
        !           712:        close( open(ttnmsv,2) );        /* magic to force mode change!!! */
        !           713:        }
        !           714: #endif
        !           715: 
        !           716: #ifdef KERLD
        !           717:     if (kerld) {
        !           718:        if (ioctl(ttyfd,TIOCSETD,&ld) < 0)
        !           719:            return(-1); /* Set line discpline. */
        !           720:     }
        !           721: #endif
        !           722: 
        !           723:     ttflui();                          /* Flush any pending input */
        !           724:     return(0);
        !           725: }
        !           726: 
        !           727: /*  T T V T -- Condition communication line for use as virtual terminal  */
        !           728: 
        !           729: ttvt(speed,flow) int speed, flow; {
        !           730:     int s;
        !           731:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           732: 
        !           733:     s = ttsspd(speed);                 /* Check the speed */
        !           734: 
        !           735: #ifndef UXIII
        !           736:     if (flow == 1) tttvt.sg_flags |= TANDEM; /* XON/XOFF if selected */
        !           737:     if (flow == 0) tttvt.sg_flags &= ~TANDEM;
        !           738:     tttvt.sg_flags |= RAW;             /* Raw mode */
        !           739: #ifdef TOWER1
        !           740:     tttvt.sg_flags &= ~(ECHO|ANYP);    /* No echo or system III ??? parity */
        !           741: #else
        !           742:     tttvt.sg_flags &= ~ECHO;           /* No echo */
        !           743: #endif    
        !           744:     if (s > -1) tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */
        !           745:     if (stty(ttyfd,&tttvt) < 0) return(-1);
        !           746: #ifdef MYREAD
        !           747: #ifdef BSD4
        !           748: /* Make reads nonblocking */
        !           749:     if (kerld == 0) {
        !           750:        if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & FNDELAY) == -1)
        !           751:            return(-1);
        !           752:        else return(0);
        !           753:     }
        !           754: #endif
        !           755: #endif
        !           756: 
        !           757: #else
        !           758:     if (flow == 1) tttvt.c_iflag |= (IXON|IXOFF);
        !           759:     if (flow == 0) tttvt.c_iflag &= ~(IXON|IXOFF);
        !           760: 
        !           761:     if (flow == DIALING)  tttvt.c_cflag |= CLOCAL|HUPCL;
        !           762:     if (flow == CONNECT)  tttvt.c_cflag &= ~CLOCAL;
        !           763: 
        !           764:     tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
        !           765:     tttvt.c_iflag |= (IGNBRK|IGNPAR);
        !           766:     tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|BRKINT|INPCK|ISTRIP|IXANY);
        !           767:     tttvt.c_oflag &= ~OPOST;
        !           768:     tttvt.c_cflag &= ~(CSIZE|PARENB);
        !           769:     tttvt.c_cflag |= (CS8|CREAD);
        !           770:     tttvt.c_cc[4] = 1;
        !           771:     tttvt.c_cc[5] = 0;
        !           772: 
        !           773:     if (s > -1) tttvt.c_cflag &= ~CBAUD, tttvt.c_cflag |= s; /* set speed */
        !           774: 
        !           775:     if (ioctl(ttyfd,TCSETAW,&tttvt) < 0) return(-1);  /* set new modes . */
        !           776:     if (flow == DIALING) {
        !           777:        if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
        !           778:                return(-1);
        !           779:        close( open(ttnmsv,2) );        /* magic to force mode change!!! */
        !           780:        }
        !           781:     return(0);
        !           782: #endif
        !           783: }
        !           784: 
        !           785: /*  T T S S P D  --  Return the internal baud rate code for 'speed'.  */
        !           786: 
        !           787: ttsspd(speed) {
        !           788:     int s, spdok;
        !           789: 
        !           790:     if (speed < 0) return(-1);
        !           791:        spdok = 1;                      /* Assume arg ok */
        !           792:        switch (speed) {
        !           793:            case 0:    s = B0;    break;        /* Just the common ones. */
        !           794:            case 110:  s = B110;  break;        /* The others from ttydev.h */
        !           795:            case 150:  s = B150;  break;        /* could also be included if */
        !           796:            case 300:  s = B300;  break;        /* necessary... */
        !           797:            case 600:  s = B600;  break;
        !           798:            case 1200: s = B1200; break;
        !           799:            case 1800: s = B1800; break;
        !           800:            case 2400: s = B2400; break;
        !           801:            case 4800: s = B4800; break;
        !           802:            case 9600: s = B9600; break;
        !           803: #ifdef PLEXUS
        !           804:            case 19200: s = EXTA; break;
        !           805: #endif
        !           806:            default:
        !           807:                spdok = 0;
        !           808:                fprintf(stderr,"Unsupported line speed - %d\n",speed);
        !           809:                fprintf(stderr,"Current speed not changed\n");
        !           810:                break;
        !           811:        }           
        !           812:        if (spdok) return(s); else return(-1);
        !           813:  }
        !           814: 
        !           815: 
        !           816: 
        !           817: /*  T T F L U I  --  Flush tty input buffer */
        !           818: 
        !           819: ttflui() {
        !           820: 
        !           821: #ifndef UXIII
        !           822:     long n;
        !           823: #endif
        !           824:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           825: 
        !           826:     ungotn = -1;                       /* Initialize myread() stuff */
        !           827:     inbufc = 0;
        !           828: 
        !           829: #ifdef UXIII
        !           830:     if (ioctl(ttyfd,TCFLSH,0) < 0) perror("flush failed");
        !           831: #else
        !           832: #ifdef TIOCFLUSH
        !           833: #if defined(ANYBSD) && !defined(BSD4_4)
        !           834:     n = FREAD;                         /* Specify read queue */
        !           835:     if (ioctl(ttyfd,TIOCFLUSH,&n) < 0) perror("flush failed");
        !           836: #else
        !           837:     if (ioctl(ttyfd,TIOCFLUSH,0) < 0) perror("flush failed");
        !           838: #endif
        !           839: #endif
        !           840: #endif
        !           841:     return(0);
        !           842: }
        !           843: 
        !           844: /* Interrupt Functions */
        !           845: 
        !           846: 
        !           847: /* Timeout handler for communication line input functions */
        !           848: 
        !           849: timerh() {
        !           850:     longjmp(sjbuf,1);
        !           851: }
        !           852: 
        !           853:  
        !           854: /* Set up terminal interrupts on console terminal */
        !           855: 
        !           856: #ifdef UXIII
        !           857: esctrp() {                             /* trap console escapes (^\) */
        !           858:     conesc = 1;
        !           859:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !           860: }
        !           861: #endif
        !           862: 
        !           863: #ifdef V7
        !           864: esctrp() {                             /* trap console escapes (^\) */
        !           865:     conesc = 1;
        !           866:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !           867: }
        !           868: #endif
        !           869: 
        !           870: #ifdef C70
        !           871: esctrp() {                             /* trap console escapes (^\) */
        !           872:     conesc = 1;
        !           873:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !           874: }
        !           875: #endif
        !           876: 
        !           877: /*  C O N I N T  --  Console Interrupt setter  */
        !           878: 
        !           879: conint(f) int (*f)(); {                        /* Set an interrupt trap. */
        !           880: 
        !           881:     if (backgrd) return;               /* must ignore signals in bkgrd */
        !           882: 
        !           883: /*
        !           884:  Except for special cases below, ignore keyboard quit signal.
        !           885:  ^\ too easily confused with connect escape, and besides, we don't want
        !           886:  to leave lock files around.  (Frank Prindle)
        !           887: */
        !           888:     signal(SIGQUIT,SIG_IGN);
        !           889: 
        !           890: #ifdef UXIII
        !           891:     signal(SIGQUIT,esctrp);            /* console escape in pkt modes */
        !           892:     if (conesc) {                      /* clear out pending escapes */
        !           893:        conesc = 0;
        !           894:     }
        !           895: #endif
        !           896: 
        !           897: #ifdef V7
        !           898:     signal(SIGQUIT,esctrp);            /* console escape in pkt modes */
        !           899:     if (conesc) {                      /* clear out pending escapes */
        !           900:        conesc = 0;
        !           901:     }
        !           902: #endif
        !           903: 
        !           904:     if (conif) return;                 /* Nothing to do if already on. */
        !           905: 
        !           906: /* check if invoked in background -- if so signals set to be ignored */
        !           907: 
        !           908:     if (signal(SIGINT,SIG_IGN) == SIG_IGN) {
        !           909:        backgrd = 1;                    /*   means running in background */
        !           910: #ifdef UXIII
        !           911:        signal(SIGQUIT,SIG_IGN);        /*   must leave signals ignored */
        !           912: #endif
        !           913: #ifdef V7
        !           914:        signal(SIGQUIT,SIG_IGN);        /*   must leave signals ignored */
        !           915: #endif
        !           916:        return;
        !           917:     }
        !           918:     signal(SIGINT,f);                  /* Function to trap to on interrupt. */
        !           919:     signal(SIGHUP,f);                  /* Or hangup, so lock file cleared. */
        !           920:     conif = 1;                         /* Flag console interrupts on. */
        !           921: }
        !           922: 
        !           923: 
        !           924: /*  C O N N O I  --  Reset console terminal interrupts */
        !           925: 
        !           926: connoi() {                             /* Console-no-interrupts */
        !           927: 
        !           928:     if (backgrd) return;               /* Ignore signals in background */
        !           929: 
        !           930:     signal(SIGINT,SIG_DFL);
        !           931:     signal(SIGHUP,SIG_DFL);
        !           932:     signal(SIGQUIT,SIG_DFL);
        !           933:     conif = 0;                         /* Flag interrupt trapping off */
        !           934: }
        !           935: 
        !           936: /*  myread() -- For use by systems that can do nonblocking read() calls  */
        !           937: /*
        !           938:  Returns:
        !           939:   -1  if no characters available,
        !           940:   -2  upon error (such as disconnect),
        !           941:   otherwise value of character (0 or greater)
        !           942: */
        !           943: myread() {
        !           944:     static int inbuf_item;
        !           945:     static CHAR inbuf[257];
        !           946:     CHAR readit;
        !           947:     
        !           948:     if (ungotn >= 0) {
        !           949:        readit = ungotn;
        !           950:     } else {
        !           951:         if (inbufc > 0) {
        !           952:            readit = inbuf[++inbuf_item];
        !           953:         } else {
        !           954:            if ((inbufc = read(ttyfd,inbuf,256)) == 0) {  /* end of file */
        !           955:                        /* means carrier dropped on modem connection */
        !           956:                errno = 9999;           /* magic number for no carrier */
        !           957:                return(-2);             /* end of file has no errno */
        !           958:                }
        !           959:            if (inbufc < 0) return(-2);
        !           960:            readit = inbuf[inbuf_item = 0];
        !           961:        }
        !           962:         inbufc--;      
        !           963:     }
        !           964:     ungotn = -1;
        !           965:     return(readit);
        !           966: }
        !           967: 
        !           968: myunrd(ch) CHAR ch; {                  /* push back up to one character */
        !           969:     ungotn = ch;
        !           970: }
        !           971: 
        !           972: /*  I N I T R A W Q  --  Set up to read /DEV/KMEM for character count.  */
        !           973: 
        !           974: #ifdef V7
        !           975: /*
        !           976:  Used in Version 7 to simulate Berkeley's FIONREAD ioctl call.  This
        !           977:  eliminates blocking on a read, because we can read /dev/kmem to get the
        !           978:  number of characters available for raw input.  If your system can't
        !           979:  or you won't let it read /dev/kmem (the world that is) then you must
        !           980:  figure out a different way to do the counting of characters available,
        !           981:  or else replace this by a dummy function that always returns 0.
        !           982: */
        !           983: /*
        !           984:  * Call this routine as: initrawq(tty)
        !           985:  * where tty is the file descriptor of a terminal.  It will return
        !           986:  * (as a char *) the kernel-mode memory address of the rawq character
        !           987:  * count, which may then be read.  It has the side-effect of flushing
        !           988:  * input on the terminal.
        !           989:  */
        !           990: /*
        !           991:  * John Mackin, Physiology Dept., University of Sydney (Australia)
        !           992:  * ...!decvax!mulga!physiol.su.oz!john
        !           993:  *
        !           994:  * Permission is hereby granted to do anything with this code, as
        !           995:  * long as this comment is retained unmodified and no commercial
        !           996:  * advantage is gained.
        !           997:  */
        !           998: #include <a.out.h>
        !           999: #include <sys/proc.h>
        !          1000: 
        !          1001: char *initrawq(tty) int tty; {
        !          1002: #ifdef UTS24
        !          1003:     return(0);
        !          1004: #else
        !          1005: #ifdef BSD29
        !          1006:     return(0);
        !          1007: #else
        !          1008:     long lseek();
        !          1009:     static struct nlist nl[] = {
        !          1010:        {PROCNAME},
        !          1011:        {NPROCNAME},
        !          1012:        {""}
        !          1013:     };
        !          1014:     static struct proc *pp;
        !          1015:     char *malloc(), *qaddr, *p, c;
        !          1016:     int m, pid, me;
        !          1017:     NPTYPE xproc;                      /* Its type is defined in makefile. */
        !          1018:     int catch();
        !          1019: 
        !          1020:     me = getpid();
        !          1021:     if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
        !          1022:     nlist(BOOTNAME, nl);
        !          1023:     if (nl[0].n_type == 0) err("proc array");
        !          1024:  
        !          1025:     if (nl[1].n_type == 0) err("nproc");
        !          1026: 
        !          1027:     lseek(m, (long)(nl[1].n_value), 0);
        !          1028:     read (m, &xproc, sizeof(xproc));
        !          1029:     signal(SIGALRM, catch);
        !          1030:     if ((pid = fork()) == 0) {
        !          1031:        while(1)
        !          1032:            read(tty, &c, 1);
        !          1033:     }
        !          1034:     alarm(2);
        !          1035:  
        !          1036:     if(setjmp(jjbuf) == 0) {
        !          1037:        while(1)
        !          1038:            read(tty, &c, 1);
        !          1039:     }
        !          1040:     signal(SIGALRM, SIG_DFL);
        !          1041: 
        !          1042: #ifdef DIRECT
        !          1043:     pp = (struct proc *) nl[0].n_value;
        !          1044: #else 
        !          1045:     if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
        !          1046:     if (read(m, &pp, sizeof(pp)) != sizeof(pp))  err("no read of proc ptr");
        !          1047: #endif
        !          1048:     lseek(m, (long)(nl[1].n_value), 0);
        !          1049:     read(m, &xproc, sizeof(xproc));
        !          1050: 
        !          1051:     if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
        !          1052:     if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
        !          1053:     if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
        !          1054:        err("read proc table");
        !          1055:     for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
        !          1056:        if (pp -> p_pid == (short) pid) goto iout;
        !          1057:     }
        !          1058:     err("no such proc");
        !          1059:  
        !          1060: iout:
        !          1061:     close(m);
        !          1062:     qaddr = (char *)(pp -> p_wchan);
        !          1063:     free (p);
        !          1064:     kill(pid, SIGKILL);
        !          1065:     wait((int *)0);            /* Destroy the ZOMBIEs! */
        !          1066:     return (qaddr);
        !          1067: #endif
        !          1068: #endif
        !          1069: }
        !          1070: 
        !          1071: /*  More V7-support functions...  */
        !          1072: 
        !          1073: static
        !          1074: err(s) char *s; {
        !          1075:     char buf[200];
        !          1076: 
        !          1077:     sprintf(buf, "fatal error in initrawq: %s", s);
        !          1078:     perror(buf);
        !          1079:     doexit(1);
        !          1080: }
        !          1081: 
        !          1082: static
        !          1083: catch() {
        !          1084:     longjmp(jjbuf, -1);
        !          1085: }
        !          1086: 
        !          1087: 
        !          1088: /*  G E N B R K  --  Simulate a modem break.  */
        !          1089: 
        !          1090: #define        BSPEED  B150
        !          1091: 
        !          1092: genbrk(fn) int fn; {
        !          1093:     struct sgttyb ttbuf;
        !          1094:     int ret, sospeed;
        !          1095: 
        !          1096:     ret = ioctl(fn, TIOCGETP, &ttbuf);
        !          1097:     sospeed = ttbuf.sg_ospeed;
        !          1098:     ttbuf.sg_ospeed = BSPEED;
        !          1099:     ret = ioctl(fn, TIOCSETP, &ttbuf);
        !          1100:     ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", 8);
        !          1101:     ttbuf.sg_ospeed = sospeed;
        !          1102:     ret = ioctl(fn, TIOCSETP, &ttbuf);
        !          1103:     ret = write(fn, "@", 1);
        !          1104:     return;
        !          1105: }
        !          1106: #endif V7
        !          1107: 
        !          1108: /*  T T C H K  --  Tell how many characters are waiting in tty input buffer  */
        !          1109: 
        !          1110: ttchk() {
        !          1111:     int x; long n;
        !          1112: #ifdef FIONREAD
        !          1113:     x = ioctl(ttyfd, FIONREAD, &n);    /* Berkeley and maybe some others */
        !          1114:     debug(F101,"ttchk","",n);
        !          1115:     return((x < 0) ? 0 : n);
        !          1116: #else
        !          1117: #ifdef V7
        !          1118:     lseek(kmem[TTY], (long) qaddr[TTY], 0);
        !          1119:     x = read(kmem[TTY], &n, sizeof(int));
        !          1120:     return((x == sizeof(int))? n: 0);
        !          1121: #else  V7
        !          1122: #ifdef UXIII
        !          1123:     return(inbufc + (ungotn >= 0) );   
        !          1124: #else
        !          1125: #ifdef C70
        !          1126:     return(inbufc + (ungotn >= 0) );
        !          1127: #else
        !          1128: #ifdef PROVX1
        !          1129:     x = ioctl(ttyfd, TIOCQCNT, &ttbuf);
        !          1130:     n = ttbuf.sg_ispeed & 0377;
        !          1131:     return((x < 0) ? 0 : n);
        !          1132: #else
        !          1133:     return(0);
        !          1134: #endif
        !          1135: #endif
        !          1136: #endif
        !          1137: #endif
        !          1138: #endif
        !          1139: }
        !          1140: 
        !          1141: 
        !          1142: /*  T T X I N  --  Get n characters from tty input buffer  */
        !          1143: 
        !          1144: /*  Returns number of characters actually gotten, or -1 on failure  */
        !          1145: 
        !          1146: /*  Intended for use only when it is known that n characters are actually */
        !          1147: /*  Available in the input buffer.  */
        !          1148: 
        !          1149: ttxin(n,buf) int n; char *buf; {
        !          1150:     int x;
        !          1151:     CHAR c;
        !          1152: 
        !          1153: #ifdef MYREAD
        !          1154:     for( x = 0; (x > -1) && (x < n); buf[x++] = myread() );
        !          1155: #else
        !          1156:     debug(F101,"ttxin: n","",n);
        !          1157:     x = read(ttyfd,buf,n);
        !          1158:     debug(F101," x","",x);
        !          1159: #endif
        !          1160:     if (x > 0) buf[x] = '\0';
        !          1161:     if (x < 0) x = -1;
        !          1162:     return(x);
        !          1163: }
        !          1164: 
        !          1165: /*  T T O L  --  Similar to "ttinl", but for writing.  */
        !          1166: 
        !          1167: ttol(s,n) int n; char *s; {
        !          1168:     int x;
        !          1169:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1170:     x = write(ttyfd,s,n);
        !          1171:     debug(F111,"ttol",s,n);
        !          1172:     if (x < 0) debug(F101,"ttol failed","",x);
        !          1173:     return(x);
        !          1174: }
        !          1175: 
        !          1176: 
        !          1177: /*  T T O C  --  Output a character to the communication line  */
        !          1178: 
        !          1179: ttoc(c) char c; {
        !          1180:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1181:     return(write(ttyfd,&c,1));
        !          1182: }
        !          1183: 
        !          1184: /*  T T I N L  --  Read a record (up to break character) from comm line.  */
        !          1185: /*
        !          1186:   If no break character encountered within "max", return "max" characters,
        !          1187:   with disposition of any remaining characters undefined.  Otherwise, return
        !          1188:   the characters that were read, including the break character, in "dest" and
        !          1189:   the number of characters read as the value of function, or 0 upon end of
        !          1190:   file, or -1 if an error occurred.  Times out & returns error if not completed
        !          1191:   within "timo" seconds.
        !          1192: */
        !          1193: 
        !          1194: ttinl(dest,max,timo,eol) int max,timo; char *dest; char eol; {
        !          1195:     int x, y;
        !          1196:     CHAR c;
        !          1197: 
        !          1198:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1199:     if (timo <= 0) {                   /* Untimed read... */
        !          1200: 
        !          1201: #ifdef MYREAD
        !          1202:        for (x = y = 0; (x < max) && (c != eol); x++) {
        !          1203:             while ((y = myread()) == -1) ;
        !          1204:             if (y == -2) return(-1);
        !          1205:             dest[x] = y & 0377;
        !          1206:        }
        !          1207: #else
        !          1208:        x = read(ttyfd,dest,max);       /* Try to read. */
        !          1209: #endif
        !          1210:        return(x);                      /* Return the count. */
        !          1211:     }
        !          1212: 
        !          1213: /* Timed read... */
        !          1214: 
        !          1215:     signal(SIGALRM,timerh);            /* Set up timeout action. */
        !          1216:     alarm(timo);                       /* Set the timer. */
        !          1217:     if (setjmp(sjbuf))                 /* Do this if timer went off. */
        !          1218:        x = -1;
        !          1219:     else if (kerld) {                  /* Efficient Kermit line discipline */
        !          1220:        x = read(ttyfd,dest,max);       /* for 4.2bsd only... */
        !          1221:     } else {                           /* Normal case... */
        !          1222:        for (x = c = y = 0; (x < max) && (c != eol); x++) {
        !          1223: #ifdef MYREAD
        !          1224:            while ((y = myread()) == -1) /* Use own buffering if we can */
        !          1225:                ;
        !          1226:            if (y == -2) y++;
        !          1227:            c = y & 0377;
        !          1228: #else
        !          1229:            while ((y = read(ttyfd,&c,1)) == 0) /* Else call system */
        !          1230:                ;                       /* ...for each character. */
        !          1231: #endif
        !          1232:            if (y < 0) {
        !          1233:                alarm(0);               /* Error, turn off timer, */
        !          1234:                signal(SIGALRM,SIG_DFL); /* and associated interrupt. */
        !          1235:                return(y);              /* Return the error indication. */
        !          1236:            }
        !          1237:            dest[x] = c;
        !          1238:        }
        !          1239:        x++;
        !          1240:     }
        !          1241:     alarm(0);                          /* Success, turn off timer, */
        !          1242:     signal(SIGALRM,SIG_DFL);           /* and associated interrupt. */
        !          1243:     return(x);                         /* Return the count. */
        !          1244: }
        !          1245: 
        !          1246: /*  T T I N C --  Read a character from the communication line  */
        !          1247: 
        !          1248: ttinc(timo) int timo; {
        !          1249:     int n = 0;
        !          1250:     CHAR ch = 0;
        !          1251: 
        !          1252:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1253:     if (timo <= 0) {                   /* Untimed. */
        !          1254: #ifdef MYREAD
        !          1255:        /* comm line failure returns -1 thru myread, so no &= 0377 */
        !          1256:        while ((n = myread()) == -1) ;  /* Wait for a character... */
        !          1257:        if (n == -2) n++;
        !          1258:        return( n );
        !          1259: #else
        !          1260:        while ((n = read(ttyfd,&ch,1)) == 0) ; /* Wait for a character. */
        !          1261:        return( (n > 0) ? (ch & 0377) : n );
        !          1262: #endif
        !          1263:     }
        !          1264: 
        !          1265:     signal(SIGALRM,timerh);            /* Timed, set up timer. */
        !          1266:     alarm(timo);
        !          1267:     if (setjmp(sjbuf)) {
        !          1268:        n = -1;
        !          1269:     } else {
        !          1270: #ifdef MYREAD
        !          1271:        while ((n = myread()) == -1) ;  /* If managing own buffer... */
        !          1272:        if (n == -2) {
        !          1273:            n++;
        !          1274:        } else {
        !          1275:            ch = n;
        !          1276:            n = 1;      
        !          1277:        }
        !          1278: #else
        !          1279:        n = read(ttyfd,&ch,1);          /* Otherwise call the system. */
        !          1280: #endif
        !          1281:     }
        !          1282:     alarm(0);                          /* Turn off timer, */
        !          1283:     signal(SIGALRM,SIG_DFL);           /* and interrupt. */
        !          1284:     return( (n > 0) ? (ch & 0377) : n ); /* Return char or -1. */
        !          1285: }
        !          1286: 
        !          1287: /*  T T S N D B  --  Send a BREAK signal  */
        !          1288: 
        !          1289: ttsndb() {
        !          1290:     int x; long n; char spd;
        !          1291: 
        !          1292:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1293: 
        !          1294: #ifdef PROVX1
        !          1295:     gtty(ttyfd,&ttbuf);                        /* Get current tty flags */
        !          1296:     spd = ttbuf.sg_ospeed;             /* Save speed */
        !          1297:     ttbuf.sg_ospeed = B50;             /* Change to 50 baud */
        !          1298:     stty(ttyfd,&ttbuf);                        /*  ... */
        !          1299:     write(ttyfd,brnuls,3);             /* Send 3 nulls */
        !          1300:     ttbuf.sg_ospeed = spd;             /* Restore speed */
        !          1301:     stty(ttyfd,&ttbuf);                        /*  ... */
        !          1302:     return(0);
        !          1303: #else
        !          1304: #ifdef UXIII
        !          1305:     if (ioctl(ttyfd,TCSBRK,(char *)0) < 0) {   /* Send a BREAK */
        !          1306:        perror("Can't send BREAK");
        !          1307:        return(-1);
        !          1308:     }
        !          1309:     return(0);
        !          1310: #else
        !          1311: #ifdef ANYBSD
        !          1312: #if !defined(BSD4_4)
        !          1313:     n = FWRITE;                                /* Flush output queue. */
        !          1314: #endif
        !          1315:     ioctl(ttyfd,TIOCFLUSH,&n);                 /* Ignore any errors.. */
        !          1316:     if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) { /* Turn on BREAK */
        !          1317:        perror("Can't send BREAK");
        !          1318:        return(-1);
        !          1319:     }
        !          1320:     x = msleep(275);                   /* Sleep for so many milliseconds */
        !          1321:     if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) { /* Turn off BREAK */
        !          1322:        perror("BREAK stuck!!!");
        !          1323:        doexit(1);                      /* Get out, closing the line. */
        !          1324:                                        /*   with exit status = 1 */
        !          1325:     }
        !          1326:     return(x);
        !          1327: #else
        !          1328: #ifdef V7
        !          1329:     genbrk(ttyfd);                     /* Simulate a BREAK */
        !          1330:     return(x);
        !          1331: #endif
        !          1332: #endif
        !          1333: #endif
        !          1334: #endif
        !          1335: }
        !          1336: 
        !          1337: /*  M S L E E P  --  Millisecond version of sleep().  */
        !          1338: 
        !          1339: /*
        !          1340:  Intended only for small intervals.  For big ones, just use sleep().
        !          1341: */
        !          1342: 
        !          1343: msleep(m) int m; {
        !          1344: 
        !          1345: #ifdef PROVX1
        !          1346:     sleep(-((m * 60 + 500) / 1000));
        !          1347:     return(0);
        !          1348: #endif
        !          1349: 
        !          1350: #ifdef ANYBSD
        !          1351:     int t1, t3, t4;
        !          1352: #ifdef BSD41
        !          1353:     if (ftime(&ftp) < 0) return(-1);   /* Get current time. */
        !          1354:     t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
        !          1355:     while (1) {
        !          1356:        ftime(&ftp);                    /* new time */
        !          1357:        t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
        !          1358:        if (t3 > m) return (t3);
        !          1359:     }
        !          1360: #else
        !          1361: /* 2.9 and 4.1 BSD do it this way */
        !          1362:     if (gettimeofday(&tv, &tz) < 0) return(-1); /* Get current time. */
        !          1363:     t1 = tv.tv_sec;                    /* Seconds */
        !          1364: 
        !          1365:     tv.tv_sec = 0;                     /* Use select() */
        !          1366:     tv.tv_usec = m * 1000;
        !          1367:     return(select( 0, (int *)0, (int *)0, (int *)0, &tv) );
        !          1368: #endif
        !          1369: #endif
        !          1370: 
        !          1371: #ifdef UXIII
        !          1372: #ifdef XENIX
        !          1373: #define CLOCK_TICK 50                  /* millisecs per clock tick */
        !          1374: #else
        !          1375: #define CLOCK_TICK 17                  /* 1/60 sec */
        !          1376: #endif
        !          1377:     extern long times();
        !          1378:     long t1, t2, tarray[4];
        !          1379:     int t3;
        !          1380: 
        !          1381:     if ((t1 = times(tarray)) < 0) return(-1);
        !          1382:     while (1) {
        !          1383:        if ((t2 = times(tarray)) < 0) return(-1);
        !          1384:        t3 = ((int)(t2 - t1)) * CLOCK_TICK;
        !          1385:        if (t3 > m) return(t3);
        !          1386:     }
        !          1387: #endif
        !          1388: 
        !          1389: #ifdef TOWER1
        !          1390:     int t1, t3;
        !          1391:     if (ftime(&ftp) < 0) return(-1);           /* Get current time. */
        !          1392:     t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
        !          1393:     while (1) {
        !          1394:        ftime(&ftp);                            /* new time */
        !          1395:        t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
        !          1396:        if (t3 > m) return (t3);
        !          1397:     }
        !          1398: #endif
        !          1399: }
        !          1400: 
        !          1401: /*  R T I M E R --  Reset elapsed time counter  */
        !          1402: 
        !          1403: rtimer() {
        !          1404:     tcount = time( (long *) 0 );
        !          1405: }
        !          1406: 
        !          1407: 
        !          1408: /*  G T I M E R --  Get current value of elapsed time counter in seconds  */
        !          1409: 
        !          1410: gtimer() {
        !          1411:     int x;
        !          1412:     x = (int) (time( (long *) 0 ) - tcount);
        !          1413:     rtimer();
        !          1414:     return( (x < 0) ? 0 : x );
        !          1415: }
        !          1416: 
        !          1417: 
        !          1418: /*  Z T I M E  --  Return date/time string  */
        !          1419: 
        !          1420: ztime(s) char **s; {
        !          1421: 
        !          1422: #ifdef UXIII
        !          1423:     extern long time();                        /* Sys III/V way to do it */
        !          1424:     char *ctime();
        !          1425:     long clock_storage;
        !          1426: 
        !          1427:     clock_storage = time( (long *) 0 );
        !          1428:     *s = ctime( &clock_storage );
        !          1429: #endif
        !          1430: 
        !          1431: #ifdef PROVX1
        !          1432:     int utime[2];                      /* Venix way */
        !          1433:     time(utime);
        !          1434:     *s = ctime(utime);
        !          1435: #endif
        !          1436: 
        !          1437: #ifdef ANYBSD
        !          1438:     char *asctime();                   /* Berkeley way */
        !          1439:     struct tm *localtime();
        !          1440:     struct tm *tp;
        !          1441: #ifndef BSD41
        !          1442:     gettimeofday(&tv, &tz);            /* BSD 2.9, 4.2 ... */
        !          1443:     time(&tv.tv_sec);
        !          1444:     tp = localtime(&tv.tv_sec);
        !          1445: #else
        !          1446:     time(&clock);                      /* BSD 4.1 ... ceb */
        !          1447:     tp = localtime(&clock);
        !          1448: #endif
        !          1449:     *s = asctime(tp);
        !          1450: #endif
        !          1451: 
        !          1452: #ifdef TOWER1
        !          1453:     char *asctime();                   /* Tower way */
        !          1454:     struct tm *localtime();
        !          1455:     struct tm *tp;
        !          1456: 
        !          1457:     time(&clock);
        !          1458:     tp = localtime(&clock);
        !          1459:     *s = asctime(tp);
        !          1460: #endif
        !          1461: #ifdef V7
        !          1462:     char *asctime();                   /* V7 way */
        !          1463:     struct tm *localtime();
        !          1464:     struct tm *tp;
        !          1465: 
        !          1466:     time(&clock);
        !          1467:     tp = localtime(&clock);
        !          1468:     *s = asctime(tp);
        !          1469: #endif
        !          1470: }
        !          1471: 
        !          1472: /*  C O N G M  --  Get console terminal modes.  */
        !          1473: 
        !          1474: /*
        !          1475:  Saves current console mode, and establishes variables for switching between 
        !          1476:  current (presumably normal) mode and other modes.
        !          1477: */
        !          1478: 
        !          1479: congm() {
        !          1480: #ifndef UXIII
        !          1481:      gtty(0,&ccold);                   /* Structure for restoring */
        !          1482:      gtty(0,&cccbrk);                  /* For setting CBREAK mode */
        !          1483:      gtty(0,&ccraw);                   /* For setting RAW mode */
        !          1484: #else
        !          1485:      ioctl(0,TCGETA,&ccold);
        !          1486:      ioctl(0,TCGETA,&cccbrk);
        !          1487:      ioctl(0,TCGETA,&ccraw);
        !          1488: #endif
        !          1489:      cgmf = 1;                         /* Flag that we got them. */
        !          1490: }
        !          1491: 
        !          1492: 
        !          1493: /*  C O N C B --  Put console in cbreak mode.  */
        !          1494: 
        !          1495: /*  Returns 0 if ok, -1 if not  */
        !          1496: 
        !          1497: concb(esc) char esc; {
        !          1498:     int x;
        !          1499:     if (cgmf == 0) congm();            /* Get modes if necessary. */
        !          1500:     escchr = esc;                      /* Make this available to other fns */
        !          1501:     ckxech = 1;                                /* Program can echo characters */
        !          1502: #ifndef UXIII
        !          1503:     cccbrk.sg_flags |= CBREAK;         /* Set to character wakeup, */
        !          1504:     cccbrk.sg_flags &= ~ECHO;          /* no echo. */
        !          1505:     x = stty(0,&cccbrk);
        !          1506: #else
        !          1507:     cccbrk.c_lflag &= ~(ICANON|ECHO);
        !          1508:     cccbrk.c_cc[0] = 003;              /* interrupt char is control-c */
        !          1509:     cccbrk.c_cc[1] = escchr;           /* escape during packet modes */
        !          1510:     cccbrk.c_cc[4] = 1;
        !          1511:     cccbrk.c_cc[5] = 1;
        !          1512:     x = ioctl(0,TCSETAW,&cccbrk);      /* set new modes . */
        !          1513: #endif
        !          1514:     if (x > -1) setbuf(stdout,NULL);   /* Make console unbuffered. */
        !          1515: #ifdef V7
        !          1516:     if (kmem[CON] < 0) {
        !          1517:        qaddr[CON] = initrawq(0);
        !          1518:        if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
        !          1519:            fprintf(stderr, "Can't read /dev/kmem in concb.\n");
        !          1520:            perror("/dev/kmem");
        !          1521:            exit(1);
        !          1522:        }
        !          1523:     }
        !          1524: #endif V7
        !          1525:     return(x);
        !          1526: }
        !          1527: 
        !          1528: /*  C O N B I N  --  Put console in binary mode  */
        !          1529: 
        !          1530: /*  Returns 0 if ok, -1 if not  */
        !          1531: 
        !          1532: conbin(esc) char esc; {
        !          1533:     if (cgmf == 0) congm();            /* Get modes if necessary. */
        !          1534:     escchr = esc;                      /* Make this available to other fns */
        !          1535:     ckxech = 1;                                /* Program can echo characters */
        !          1536: #ifndef UXIII
        !          1537:     ccraw.sg_flags |= (RAW|TANDEM);    /* Set rawmode, XON/XOFF */
        !          1538:     ccraw.sg_flags &= ~(ECHO|CRMOD);   /* Set char wakeup, no echo */
        !          1539:     return(stty(0,&ccraw));
        !          1540: #else
        !          1541:     ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
        !          1542:     ccraw.c_iflag |= (BRKINT|IGNPAR);
        !          1543:     ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
        !          1544:                        |INPCK|ISTRIP);
        !          1545:     ccraw.c_oflag &= ~OPOST;
        !          1546: 
        !          1547: /*** Kermit used to put the console in 8-bit raw mode, but some users have
        !          1548:  *** pointed out that this should not be done, since some sites actually
        !          1549:  *** use terminals with parity settings on their Unix systems, and if we
        !          1550:  *** override the current settings and stop doing parity, then their terminals
        !          1551:  *** will display blotches for characters whose parity is wrong.  Therefore,
        !          1552:  *** the following two lines are commented out (Larry Afrin, Clemson U):
        !          1553:  ***
        !          1554:  ***   ccraw.c_cflag &= ~(PARENB|CSIZE);
        !          1555:  ***   ccraw.c_cflag |= (CS8|CREAD);
        !          1556:  ***
        !          1557:  *** Sys III/V sites that have trouble with this can restore these lines.
        !          1558:  ***/
        !          1559:     ccraw.c_cc[4] = 1;
        !          1560:     ccraw.c_cc[5] = 1;
        !          1561:     return(ioctl(0,TCSETAW,&ccraw) );          /* set new modes . */
        !          1562: #endif
        !          1563: }
        !          1564: 
        !          1565: 
        !          1566: /*  C O N R E S  --  Restore the console terminal  */
        !          1567: 
        !          1568: conres() {
        !          1569:     if (cgmf == 0) return(0);          /* Don't do anything if modes */
        !          1570: #ifndef UXIII                          /* except for sIII, */
        !          1571:     sleep(1);                          /*  not known! */
        !          1572: #endif                                 /*   (sIII does wait in ioctls) */
        !          1573:     ckxech = 0;                                /* System should echo chars */
        !          1574: #ifndef UXIII
        !          1575:     return(stty(0,&ccold));            /* Restore controlling tty */
        !          1576: #else
        !          1577:     return(ioctl(0,TCSETAW,&ccold));
        !          1578: #endif
        !          1579: }
        !          1580: 
        !          1581: /*  C O N O C  --  Output a character to the console terminal  */
        !          1582: 
        !          1583: conoc(c) char c; {
        !          1584:     write(1,&c,1);
        !          1585: }
        !          1586: 
        !          1587: /*  C O N X O  --  Write x characters to the console terminal  */
        !          1588: 
        !          1589: conxo(x,s) char *s; int x; {
        !          1590:     write(1,s,x);
        !          1591: }
        !          1592: 
        !          1593: /*  C O N O L  --  Write a line to the console terminal  */
        !          1594: 
        !          1595: conol(s) char *s; {
        !          1596:     int len;
        !          1597:     len = strlen(s);
        !          1598:     write(1,s,len);
        !          1599: }
        !          1600: 
        !          1601: /*  C O N O L A  --  Write an array of lines to the console terminal */
        !          1602: 
        !          1603: conola(s) char *s[]; {
        !          1604:     int i;
        !          1605:     for (i=0 ; *s[i] ; i++) conol(s[i]);
        !          1606: }
        !          1607: 
        !          1608: /*  C O N O L L  --  Output a string followed by CRLF  */
        !          1609: 
        !          1610: conoll(s) char *s; {
        !          1611:     conol(s);
        !          1612:     write(1,"\r\n",2);
        !          1613: }
        !          1614: 
        !          1615: /*  C O N C H K  --  Return how many characters available at console  */
        !          1616: 
        !          1617: conchk() {
        !          1618:     int x; long n;
        !          1619: 
        !          1620: #ifdef PROVX1 
        !          1621:     x = ioctl(0, TIOCQCNT, &ttbuf);
        !          1622:     n = ttbuf.sg_ispeed & 0377;
        !          1623:     return((x < 0) ? 0 : n);
        !          1624: #else
        !          1625: #ifdef V7
        !          1626:     lseek(kmem[CON], (long) qaddr[CON], 0);
        !          1627:     x = read(kmem[CON], &n, sizeof(int));
        !          1628:     return((x == sizeof(int))? n: 0);
        !          1629: #else
        !          1630: #ifdef UXIII
        !          1631:     if (conesc) {                      /* Escape typed */
        !          1632:        conesc = 0;
        !          1633:        signal(SIGQUIT,esctrp);         /* Restore escape */
        !          1634:        return(1);
        !          1635:     }
        !          1636:     return(0);
        !          1637: #else
        !          1638: #ifdef C70
        !          1639:     if (conesc) {                      /* Escape typed */
        !          1640:        conesc = 0;
        !          1641:        signal(SIGQUIT,esctrp);         /* Restore escape */
        !          1642:        return(1);
        !          1643:     }
        !          1644:     return(0);
        !          1645: #else
        !          1646: #ifdef FIONREAD
        !          1647:     x = ioctl(0, FIONREAD, &n);                /* BSD and maybe some others */
        !          1648:     return((x < 0) ? 0 : n);
        !          1649: #else
        !          1650:     return(0);                         /* Others can't do. */
        !          1651: #endif
        !          1652: #endif
        !          1653: #endif
        !          1654: #endif
        !          1655: #endif
        !          1656: }
        !          1657: 
        !          1658: /*  C O N I N C  --  Get a character from the console  */
        !          1659: 
        !          1660: coninc(timo) int timo; {
        !          1661:     int n = 0; char ch;
        !          1662:     if (timo <= 0 ) {                  /* untimed */
        !          1663:        n = read(0, &ch, 1);            /* Read a character. */
        !          1664:        ch &= 0377;
        !          1665:        if (n > 0) return(ch);          /* Return the char if read */
        !          1666:        else 
        !          1667: #ifdef UXIII
        !          1668:            if (n < 0 && errno == EINTR) /* if read was interrupted by QUIT */
        !          1669:                return(escchr);          /* user entered escape character */
        !          1670:            else                    /* couldnt be ^c, sigint never returns */
        !          1671: #endif
        !          1672:                return(-1);             /* Return the char, or -1. */
        !          1673:        }
        !          1674:     signal(SIGALRM,timerh);            /* Timed read, so set up timer */
        !          1675:     alarm(timo);
        !          1676:     if (setjmp(sjbuf)) n = -2;
        !          1677:     else {
        !          1678:        n = read(0, &ch, 1);
        !          1679:        ch &= 0377;
        !          1680:     }
        !          1681:     alarm(0);                          /* Stop timing, we got our character */
        !          1682:     signal(SIGALRM,SIG_DFL);
        !          1683:     if (n > 0) return(ch);  
        !          1684:     else
        !          1685: #ifdef UXIII
        !          1686:         if (n == -1 && errno == EINTR)  /* If read interrupted by QUIT, */
        !          1687:            return(escchr);             /* user entered escape character, */
        !          1688:         else                           /* can't be ^c, sigint never returns */
        !          1689: #endif
        !          1690:        return(-1);
        !          1691: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.