Annotation of researchv10dc/lbin/kermit/ckutio.c, revision 1.1

1.1     ! root        1: char *ckxv = "Unix tty I/O, 4E(047), 27 Jan 88";
        !             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, 1988, Trustees of Columbia University in the City of New 
        !            11:  York.  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: 
        !            19: #include <sys/dir.h>                   /* Directory */
        !            20: #include <ctype.h>                     /* Character types */
        !            21: #ifdef NULL
        !            22: #undef NULL
        !            23: #endif /* NULL */
        !            24: #include <stdio.h>                     /* Unix Standard i/o */
        !            25: #include <signal.h>                    /* Interrupts */
        !            26: 
        !            27: #ifndef ZILOG
        !            28: #include <setjmp.h>                    /* Longjumps */
        !            29: #else
        !            30: #include <setret.h>
        !            31: #endif
        !            32: 
        !            33: #include "ckcdeb.h"                    /* Typedefs, formats for debug() */
        !            34: 
        !            35: /* Maximum length for the name of a tty device */
        !            36: 
        !            37: #ifndef DEVNAMLEN
        !            38: #define DEVNAMLEN 25
        !            39: #endif
        !            40: 
        !            41: /* 4.1 BSD support added by Charles E. Brooks, EDN-VAX */
        !            42: /* Fortune 32:16 Pro:For 1.8 support mostly like 4.1, added by J-P Dumas */
        !            43: 
        !            44: #ifdef BSD4
        !            45: #define ANYBSD
        !            46: #ifdef MAXNAMLEN
        !            47: #define BSD42
        !            48: #ifdef aegis
        !            49: char *ckxsys = " Apollo DOMAIN/IX 4.2 BSD";
        !            50: #else
        !            51: char *ckxsys = " 4.2 BSD";
        !            52: #endif /* aegis */
        !            53: #else
        !            54: #ifdef FT18
        !            55: #define BSD41
        !            56: char *ckxsys = " Fortune For:Pro 1.8";
        !            57: #else
        !            58: #define BSD41
        !            59: #ifndef C70
        !            60: char *ckxsys = " 4.1 BSD";
        !            61: #endif /* not c70 */
        !            62: #endif /* ft18 */
        !            63: #endif /* maxnamlen */
        !            64: #endif /* bsd4 */
        !            65: 
        !            66: /* 2.9bsd support contributed by Bradley Smith, UCLA */
        !            67: #ifdef BSD29
        !            68: #define ANYBSD
        !            69: char *ckxsys = " 2.9 BSD";
        !            70: #endif /* bsd29 */
        !            71: 
        !            72: /*
        !            73:  Version 7 UNIX support contributed by Gregg Wonderly,
        !            74:  Oklahoma State University:  [email protected]
        !            75: */
        !            76: #ifdef V7
        !            77: char *ckxsys = " Version 7 UNIX (tm)";
        !            78: #endif /* v7 */
        !            79: 
        !            80: /*
        !            81:  Version 9 UNIX support contributed by Paul Glick,
        !            82:  AT&T Bell Laboratories:  [email protected]
        !            83: */
        !            84: #ifdef V9
        !            85: char *ckxsys = " Version 9 UNIX (tm)";
        !            86: #endif /* v9 */
        !            87: 
        !            88: /* BBN C70 support from Frank Wancho, WANCHO@SIMTEL20 */
        !            89: #ifdef C70
        !            90: char *ckxsys = " BBN C/70";
        !            91: #endif /* c70 */
        !            92: 
        !            93: /* IBM 370 IX/370 support from Wayne Van Pelt, GE/CRD, Schenectedy, NY */
        !            94: #ifdef IX370
        !            95: char *ckxsys = " IBM IX/370";
        !            96: #endif /* ix370 */
        !            97: 
        !            98: /* Amdahl UTS 2.4 (v7 derivative) for IBM 370 series compatible mainframes */
        !            99: /* Contributed by Garard Gaye, Jean-Pierre Dumas, DUMAS@SUMEX-AIM. */
        !           100: #ifdef UTS24
        !           101: char *ckxsys = " Amdahl UTS 2.4";
        !           102: #endif /* uts24 */
        !           103: 
        !           104: /* Pro/Venix Version 1.x support from Columbia U. */
        !           105: #ifdef PROVX1
        !           106: char *ckxsys = " Pro-3xx Venix v1";
        !           107: #endif /* provx1 */
        !           108: 
        !           109: /* Tower support contributed by John Bray, Auburn, Alabama */
        !           110: #ifdef TOWER1
        !           111: char *ckxsys = " NCR Tower 1632, OS 1.02";
        !           112: #endif /* tower1 */
        !           113: 
        !           114: /* Sys III/V, Xenix, PC/IX support by Herm Fischer, Encino, CA */
        !           115: #ifdef UXIII
        !           116: #ifdef XENIX
        !           117: char *ckxsys = " Xenix/286";
        !           118: #else
        !           119: #ifdef PCIX
        !           120: char *ckxsys = " PC/IX";
        !           121: #else
        !           122: #ifdef ISIII
        !           123: char *ckxsys = " Interactive Systems Corp System III";
        !           124: #else
        !           125: #ifdef hpux
        !           126: /* HP 9000 Series changes contributed by Bill Coalson */
        !           127: char *ckxsys = " HP 9000 Series HP-UX";
        !           128: #else
        !           129: #ifdef aegis
        !           130: /* Apollo Aegis support from SAS Institute, Cary, NC */
        !           131: char *ckxsys = " Apollo DOMAIN/IX System V";
        !           132: #else
        !           133: #ifdef ZILOG
        !           134: char *ckxsys = " Zilog S8000 Zeus 3.21+";
        !           135: #else
        !           136: #ifdef VXVE
        !           137: /* Control Data Corp VX/VE 5.2.1 System V support by */
        !           138: /* S.O. Lidie, Lehigh University, [email protected] */
        !           139: char *ckxsys = " CDC VX/VE 5.2.1 System V";
        !           140: #else
        !           141: char *ckxsys = " AT&T System III/System V";
        !           142: #endif /* vxve  */
        !           143: #endif /* zilog */
        !           144: #endif /* aegis */
        !           145: #endif /* hpux  */
        !           146: #endif /* isiii */
        !           147: #endif /* pcix  */
        !           148: #endif /* xenix */
        !           149: #endif /* uxiii */
        !           150: 
        !           151: /* Features... */
        !           152: 
        !           153: /* Do own buffering, using unbuffered read() calls... */
        !           154: #ifdef UXIII
        !           155: #define MYREAD
        !           156: #endif /* uxiii */
        !           157: 
        !           158: #ifdef BSD42
        !           159: #undef MYREAD
        !           160: #include <errno.h>
        !           161: #endif /* bsd42 */
        !           162: 
        !           163: /*
        !           164:  Variables available to outside world:
        !           165: 
        !           166:    dftty  -- Pointer to default tty name string, like "/dev/tty".
        !           167:    dfloc  -- 0 if dftty is console, 1 if external line.
        !           168:    dfprty -- Default parity
        !           169:    dfflow -- Default flow control
        !           170:    ckxech -- Flag for who echoes console typein:
        !           171:      1 - The program (system echo is turned off)
        !           172:      0 - The system (or front end, or terminal).
        !           173:    functions that want to do their own echoing should check this flag
        !           174:    before doing so.
        !           175: 
        !           176:    flfnam -- Name of lock file, including its path, e.g.,
        !           177:                "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
        !           178:    hasLock -- Flag set if this kermit established a uucp lock.
        !           179:    inbufc -- number of tty line rawmode unread characters
        !           180:                (system III/V unixes)
        !           181:    backgrd -- Flag indicating program executing in background ( & on
        !           182:                end of shell command). Used to ignore INT and QUIT signals.
        !           183: 
        !           184:  Functions for assigned communication line (either external or console tty):
        !           185: 
        !           186:    sysinit()               -- System dependent program initialization
        !           187:    syscleanup()            -- System dependent program shutdown
        !           188:    ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access.
        !           189:    ttclos()                -- Close & reset the tty, releasing any access lock.
        !           190:    ttpkt(speed,flow)       -- Put the tty in packet mode and set the speed.
        !           191:    ttvt(speed,flow)        -- Put the tty in virtual terminal mode.
        !           192:                                or in DIALING or CONNECTED modem control state.
        !           193:    ttinl(dest,max,timo)    -- Timed read line from the tty.
        !           194:    ttinc(timo)             -- Timed read character from tty.
        !           195:    myread()               -- System 3 raw mode bulk buffer read, gives
        !           196:                           --   subsequent chars one at a time and simulates
        !           197:                           --   FIONREAD!
        !           198:    myunrd(c)              -- Places c back in buffer to be read (one only)
        !           199:    ttchk()                 -- See how many characters in tty input buffer.
        !           200:    ttxin(n,buf)            -- Read n characters from tty (untimed).
        !           201:    ttol(string,length)     -- Write a string to the tty.
        !           202:    ttoc(c)                 -- Write a character to the tty.
        !           203:    ttflui()                -- Flush tty input buffer.
        !           204: 
        !           205:    ttlock(ttname)         -- Lock against uucp collisions (Sys III)
        !           206:    ttunlck()              -- Unlock "       "     "
        !           207:    look4lk(ttname)        -- Check if a lock file exists
        !           208: */
        !           209: 
        !           210: /*
        !           211: Functions for console terminal:
        !           212: 
        !           213:    congm()   -- Get console terminal modes.
        !           214:    concb(esc) -- Put the console in single-character wakeup mode with no echo.
        !           215:    conbin(esc) -- Put the console in binary (raw) mode.
        !           216:    conres()  -- Restore the console to mode obtained by congm().
        !           217:    conoc(c)  -- Unbuffered output, one character to console.
        !           218:    conol(s)  -- Unbuffered output, null-terminated string to the console.
        !           219:    conola(s) -- Unbuffered output, array of strings to the console.
        !           220:    conxo(n,s) -- Unbuffered output, n characters to the console.
        !           221:    conchk()  -- Check if characters available at console (bsd 4.2).
        !           222:                Check if escape char (^\) typed at console (System III/V).
        !           223:    coninc(timo)  -- Timed get a character from the console.
        !           224:    conint()  -- Enable terminal interrupts on the console if not background.
        !           225:    connoi()  -- Disable terminal interrupts on the console if not background.
        !           226: 
        !           227: Time functions
        !           228: 
        !           229:    msleep(m) -- Millisecond sleep
        !           230:    ztime(&s) -- Return pointer to date/time string
        !           231:    rtimer() --  Reset timer
        !           232:    gtimer()  -- Get elapsed time since last call to rtimer()
        !           233: */
        !           234: 
        !           235: /* Conditional Includes */
        !           236: 
        !           237: #ifdef FT18
        !           238: #include <sys/file.h>                  /* File information */
        !           239: #endif /* ft18 */
        !           240: 
        !           241: /* Whether to #include <sys/file.h>... */
        !           242: #ifndef PROVX1
        !           243: #ifndef aegis
        !           244: #ifndef XENIX
        !           245: #include <sys/file.h>                  /* File information */
        !           246: #endif /* xenix */
        !           247: #endif /* aegis */
        !           248: #endif /* provx1 */
        !           249: 
        !           250: #ifdef aegis
        !           251: #ifdef BSD4
        !           252: #include <sys/file.h>
        !           253: #include <fcntl.h>
        !           254: #endif /* bsd4 */
        !           255: #endif /* aegis */
        !           256: 
        !           257: /* System III, System V */
        !           258: 
        !           259: #ifdef UXIII
        !           260: #include <termio.h>
        !           261: #include <sys/ioctl.h>
        !           262: #include <fcntl.h>                     /* directory reading for locking */
        !           263: #include <errno.h>                     /* error numbers for system returns */
        !           264: #endif /* uxiii */
        !           265: 
        !           266: #ifdef HPUX
        !           267: #include <sys/modem.h>
        !           268: #endif
        !           269: 
        !           270: /* Not Sys III/V */
        !           271: 
        !           272: #ifdef V9
        !           273: #include <sys/filio.h>
        !           274: #include <sys/ttyio.h>
        !           275: 
        !           276: extern int     tty_ld;
        !           277: #endif
        !           278: #ifndef UXIII
        !           279: #ifndef V9
        !           280: #include <sgtty.h>                     /* Set/Get tty modes */
        !           281: #ifndef PROVX1
        !           282: #ifndef V7
        !           283: #ifndef BSD41
        !           284: #include <sys/time.h>                  /* Clock info (for break generation) */
        !           285: #endif /* not bsd41 */
        !           286: #endif /* not v7 */
        !           287: #endif /* not provx1 */
        !           288: #endif /* not v9 */
        !           289: #endif /* not uxiii */
        !           290: 
        !           291: #ifdef BSD41
        !           292: #include <sys/timeb.h>                 /* BSD 4.1 ... ceb */
        !           293: #endif /* bsd41 */
        !           294: 
        !           295: #ifdef BSD29
        !           296: #include <sys/timeb.h>                 /* BSD 2.9 (Vic Abell, Purdue) */
        !           297: #endif /* bsd29 */
        !           298: 
        !           299: #ifdef TOWER1
        !           300: #include <sys/timeb.h>                 /* Clock info for NCR Tower */
        !           301: #endif /* tower1 */
        !           302: 
        !           303: #ifdef aegis
        !           304: #include "/sys/ins/base.ins.c"
        !           305: #include "/sys/ins/error.ins.c"
        !           306: #include "/sys/ins/ios.ins.c"
        !           307: #include "/sys/ins/sio.ins.c"
        !           308: #include "/sys/ins/pad.ins.c"
        !           309: #include "/sys/ins/time.ins.c"
        !           310: #include "/sys/ins/pfm.ins.c"
        !           311: #include "/sys/ins/pgm.ins.c"
        !           312: #include "/sys/ins/ec2.ins.c"
        !           313: #include "/sys/ins/type_uids.ins.c"
        !           314: #include <default_acl.h>
        !           315: #undef TIOCEXCL
        !           316: #undef FIONREAD
        !           317: #endif
        !           318: 
        !           319: /* The following two conditional #defines are catch-alls for those systems */
        !           320: /* that didn't have or couldn't find <file.h>... */
        !           321: 
        !           322: #ifndef FREAD
        !           323: #define FREAD 0x01
        !           324: #endif
        !           325: 
        !           326: #ifndef FWRITE
        !           327: #define FWRITE 0x10
        !           328: #endif
        !           329: 
        !           330: /* Declarations */
        !           331: 
        !           332: long time();                           /* All Unixes should have this... */
        !           333: extern int errno;                      /* System call error code. */
        !           334: 
        !           335: /* Special stuff for V7 input buffer peeking */
        !           336: 
        !           337: #ifdef V7
        !           338: int kmem[2] = { -1, -1};
        !           339: char *initrawq(), *qaddr[2]={0,0};
        !           340: #define CON 0
        !           341: #define TTY 1
        !           342: #endif /* v7 */
        !           343: 
        !           344: /* dftty is the device name of the default device for file transfer */
        !           345: /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
        !           346: 
        !           347: #ifdef PROVX1
        !           348:     char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
        !           349:     int dfloc = 1;                 /* that goes in local mode by default */
        !           350: #else
        !           351:     char *dftty = CTTNAM;              /* Remote by default, use normal */
        !           352:     int dfloc = 0;                     /* controlling terminal name. */
        !           353: #endif /* provx1 */
        !           354: 
        !           355:     int dfprty = 0;                    /* Default parity (0 = none) */
        !           356:     int ttprty = 0;                    /* Parity in use. */
        !           357:     int ttmdm = 0;                     /* Modem in use. */
        !           358:     int dfflow = 1;                    /* Xon/Xoff flow control */
        !           359:     int backgrd = 0;                   /* Assume in foreground (no '&' ) */
        !           360: 
        !           361: int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
        !           362: 
        !           363: /* Declarations of variables global within this module */
        !           364: 
        !           365: static long tcount;                    /* Elapsed time counter */
        !           366: 
        !           367: static char *brnuls = "\0\0\0\0\0\0\0"; /* A string of nulls */
        !           368: 
        !           369: static jmp_buf sjbuf, jjbuf;           /* Longjump buffer */
        !           370: static int lkf = 0,                    /* Line lock flag */
        !           371:     conif = 0,                         /* Console interrupts on/off flag */
        !           372:     cgmf = 0,                          /* Flag that console modes saved */
        !           373:     xlocal = 0,                                /* Flag for tty local or remote */
        !           374:     ttyfd = -1;                                /* TTY file descriptor */
        !           375: static char escchr;                    /* Escape or attn character */
        !           376: 
        !           377: #ifdef BSD42
        !           378:     static struct timeval tv;          /* For getting time, from sys/time.h */
        !           379:     static struct timezone tz;
        !           380: #endif /* bsd42 */
        !           381: 
        !           382: #ifdef BSD29
        !           383:     static long clock;                 /* For getting time from sys/time.h */
        !           384:     static struct timeb ftp;           /* And from sys/timeb.h */
        !           385: #endif /* bsd29 */
        !           386: 
        !           387: #ifdef BSD41
        !           388:     static long clock;                 /* For getting time from sys/time.h */
        !           389:     static struct timeb ftp;           /* And from sys/timeb.h */
        !           390: #endif /* bsd41 */
        !           391: 
        !           392: #ifdef TOWER1
        !           393: static long clock;                     /* For getting time from sys/time.h */
        !           394: static struct timeb ftp;               /* And from sys/timeb.h */
        !           395: #endif /* tower1 */
        !           396: 
        !           397: #ifdef V7
        !           398: static long clock;
        !           399: #endif /* v7 */
        !           400: 
        !           401: #ifdef V9
        !           402: static long clock;
        !           403: #endif
        !           404: 
        !           405: /* sgtty/termio information... */
        !           406: 
        !           407: #ifdef UXIII
        !           408:   static struct termio ttold = {0};    /* Init'd for word alignment, */
        !           409:   static struct termio ttraw = {0};    /* which is important for some */
        !           410:   static struct termio tttvt = {0};    /* systems, like Zilog... */
        !           411:   static struct termio ccold = {0};
        !           412:   static struct termio ccraw = {0};
        !           413:   static struct termio cccbrk = {0};
        !           414: #else
        !           415:   static struct sgttyb                         /* sgtty info... */
        !           416:     ttold, ttraw, tttvt, ttbuf,                /* for communication line */
        !           417:     ccold, ccraw, cccbrk;              /* and for console */
        !           418: #endif /* uxiii */
        !           419: 
        !           420: static char flfnam[80];                        /* uucp lock file path name */
        !           421: static int hasLock = 0;                        /* =1 if this kermit locked uucp */
        !           422: static int inbufc = 0;                 /* stuff for efficient SIII raw line */
        !           423: static int ungotn = -1;                        /* pushback to unread character */
        !           424: static int conesc = 0;                 /* set to 1 if esc char (^\) typed */
        !           425: 
        !           426: static int ttlock();                   /* definition of ttlock subprocedure */
        !           427: static int ttunlck();                  /* and unlock subprocedure */
        !           428: static char ttnmsv[DEVNAMLEN];         /* copy of open path for tthang */
        !           429: 
        !           430: #ifdef aegis
        !           431: static status_$t st;                   /* error status return value */
        !           432: static short concrp = 0;               /* true if console is CRP pad */
        !           433: #define CONBUFSIZ 10
        !           434: static char conbuf[CONBUFSIZ];         /* console readahead buffer */
        !           435: static int  conbufn = 0;               /* # chars in readahead buffer */
        !           436: static char *conbufp;                  /* next char in readahead buffer */
        !           437: static uid_$t ttyuid;                  /* tty type uid */
        !           438: static uid_$t conuid;                  /* stdout type uid */
        !           439: 
        !           440: /* APOLLO Aegis main()
        !           441:  * establish acl usage and cleanup handling
        !           442:  *    this makes sure that CRP pads
        !           443:  *    get restored to a usable mode
        !           444:  */
        !           445: main(argc,argv) int argc; char **argv; {
        !           446:        status_$t status;
        !           447:        pfm_$cleanup_rec dirty;
        !           448: 
        !           449:        int pid = getpid();
        !           450: 
        !           451:        /* acl usage according to invoking environment */
        !           452:        default_acl(USE_DEFENV);
        !           453: 
        !           454:        /* establish a cleanup continuation */
        !           455:        status = pfm_$cleanup(dirty);
        !           456:        if (status.all != pfm_$cleanup_set)
        !           457:        {
        !           458:                /* only handle faults for the original process */
        !           459:                if (pid == getpid() && status.all > pgm_$max_severity)
        !           460:                {       /* blew up in main process */
        !           461:                        status_$t quo;
        !           462:                        pfm_$cleanup_rec clean;
        !           463: 
        !           464:                        /* restore the console in any case */
        !           465:                        conres();
        !           466: 
        !           467:                        /* attempt a clean exit */
        !           468:                        debug(F101, "cleanup fault status", "", status.all);
        !           469: 
        !           470:                        /* doexit(), then send status to continuation */
        !           471:                        quo = pfm_$cleanup(clean);
        !           472:                        if (quo.all == pfm_$cleanup_set)
        !           473:                                doexit(pgm_$program_faulted);
        !           474:                        else if (quo.all > pgm_$max_severity)
        !           475:                                pfm_$signal(quo); /* blew up in doexit() */
        !           476:                }
        !           477:                /* send to the original continuation */
        !           478:                pfm_$signal(status);
        !           479:                /*NOTREACHED*/
        !           480:        }
        !           481:        return(ckcmai(argc, argv));
        !           482: }
        !           483: #endif /* aegis */
        !           484: 
        !           485: /*  S Y S I N I T  --  System-dependent program initialization.  */
        !           486: 
        !           487: sysinit() {
        !           488: 
        !           489: /* for now, nothing... */
        !           490:     return(0);
        !           491: }
        !           492: 
        !           493: /*  S Y S C L E A N U P  --  System-dependent program cleanup.  */
        !           494: 
        !           495: syscleanup() {
        !           496: 
        !           497: /* for now, nothing... */
        !           498:     return(0);
        !           499: }
        !           500: 
        !           501: /*  T T O P E N  --  Open a tty for exclusive access.  */
        !           502: 
        !           503: /*  Returns 0 on success, -1 on failure.  */
        !           504: /*
        !           505:   If called with lcl < 0, sets value of lcl as follows:
        !           506:   0: the terminal named by ttname is the job's controlling terminal.
        !           507:   1: the terminal named by ttname is not the job's controlling terminal.
        !           508:   But watch out: if a line is already open, or if requested line can't
        !           509:   be opened, then lcl remains (and is returned as) -1.
        !           510: */
        !           511: ttopen(ttname,lcl,modem) char *ttname; int *lcl, modem; {
        !           512: 
        !           513: #ifdef UXIII
        !           514: #ifndef CIE
        !           515:     char *ctermid();                   /* Wish they all had this! */
        !           516: #endif /* not cie */
        !           517: #endif /* uxiii */
        !           518: 
        !           519: #ifdef CIE                             /* CIE Regulus doesn't... */
        !           520: #define ctermid(x) strcpy(x,"")
        !           521: #endif
        !           522: 
        !           523:     char *x; extern char* ttyname();
        !           524:     char cname[DEVNAMLEN+4];
        !           525: 
        !           526:     if (ttyfd > -1) return(0);         /* If already open, ignore this call */
        !           527:     ttmdm = modem;                     /* Make this available to other fns */
        !           528:     xlocal = *lcl;                     /* Make this available to other fns */
        !           529: #ifdef NEWUUCP
        !           530:     acucntrl("disable",ttname);                /* Open getty on line (4.3BSD) */
        !           531: #endif /* newuucp */
        !           532: #ifdef UXIII
        !           533:     /* if modem connection, don't wait for carrier */
        !           534:     ttyfd = open(ttname,O_RDWR | (modem ? O_NDELAY : 0) );
        !           535: #else
        !           536: #ifdef V9
        !           537:     if (strncmp(ttname, "/cs", 3) == 0) {
        !           538:        if ((ttyfd = ipcopen(ttname, "")) >= 0)
        !           539:            if ( ioctl(ttyfd, FIOPUSHLD, &tty_ld) == -1 )
        !           540:                fprintf(stderr, "ioctl error - FIOPUSHLD\n");
        !           541:     } else
        !           542: #endif /* V9 */
        !           543:     ttyfd = open(ttname,2);            /* Try to open for read/write */
        !           544: #endif /* uxiii */
        !           545: 
        !           546:     if (ttyfd < 0) {                   /* If couldn't open, fail. */
        !           547:        perror(ttname);
        !           548:        return(-1);
        !           549:     }
        !           550: #ifdef aegis
        !           551:     /* Apollo C runtime claims that console pads are tty devices, which
        !           552:      * is reasonable, but they aren't any good for packet transfer. */
        !           553:     ios_$inq_type_uid((short)ttyfd, ttyuid, st);
        !           554:     if (st.all != status_$ok) {
        !           555:        fprintf(stderr, "problem getting tty object type: ");
        !           556:        error_$print(st);
        !           557:     } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */
        !           558:        close(ttyfd); ttyfd = -1;
        !           559:        errno = ENOTTY; perror(ttname);
        !           560:        return(-1);
        !           561:     }
        !           562: #endif /* aegis */
        !           563:     strncpy(ttnmsv,ttname,DEVNAMLEN);  /* Open, keep copy of name locally. */
        !           564: 
        !           565: /* Caller wants us to figure out if line is controlling tty */
        !           566: 
        !           567:     debug(F111,"ttopen ok",ttname,*lcl);
        !           568:     if (*lcl == -1) {
        !           569:        if (strcmp(ttname,CTTNAM) == 0) {   /* "/dev/tty" always remote */
        !           570:            debug(F110," Same as CTTNAM",ttname,0);
        !           571:            xlocal = 0;
        !           572:        } else if (isatty(0)) {         /* Else, if stdin not redirected */
        !           573:            x = ttyname(0);             /* then compare its device name */
        !           574:            strncpy(cname,x,DEVNAMLEN); /* (copy from internal static buf) */
        !           575:            debug(F110," ttyname(0)",x,0);
        !           576:            x = ttyname(ttyfd);         /* ...with real name of ttname. */
        !           577:            xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1;
        !           578:            debug(F111," ttyname",x,xlocal);
        !           579:        } else {                        /* Else, if stdin redirected... */
        !           580: #ifdef UXIII
        !           581: /* Sys III/V provides nice ctermid() function to get name of controlling tty */
        !           582:            ctermid(cname);             /* Get name of controlling terminal */
        !           583:            debug(F110," ctermid",cname,0);
        !           584:            x = ttyname(ttyfd);         /* Compare with name of comm line. */
        !           585:            xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1;
        !           586:            debug(F111," ttyname",x,xlocal);
        !           587: #else
        !           588: /* Just assume local, so "set speed" and similar commands will work */
        !           589: /* If not really local, how could it work anyway?... */
        !           590:            xlocal = 1;
        !           591:            debug(F101," redirected stdin","",xlocal);
        !           592: #endif /* uxiii */
        !           593:         }
        !           594:     }    
        !           595: 
        !           596: /* Now check if line is locked -- if so fail, else lock for ourselves */
        !           597: 
        !           598:     lkf = 0;                           /* Check lock */
        !           599:     if (xlocal > 0) {
        !           600:        if (ttlock(ttname) < 0) {
        !           601:            fprintf(stderr,"Exclusive access to %s denied\n",ttname);
        !           602:            close(ttyfd); ttyfd = -1;
        !           603:            debug(F110," Access denied by lock",ttname,0);
        !           604:            return(-1);                 /* Not if already locked */
        !           605:        } else lkf = 1;
        !           606:     }
        !           607: 
        !           608: /* Got the line, now set the desired value for local. */
        !           609: 
        !           610:     if (*lcl < 0) *lcl = xlocal;
        !           611: 
        !           612: /* Some special stuff for v7... */
        !           613: 
        !           614: #ifdef V7
        !           615:        if (kmem[TTY] < 0) {    /*  If open, then skip this.  */
        !           616:                qaddr[TTY] = initrawq(ttyfd);   /* Init the queue. */
        !           617:                if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
        !           618:                        fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
        !           619:                        perror("/dev/kmem");
        !           620:                        exit(1);
        !           621:                }
        !           622:        }
        !           623: #endif /* v7 */
        !           624: 
        !           625: /* Request exclusive access on systems that allow it. */
        !           626: 
        !           627: #ifndef XENIX
        !           628: /* Xenix exclusive access prevents open(close(...)) from working... */
        !           629: #ifdef TIOCEXCL
        !           630:        if (ioctl(ttyfd,TIOCEXCL, NULL) < 0)
        !           631:            fprintf(stderr,"Warning, problem getting exclusive access\n");
        !           632: #endif /* tiocexcl */
        !           633: #endif /* xenix */
        !           634: 
        !           635: /* Get tty device settings */
        !           636: 
        !           637: #ifndef UXIII
        !           638: #ifdef V9
        !           639:     ioctl(ttyfd,TIOCGETP,&ttold);              /* Same deal for Sys III, Sys V */
        !           640:     ioctl(ttyfd,TIOCGETP,&ttraw);
        !           641:     ioctl(ttyfd,TIOCGETP,&tttvt);
        !           642: #else
        !           643:     gtty(ttyfd,&ttold);                        /* Get sgtty info */
        !           644: #ifdef aegis
        !           645:     sio_$control((short)ttyfd, sio_$raw_nl, false, st);
        !           646:     if (xlocal) {      /* ignore breaks from local line */
        !           647:        sio_$control((short)ttyfd, sio_$int_enable, false, st);
        !           648:        sio_$control((short)ttyfd, sio_$quit_enable, false, st);
        !           649:     }
        !           650: #endif /* aegis */
        !           651:     gtty(ttyfd,&ttraw);                        /* And a copy of it for packets*/
        !           652:     gtty(ttyfd,&tttvt);                        /* And one for virtual tty service */
        !           653: #endif /* v9 */
        !           654: #else
        !           655:     ioctl(ttyfd,TCGETA,&ttold);                /* Same deal for Sys III, Sys V */
        !           656: #ifdef aegis
        !           657:     sio_$control((short)ttyfd, sio_$raw_nl, false, st);
        !           658:     if (xlocal) {      /* ignore breaks from local line */
        !           659:        sio_$control((short)ttyfd, sio_$int_enable, false, st);
        !           660:        sio_$control((short)ttyfd, sio_$quit_enable, false, st);
        !           661:     }
        !           662: #endif /* aegis */
        !           663:     ioctl(ttyfd,TCGETA,&ttraw);
        !           664:     ioctl(ttyfd,TCGETA,&tttvt);
        !           665: #endif /* not uxiii */
        !           666: 
        !           667: #ifdef VXVE
        !           668:     ttraw.c_line = 0;                  /* STTY line 0 for VX/VE */
        !           669:     ioctl(ttyfd,TCSETA,&ttraw);
        !           670:     tttvt.c_line = 0;                  /* STTY line 0 for VX/VE */
        !           671:     ioctl(ttyfd,TCSETA,&tttvt);
        !           672: #endif /* vxve */
        !           673: 
        !           674:     debug(F101,"ttopen, ttyfd","",ttyfd);
        !           675:     debug(F101," lcl","",*lcl);
        !           676:     debug(F111," lock file",flfnam,lkf);
        !           677:     return(0);
        !           678: }
        !           679: 
        !           680: /*  T T C L O S  --  Close the TTY, releasing any lock.  */
        !           681: 
        !           682: ttclos() {
        !           683:     if (ttyfd < 0) return(0);          /* Wasn't open. */
        !           684:     if (xlocal) {
        !           685:        if (tthang())                   /* Hang up phone line */
        !           686:            fprintf(stderr,"Warning, problem hanging up the phone\n");
        !           687:        if (ttunlck())                  /* Release uucp-style lock */
        !           688:            fprintf(stderr,"Warning, problem releasing lock\n");
        !           689:     }
        !           690:     ttres();                           /* Reset modes. */
        !           691: /* Relinquish exclusive access if we might have had it... */
        !           692: #ifndef XENIX
        !           693: #ifdef TIOCEXCL
        !           694: #ifdef TIOCNXCL
        !           695:     if (ioctl(ttyfd, TIOCNXCL, NULL) < 0)
        !           696:        fprintf(stderr,"Warning, problem relinquishing exclusive access\n");
        !           697: #endif /* tiocnxcl */
        !           698: #endif /* tiocexcl */
        !           699: #endif /* not xenix */
        !           700:     close(ttyfd);                      /* Close it. */
        !           701: #ifdef NEWUUCP
        !           702:     acucntrl("enable",flfnam);         /* Close getty on line. */
        !           703: #endif /* newuucp */
        !           704:     ttyfd = -1;                                /* Mark it as closed. */
        !           705:     return(0);
        !           706: }
        !           707: 
        !           708: /*  T T H A N G -- Hangup phone line */
        !           709: 
        !           710: tthang() {
        !           711: #ifdef UXIII
        !           712: #ifdef HPUX
        !           713:     unsigned long dtr_down = 00000000000,
        !           714:                   modem_rtn;
        !           715: #else
        !           716:     unsigned short ttc_save;
        !           717: #endif /* hpux */
        !           718: #endif /* uxiii */
        !           719: 
        !           720:     if (ttyfd < 0) return(0);          /* Not open. */
        !           721: #ifdef aegis
        !           722:     sio_$control((short)ttyfd, sio_$dtr, false, st);   /* DTR down */
        !           723:     msleep(500);                                       /* pause */
        !           724:     sio_$control((short)ttyfd, sio_$dtr, true,  st);   /* DTR up */
        !           725: #else
        !           726: #ifdef ANYBSD
        !           727:     ioctl(ttyfd,TIOCCDTR,0);           /* Clear DTR */
        !           728:     msleep(500);                       /* Let things settle */
        !           729:     ioctl(ttyfd,TIOCSDTR,0);           /* Restore DTR */
        !           730: #endif /* anybsd */
        !           731: #ifdef UXIII
        !           732: #ifdef HPUX   /* Hewlett Packard way of modem control  */
        !           733:     if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0) return(-1); /* lower DTR */
        !           734:     msleep(500);
        !           735:     if (ioctl(ttyfd,MCGETA,&modem_rtn) < 0) return(-1); /* get line status */
        !           736:     if ((modem_rtn & MDCD) != 0) return(-1);        /* check if DCD is low */
        !           737:     modem_rtn = MRTS | MDTR;                        /* bits for RTS & DTR  */
        !           738:     if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) return(-1);    /*  set lines  */
        !           739: #else
        !           740:     ttc_save = ttraw.c_cflag;
        !           741:     ttraw.c_cflag &= ~CBAUD;           /* swa: set baud rate to 0 to hangup */
        !           742:     if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* do it */
        !           743:     msleep(100);                       /* let things settle */
        !           744:     ttraw.c_cflag = ttc_save;
        !           745: 
        !           746: /* NOTE - The following #ifndef...#endif can be removed for SCO Xenix 2.1.3 */
        !           747: /* or later, but must keep for earlier versions, which can't do close/open. */
        !           748: 
        !           749: #ifndef XENIX          /* xenix cannot do close/open when carrier drops */
        !           750:                                /* following corrects a PC/IX defficiency */
        !           751:     ttc_save = fcntl(ttyfd,F_GETFL,0);
        !           752:     close(ttyfd);              /* close/reopen file descriptor */
        !           753:     if ((ttyfd = open(ttnmsv, ttc_save)) < 0) return(-1);
        !           754: #endif /* not xenix */
        !           755:     if (ioctl(ttyfd,TCSETAF,&ttraw) < 0) return(-1); /* un-do it */
        !           756: #endif /* uxiii */
        !           757: #endif /* hpux  */
        !           758: #endif /* aegis */
        !           759:     return (0);
        !           760: }
        !           761: 
        !           762: 
        !           763: /*  T T R E S  --  Restore terminal to "normal" mode.  */
        !           764: 
        !           765: ttres() {                              /* Restore the tty to normal. */
        !           766:     int x;
        !           767: 
        !           768:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           769: #ifndef UXIII                          /* except for sIII, */
        !           770:     sleep(1);                          /* Wait for pending i/o to finish. */
        !           771: #endif /* uxiii */                     /*   (sIII does wait in ioctls) */
        !           772: 
        !           773: #ifdef UXIII
        !           774:     if (ioctl(ttyfd,TCSETAW,&ttold) < 0) return(-1); /* restore termio stuff */
        !           775:     if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
        !           776:       return(-1);
        !           777: #else /* not uxiii */
        !           778: #ifdef V9
        !           779:     if (ioctl(ttyfd, TIOCSETP, &ttold) < 0) return(-1); /* Restore sgttyb stuff */
        !           780: #else
        !           781: #ifdef FIONBIO
        !           782:     x = 0;
        !           783:     x = ioctl(ttyfd,FIONBIO,&x);
        !           784:     if (x < 0) {
        !           785:        perror("ttres ioctl");
        !           786:        debug(F101,"ttres ioctl","",x);
        !           787:     }
        !           788: #else /* not fionbio */
        !           789: #ifdef FNDELAY
        !           790:     x = (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) & ~FNDELAY) == -1);
        !           791:     debug(F101,"ttres fcntl","",x);
        !           792:     if (x < 0) perror("fcntl");
        !           793: #endif /* fndelay */
        !           794: #endif /* fionbio */
        !           795:     x = stty(ttyfd,&ttold);            /* Restore sgtty stuff */
        !           796:     debug(F101,"ttres stty","",x);
        !           797:     if (x < 0) perror("stty");
        !           798: #endif /* v9 */
        !           799: #endif /* uxiii */
        !           800:     return(x);
        !           801: }
        !           802: 
        !           803: /* Exclusive uucp file locking control */
        !           804: /*
        !           805:  by H. Fischer, creative non-Bell coding !
        !           806:  copyright rights for lock modules assigned to Columbia University
        !           807: */
        !           808: static char *
        !           809: xxlast(s,c) char *s; char c; {         /* Equivalent to strrchr() */
        !           810:     int i;
        !           811:     for (i = strlen(s); i > 0; i--)
        !           812:        if ( s[i-1] == c ) return( s + (i - 1) );
        !           813:     return(NULL);    
        !           814: }
        !           815: static
        !           816: look4lk(ttname) char *ttname; {
        !           817:     extern char *strcat(), *strcpy();
        !           818:     char *device, *devname;
        !           819:     char lockfil[50];                  /* Max length for lock file name */
        !           820: 
        !           821: #ifdef ISIII
        !           822:     char *lockdir = "/etc/locks";
        !           823: #else
        !           824: #ifdef ATT3BX
        !           825:     char *lockdir = "/usr/spool/locks";
        !           826: #else
        !           827: #ifdef NEWUUCP
        !           828:     char *lockdir = "/usr/spool/uucp/LCK";
        !           829: #else
        !           830:     char *lockdir = "/usr/spool/uucp";
        !           831: #endif /* newuucp */
        !           832: #endif /* att3bx */
        !           833: #endif /* isiii */
        !           834: 
        !           835:     device = ( (devname=xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
        !           836: 
        !           837: #ifdef ISIII
        !           838:     (void) strcpy( lockfil, device );
        !           839: #else
        !           840:     strcat( strcpy( lockfil, "LCK.." ), device );
        !           841: #endif /* isiii */
        !           842: 
        !           843:     if (access( lockdir, 04 ) < 0) {   /* read access denied on lock dir */
        !           844:        fprintf(stderr,"Warning, read access to lock directory denied\n");
        !           845:        return( 1 );                    /* cannot check or set lock file */
        !           846:     }
        !           847:        
        !           848:     strcat(strcat(strcpy(flfnam,lockdir),"/"), lockfil);
        !           849:     debug(F110,"look4lk",flfnam,0);
        !           850: 
        !           851:     if ( ! access( flfnam, 00 ) ) {    /* print out lock file entry */
        !           852:        char lckcmd[40] ;
        !           853:        strcat( strcpy(lckcmd, "ls -l ") , flfnam);
        !           854:        system(lckcmd);
        !           855:        if (access(flfnam,02) == 0)
        !           856:            printf("(You may type \"! rm %s\" to remove this file)\n",flfnam);
        !           857:        return( -1 );
        !           858:     }
        !           859:     if ( access( lockdir, 02 ) < 0 ) { /* lock file cannot be written */
        !           860:        fprintf(stderr,"Warning, write access to lock directory denied\n");
        !           861:        return( 1 );
        !           862:     }
        !           863:     return( 0 );                       /* okay to go ahead and lock */
        !           864: }
        !           865: 
        !           866: /*  T T L O C K  */
        !           867: 
        !           868: static
        !           869: ttlock(ttfd) char *ttfd; {             /* lock uucp if possible */
        !           870: #ifndef aegis
        !           871: #ifdef ATT3BX
        !           872:     FILE *lck_fild;
        !           873: #endif /* att3bx */
        !           874:     int lck_fil, l4l;
        !           875:     int pid_buf = getpid();            /* pid to save in lock file */
        !           876:        
        !           877:     hasLock = 0;                       /* not locked yet */
        !           878:     l4l = look4lk(ttfd);
        !           879:     if (l4l < 0) return (-1);          /* already locked */
        !           880:     if (l4l == 1) return (0);          /* can't read/write lock directory */
        !           881:     lck_fil = creat(flfnam, 0444);     /* create lock file ... */
        !           882:     if (lck_fil < 0) return (-1);      /* create of lockfile failed */
        !           883:                /* creat leaves file handle open for writing -- hf */
        !           884: #ifdef ATT3BX
        !           885:     fprintf((lck_fild = fdopen(lck_fil, "w")), "%10d\n", pid_buf);
        !           886:     fflush(lck_fild);
        !           887: #else
        !           888:     write (lck_fil, &pid_buf, sizeof(pid_buf) ); /* uucp expects int in file */
        !           889: #endif /* att3bx */
        !           890:     close (lck_fil);
        !           891:     hasLock = 1;                       /* now is locked */
        !           892: #endif /* not aegis */
        !           893:     return(0);
        !           894: }
        !           895: 
        !           896: /*  T T U N L O C K  */
        !           897: 
        !           898: static
        !           899: ttunlck() {                            /* kill uucp lock if possible */
        !           900:     if (hasLock) return( unlink( flfnam ) );
        !           901:     return(0);
        !           902: }
        !           903: 
        !           904: /* New-style (4.3BSD) UUCP line direction control (Stan Barber, Rice U) */
        !           905: 
        !           906: #ifdef NEWUUCP
        !           907: acucntrl(flag,ttname) char *flag, *ttname; {
        !           908:     char x[DEVNAMLEN+32], *device, *devname;
        !           909: 
        !           910:     if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
        !           911:         return;                                /* just return. */
        !           912:     device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
        !           913:     if (strncmp(device,"LCK..",4) == 0) device += 5;
        !           914:     sprintf(x,"/usr/lib/uucp/acucntrl %s %s",flag,device);
        !           915:     debug(F000,"called ",x,0);
        !           916:     system(x);
        !           917: }
        !           918: #endif /* newuucp */
        !           919: 
        !           920: /*  T T P K T  --  Condition the communication line for packets. */
        !           921: /*             or for modem dialing */
        !           922: 
        !           923: #define DIALING        4               /* flags (via flow) for modem handling */
        !           924: #define CONNECT 5
        !           925: 
        !           926: /*  If called with speed > -1, also set the speed.  */
        !           927: 
        !           928: /*  Returns 0 on success, -1 on failure.  */
        !           929: 
        !           930: ttpkt(speed,flow,parity) int speed, flow, parity; {
        !           931:     int s, x;
        !           932: 
        !           933:     if (ttyfd < 0) return(-1);         /* Not open. */
        !           934:     ttprty = parity;                   /* Let other tt functions see this. */
        !           935:     debug(F101,"ttpkt setting ttprty","",ttprty);
        !           936:     s = ttsspd(speed);                 /* Check the speed */
        !           937: 
        !           938: #ifndef UXIII
        !           939:     if (flow == 1) ttraw.sg_flags |= TANDEM; /* Use XON/XOFF if selected */
        !           940:     if (flow == 0) ttraw.sg_flags &= ~TANDEM;
        !           941:     ttraw.sg_flags |= RAW;             /* Go into raw mode */
        !           942:     ttraw.sg_flags &= ~(ECHO|CRMOD);   /* Use CR for break character */
        !           943: #ifdef TOWER1
        !           944:     ttraw.sg_flags &= ~ANYP;           /* Must tell Tower no parity */
        !           945: #endif /* tower1 */
        !           946:     if (s > -1) ttraw.sg_ispeed = ttraw.sg_ospeed = s; /* Do the speed */
        !           947: #ifdef V9
        !           948:     if (ioctl(ttyfd,TIOCSETP,&ttraw) < 0) return(-1);  /* Set the new modes. */
        !           949: #else
        !           950:     if (stty(ttyfd,&ttraw) < 0) return(-1);    /* Set the new modes. */
        !           951: #endif /* v9 */
        !           952: 
        !           953: #ifdef MYREAD
        !           954: #ifdef BSD4
        !           955: /* Try to make reads nonblocking */
        !           956: #ifdef aegis
        !           957:     return(0);
        !           958: #endif /* aegis */
        !           959: #ifdef FIONBIO
        !           960:     x = 1;
        !           961:     if (ioctl(ttyfd,FIONBIO,&x) < 0) {
        !           962:        perror("ttpkt ioctl");
        !           963:        return(-1);
        !           964:     }
        !           965: #else /* fionbio */
        !           966: #ifdef FNDELAY
        !           967:     if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) | FNDELAY) == -1) {
        !           968:        return(-1);
        !           969:     }
        !           970: #endif /* fndelay */
        !           971: #endif /* bsd4 */
        !           972:     ttflui();                          /* Flush any pending input */
        !           973:     return(0);
        !           974: #endif /* bsd4 */
        !           975: #else  /* myread */
        !           976:     ttflui();                          /* Flush any pending input */
        !           977:     return(0);
        !           978: #endif /* myread */
        !           979: #endif /* not uxiii */
        !           980: 
        !           981: #ifdef UXIII
        !           982:     if (flow == 1) ttraw.c_iflag |= (IXON|IXOFF);
        !           983:     if (flow == 0) ttraw.c_iflag &= ~(IXON|IXOFF);
        !           984: 
        !           985:     if (flow == DIALING)  ttraw.c_cflag |= CLOCAL|HUPCL;
        !           986:     if (flow == CONNECT)  ttraw.c_cflag &= ~CLOCAL;
        !           987: 
        !           988:     ttraw.c_lflag &= ~(ICANON|ECHO);
        !           989:     ttraw.c_lflag |= ISIG;             /* do check for interrupt */
        !           990:     ttraw.c_iflag |= (BRKINT|IGNPAR);
        !           991:     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
        !           992:     ttraw.c_oflag &= ~OPOST;
        !           993:     ttraw.c_cflag &= ~(CSIZE|PARENB);
        !           994:     ttraw.c_cflag |= (CS8|CREAD);
        !           995: #ifdef IX370
        !           996:     ttraw.c_cc[4] = 48;         /* So Series/1 doesn't interrupt on every char */
        !           997:     ttraw.c_cc[5] = 1;
        !           998: #else
        !           999: #ifdef VXVE
        !          1000:     ttraw.c_cc[4] = 1;   /* [VMIN]  for CDC VX/VE */
        !          1001:     ttraw.c_cc[5] = 0;   /* [VTIME] for CDC VX/VE */
        !          1002: #else
        !          1003: #ifdef MYREAD
        !          1004:     ttraw.c_cc[4] = 200; /* return max of this many characters */
        !          1005:     ttraw.c_cc[5] = 1;   /* or when this many secs/10 expire w/no input */
        !          1006: #else
        !          1007:     ttraw.c_cc[4] = 1;   /* [VMIN]  Maybe should be bigger for all Sys V? */
        !          1008:     ttraw.c_cc[5] = 0;   /* [VTIME] Should be set high enough to ignore */
        !          1009:                                        /* intercharacter spacing? */
        !          1010:     /* But then we have to distinguish between Sys III and Sys V.. */
        !          1011: #endif
        !          1012: #endif
        !          1013: #endif
        !          1014:     if (s > -1) {                      /* set speed */
        !          1015:         ttraw.c_cflag &= ~CBAUD;
        !          1016:        ttraw.c_cflag |= s;
        !          1017:     }
        !          1018:     if (ioctl(ttyfd,TCSETAW,&ttraw) < 0) return(-1);  /* set new modes . */
        !          1019:     if (flow == DIALING) {
        !          1020: #ifndef aegis
        !          1021:        if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
        !          1022:                return(-1);
        !          1023: #endif /* not aegis */
        !          1024:        close( open(ttnmsv,2) );        /* magic to force mode change!!! */
        !          1025:     }
        !          1026:     ttflui();
        !          1027:     return(0);
        !          1028: #endif /* uxiii */
        !          1029: }
        !          1030: 
        !          1031: /*  T T V T -- Condition communication line for use as virtual terminal  */
        !          1032: 
        !          1033: ttvt(speed,flow) int speed, flow; {
        !          1034:     int s;
        !          1035:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1036: 
        !          1037:     s = ttsspd(speed);                 /* Check the speed */
        !          1038: 
        !          1039: #ifndef UXIII
        !          1040:     if (flow == 1) tttvt.sg_flags |= TANDEM; /* XON/XOFF if selected */
        !          1041:     if (flow == 0) tttvt.sg_flags &= ~TANDEM;
        !          1042:     tttvt.sg_flags |= RAW;             /* Raw mode */
        !          1043: #ifdef TOWER1
        !          1044:     tttvt.sg_flags &= ~(ECHO|ANYP);    /* No echo or system III ??? parity */
        !          1045: #else
        !          1046:     tttvt.sg_flags &= ~ECHO;           /* No echo */
        !          1047: #endif
        !          1048:     if (s > -1) tttvt.sg_ispeed = tttvt.sg_ospeed = s; /* Do the speed */
        !          1049: #ifdef V9
        !          1050:     if (ioctl(ttyfd,TIOCSETP,&tttvt) < 0) return(-1);
        !          1051: #else
        !          1052:     if (stty(ttyfd,&tttvt) < 0) return(-1);
        !          1053: #endif
        !          1054: 
        !          1055: #ifdef MYREAD
        !          1056: #ifdef BSD4
        !          1057: /* Make reads nonblocking */
        !          1058: #ifdef aegis
        !          1059:        return(0);
        !          1060: #endif
        !          1061:        if (fcntl(ttyfd,F_SETFL,fcntl(ttyfd,F_GETFL,0) | FNDELAY) == -1)
        !          1062:            return(-1);
        !          1063:        else return(0);
        !          1064: #endif /* bsd4 */
        !          1065: #endif /* myread */
        !          1066: 
        !          1067: #else /* uxiii */
        !          1068:     if (flow == 1) tttvt.c_iflag |= (IXON|IXOFF);
        !          1069:     if (flow == 0) tttvt.c_iflag &= ~(IXON|IXOFF);
        !          1070: 
        !          1071:     if (flow == DIALING)  tttvt.c_cflag |= CLOCAL|HUPCL;
        !          1072:     if (flow == CONNECT)  tttvt.c_cflag &= ~CLOCAL;
        !          1073: 
        !          1074:     tttvt.c_lflag &= ~(ISIG|ICANON|ECHO);
        !          1075:     tttvt.c_iflag |= (IGNBRK|IGNPAR);
        !          1076:     tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|BRKINT|INPCK|ISTRIP|IXANY);
        !          1077:     tttvt.c_oflag &= ~OPOST;
        !          1078:     tttvt.c_cflag &= ~(CSIZE|PARENB);
        !          1079:     tttvt.c_cflag |= (CS8|CREAD);
        !          1080:     tttvt.c_cc[4] = 1;
        !          1081:     tttvt.c_cc[5] = 0;
        !          1082: 
        !          1083:     if (s > -1) {                      /* set speed */
        !          1084:        tttvt.c_cflag &= ~CBAUD;
        !          1085:        tttvt.c_cflag |= s;
        !          1086:     }
        !          1087:     if (ioctl(ttyfd,TCSETAW,&tttvt) < 0) return(-1);  /* set new modes . */
        !          1088: 
        !          1089:     if (flow == DIALING) {
        !          1090: #ifndef aegis
        !          1091:        if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
        !          1092:                return(-1);
        !          1093: #endif
        !          1094:        close( open(ttnmsv,2) );        /* magic to force mode change!!! */
        !          1095:        }
        !          1096: #endif
        !          1097:     return(0);
        !          1098: }
        !          1099: 
        !          1100: /*  T T S S P D  --  Return the internal baud rate code for 'speed'.  */
        !          1101: 
        !          1102: ttsspd(speed) {
        !          1103:     int s, spdok;
        !          1104: 
        !          1105:     if (speed < 0) return(-1);
        !          1106:        spdok = 1;                      /* Assume arg ok */
        !          1107:        switch (speed) {
        !          1108:            case 0:    s = B0;    break;        /* Just the common ones. */
        !          1109:            case 110:  s = B110;  break;        /* The others from ttydev.h */
        !          1110:            case 150:  s = B150;  break;        /* could also be included if */
        !          1111:            case 300:  s = B300;  break;        /* necessary... */
        !          1112:            case 600:  s = B600;  break;
        !          1113:            case 1200: s = B1200; break;
        !          1114:            case 1800: s = B1800; break;
        !          1115:            case 2400: s = B2400; break;
        !          1116:            case 4800: s = B4800; break;
        !          1117:            case 9600: s = B9600; break;
        !          1118: #ifdef PLEXUS
        !          1119:            case 19200: s = EXTA; break;
        !          1120: #endif
        !          1121: #ifdef aegis
        !          1122:            case 19200: s = EXTA; break;
        !          1123: #endif
        !          1124:            default:
        !          1125:                spdok = 0;
        !          1126:                fprintf(stderr,"Unsupported line speed - %d\n",speed);
        !          1127:                fprintf(stderr,"Current speed not changed\n");
        !          1128:                break;
        !          1129:        }    
        !          1130:        if (spdok) return(s); else return(-1);
        !          1131:  }
        !          1132: 
        !          1133: /*  T T F L U I  --  Flush tty input buffer */
        !          1134: 
        !          1135: ttflui() {
        !          1136: 
        !          1137: #ifndef UXIII
        !          1138:     long n;
        !          1139: #endif
        !          1140:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1141: 
        !          1142:     ungotn = -1;                       /* Initialize myread() stuff */
        !          1143:     inbufc = 0;
        !          1144: 
        !          1145: #ifdef aegis
        !          1146:     sio_$control((short)ttyfd, sio_$flush_in, true, st);
        !          1147:     if (st.all != status_$ok)
        !          1148:     {  fprintf(stderr, "flush failed: "); error_$print(st); }
        !          1149:     else {     /* sometimes the flush doesn't work */
        !          1150:        for (;;)
        !          1151:        {   char buf[256];
        !          1152:            /* eat all the characters that shouldn't be available */
        !          1153:            (void)ios_$get((short)ttyfd, ios_$cond_opt, buf, 256L, st);
        !          1154:            if (st.all == ios_$get_conditional_failed) break;
        !          1155:            fprintf(stderr, "flush failed(2): "); error_$print(st);
        !          1156:        }
        !          1157:     }
        !          1158: #else
        !          1159: #ifdef UXIII
        !          1160: #ifndef VXVE
        !          1161:     if (ioctl(ttyfd,TCFLSH,0) < 0) perror("flush failed");
        !          1162: #endif /* vxve */
        !          1163: #else
        !          1164: #ifdef TIOCFLUSH
        !          1165: #ifdef ANYBSD
        !          1166:     n = FREAD;                         /* Specify read queue */
        !          1167:     if (ioctl(ttyfd,TIOCFLUSH,&n) < 0) perror("flush failed");
        !          1168: #else
        !          1169:     if (ioctl(ttyfd,TIOCFLUSH,0) < 0) perror("flush failed");
        !          1170: #endif
        !          1171: #endif
        !          1172: #endif
        !          1173: #endif
        !          1174:     return(0);
        !          1175: }
        !          1176: 
        !          1177: /* Interrupt Functions */
        !          1178: 
        !          1179: 
        !          1180: /* Timeout handler for communication line input functions */
        !          1181: 
        !          1182: timerh() {
        !          1183:     longjmp(sjbuf,1);
        !          1184: }
        !          1185: 
        !          1186:  
        !          1187: /* Set up terminal interrupts on console terminal */
        !          1188: 
        !          1189: #ifdef UXIII
        !          1190: esctrp() {                             /* trap console escapes (^\) */
        !          1191:     conesc = 1;
        !          1192:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !          1193: }
        !          1194: #endif
        !          1195: 
        !          1196: #ifdef V7
        !          1197: esctrp() {                             /* trap console escapes (^\) */
        !          1198:     conesc = 1;
        !          1199:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !          1200: }
        !          1201: #endif
        !          1202: 
        !          1203: #ifdef V9
        !          1204: esctrp() {                             /* trap console escapes (^\) */
        !          1205:     conesc = 1;
        !          1206:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !          1207: }
        !          1208: #endif
        !          1209: 
        !          1210: #ifdef C70
        !          1211: esctrp() {                             /* trap console escapes (^\) */
        !          1212:     conesc = 1;
        !          1213:     signal(SIGQUIT,SIG_IGN);           /* ignore until trapped */
        !          1214: }
        !          1215: #endif
        !          1216: 
        !          1217: /*  C O N I N T  --  Console Interrupt setter  */
        !          1218: 
        !          1219: conint(f) int (*f)(); {                        /* Set an interrupt trap. */
        !          1220:     int x, y;
        !          1221: #ifdef SIGTSTP
        !          1222:     int stptrap();                     /* Suspend trap */
        !          1223: #endif
        !          1224: 
        !          1225: /* Check for background operation, even if not running on real tty, so that */
        !          1226: /* background flag can be set correctly. */
        !          1227: 
        !          1228: #ifdef BSD4
        !          1229:     int mypgrp;                                /* In BSD, we can check whether */
        !          1230:     int ctpgrp;                                /* this process's group is the */
        !          1231:                                        /* same as the controlling */
        !          1232:     mypgrp = getpgrp(0);               /* terminal's process group. */
        !          1233:     ioctl (1, TIOCGPGRP, &ctpgrp);
        !          1234:     x = (mypgrp != ctpgrp);            /* If they differ, then background. */
        !          1235:     debug(F101,"conint process group test","",x);
        !          1236: #else
        !          1237:     x = (signal(SIGINT,SIG_IGN) == SIG_IGN);
        !          1238:     debug(F101,"conint signal test","",x);
        !          1239: #endif
        !          1240:     y = isatty(0);
        !          1241:     debug(F101,"conint isatty test","",y);
        !          1242: #ifdef BSD29
        !          1243: /* For some reason the signal() test doesn't work under 2.9 BSD... */
        !          1244:     backgrd = !y;
        !          1245: #else
        !          1246:     backgrd = (x || !y);
        !          1247: #endif
        !          1248:     debug(F101,"conint backgrd","",backgrd);
        !          1249: 
        !          1250:     signal(SIGHUP,f);                  /* Ensure lockfile cleared on hangup */
        !          1251:     signal(SIGTERM,f);                 /* or soft kill. */
        !          1252: 
        !          1253: /* check if invoked in background -- if so signals set to be ignored */
        !          1254: 
        !          1255:     if (backgrd) {                     /* In background, ignore signals */
        !          1256: #ifdef SIGTSTP
        !          1257:        signal(SIGTSTP,SIG_IGN);        /* Keyboard stop */
        !          1258: #endif
        !          1259:        signal(SIGQUIT,SIG_IGN);        /* Keyboard quit */
        !          1260:        signal(SIGINT,SIG_IGN);         /* Keyboard interrupt */
        !          1261:     } else {
        !          1262:        signal(SIGINT,f);               /* Catch terminal interrupt */
        !          1263: #ifdef SIGTSTP
        !          1264:        signal(SIGTSTP,stptrap);        /* Keyboard stop */
        !          1265: #endif
        !          1266: #ifdef UXIII
        !          1267:         signal(SIGQUIT,esctrp);                /* Quit signal, Sys III/V. */
        !          1268:        if (conesc) conesc = 0;         /* Clear out pending escapes */
        !          1269: #else
        !          1270: #ifdef V7
        !          1271:         signal(SIGQUIT,esctrp);                /* V7 like Sys III/V */
        !          1272:        if (conesc) conesc = 0;
        !          1273: #else
        !          1274: #ifdef V9
        !          1275:         signal(SIGQUIT,esctrp);                /* V7 like Sys III/V */
        !          1276:        if (conesc) conesc = 0;
        !          1277: #else
        !          1278: #ifdef aegis
        !          1279:         signal(SIGQUIT,f);             /* Apollo, catch it like others. */
        !          1280: #else
        !          1281:         signal(SIGQUIT,SIG_IGN);       /* Others, ignore like 4D & earlier. */
        !          1282: #endif
        !          1283: #endif
        !          1284: #endif
        !          1285: #endif
        !          1286:        conif = 1;                      /* Flag console interrupts on. */
        !          1287:     }
        !          1288:     return;
        !          1289: }
        !          1290: 
        !          1291: 
        !          1292: /*  C O N N O I  --  Reset console terminal interrupts */
        !          1293: 
        !          1294: connoi() {                             /* Console-no-interrupts */
        !          1295: 
        !          1296: #ifdef SIGTSTP
        !          1297:     signal(SIGTSTP,SIG_DFL);
        !          1298: #endif
        !          1299:     signal(SIGINT,SIG_DFL);
        !          1300:     signal(SIGHUP,SIG_DFL);
        !          1301:     signal(SIGQUIT,SIG_DFL);
        !          1302:     signal(SIGTERM,SIG_DFL);
        !          1303:     conif = 0;                         /* Flag interrupt trapping off */
        !          1304: }
        !          1305: 
        !          1306: /*  myread() -- For use by systems that can do nonblocking read() calls  */
        !          1307: /*
        !          1308:  Returns:
        !          1309:   -1  if no characters available, timer expired
        !          1310:   -2  upon error (such as disconnect),
        !          1311:   otherwise value of character (0 or greater)
        !          1312: */
        !          1313: myread() {
        !          1314:     static int inbuf_item;
        !          1315:     static CHAR inbuf[257];
        !          1316:     CHAR readit;
        !          1317: 
        !          1318:     if (ungotn >= 0) {
        !          1319:        readit = ungotn;
        !          1320:        ungotn = -1;
        !          1321:     } else {
        !          1322:         if (inbufc > 0) {
        !          1323:            readit = inbuf[++inbuf_item];
        !          1324:         } else {
        !          1325: #ifdef aegis
        !          1326:     /* myread() returns -1 when no input is available.  All the users of */
        !          1327:     /* myread() explicitly loop until it returns a character or error. */
        !          1328:     /* The Apollo code waits for input to be available. */
        !          1329: 
        !          1330:     /* read in characters */
        !          1331:            inbufc = ios_$get((short)ttyfd, ios_$cond_opt, inbuf, 256L, st);
        !          1332:            errno = EIO;
        !          1333:            if (st.all == ios_$get_conditional_failed) /* get at least one */
        !          1334:                inbufc = ios_$get((short)ttyfd, 0, inbuf, 1L, st);
        !          1335:            if (st.all == ios_$end_of_file) inbufc = 0;
        !          1336:            else if (st.all != status_$ok)
        !          1337:            {   inbufc = -1; errno = EIO; }
        !          1338: #else
        !          1339:             inbufc = read(ttyfd,inbuf,256);
        !          1340:            if (inbufc > 0) {
        !          1341:                inbuf[inbufc] = '\0';
        !          1342:                debug(F101,"myread read","",inbufc);
        !          1343:            }
        !          1344: #endif /* aegis */
        !          1345:            if (inbufc == 0) {
        !          1346:                if (ttmdm) {
        !          1347:                    debug(F101,"myread read=0, ttmdm","",ttmdm);
        !          1348:                    errno = 9999;       /* magic number for no carrier */
        !          1349:                    return(-2);         /* end of file has no errno */
        !          1350:                } else return(-1);      /* in sys 5 means no data available */
        !          1351:            }
        !          1352:            if (inbufc < 0) {           /* Real error */
        !          1353: #ifdef EWOULDBLOCK
        !          1354:                if (errno == EWOULDBLOCK) return(-1); else return(-2);
        !          1355: #else
        !          1356:                return(-2);
        !          1357: #endif /* ewouldblock */
        !          1358:            }
        !          1359:            readit = inbuf[inbuf_item = 0];
        !          1360:        }
        !          1361:         inbufc--;      
        !          1362:     }
        !          1363:     return(((int) readit) & 255);
        !          1364: }
        !          1365: 
        !          1366: myunrd(ch) CHAR ch; {                  /* push back up to one character */
        !          1367:     ungotn = ch;
        !          1368: }
        !          1369: 
        !          1370: /*  I N I T R A W Q  --  Set up to read /DEV/KMEM for character count.  */
        !          1371: 
        !          1372: #ifdef V7
        !          1373: /*
        !          1374:  Used in Version 7 to simulate Berkeley's FIONREAD ioctl call.  This
        !          1375:  eliminates blocking on a read, because we can read /dev/kmem to get the
        !          1376:  number of characters available for raw input.  If your system can't
        !          1377:  or you won't let it read /dev/kmem (the world that is) then you must
        !          1378:  figure out a different way to do the counting of characters available,
        !          1379:  or else replace this by a dummy function that always returns 0.
        !          1380: */
        !          1381: /*
        !          1382:  * Call this routine as: initrawq(tty)
        !          1383:  * where tty is the file descriptor of a terminal.  It will return
        !          1384:  * (as a char *) the kernel-mode memory address of the rawq character
        !          1385:  * count, which may then be read.  It has the side-effect of flushing
        !          1386:  * input on the terminal.
        !          1387:  */
        !          1388: /*
        !          1389:  * John Mackin, Physiology Dept., University of Sydney (Australia)
        !          1390:  * ...!decvax!mulga!physiol.su.oz!john
        !          1391:  *
        !          1392:  * Permission is hereby granted to do anything with this code, as
        !          1393:  * long as this comment is retained unmodified and no commercial
        !          1394:  * advantage is gained.
        !          1395:  */
        !          1396: #include <a.out.h>
        !          1397: #include <sys/proc.h>
        !          1398: 
        !          1399: char *initrawq(tty) int tty; {
        !          1400: #ifdef UTS24
        !          1401:     return(0);
        !          1402: #else
        !          1403: #ifdef BSD29
        !          1404:     return(0);
        !          1405: #else
        !          1406:     long lseek();
        !          1407:     static struct nlist nl[] = {
        !          1408:        {PROCNAME},
        !          1409:        {NPROCNAME},
        !          1410:        {""}
        !          1411:     };
        !          1412:     static struct proc *pp;
        !          1413:     char *malloc(), *qaddr, *p, c;
        !          1414:     int m, pid, me;
        !          1415:     NPTYPE xproc;                      /* Its type is defined in makefile. */
        !          1416:     int catch();
        !          1417: 
        !          1418:     me = getpid();
        !          1419:     if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
        !          1420:     nlist(BOOTNAME, nl);
        !          1421:     if (nl[0].n_type == 0) err("proc array");
        !          1422:  
        !          1423:     if (nl[1].n_type == 0) err("nproc");
        !          1424: 
        !          1425:     lseek(m, (long)(nl[1].n_value), 0);
        !          1426:     read (m, &xproc, sizeof(xproc));
        !          1427:     signal(SIGALRM, catch);
        !          1428:     if ((pid = fork()) == 0) {
        !          1429:        while(1)
        !          1430:            read(tty, &c, 1);
        !          1431:     }
        !          1432:     alarm(2);
        !          1433:  
        !          1434:     if(setjmp(jjbuf) == 0) {
        !          1435:        while(1)
        !          1436:            read(tty, &c, 1);
        !          1437:     }
        !          1438:     signal(SIGALRM, SIG_DFL);
        !          1439: 
        !          1440: #ifdef DIRECT
        !          1441:     pp = (struct proc *) nl[0].n_value;
        !          1442: #else
        !          1443:     if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
        !          1444:     if (read(m, &pp, sizeof(pp)) != sizeof(pp))  err("no read of proc ptr");
        !          1445: #endif
        !          1446:     lseek(m, (long)(nl[1].n_value), 0);
        !          1447:     read(m, &xproc, sizeof(xproc));
        !          1448: 
        !          1449:     if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
        !          1450:     if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
        !          1451:     if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
        !          1452:        err("read proc table");
        !          1453:     for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
        !          1454:        if (pp -> p_pid == (short) pid) goto iout;
        !          1455:     }
        !          1456:     err("no such proc");
        !          1457:  
        !          1458: iout:
        !          1459:     close(m);
        !          1460:     qaddr = (char *)(pp -> p_wchan);
        !          1461:     free (p);
        !          1462:     kill(pid, SIGKILL);
        !          1463:     wait((int *)0);            /* Destroy the ZOMBIEs! */
        !          1464:     return (qaddr);
        !          1465: #endif
        !          1466: #endif
        !          1467: }
        !          1468: 
        !          1469: /*  More V7-support functions...  */
        !          1470: 
        !          1471: static
        !          1472: err(s) char *s; {
        !          1473:     char buf[200];
        !          1474: 
        !          1475:     sprintf(buf, "fatal error in initrawq: %s", s);
        !          1476:     perror(buf);
        !          1477:     doexit(1);
        !          1478: }
        !          1479: 
        !          1480: static
        !          1481: catch() {
        !          1482:     longjmp(jjbuf, -1);
        !          1483: }
        !          1484: 
        !          1485: 
        !          1486: /*  G E N B R K  --  Simulate a modem break.  */
        !          1487: 
        !          1488: #define        BSPEED  B150
        !          1489: 
        !          1490: genbrk(fn) int fn; {
        !          1491:     struct sgttyb ttbuf;
        !          1492:     int ret, sospeed;
        !          1493: 
        !          1494:     ret = ioctl(fn, TIOCGETP, &ttbuf);
        !          1495:     sospeed = ttbuf.sg_ospeed;
        !          1496:     ttbuf.sg_ospeed = BSPEED;
        !          1497:     ret = ioctl(fn, TIOCSETP, &ttbuf);
        !          1498:     ret = write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", 8);
        !          1499:     ttbuf.sg_ospeed = sospeed;
        !          1500:     ret = ioctl(fn, TIOCSETP, &ttbuf);
        !          1501:     ret = write(fn, "@", 1);
        !          1502:     return;
        !          1503: }
        !          1504: #endif
        !          1505: 
        !          1506: /*  T T C H K  --  Tell how many characters are waiting in tty input buffer  */
        !          1507: 
        !          1508: ttchk() {
        !          1509:     int x; long n;
        !          1510: #ifdef FIONREAD
        !          1511:     x = ioctl(ttyfd, FIONREAD, &n);    /* Berkeley and maybe some others */
        !          1512:     debug(F101,"ttchk","",n);
        !          1513:     return((x < 0) ? 0 : n);
        !          1514: #else
        !          1515: #ifdef V7
        !          1516:     lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */
        !          1517:     x = read(kmem[TTY], &n, sizeof(int));
        !          1518:     return((x == sizeof(int))? n: 0);
        !          1519: #else
        !          1520: #ifdef UXIII
        !          1521:     return(inbufc + (ungotn >= 0) );   /* Sys III, Sys V */
        !          1522: #else
        !          1523: #ifdef PROVX1
        !          1524:     x = ioctl(ttyfd, TIOCQCNT, &ttbuf);        /* Pro/3xx Venix V.1 */
        !          1525:     n = ttbuf.sg_ispeed & 0377;
        !          1526:     return((x < 0) ? 0 : n);
        !          1527: #else
        !          1528: #ifdef aegis
        !          1529:     return(inbufc + (ungotn >= 0) );   /* Apollo Aegis */
        !          1530: #else
        !          1531: #ifdef C70
        !          1532:     return(inbufc + (ungotn >= 0) );   /* etc... */
        !          1533: #else
        !          1534:     return(0);
        !          1535: #endif
        !          1536: #endif
        !          1537: #endif
        !          1538: #endif
        !          1539: #endif
        !          1540: #endif
        !          1541: }
        !          1542: 
        !          1543: 
        !          1544: /*  T T X I N  --  Get n characters from tty input buffer  */
        !          1545: 
        !          1546: /*  Returns number of characters actually gotten, or -1 on failure  */
        !          1547: 
        !          1548: /*  Intended for use only when it is known that n characters are actually */
        !          1549: /*  Available in the input buffer.  */
        !          1550: 
        !          1551: ttxin(n,buf) int n; char *buf; {
        !          1552:     int x;
        !          1553: 
        !          1554: #ifdef MYREAD
        !          1555:     for( x = 0; (x > -1) && (x < n); buf[x++] = myread() );
        !          1556: #else
        !          1557:     debug(F101,"ttxin: n","",n);
        !          1558:     x = read(ttyfd,buf,n);
        !          1559:     debug(F101," x","",x);
        !          1560: #endif
        !          1561:     if (x > 0) buf[x] = '\0';
        !          1562:     if (x < 0) x = -1;
        !          1563:     return(x);
        !          1564: }
        !          1565: 
        !          1566: /*  T T O L  --  Similar to "ttinl", but for writing.  */
        !          1567: 
        !          1568: ttol(s,n) int n; char *s; {
        !          1569:     int x;
        !          1570:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1571:     x = write(ttyfd,s,n);
        !          1572:     debug(F111,"ttol",s,n);
        !          1573:     if (x < 0) debug(F101,"ttol failed","",x);
        !          1574:     return(x);
        !          1575: }
        !          1576: 
        !          1577: 
        !          1578: /*  T T O C  --  Output a character to the communication line  */
        !          1579: 
        !          1580: ttoc(c) char c; {
        !          1581:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1582:     return(write(ttyfd,&c,1));
        !          1583: }
        !          1584: 
        !          1585: /*  T T I N L  --  Read a record (up to break character) from comm line.  */
        !          1586: /*
        !          1587:   If no break character encountered within "max", return "max" characters,
        !          1588:   with disposition of any remaining characters undefined.  Otherwise, return
        !          1589:   the characters that were read, including the break character, in "dest" and
        !          1590:   the number of characters read as the value of the function, or 0 upon end of
        !          1591:   file, or -1 if an error occurred.  Times out & returns error if not completed
        !          1592:   within "timo" seconds.
        !          1593: */
        !          1594: #define CTRLC '\03'
        !          1595: ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol; {
        !          1596:     int x = 0, ccn = 0, c, i, j, m, n; /* local variables */
        !          1597: 
        !          1598:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1599: 
        !          1600:     m = (ttprty) ? 0177 : 0377;                /* Parity stripping mask. */
        !          1601:     *dest = '\0';                      /* Clear destination buffer */
        !          1602:     if (timo) signal(SIGALRM,timerh);  /* Enable timer interrupt */
        !          1603:     alarm(timo);                       /* Set it. */
        !          1604:     if (setjmp(sjbuf)) {               /* Timer went off? */
        !          1605:         x = -1;
        !          1606:     } else {
        !          1607:        i = 0;                          /* Next char to process */
        !          1608:        j = 0;                          /* Buffer position */
        !          1609:         while (1) {
        !          1610:             if ((n = ttchk()) > 0) {   /* See how many chars have arrived */
        !          1611:                 if (n > (max - j)) n = max - j;
        !          1612:                 if ((n = ttxin(n,dest+i)) < 0) { /* Get them all at once */
        !          1613:                    x = -1;
        !          1614:                    break;
        !          1615:                }
        !          1616:            } else {                    /* Or else... */
        !          1617:                n = 1;                  /* just wait for a char */
        !          1618:                if ((c = ttinc(0)) == -1) {
        !          1619:                    x = -1;
        !          1620:                    break;
        !          1621:                }
        !          1622:                 dest[i] = c;           /* Got one. */
        !          1623:            }
        !          1624:            j = i + n;                  /* Remember next buffer position. */
        !          1625:            if (j >= max) {
        !          1626:                debug(F101,"ttinl buffer overflow","",j);
        !          1627:                x = -1;
        !          1628:                break;
        !          1629:            }
        !          1630:            for (i; i < j; i++) {       /* Go thru all chars we just got */
        !          1631:                dest[i] &= m;           /* Strip any parity */
        !          1632:                if (dest[i] == eol) {   /* Got eol? */
        !          1633:                  dest[++i] = '\0';     /* Yes, tie off string, */
        !          1634:                  alarm(0);             /* turn off timers, etc, */
        !          1635:                  if (timo) signal(SIGALRM,SIG_DFL); /* and return length. */
        !          1636:                  return(i);
        !          1637:              } else if ((dest[i] & 0177) == CTRLC) { /* Check for ^C^C */
        !          1638:                  if (++ccn > 1) {      /* If we got 2 in a row, clean up */
        !          1639:                     alarm(0);          /* and exit. */
        !          1640:                     signal(SIGALRM,SIG_DFL);
        !          1641:                     fprintf(stderr,"^C...");
        !          1642:                     ttres();
        !          1643:                     fprintf(stderr,"\n");
        !          1644:                     return(-2);
        !          1645:                  }
        !          1646:              } else ccn = 0;   /* Not ^C, so reset ^C counter, */
        !          1647:          }
        !          1648:        }
        !          1649:     }
        !          1650:     debug(F100,"ttinl timout","",0);   /* Get here on timeout. */
        !          1651:     debug(F111," with",dest,i);
        !          1652:     alarm(0);                          /* Turn off timer */
        !          1653:     signal(SIGALRM,SIG_DFL);           /* and interrupt, */
        !          1654:     return(x);                         /* and return error code. */
        !          1655: }
        !          1656: 
        !          1657: /*  T T I N C --  Read a character from the communication line  */
        !          1658: 
        !          1659: ttinc(timo) int timo; {
        !          1660:     int m, n = 0;
        !          1661:     CHAR ch = 0;
        !          1662: 
        !          1663:     m = (ttprty) ? 0177 : 0377;                /* Parity stripping mask. */
        !          1664:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1665:     if (timo <= 0) {                   /* Untimed. */
        !          1666: #ifdef MYREAD
        !          1667:        /* comm line failure returns -1 thru myread, so no &= 0377 */
        !          1668:        while ((n = myread()) == -1) ;  /* Wait for a character... */
        !          1669:        if (n == -2) n++;
        !          1670:        return( (n < 0) ? -1 : n & m );
        !          1671: #else
        !          1672:        while ((n = read(ttyfd,&ch,1)) == 0) ; /* Wait for a character. */
        !          1673:        return( (n < 0) ? -1 : (ch & 0377) );
        !          1674: #endif
        !          1675:     }
        !          1676:     signal(SIGALRM,timerh);            /* Timed, set up timer. */
        !          1677:     alarm(timo);
        !          1678:     if (setjmp(sjbuf)) {
        !          1679:        n = -1;
        !          1680:     } else {
        !          1681: #ifdef MYREAD
        !          1682:        while ((n = myread()) == -1) ;  /* If managing own buffer... */
        !          1683:        if (n == -2) {
        !          1684:            n++;
        !          1685:        } else {
        !          1686:            ch = n;
        !          1687:            n = 1;      
        !          1688:        }
        !          1689: #else
        !          1690:        n = read(ttyfd,&ch,1);          /* Otherwise call the system. */
        !          1691: #endif
        !          1692:     }
        !          1693:     alarm(0);                          /* Turn off timer, */
        !          1694:     signal(SIGALRM,SIG_DFL);           /* and interrupt. */
        !          1695:     return( (n < 0) ? -1 : (ch & m) );  /* Return char or -1. */
        !          1696: }
        !          1697: 
        !          1698: /*  T T S N D B  --  Send a BREAK signal  */
        !          1699: 
        !          1700: ttsndb() {
        !          1701:     int x; long n; char spd;
        !          1702: 
        !          1703:     if (ttyfd < 0) return(-1);         /* Not open. */
        !          1704: 
        !          1705: #ifdef PROVX1
        !          1706:     gtty(ttyfd,&ttbuf);                        /* Get current tty flags */
        !          1707:     spd = ttbuf.sg_ospeed;             /* Save speed */
        !          1708:     ttbuf.sg_ospeed = B50;             /* Change to 50 baud */
        !          1709:     stty(ttyfd,&ttbuf);                        /*  ... */
        !          1710:     write(ttyfd,brnuls,3);             /* Send 3 nulls */
        !          1711:     ttbuf.sg_ospeed = spd;             /* Restore speed */
        !          1712:     stty(ttyfd,&ttbuf);                        /*  ... */
        !          1713:     return(0);
        !          1714: #else
        !          1715: #ifdef aegis
        !          1716:     sio_$control((short)ttyfd, sio_$send_break, 250, st);
        !          1717:     return(0);
        !          1718: #else
        !          1719: #ifdef UXIII
        !          1720:     if (ioctl(ttyfd,TCSBRK,(char *)0) < 0) {   /* Send a BREAK */
        !          1721:        perror("Can't send BREAK");
        !          1722:        return(-1);
        !          1723:     }
        !          1724:     return(0);
        !          1725: #else
        !          1726: #ifdef ANYBSD
        !          1727:     n = FWRITE;                                /* Flush output queue. */
        !          1728:     ioctl(ttyfd,TIOCFLUSH,&n);                 /* Ignore any errors.. */
        !          1729:     if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) { /* Turn on BREAK */
        !          1730:        perror("Can't send BREAK");
        !          1731:        return(-1);
        !          1732:     }
        !          1733:     x = msleep(275);                   /* Sleep for so many milliseconds */
        !          1734:     if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) { /* Turn off BREAK */
        !          1735:        perror("BREAK stuck!!!");
        !          1736:        doexit(1);                      /* Get out, closing the line. */
        !          1737:                                        /*   with exit status = 1 */
        !          1738:     }
        !          1739:     return(x);
        !          1740: #else
        !          1741: #ifdef V7
        !          1742:     genbrk(ttyfd);                     /* Simulate a BREAK */
        !          1743:     return(x);
        !          1744: #endif
        !          1745: #endif
        !          1746: #endif
        !          1747: #endif
        !          1748: #endif
        !          1749: }
        !          1750: 
        !          1751: /*  M S L E E P  --  Millisecond version of sleep().  */
        !          1752: 
        !          1753: /*
        !          1754:  Intended only for small intervals.  For big ones, just use sleep().
        !          1755: */
        !          1756: 
        !          1757: msleep(m) int m; {
        !          1758: 
        !          1759: #ifdef aegis
        !          1760:     time_$clock_t dur;
        !          1761: 
        !          1762:     dur.c2.high16 = 0;
        !          1763:     dur.c2.low32  = 250 * m; /* one millisecond = 250 four microsecond ticks */
        !          1764:     time_$wait(time_$relative, dur, st);
        !          1765:     return(0);
        !          1766: #else 
        !          1767: #ifdef PROVX1
        !          1768:     if (m <= 0) return(0);
        !          1769:     sleep(-((m * 60 + 500) / 1000));
        !          1770:     return(0);
        !          1771: #endif
        !          1772: 
        !          1773: #ifdef ANYBSD
        !          1774:     int t1, t3, t4;
        !          1775:     if (m <= 0) return(0);
        !          1776: #ifndef BSD42
        !          1777: /* 2.9 and 4.1 BSD do it this way */
        !          1778:     if (ftime(&ftp) < 0) return(-1);   /* Get current time. */
        !          1779:     t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
        !          1780:     while (1) {
        !          1781:        ftime(&ftp);                    /* new time */
        !          1782:        t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
        !          1783:        if (t3 > m) return(t3);
        !          1784:     }
        !          1785: #else
        !          1786: /* 4.2 & above can do it with select()... */
        !          1787:     if (gettimeofday(&tv, &tz) < 0) return(-1); /* Get current time. */
        !          1788:     t1 = tv.tv_sec;                    /* Seconds */
        !          1789: 
        !          1790:     tv.tv_sec = 0;                     /* Use select() */
        !          1791:     tv.tv_usec = m * 1000;
        !          1792:     return(select( 0, (int *)0, (int *)0, (int *)0, &tv) );
        !          1793: #endif
        !          1794: #endif
        !          1795: 
        !          1796: /* The clock-tick business is a pain.  Wm. E. Davidsen suggested: */
        !          1797: /*   #include <sys/param.h>      */
        !          1798: /*   #define CLOCK_TICK 1000/HZ  */
        !          1799: /* But I don't see the symbol HZ in this file on my VAX. */
        !          1800: /* Maybe just for XENIX. */
        !          1801: 
        !          1802: #ifdef UXIII
        !          1803: #ifdef XENIX
        !          1804: /* Actually, watch out.  It's 50 on the AT, 20 on older PCs... */
        !          1805: #define CLOCK_TICK 50                  /* millisecs per clock tick */
        !          1806: #else
        !          1807: #ifndef XENIX
        !          1808: #define CLOCK_TICK 17                  /* 1/60 sec */
        !          1809: #endif
        !          1810: #endif
        !          1811: 
        !          1812:     extern long times();
        !          1813:     long t1, t2, tarray[4];
        !          1814:     int t3;
        !          1815: 
        !          1816: /* In SCO Xenix 2.1.3 or later, you can use nap((long)m) to do this. */
        !          1817: 
        !          1818:     if (m <= 0) return(0);
        !          1819:     if ((t1 = times(tarray)) < 0) return(-1);
        !          1820:     while (1) {
        !          1821:        if ((t2 = times(tarray)) < 0) return(-1);
        !          1822:        t3 = ((int)(t2 - t1)) * CLOCK_TICK;
        !          1823:        if (t3 > m) return(t3);
        !          1824:     }
        !          1825: #endif
        !          1826: 
        !          1827: #ifdef TOWER1
        !          1828:     int t1, t3;
        !          1829:     if (m <= 0) return(0);
        !          1830:     if (ftime(&ftp) < 0) return(-1);           /* Get current time. */
        !          1831:     t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
        !          1832:     while (1) {
        !          1833:        ftime(&ftp);                            /* new time */
        !          1834:        t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
        !          1835:        if (t3 > m) return (t3);
        !          1836:     }
        !          1837: #endif
        !          1838: #endif
        !          1839: }
        !          1840: 
        !          1841: /*  R T I M E R --  Reset elapsed time counter  */
        !          1842: 
        !          1843: rtimer() {
        !          1844:     tcount = time( (long *) 0 );
        !          1845: }
        !          1846: 
        !          1847: 
        !          1848: /*  G T I M E R --  Get current value of elapsed time counter in seconds  */
        !          1849: 
        !          1850: gtimer() {
        !          1851:     int x;
        !          1852:     x = (int) (time( (long *) 0 ) - tcount);
        !          1853:     rtimer();
        !          1854:     return( (x < 0) ? 0 : x );
        !          1855: }
        !          1856: 
        !          1857: 
        !          1858: /*  Z T I M E  --  Return date/time string  */
        !          1859: 
        !          1860: ztime(s) char **s; {
        !          1861: 
        !          1862: #ifdef UXIII
        !          1863:     extern long time();                        /* Sys III/V way to do it */
        !          1864:     char *ctime();
        !          1865:     long clock_storage;
        !          1866: 
        !          1867:     clock_storage = time( (long *) 0 );
        !          1868:     *s = ctime( &clock_storage );
        !          1869: #endif
        !          1870: 
        !          1871: #ifdef PROVX1
        !          1872:     int utime[2];                      /* Venix way */
        !          1873:     time(utime);
        !          1874:     *s = ctime(utime);
        !          1875: #endif
        !          1876: 
        !          1877: #ifdef ANYBSD
        !          1878:     char *asctime();                   /* Berkeley way */
        !          1879:     struct tm *localtime();
        !          1880:     struct tm *tp;
        !          1881: #ifdef BSD42
        !          1882:     gettimeofday(&tv, &tz);            /* BSD 4.2 */
        !          1883:     time(&tv.tv_sec);
        !          1884:     tp = localtime(&tv.tv_sec);
        !          1885: #else
        !          1886:     time(&clock);                      /* BSD 4.1, 2.9 ... ceb */
        !          1887:     tp = localtime(&clock);
        !          1888: #endif
        !          1889:     *s = asctime(tp);
        !          1890: #endif
        !          1891: 
        !          1892: #ifdef TOWER1
        !          1893:     char *asctime();                   /* Tower way */
        !          1894:     struct tm *localtime();
        !          1895:     struct tm *tp;
        !          1896: 
        !          1897:     time(&clock);
        !          1898:     tp = localtime(&clock);
        !          1899:     *s = asctime(tp);
        !          1900: #endif
        !          1901: #ifdef V7
        !          1902:     char *asctime();                   /* V7 way */
        !          1903:     struct tm *localtime();
        !          1904:     struct tm *tp;
        !          1905: 
        !          1906:     time(&clock);
        !          1907:     tp = localtime(&clock);
        !          1908:     *s = asctime(tp);
        !          1909: #endif
        !          1910: }
        !          1911: 
        !          1912: /*  C O N G M  --  Get console terminal modes.  */
        !          1913: 
        !          1914: /*
        !          1915:  Saves current console mode, and establishes variables for switching between 
        !          1916:  current (presumably normal) mode and other modes.
        !          1917: */
        !          1918: 
        !          1919: congm() {
        !          1920:     if (!isatty(0)) return(0);         /* only for real ttys */
        !          1921: #ifdef aegis
        !          1922:     ios_$inq_type_uid(ios_$stdin, conuid, st);
        !          1923:     if (st.all != status_$ok)
        !          1924:     {  fprintf(stderr, "problem getting stdin objtype: "); error_$print(st); }
        !          1925:     concrp = (conuid == mbx_$uid);
        !          1926:     conbufn = 0;
        !          1927: #endif
        !          1928: #ifndef UXIII
        !          1929: #ifdef V9
        !          1930:      if (ioctl(0,TIOCGETP,&ccold) < 0) {
        !          1931:                perror("ckutio:congm:ioctl(...ccold)");
        !          1932:                return(-1);
        !          1933:      }
        !          1934:      if (ioctl(0,TIOCGETP,&cccbrk) < 0) {
        !          1935:                perror("ckutio:congm:ioctl(...cccbrk)");
        !          1936:                return(-1);
        !          1937:      }
        !          1938:      if (ioctl(0,TIOCGETP,&ccraw) < 0) {
        !          1939:                perror("ckutio:congm:ioctl(...ccraw)");
        !          1940:                return(-1);
        !          1941:      }
        !          1942: #else
        !          1943:      gtty(0,&ccold);                   /* Structure for restoring */
        !          1944:      gtty(0,&cccbrk);                  /* For setting CBREAK mode */
        !          1945:      gtty(0,&ccraw);                   /* For setting RAW mode */
        !          1946: #endif
        !          1947: #else
        !          1948:      ioctl(0,TCGETA,&ccold);
        !          1949:      ioctl(0,TCGETA,&cccbrk);
        !          1950:      ioctl(0,TCGETA,&ccraw);
        !          1951: #endif
        !          1952: #ifdef VXVE
        !          1953:      cccbrk.c_line = 0;                        /* STTY line 0 for CDC VX/VE */
        !          1954:      ioctl(0,TCSETA,&cccbrk);
        !          1955:      ccraw.c_line = 0;                 /* STTY line 0 for CDC VX/VE */
        !          1956:      ioctl(0,TCSETA,&ccraw);
        !          1957: #endif /* vxve */
        !          1958:      cgmf = 1;                         /* Flag that we got them. */
        !          1959:      return(0);
        !          1960: }
        !          1961: 
        !          1962: 
        !          1963: /*  C O N C B --  Put console in cbreak mode.  */
        !          1964: 
        !          1965: /*  Returns 0 if ok, -1 if not  */
        !          1966: 
        !          1967: concb(esc) char esc; {
        !          1968:     int x;
        !          1969:     if (!isatty(0)) return(0);         /* only for real ttys */
        !          1970:     if (cgmf == 0) congm();            /* Get modes if necessary. */
        !          1971:     escchr = esc;                      /* Make this available to other fns */
        !          1972:     ckxech = 1;                                /* Program can echo characters */
        !          1973: #ifdef aegis
        !          1974:     conbufn = 0;
        !          1975:     if (concrp) return(write(1, "\035\002", 2));
        !          1976:     if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
        !          1977: #endif
        !          1978: #ifndef UXIII
        !          1979:     cccbrk.sg_flags |= CBREAK;         /* Set to character wakeup, */
        !          1980:     cccbrk.sg_flags &= ~ECHO;          /* no echo. */
        !          1981: #ifdef V9
        !          1982:     x = ioctl(0,TIOCSETP,&cccbrk);     /* set new modes . */
        !          1983: #else
        !          1984:     x = stty(0,&cccbrk);
        !          1985: #endif
        !          1986: #else
        !          1987:     cccbrk.c_lflag &= ~(ICANON|ECHO);
        !          1988:     cccbrk.c_cc[0] = 003;              /* interrupt char is control-c */
        !          1989:     cccbrk.c_cc[1] = escchr;           /* escape during packet modes */
        !          1990:     cccbrk.c_cc[4] = 1;
        !          1991: #ifdef ZILOG
        !          1992:     cccbrk.c_cc[5] = 0;
        !          1993: #else
        !          1994:     cccbrk.c_cc[5] = 1;
        !          1995: #endif /* zilog */
        !          1996:     x = ioctl(0,TCSETAW,&cccbrk);      /* set new modes . */
        !          1997: #endif
        !          1998: 
        !          1999: #ifndef aegis
        !          2000:     if (x > -1) setbuf(stdout,NULL);   /* Make console unbuffered. */
        !          2001: #endif
        !          2002: #ifdef V7
        !          2003:     if (kmem[CON] < 0) {
        !          2004:        qaddr[CON] = initrawq(0);
        !          2005:        if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
        !          2006:            fprintf(stderr, "Can't read /dev/kmem in concb.\n");
        !          2007:            perror("/dev/kmem");
        !          2008:            exit(1);
        !          2009:        }
        !          2010:     }
        !          2011: #endif
        !          2012:     return(x);
        !          2013: }
        !          2014: 
        !          2015: /*  C O N B I N  --  Put console in binary mode  */
        !          2016: 
        !          2017: /*  Returns 0 if ok, -1 if not  */
        !          2018: 
        !          2019: conbin(esc) char esc; {
        !          2020:     if (!isatty(0)) return(0);         /* only for real ttys */
        !          2021:     if (cgmf == 0) congm();            /* Get modes if necessary. */
        !          2022:     escchr = esc;                      /* Make this available to other fns */
        !          2023:     ckxech = 1;                                /* Program can echo characters */
        !          2024: #ifdef aegis
        !          2025:     conbufn = 0; if (concrp) return(write(1, "\035\002", 2));
        !          2026:     if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
        !          2027: #endif
        !          2028: #ifndef UXIII
        !          2029:     ccraw.sg_flags |= (RAW|TANDEM);    /* Set rawmode, XON/XOFF */
        !          2030:     ccraw.sg_flags &= ~(ECHO|CRMOD);   /* Set char wakeup, no echo */
        !          2031: #ifdef V9
        !          2032:     return(ioctl(0,TIOCSETP,&ccraw));
        !          2033: #else
        !          2034:     return(stty(0,&ccraw));
        !          2035: #endif
        !          2036: #else
        !          2037:     ccraw.c_lflag &= ~(ISIG|ICANON|ECHO);
        !          2038:     ccraw.c_iflag |= (BRKINT|IGNPAR);
        !          2039:     ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
        !          2040:                        |INPCK|ISTRIP);
        !          2041:     ccraw.c_oflag &= ~OPOST;
        !          2042: 
        !          2043: /*** Kermit used to put the console in 8-bit raw mode, but some users have
        !          2044:  *** pointed out that this should not be done, since some sites actually
        !          2045:  *** use terminals with parity settings on their Unix systems, and if we
        !          2046:  *** override the current settings and stop doing parity, then their terminals
        !          2047:  *** will display blotches for characters whose parity is wrong.  Therefore,
        !          2048:  *** the following two lines are commented out (Larry Afrin, Clemson U):
        !          2049:  ***
        !          2050:  ***   ccraw.c_cflag &= ~(PARENB|CSIZE);
        !          2051:  ***   ccraw.c_cflag |= (CS8|CREAD);
        !          2052:  ***
        !          2053:  *** Sys III/V sites that have trouble with this can restore these lines.
        !          2054:  ***/
        !          2055:     ccraw.c_cc[4] = 1;
        !          2056:     ccraw.c_cc[5] = 1;
        !          2057:     return(ioctl(0,TCSETAW,&ccraw) );          /* set new modes . */
        !          2058: #endif
        !          2059: }
        !          2060: 
        !          2061: 
        !          2062: /*  C O N R E S  --  Restore the console terminal  */
        !          2063: 
        !          2064: conres() {
        !          2065:     if (cgmf == 0) return(0);          /* Don't do anything if modes */
        !          2066:     if (!isatty(0)) return(0);         /* only for real ttys */
        !          2067: #ifndef UXIII                          /* except for sIII, */
        !          2068:     sleep(1);                          /*  not known! */
        !          2069: #endif                                 /*   (sIII does wait in ioctls) */
        !          2070:     ckxech = 0;                                /* System should echo chars */
        !          2071: #ifdef aegis
        !          2072:     conbufn = 0; if (concrp) return(write(1, "\035\001", 2));
        !          2073:     if (conuid == input_pad_$uid) {pad_$cooked(ios_$stdin, st); return(0);}
        !          2074: #endif
        !          2075: #ifndef UXIII
        !          2076: #ifdef V9
        !          2077:     return(ioctl(0,TIOCSETP,&ccold));
        !          2078: #else
        !          2079:     return(stty(0,&ccold));            /* Restore controlling tty */
        !          2080: #endif
        !          2081: #else
        !          2082:     return(ioctl(0,TCSETAW,&ccold));
        !          2083: #endif
        !          2084: }
        !          2085: 
        !          2086: /*  C O N O C  --  Output a character to the console terminal  */
        !          2087: 
        !          2088: conoc(c) char c; {
        !          2089:     write(1,&c,1);
        !          2090: }
        !          2091: 
        !          2092: /*  C O N X O  --  Write x characters to the console terminal  */
        !          2093: 
        !          2094: conxo(x,s) char *s; int x; {
        !          2095:     write(1,s,x);
        !          2096: }
        !          2097: 
        !          2098: /*  C O N O L  --  Write a line to the console terminal  */
        !          2099: 
        !          2100: conol(s) char *s; {
        !          2101:     int len;
        !          2102:     len = strlen(s);
        !          2103:     write(1,s,len);
        !          2104: }
        !          2105: 
        !          2106: /*  C O N O L A  --  Write an array of lines to the console terminal */
        !          2107: 
        !          2108: conola(s) char *s[]; {
        !          2109:     int i;
        !          2110:     for (i=0 ; *s[i] ; i++) conol(s[i]);
        !          2111: }
        !          2112: 
        !          2113: /*  C O N O L L  --  Output a string followed by CRLF  */
        !          2114: 
        !          2115: conoll(s) char *s; {
        !          2116:     conol(s);
        !          2117:     write(1,"\r\n",2);
        !          2118: }
        !          2119: 
        !          2120: /*  C O N C H K  --  Return how many characters available at console  */
        !          2121: 
        !          2122: conchk() {
        !          2123:     int x; long n;
        !          2124: 
        !          2125: #ifdef PROVX1
        !          2126:     x = ioctl(0, TIOCQCNT, &ttbuf);
        !          2127:     n = ttbuf.sg_ispeed & 0377;
        !          2128:     return((x < 0) ? 0 : n);
        !          2129: #else
        !          2130: #ifdef aegis
        !          2131:     if (conbufn > 0) return(conbufn);  /* use old count if nonzero */
        !          2132: 
        !          2133:     /* read in more characters */
        !          2134:     conbufn = ios_$get(ios_$stdin,
        !          2135:              ios_$cond_opt, conbuf, (long)sizeof(conbuf), st);
        !          2136:     if (st.all != status_$ok) conbufn = 0;
        !          2137:     conbufp = conbuf;
        !          2138:     return(conbufn);
        !          2139: #else
        !          2140: #ifdef V7
        !          2141:     lseek(kmem[CON], (long) qaddr[CON], 0);
        !          2142:     x = read(kmem[CON], &n, sizeof(int));
        !          2143:     return((x == sizeof(int))? n: 0);
        !          2144: #else
        !          2145: #ifdef UXIII
        !          2146:     if (conesc) {                      /* Escape typed */
        !          2147:        conesc = 0;
        !          2148:        signal(SIGQUIT,esctrp);         /* Restore escape */
        !          2149:        return(1);
        !          2150:     }
        !          2151:     return(0);
        !          2152: #else
        !          2153: #ifdef C70
        !          2154:     if (conesc) {                      /* Escape typed */
        !          2155:        conesc = 0;
        !          2156:        signal(SIGQUIT,esctrp);         /* Restore escape */
        !          2157:        return(1);
        !          2158:     }
        !          2159:     return(0);
        !          2160: #else
        !          2161: #ifdef FIONREAD
        !          2162:     x = ioctl(0, FIONREAD, &n);                /* BSD and maybe some others */
        !          2163:     return((x < 0) ? 0 : n);
        !          2164: #else
        !          2165:     return(0);                         /* Others can't do. */
        !          2166: #endif
        !          2167: #endif
        !          2168: #endif
        !          2169: #endif
        !          2170: #endif
        !          2171: #endif
        !          2172: }
        !          2173: 
        !          2174: /*  C O N I N C  --  Get a character from the console  */
        !          2175: 
        !          2176: coninc(timo) int timo; {
        !          2177:     int n = 0; char ch;
        !          2178: #ifdef aegis
        !          2179:     fflush(stdout);
        !          2180:     if (conchk() > 0)
        !          2181:     {  --conbufn; return(*conbufp++ & 0377); }
        !          2182: #endif
        !          2183:     if (timo <= 0 ) {                  /* untimed */
        !          2184:        n = read(0, &ch, 1);            /* Read a character. */
        !          2185:        ch &= 0377;
        !          2186:        if (n > 0) return(ch);          /* Return the char if read */
        !          2187:        else 
        !          2188: #ifdef UXIII
        !          2189: #ifndef CIE                            /* CIE Regulus has no such symbol */
        !          2190:            if (n < 0 && errno == EINTR) /* if read was interrupted by QUIT */
        !          2191:                return(escchr);          /* user entered escape character */
        !          2192:            else                    /* couldnt be ^c, sigint never returns */
        !          2193: #endif
        !          2194: #endif
        !          2195:                return(-1);             /* Return the char, or -1. */
        !          2196:        }
        !          2197:     signal(SIGALRM,timerh);            /* Timed read, so set up timer */
        !          2198:     alarm(timo);
        !          2199:     if (setjmp(sjbuf)) n = -2;
        !          2200:     else {
        !          2201:        n = read(0, &ch, 1);
        !          2202:        ch &= 0377;
        !          2203:     }
        !          2204:     alarm(0);                          /* Stop timing, we got our character */
        !          2205:     signal(SIGALRM,SIG_DFL);
        !          2206:     if (n > 0) return(ch);
        !          2207:     else
        !          2208: #ifdef UXIII
        !          2209: #ifndef CIE                            /* CIE Regulus has no such symbol */
        !          2210:         if (n == -1 && errno == EINTR)  /* If read interrupted by QUIT, */
        !          2211:            return(escchr);             /* user entered escape character, */
        !          2212:         else                           /* can't be ^c, sigint never returns */
        !          2213: #endif
        !          2214: #endif
        !          2215:        return(-1);
        !          2216: }
        !          2217: 
        !          2218: #ifdef ATT7300
        !          2219: #include <sys/phone.h>
        !          2220: #include <dial.h>
        !          2221: #define ATT7300 4                      /* REH */
        !          2222: CALL tcfig;
        !          2223: struct termio ctermio = {0};
        !          2224: struct updata ph;
        !          2225: static int att7300 = 0;                        /* REH */
        !          2226: 
        !          2227: /*  A T T D I A L  --  Dial up the remote system */
        !          2228: 
        !          2229: /* Purpose: to open and dial a number on the internal modem available on the 
        !          2230:  * ATT7300 UNIX PC.  Richard E. Hill, Dickinson, TX.
        !          2231:  */
        !          2232: 
        !          2233: attdial(ttname,speed,telnbr) char *ttname,*telnbr; int speed; {
        !          2234:     int err;
        !          2235: 
        !          2236:     if (ttyfd > 0) {
        !          2237:        ioctl(ttyfd,TCGETA,&ctermio);   /* save current settings */
        !          2238:        err=ttclos();                   /* close port */
        !          2239:     } else ioctl(0,TCGETA,&ctermio);   /* get standard settings */
        !          2240: 
        !          2241: /* Open line, check availability & data mode, turn on speaker, close port. */
        !          2242: 
        !          2243:     ttyfd = open (ttname,O_RDWR | O_NDELAY);
        !          2244:     if (err=ioctl(ttyfd,PIOCOFFHOOK,&ph)) {
        !          2245:        printf("Phone line for %s not available:%d %d %d\n",
        !          2246:               ttname,ttyfd,err,errno);
        !          2247:        close(ttyfd);
        !          2248:        ttyfd = -1;
        !          2249:        return(-1);
        !          2250:     }
        !          2251:     ioctl(ttyfd,PIOCGETP,&ph);     /* set phone parameters   */
        !          2252:     if (ph.c_lineparam & VOICE) {
        !          2253:        printf("Phone line %s not in data mode. Switch to data & redial\n",
        !          2254:               ttname);
        !          2255:        ioctl(ttyfd,PIOCDISC,&ph);
        !          2256:        close(ttyfd);
        !          2257:        ttyfd = -1;
        !          2258:          return(-1);
        !          2259:     }
        !          2260:     ph.c_feedback |= (SPEAKERON | RINGON | NORMSPK);
        !          2261:     ioctl(ttyfd,PIOCSETP,&ph);         /* set phone parameters   */
        !          2262:     ioctl(ttyfd,PIOCDISC,&ph);         /* release phone resources for dial */
        !          2263:     close(ttyfd);
        !          2264: /*
        !          2265:        fprintf(stderr,"Phone line status. line_par:%o dialtone_wait:%o \
        !          2266: line_status:%o feedback:%o\n",
        !          2267:         ph.c_lineparam, ph.c_waitdialtone, ph.c_linestatus,ph.c_feedback);
        !          2268: */
        !          2269: 
        !          2270: /*  Close line so that it can be reopened using system routine "dial". */
        !          2271: /*  Set terminal configuration parameters. */
        !          2272: 
        !          2273:     ctermio.c_iflag |= (BRKINT|IGNPAR|IXON|IXOFF);
        !          2274:     ctermio.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP| IXANY);
        !          2275:     ctermio.c_oflag &= ~OPOST;
        !          2276:     ctermio.c_cflag = (B1200 | CS8 | CREAD | CLOCAL | HUPCL);
        !          2277:     ctermio.c_lflag &= ~(ICANON|ECHO);
        !          2278:     ctermio.c_cc[4] = 1;
        !          2279:     ctermio.c_cc[5] = 0;
        !          2280:     tcfig.attr = &ctermio;
        !          2281:     tcfig.baud = speed <= 1200 ? speed : 1200;
        !          2282:     tcfig.speed = speed <= 300 ? 300 : 1200;
        !          2283:     tcfig.line = ttname;
        !          2284:     tcfig.telno = telnbr;
        !          2285:     tcfig.modem = 0;
        !          2286:     fprintf (stderr,"dialing:%s on line:%s at %d baud, speed:%d\n",
        !          2287:             tcfig.telno,tcfig.line,tcfig.baud,tcfig.speed);
        !          2288:     if ((ttyfd = dial(tcfig)) > 0) {
        !          2289:        att7300 = 1;
        !          2290: /*
        !          2291:        ioctl(ttyfd,TCGETA,&ctermio);
        !          2292:        fprintf(stderr,"after dial:iflag:%o, oflag:%o, cflag:%o, lflag:%o,\
        !          2293:        line:%o\n", ctermio.c_iflag,ctermio.c_oflag,ctermio.c_cflag,
        !          2294:        ctermio.c_lflag, ctermio.c_line);
        !          2295: */
        !          2296:        return(0);
        !          2297:     }
        !          2298:     printf("Sorry, connection not made. Error status: %d\n",ttyfd);
        !          2299:     return(-2);
        !          2300: }
        !          2301: #endif /* ATT7300 */
        !          2302: 

unix.superglobalmegacorp.com

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