# 2.11BSD#431 - /usr/src/new/kermit5.188/ckutio.c

##### Functions

    SIGTYP            X
    acucntrl          X
    attdial           X
    carrctl           X
    cctrap            X
    conbgt            X
    conbin            X
    concb             X
    conchk            X
    congks            X
    congm             X
    coninc            X
    conint            X
    connoi            X
    conoc             X
    conol             X
    conola            X
    conoll            X
    conres            X
    conxo             X
    do_open           X
    esctrp            X
    genbrk            X
    gtimer            X
    initrawq          X
    main              X
    msleep            X
    myfillbuf         X
    mygetbuf          X
    myunrd            X
    offgetty          X
    ongetty           X
    priv_can          X
    priv_chk          X
    priv_ini          X
    priv_off          X
    priv_on           X
    priv_opn          X
    psuspend          X
    real_uid          X
    rtimer            X
    sig_ign           X
    syscleanup        X
    sysinit           X
    timerh            X
    ttchk             X
    ttclos            X
    ttflui            X
    ttfluo            X
    ttgmdm            X
    ttgspd            X
    tthang            X
    ttimoff           X
    ttinc             X
    ttinl             X
    ttoc              X
    ttol              X
    ttopen            X
    ttpkt             X
    ttres             X
    ttrpid            X
    ttscarr           X
    ttsndb            X
    ttsndlb           X
    ttsspd            X
    ttvt              X
    ttxin             X
    ztime             X

##### Variables

    UID_T             X
    VOID              X
    backgrd           X
    cc_int            X
    ckxech            X
    ckxsys            X
    ckxv              X
    dfflow            X
    dfloc             X
    dfmdm             X
    dfprty            X
    dftty             X
    dialer            X
    fdflag            X
    flfnam            X
    haslock           X
    iniflags          X
    kmem              X
    lkflfn            X
    lmode             X
    lmodef            X
    qaddr             X
    rctsx             X
    rtu_bug           X
    ttcarr            X
    ttfdflg           X
    ttflow            X
    ttld              X
    ttmdm             X
    ttpflg            X
    ttprty            X
    ttspeed           X
    tvtflg            X

##### Macros

    BREAKNULS         X
    BSD42             X
    BSDBREAK          X
    BSPEED            X
    CON               X
    CONBUFSIZ         X
    CRTSCTS           X
    CTRLC             X
    DEVNAMLEN         X
    DIRENT            X
    DOGETY            X
    EINTR             X
    ENOTCONN          X
    FIONREAD          X
    FREAD             X
    FWRITE            X
    GID_ROOT          X
    HPUXJOBCTL        X
    HUPTIME           X
    HZ                X
    IEXTEN            X
    ISMODEM           X
    K_MDMCTL          X
    LCKDIR            X
    LFDEVNO           X
    LFNAML            X
    LOCKF             X
    LOCK_DIR          X
    MSLFTIME          X
    MYBUFLEN          X
    MYREAD            X
    NAMEFD            X
    NAP               X
    NCCS              X
    NOFILEH           X
    NOSETREU          X
    NOSYSIOCTLH       X
    OPENFLGS          X
    O_RDONLY          X
    PEEKTYPE          X
    PGROUP_T          X
    PIDSTRING         X
    SELECT            X
    SETREUID          X
    TANDEM            X
    TCGETS            X
    TCSANOW           X
    TCSETS            X
    TERMIOS           X
    TTOC_TMO          X
    TTOLMAXT          X
    TTY               X
    UID_ROOT          X
    USLEEP            X
    ZTIMEV7           X
    ctermid           X
    major             X
    minor             X
    myread            X
    nap               X
    switchgid         X
    switchuid         X
    xunchar           X

##### struct's

    termios           X

##### typedef's

    mflag             X

       1: char *ckxv = "UNIX Communications support, 5A(0102), 23 Nov 92";
       2:
       3: /*  C K U T I O  */
       4:
       5: /* C-Kermit interrupt, terminal control & i/o functions for UNIX */
       6:
       7: /*
       8:   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
       9:   Columbia University Center for Computing Activities.
      10:   First released January 1985.
      11:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
      12:   York.  Permission is granted to any individual or institution to use this
      13:   software as long as it is not sold for profit.  This copyright notice must be
      14:   retained.  This software may not be included in commercial products without
      15:   written permission of Columbia University.
      16: */
      17:
      18: /* Includes */
      19:
      20: #include "ckcdeb.h"         /* This moved to here. */
      21: #include <errno.h>          /* System error numbers */
      22: #ifdef __386BSD__
      23: #define ENOTCONN 57
      24: #endif /* __386BSD__ */
      25:
      26: #include "ckcnet.h"         /* Symbols for network types. */
      27:
      28: /*
      29:   The directory-related includes are here because we need to test some
      30:   file-system-related symbols to find out which system we're being compiled
      31:   under.  For example, MAXNAMLEN is defined in BSD4.2 but not 4.1.
      32: */
      33: #ifdef SDIRENT              /* Directory bits... */
      34: #define DIRENT
      35: #endif /* SDIRENT */
      36:
      37: #ifdef XNDIR
      38: #include <sys/ndir.h>
      39: #else /* !XNDIR */
      40: #ifdef NDIR
      41: #include <ndir.h>
      42: #else /* !NDIR, !XNDIR */
      43: #ifdef RTU
      44: #include "/usr/lib/ndir.h"
      45: #else /* !RTU, !NDIR, !XNDIR */
      46: #ifdef DIRENT
      47: #ifdef SDIRENT
      48: #include <sys/dirent.h>
      49: #else
      50: #include <dirent.h>
      51: #endif /* SDIRENT */
      52: #else /* !RTU, !NDIR, !XNDIR, !DIRENT, i.e. all others */
      53: #include <sys/dir.h>
      54: #endif /* DIRENT */
      55: #endif /* RTU */
      56: #endif /* NDIR */
      57: #endif /* XNDIR */
      58:
      59: /* Definition of HZ, used in msleep() */
      60:
      61: #ifdef MIPS
      62: #define HZ ( 1000 / CLOCK_TICK )
      63: #else
      64: #ifdef ATTSV
      65: #ifndef NAP
      66: #ifndef TRS16
      67: #include <sys/param.h>
      68: #else
      69: #define HZ ( 1000 / CLOCK_TICK )
      70: #endif /* TRS16 */
      71: #ifdef NAPHACK
      72: #define nap(x) (void)syscall(3112, (x))
      73: #define NAP
      74: #endif /* NAPHACK */
      75: #endif /* NAP */
      76: #endif /* ATTSV */
      77: #endif /* MIPS */
      78:
      79: #ifdef M_UNIX
      80: #undef NGROUPS_MAX      /* Prevent multiple definition warnings */
      81: #endif /* M_UNIX */
      82:
      83: #include <signal.h>                     /* Signals */
      84:
      85: /* For setjmp and longjmp */
      86:
      87: #ifndef ZILOG
      88: #include <setjmp.h>
      89: #else
      90: #include <setret.h>
      91: #endif /* ZILOG */
      92:
      93: /* Maximum length for the name of a tty device */
      94:
      95: #ifndef DEVNAMLEN
      96: #define DEVNAMLEN 25
      97: #endif
      98:
      99: #ifdef  NETCONN
     100: #undef DEVNAMLEN
     101: #define DEVNAMLEN 50            /* longer field for host:service */
     102: #endif  /* NETCONN */
     103:
     104: /*
     105:   The following test differentiates between 4.1 BSD and 4.2 & later.
     106:   If you have a 4.1BSD system with the DIRENT library, this test could
     107:   mistakenly diagnose 4.2BSD and then later enable the use of system calls
     108:   that aren't defined.  If indeed there are such systems, we can use some
     109:   other way of testing for 4.1BSD, or add yet another compile-time switch.
     110: */
     111: #ifdef BSD4
     112: #ifdef MAXNAMLEN
     113: #ifndef FT21
     114: #ifndef FT18                /* Except for Fortune. */
     115: #define BSD42
     116: #endif /* FT18 */
     117: #endif /* FT21 */
     118: #endif /* MAXNAMLEN */
     119: #endif /* BSD4 */
     120: /*
     121:  Minix support added by Charles Hedrick,
     122:  Rutgers University:  hedrick@aramis.rutgers.edu
     123:  Minix also has V7 enabled.
     124: */
     125: #ifdef MINIX
     126: #define TANDEM 0
     127: #define MYREAD
     128: #include <limits.h>
     129: #endif /* MINIX */
     130:
     131: #include "ckuver.h"         /* Version herald */
     132: char *ckxsys = HERALD;
     133:
     134: /* UUCP lock file name definition */
     135:
     136: #ifndef NOUUCP
     137:
     138: /* Name of UUCP tty device lock file */
     139:
     140: #ifdef ACUCNTRL
     141: #define LCKDIR
     142: #endif /* ACUCNTRL */
     143: /*
     144:   LOCK_DIR is the name of the lockfile directory.
     145:   If LOCK_DIR is already defined (e.g. on command line), we don't change it.
     146:   PIDSTRING means use ASCII string to represent pid in lockfile.
     147: */
     148: #ifndef LOCK_DIR
     149: #ifdef BSD44
     150: #define LOCK_DIR "/var/spool/uucp";
     151: #else
     152: #ifdef DGUX430
     153: #define LOCK_DIR "/var/spool/locks";
     154: #else
     155: #ifdef RTAIX                /* IBM RT PC AIX 2.2.1 */
     156: #define PIDSTRING
     157: #define LOCK_DIR "/etc/locks";
     158: #else
     159: #ifdef AIXRS
     160: #define PIDSTRING
     161: #define LOCK_DIR "/etc/locks";
     162: #else
     163: #ifdef ISIII
     164: #define LOCK_DIR "/etc/locks";
     165: #else
     166: #ifdef HDBUUCP
     167: #define PIDSTRING
     168: #ifdef M_SYS5  /* wht@n4hgf - SCO */
     169: #define LOCK_DIR "/usr/spool/uucp";
     170: #else
     171: #ifdef M_UNIX
     172: #define LOCK_DIR "/usr/spool/uucp";
     173: #else
     174: #ifdef SVR4
     175: #define LOCK_DIR "/var/spool/locks";
     176: #ifndef LOCKF
     177: #define LOCKF               /* Use lockf() too in SVR4 */
     178: #endif /* LOCKF */
     179: #else
     180: #ifdef SUNOS4
     181: #define LOCK_DIR "/var/spool/locks";
     182: #else
     183: #define LOCK_DIR "/usr/spool/locks";
     184: #endif /* SUNOS4 */
     185: #endif /* SVR4 */
     186: #endif /* M_UNIX */
     187: #endif /* M_SYS5 */
     188: #else
     189: #ifdef LCKDIR
     190: #define LOCK_DIR "/usr/spool/uucp/LCK";
     191: #else
     192: #define LOCK_DIR "/usr/spool/uucp";
     193: #endif /* LCKDIR */
     194: #endif /* HDBUUCP */
     195: #endif /* ISIII */
     196: #endif /* AIXRS */
     197: #endif /* RTAIX */
     198: #endif /* DGUX430 */
     199: #endif /* BSD44 */
     200: #endif /* !LOCK_DIR (outside ifndef) */
     201:
     202: #endif /* !NOUUCP */
     203:
     204: #ifdef ATTSV
     205: #define MYREAD
     206: #endif /* ATTSV */
     207:
     208: #ifdef ATT7300
     209: #ifndef MYREAD
     210: #define MYREAD
     211: #endif /* MYREAD */
     212: /* bits for attmodem: internal modem in use, restart getty */
     213: #define ISMODEM 1
     214: #define DOGETY 512
     215: #endif  /* ATT7300 */
     216:
     217: #ifdef BSD42
     218: #define MYREAD
     219: #endif /* BSD42 */
     220:
     221: #ifdef POSIX
     222: #define MYREAD
     223: #endif /* POSIX */
     224:
     225: /*
     226:  Variables available to outside world:
     227:
     228:    dftty  -- Pointer to default tty name string, like "/dev/tty".
     229:    dfloc  -- 0 if dftty is console, 1 if external line.
     230:    dfprty -- Default parity
     231:    dfflow -- Default flow control
     232:    ckxech -- Flag for who echoes console typein:
     233:      1 - The program (system echo is turned off)
     234:      0 - The system (or front end, or terminal).
     235:    functions that want to do their own echoing should check this flag
     236:    before doing so.
     237:
     238:    flfnam  -- Name of lock file, including its path, e.g.,
     239:                 "/usr/spool/uucp/LCK..cul0" or "/etc/locks/tty77"
     240:    lkflfn  -- Name of link to lock file, including its paths
     241:    haslock -- Flag set if this kermit established a uucp lock.
     242:    backgrd -- Flag indicating program executing in background ( & on
     243:                 end of shell command). Used to ignore INT and QUIT signals.
     244:    rtu_bug -- Set by stptrap().  RTU treats ^Z as EOF (but only when we handle
     245:                 SIGTSTP)
     246:
     247:  Functions for assigned communication line (either external or console tty):
     248:
     249:    sysinit()               -- System dependent program initialization
     250:    syscleanup()            -- System dependent program shutdown
     251:    ttopen(ttname,local,mdmtyp,timo) -- Open the named tty for exclusive access.
     252:    ttclos()                -- Close & reset the tty, releasing any access lock.
     253:    ttsspd(cps)             -- Set the transmission speed of the tty.
     254:    ttgspd()                -- Get (read) the the transmission speed of the tty.
     255:    ttpkt(speed,flow,parity) -- Put the tty in packet mode and set the speed.
     256:    ttvt(speed,flow)        -- Put the tty in virtual terminal mode.
     257:                                 or in DIALING or CONNECTED modem control state.
     258:    ttres()                 -- Restore original tty modes.
     259:    ttscarr(carrier)        -- Set carrier control mode, on/off/auto.
     260:    ttinl(dest,max,timo)    -- Timed read line from the tty.
     261:    ttinc(timo)             -- Timed read character from tty.
     262:    myread()                -- Raw mode bulk buffer read, gives subsequent
     263:                                 chars one at a time and simulates FIONREAD.
     264:    myunrd(c)               -- Places c back in buffer to be read (one only)
     265:    ttchk()                 -- See how many characters in tty input buffer.
     266:    ttxin(n,buf)            -- Read n characters from tty (untimed).
     267:    ttol(string,length)     -- Write a string to the tty.
     268:    ttoc(c)                 -- Write a character to the tty.
     269:    ttflui()                -- Flush tty input buffer.
     270:    ttsndb()                -- Send BREAK signal.
     271:    ttsndlb()               -- Send Long BREAK signal.
     272:
     273:    ttlock(ttname)          -- "Lock" tty device against uucp collisions.
     274:    ttunlck()               -- Unlock tty device.
     275:
     276:                               For ATT7300/Unix PC, System V:
     277:    attdial(ttname,speed,telnbr) -- dials ATT7300/Unix PC internal modem
     278:    offgetty(ttname)        -- Turns off getty(1m) for comms line
     279:    ongetty(ttname)         -- Restores getty() to comms line
     280: */
     281:
     282: /*
     283: Functions for console terminal:
     284:
     285:    congm()   -- Get console terminal modes.
     286:    concb(esc) -- Put the console in single-character wakeup mode with no echo.
     287:    conbin(esc) -- Put the console in binary (raw) mode.
     288:    conres()  -- Restore the console to mode obtained by congm().
     289:    conoc(c)  -- Unbuffered output, one character to console.
     290:    conol(s)  -- Unbuffered output, null-terminated string to the console.
     291:    conola(s) -- Unbuffered output, array of strings to the console.
     292:    conxo(n,s) -- Unbuffered output, n characters to the console.
     293:    conchk()  -- Check if characters available at console (bsd 4.2).
     294:                 Check if escape char (^\) typed at console (System III/V).
     295:    coninc(timo)  -- Timed get a character from the console.
     296:    congks(timo)  -- Timed get keyboard scan code.
     297:    conint()  -- Enable terminal interrupts on the console if not background.
     298:    connoi()  -- Disable terminal interrupts on the console if not background.
     299:
     300: Time functions
     301:
     302:    msleep(m) -- Millisecond sleep
     303:    ztime(&s) -- Return pointer to date/time string
     304:    rtimer() --  Reset timer
     305:    gtimer()  -- Get elapsed time since last call to rtimer()
     306: */
     307:
     308: /* Conditional Includes */
     309:
     310: /* Whether to include <sys/file.h> */
     311:
     312: #ifdef RTU              /* RTU doesn't */
     313: #define NOFILEH
     314: #endif /* RTU */
     315:
     316: #ifdef CIE              /* CIE does. */
     317: #undef NOFILEH
     318: #endif /* CIE */
     319:
     320: #ifdef BSD41                /* 4.1 BSD doesn't */
     321: #define NOFILEH
     322: #endif /* BSD41 */
     323:
     324: #ifdef is68k                /* is68k (whatever that is)  */
     325: #define NOFILEH
     326: #endif /* is68k */
     327:
     328: #ifdef MINIX                /* MINIX */
     329: #define NOFILEH
     330: #endif /* MINIX */
     331:
     332: #ifdef COHERENT             /* Coherent */
     333: #define NOFILEH
     334: #endif /* COHERENT */
     335:
     336: #ifndef NOFILEH             /* Now include if selected. */
     337: #include <sys/file.h>
     338: #endif /* NOFILEH */
     339:
     340: /* POSIX */
     341:
     342: #ifdef BSD44ORPOSIX         /* POSIX uses termios.h */
     343: #define TERMIOS
     344: #ifdef bsdi
     345: #ifndef NCCS
     346: #define NCCS 20
     347: #endif /* NCCS */
     348: #endif /* bsdi */
     349: #include <termios.h>
     350: #ifndef BSD44               /* Really POSIX */
     351: #define NOSYSIOCTLH         /* No ioctl's allowed. */
     352: #undef ultrix               /* Turn off any ultrix features. */
     353: #endif /* BSD44 */
     354: #endif /* POSIX */
     355:
     356: /* System III, System V */
     357:
     358: #ifdef ATTSV
     359: #ifndef BSD44
     360: #include <termio.h>
     361: #endif /* BSD44 */
     362: #ifdef SVR4             /* Sys V R4 and later */
     363: #ifdef TERMIOX
     364: /* Need this for termiox structure, RTS/CTS and DTR/CD flow control */
     365: #include <termiox.h>
     366:   struct termiox rctsx;
     367: #else
     368: #ifdef STERMIOX
     369: #include <sys/termiox.h>
     370:   struct termiox rctsx;
     371: #endif /* STERMIOX */
     372: #endif /* TERMIOX */
     373: #endif /* SVR4 */
     374: #endif /* ATTSV */
     375:
     376: #ifdef MINIX                /* MINIX uses ioctl's */
     377: #define NOSYSIOCTLH         /* but has no <sys/ioctl.h> */
     378: #endif /* MINIX */
     379:
     380: /* Others */
     381:
     382: #ifndef NOSYSIOCTLH         /* Others use ioctl() */
     383: #ifdef SUN4S5
     384: /*
     385:   This is to get rid of cpp warning messages that occur because all of
     386:   these symbols are defined by both termios.h and ioctl.h on the SUN.
     387: */
     388: #undef ECHO
     389: #undef NL0
     390: #undef NL1
     391: #undef TAB0
     392: #undef TAB1
     393: #undef TAB2
     394: #undef XTABS
     395: #undef CR0
     396: #undef CR1
     397: #undef CR2
     398: #undef CR3
     399: #undef FF0
     400: #undef FF1
     401: #undef BS0
     402: #undef BS1
     403: #undef TOSTOP
     404: #undef FLUSHO
     405: #undef PENDIN
     406: #undef NOFLSH
     407: #endif /* SUN4S5 */
     408: #include <sys/ioctl.h>
     409: #endif /* NOSYSIOCTLH */
     410:
     411: /* Whether to include <fcntl.h> */
     412:
     413: #ifndef is68k               /* Only a few don't have this one. */
     414: #ifndef BSD41
     415: #ifndef FT21
     416: #ifndef FT18
     417: #ifndef COHERENT
     418: #include <fcntl.h>
     419: #endif /* COHERENT */
     420: #endif /* FT18 */
     421: #endif /* FT21 */
     422: #endif /* BSD41 */
     423: #endif /* not is68k */
     424:
     425: #ifdef COHERENT
     426: #include <sys/fcntl.h>
     427: #endif /* COHERENT */
     428:
     429: #ifdef ATT7300              /* Unix PC, internal modem dialer */
     430: #include <sys/phone.h>
     431: #endif /* ATT7300 */
     432:
     433: #ifdef HPUX             /* HP-UX variations. */
     434: #define HPUXJOBCTL
     435: #include <sys/modem.h>          /* HP-UX modem signals */
     436: #ifdef hp9000s500           /* Model 500 */
     437: #undef HPUXJOBCTL
     438: #endif /* hp9000s500 */
     439: #ifdef HPUXPRE65
     440: #undef HPUXJOBCTL
     441: typedef int mflag;
     442: #endif /* HPUXPRE65 */
     443: #ifdef HPUXJOBCTL
     444: #include <sys/bsdtty.h>         /* HP-UX Berkeley tty support */
     445: #endif /* HPUXJOBCTL */
     446: #endif /* HPUX */
     447:
     448: /* BSD, V7, Coherent, Minix, et al. */
     449:
     450: #ifdef SVORPOSIX            /* Sys V or POSIX */
     451: #ifdef BSD44
     452: #include <sys/time.h>
     453: #endif /* BSD44 */
     454: #ifdef AIXRS
     455: #include <sys/time.h>
     456: #endif /* AIXRS */
     457: #ifdef NOIEXTEN             /* This is broken on some systems */
     458: #undef IEXTEN               /* like Convex/OS 9.1 */
     459: #endif /* NOIEXTEN */
     460: #ifndef IEXTEN              /* Turn off ^O/^V processing. */
     461: #define IEXTEN 0            /* Needed, at least, on BSDI. */
     462: #endif /* IEXTEN */
     463: #else                   /* Not AT&T Sys V or POSIX */
     464: #include <sgtty.h>                      /* So we use <sgtty.h> */
     465: #ifndef PROVX1              /* Now <sys/time.h> ... */
     466: #ifndef V7
     467: #ifndef BSD41
     468: #ifndef COHERENT
     469: #include <sys/time.h>                   /* Clock info (for break generation) */
     470: #endif /* COHERENT */
     471: #endif /* BSD41 */
     472: #endif /* V7 */
     473: #endif /* PROVX1 */
     474: #endif /* SVORPOSIX */
     475:
     476: #ifdef OSF              /* DEC OSF/1 1.0 */
     477: #include <sys/timeb.h>
     478: #endif /* OSF */
     479:
     480: #ifdef BSD41                /* BSD 4.1 */
     481: #include <sys/timeb.h>
     482: #endif /* BSD41 */
     483:
     484: #ifdef FT21             /* For:Pro 2.1 */
     485: #include <sys/timeb.h>
     486: #endif /* FT21 */
     487:
     488: #ifdef BSD29                /* BSD 2.9 */
     489: #include <sys/timeb.h>
     490: #endif /* BSD29 */
     491:
     492: #ifdef TOWER1
     493: #include <sys/timeb.h>                  /* Clock info for NCR Tower */
     494: #endif /* TOWER1 */
     495:
     496: #ifdef COHERENT
     497: #include <sys/timeb.h>                  /* Clock info for NCR Tower */
     498: #endif /* COHERENT */
     499:
     500: #ifdef aegis
     501: #include "/sys/ins/base.ins.c"
     502: #include "/sys/ins/error.ins.c"
     503: #include "/sys/ins/ios.ins.c"
     504: #include "/sys/ins/sio.ins.c"
     505: #include "/sys/ins/pad.ins.c"
     506: #include "/sys/ins/time.ins.c"
     507: #include "/sys/ins/pfm.ins.c"
     508: #include "/sys/ins/pgm.ins.c"
     509: #include "/sys/ins/ec2.ins.c"
     510: #include "/sys/ins/type_uids.ins.c"
     511: #include <default_acl.h>
     512: #undef TIOCEXCL
     513: #undef FIONREAD
     514: #endif /* aegis */
     515:
     516: #ifdef sxaE50               /* PFU Compact A SX/A TISP V10/L50 */
     517: #undef FIONREAD
     518: #endif /* sxaE50 */
     519:
     520: /* The following #defines are catch-alls for those systems */
     521: /* that didn't have or couldn't find <file.h>... */
     522:
     523: #ifndef FREAD
     524: #define FREAD 0x01
     525: #endif /* FREAD */
     526:
     527: #ifndef FWRITE
     528: #define FWRITE 0x10
     529: #endif /* FWRITE */
     530:
     531: #ifndef O_RDONLY
     532: #define O_RDONLY 000
     533: #endif /* O_RDONLY */
     534:
     535: /* Declarations */
     536:
     537: #ifdef _POSIX_SOURCE            /* This includes MINIX */
     538: #ifndef AIXRS
     539: #include <time.h>
     540: #endif /* AIXRS */
     541: #ifdef __GNUC__
     542: #ifdef XENIX
     543: /*
     544:   Because Xenix <time.h> doesn't declare time() if we're using gcc.
     545: */
     546: time_t time();
     547: #endif /* XENIX */
     548: #endif /* __GNUC__ */
     549: #else
     550: time_t time();              /* All Unixes should have this... */
     551: #endif /* _POSIX_SOURCE */
     552:
     553: /* Special stuff for V7 input buffer peeking */
     554:
     555: #ifdef  V7
     556: int kmem[2] = { -1, -1};
     557: char *initrawq(), *qaddr[2]={0,0};
     558: #define CON 0
     559: #define TTY 1
     560: #endif /* V7 */
     561:
     562: /* dftty is the device name of the default device for file transfer */
     563: /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
     564:
     565: #ifndef DFTTY
     566: #ifdef PROVX1
     567:     char *dftty = "/dev/com1.dout"; /* Only example so far of a system */
     568:     char *dfmdm = "none";
     569:     int dfloc = 1;                  /* that goes in local mode by default */
     570: #else
     571: #ifdef COHERENT
     572:     char *dftty = "/dev/modem";
     573:     char *dfmdm = "none";
     574:     int dfloc = 1;
     575: #else
     576:     char *dftty = CTTNAM;               /* Remote by default, use normal */
     577:     char *dfmdm = "none";
     578:     int dfloc = 0;                      /* controlling terminal name. */
     579: #endif /* COHERENT */
     580: #endif /* PROVX1 */
     581: #else
     582:     char *dftty = DFTTY;        /* Default location specified on */
     583:     char *dfmdm = "none";       /* command line. */
     584:     int dfloc = 1;                      /* controlling terminal name. */
     585: #endif /* DFTTY */
     586:
     587: #ifdef RTU
     588:     int rtu_bug = 0;            /* set to 1 when returning from SIGTSTP */
     589: #endif /* RTU */
     590:
     591:     int dfprty = 0;                     /* Default parity (0 = none) */
     592:     int ttprty = 0;                     /* The parity that is in use. */
     593:     int ttpflg = 0;         /* Parity not sensed yet. */
     594:     static int ttpmsk = 0377;       /* Parity stripping mask. */
     595:     int ttmdm = 0;                      /* Modem in use. */
     596:     int ttcarr = CAR_AUT;       /* Carrier handling mode. */
     597:     int dfflow = FLO_XONX;      /* Default is Xon/Xoff */
     598:     int backgrd = 0;                    /* Assume in foreground (no '&' ) */
     599: #ifdef ultrix
     600:     int iniflags = 0;           /* fcntl flags for ttyfd */
     601: #endif /* ultrix */
     602:     int fdflag = 0;         /* Flag for redirected stdio */
     603:     int ttfdflg = 0;            /* Open File descriptor was given */
     604:     int tvtflg = 0;         /* Flag that ttvt has been called */
     605:     long ttspeed = -1;          /* For saving speed */
     606:     int ttflow = -9;            /* For saving flow */
     607:     int ttld = -1;          /* Line discipline */
     608:
     609: #ifdef sony_news
     610:     static int km_con = -1;     /* Kanji mode for console tty */
     611:     static int km_ext = -1;     /* Kanji mode for external device */
     612: #endif /* sony_news */
     613:
     614: extern int ttnproto;            /* Defined in ckcnet.c */
     615: extern int ttnet;           /* Defined in ckcnet.c */
     616:
     617: int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
     618:
     619: /* Declarations of variables global within this module */
     620:
     621: static time_t tcount;           /* Elapsed time counter */
     622: static SIGTYP (*saval)() = NULL;    /* For saving alarm() handler */
     623:
     624: /*
     625:   BREAKNULS is defined for systems that simulate sending a BREAK signal
     626:   by sending a bunch of NUL characters at low speed.
     627: */
     628: #ifdef PROVX1
     629: #ifndef BREAKNULS
     630: #define BREAKNULS
     631: #endif /* BREAKNULS */
     632: #endif /* PROVX1 */
     633:
     634: #ifdef V7
     635: #ifndef BREAKNULS
     636: #define BREAKNULS
     637: #endif /* BREAKNULS */
     638: #endif /* V7 */
     639:
     640: #ifdef BREAKNULS
     641: static char             /* A string of nulls */
     642: *brnuls = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
     643: #endif /* BREAKNULS */
     644:
     645: static jmp_buf sjbuf;           /* Longjump buffers */
     646: #ifdef V7
     647: static jmp_buf jjbuf;
     648: #endif /* V7 */
     649:
     650: /* static */                /* (Not static any more) */
     651: int ttyfd = -1;             /* TTY file descriptor */
     652:
     653: int telnetfd = 0;           /* File descriptor is for telnet */
     654: int x25fd = 0;              /* File descriptor is for X.25 */
     655:
     656: static int lkf = 0,                     /* Line lock flag */
     657:     cgmf = 0,                           /* Flag that console modes saved */
     658:     xlocal = 0,                         /* Flag for tty local or remote */
     659:     curcarr = 0;            /* Carrier mode: require/ignore. */
     660:
     661: static int netconn = 0;         /* 1 if network connection active */
     662:
     663: static char escchr;                     /* Escape or attn character */
     664:
     665: #ifdef AIXRS
     666:     static struct timeval tv;       /* For getting time, from sys/time.h */
     667:     static struct timezone tz;
     668: #else
     669: #ifdef BSD44
     670:     static struct timeval tv;       /* For getting time, from sys/time.h */
     671:     static struct timezone tz;
     672: #else
     673: #ifdef BSD42
     674:     static struct timeval tv;       /* For getting time, from sys/time.h */
     675:     static struct timezone tz;
     676: #ifdef OSF
     677:     static struct timeb ftp;            /* And from sys/timeb.h */
     678: #endif /* OSF */
     679: #endif /* BSD42 */
     680: #endif /* BSD44 */
     681: #endif /* AIXRS */
     682:
     683: #ifdef BSD29
     684:     static long xclock;                  /* For getting time from sys/time.h */
     685:     static struct timeb ftp;            /* And from sys/timeb.h */
     686: #endif /* BSD29 */
     687:
     688: #ifdef BSD41
     689:     static long xclock;                  /* For getting time from sys/time.h */
     690:     static struct timeb ftp;            /* And from sys/timeb.h */
     691: #endif /* BSD41 */
     692:
     693: #ifdef FT21
     694:     static long xclock;                  /* For getting time from sys/time.h */
     695:     static struct timeb ftp;            /* And from sys/timeb.h */
     696: #endif /* FT21 */
     697:
     698: #ifdef TOWER1
     699:     static long xclock;         /* For getting time from sys/time.h */
     700:     static struct timeb ftp;        /* And from sys/timeb.h */
     701: #endif /* TOWER1 */
     702:
     703: #ifdef COHERENT
     704:     static long xclock;         /* For getting time from sys/time.h */
     705:     static struct timeb ftp;        /* And from sys/timeb.h */
     706: #endif /* COHERENT */
     707:
     708: #ifdef V7
     709:     static long xclock;
     710: #endif /* V7 */
     711:
     712: /* sgtty/termio information... */
     713:
     714: #ifdef BSD44ORPOSIX         /* POSIX or BSD44 */
     715:   static struct termios
     716:     ttold, ttraw, tttvt, ttcur,
     717:     ccold, ccraw, cccbrk;
     718: #else                   /* BSD, V7, etc */
     719: #ifdef ATTSV
     720:   static struct termio ttold = {0}; /* Init'd for word alignment, */
     721:   static struct termio ttraw = {0}; /* which is important for some */
     722:   static struct termio tttvt = {0}; /* systems, like Zilog... */
     723:   static struct termio ttcur = {0};
     724:   static struct termio ccold = {0};
     725:   static struct termio ccraw = {0};
     726:   static struct termio cccbrk = {0};
     727: #else
     728:   static struct sgttyb                  /* sgtty info... */
     729:     ttold, ttraw, tttvt, ttcur,     /* for communication line */
     730:     ccold, ccraw, cccbrk;       /* and for console */
     731: #ifdef TIOCGETC
     732: #ifdef MINIX
     733:   static struct sgttyb tchold, tchnoi;  /* Special chars */
     734: #else
     735:   static struct tchars tchold, tchnoi;
     736: #endif /* MINIX */
     737:   static int tcharf;
     738: #endif /* TIOCGETC */
     739: #ifdef TIOCGLTC
     740: #ifdef MINIX
     741:   static struct sgttyb ltchold, ltchnoi;
     742: #else
     743:   static struct ltchars ltchold, ltchnoi;
     744: #endif /* MINIX */
     745:   static int ltcharf;
     746: #endif /* TIOCGLTC */
     747:   int lmodef = 0;           /* Local modes */
     748:   int lmode = 0;
     749: #endif /* ATTSV */
     750: #endif /* BSD44ORPOSIX */
     751:
     752: #ifdef PROVX1
     753:   static struct sgttyb ttbuf;
     754: #endif /* PROVX1 */
     755:
     756: #ifdef ultrix
     757: /* do we really need this? */
     758:   static struct sgttyb vanilla;
     759: #endif /* ultrix */
     760:
     761: #ifdef ATT7300
     762: static int attmodem = 0;                /* ATT7300 internal-modem status */
     763: struct updata dialer = {0};     /* Condition dialer for data call */
     764: #endif /* ATT7300 */
     765:
     766: char flfnam[80];            /* uucp lock file path name */
     767: #ifdef RTAIX
     768: char lkflfn[80];            /* and possible link to it */
     769: #endif /* RTAIX */
     770: int haslock = 0;            /* =1 if this kermit locked uucp */
     771:
     772: #ifdef SVORPOSIX
     773: static int conesc = 0;                  /* set to 1 if esc char (^\) typed */
     774: #else
     775: #ifdef V7
     776: static int conesc = 0;
     777: #else
     778: #ifdef C70
     779: static int conesc = 0;
     780: #endif /* C70 */
     781: #endif /* V7 */
     782: #endif /* ATTSV */
     783:
     784: static char ttnmsv[DEVNAMLEN];      /* Copy of open path for tthang */
     785:
     786: #ifdef aegis
     787: static status_$t st;                    /* error status return value */
     788: static short concrp = 0;                /* true if console is CRP pad */
     789: #define CONBUFSIZ 10
     790: static char conbuf[CONBUFSIZ];          /* console readahead buffer */
     791: static int  conbufn = 0;                /* # chars in readahead buffer */
     792: static char *conbufp;                   /* next char in readahead buffer */
     793: static uid_$t ttyuid;                   /* tty type uid */
     794: static uid_$t conuid;                   /* stdout type uid */
     795:
     796: /* APOLLO Aegis main()
     797:  * establish acl usage and cleanup handling
     798:  *    this makes sure that CRP pads
     799:  *    get restored to a usable mode
     800:  */
     801: main(argc,argv) int argc; char **argv; {
     802:         status_$t status;
     803:         pfm_$cleanup_rec dirty;
     804:
     805:         PID_T pid = getpid();
     806:
     807:         /* acl usage according to invoking environment */
     808:         default_acl(USE_DEFENV);
     809:
     810:         /* establish a cleanup continuation */
     811:         status = pfm_$cleanup(dirty);
     812:         if (status.all != pfm_$cleanup_set) {
     813:                 /* only handle faults for the original process */
     814:                 if (pid == getpid() && status.all > pgm_$max_severity) {
     815:             /* blew up in main process */
     816:             status_$t quo;
     817:             pfm_$cleanup_rec clean;
     818:
     819:             /* restore the console in any case */
     820:             conres();
     821:
     822:             /* attempt a clean exit */
     823:             debug(F101, "cleanup fault status", "", status.all);
     824:
     825:             /* doexit(), then send status to continuation */
     826:             quo = pfm_$cleanup(clean);
     827:             if (quo.all == pfm_$cleanup_set)
     828:               doexit(pgm_$program_faulted,-1);
     829:             else if (quo.all > pgm_$max_severity)
     830:               pfm_$signal(quo); /* blew up in doexit() */
     831:                 }
     832:                 /* send to the original continuation */
     833:                 pfm_$signal(status);
     834:                 /*NOTREACHED*/
     835:         }
     836:         return(ckcmai(argc, argv));
     837: }
     838: #endif /* aegis */
     839:
     840: /* ANSI-style prototypes for internal functions. */
     841: /* Functions used outside this module are prototyped in ckcker.h. */
     842:
     843: #ifdef apollo
     844: _PROTOTYP( SIGTYP timerh, () );
     845: _PROTOTYP( SIGTYP cctrap, () );
     846: _PROTOTYP( SIGTYP esctrp, () );
     847: _PROTOTYP( SIGTYP sig_ign, () );
     848: #else
     849: _PROTOTYP( SIGTYP timerh, (int) );
     850: _PROTOTYP( SIGTYP cctrap, (int) );
     851: _PROTOTYP( SIGTYP esctrp, (int) );
     852: #endif /* apollo */
     853: _PROTOTYP( int do_open, (char *) );
     854: _PROTOTYP( int ttrpid, (char *) );
     855: _PROTOTYP( static int ttlock, (char *) );
     856: _PROTOTYP( static int ttunlck, (void) );
     857: _PROTOTYP( int mygetbuf, (void) );
     858: _PROTOTYP( int myfillbuf, (void) );
     859: _PROTOTYP( VOID conbgt, (int) );
     860: #ifdef ACUCNTRL
     861: _PROTOTYP( VOID acucntrl, (char *, char *) );
     862: #endif /* ACUCNTRL */
     863:
     864: #ifdef BSD44ORPOSIX
     865: _PROTOTYP( int carrctl, (struct termios *, int) );
     866: #else
     867: #ifdef ATTSV
     868: _PROTOTYP( int carrctl, (struct termio *, int) );
     869: #else
     870: _PROTOTYP( int carrctl, (struct sgttyb *, int) );
     871: #endif /* ATTSV */
     872: #endif /* BSD44ORPOSIX */
     873:
     874: #ifdef ATT7300
     875: _PROTOTYP( int attdial, (char *, long, char *) );
     876: _PROTOTYP( int offgetty, (char *) );
     877: _PROTOTYP( int ongetty, (char *) );
     878: #endif /* ATT7300 */
     879:
     880: #ifdef CK_ANSIC
     881: static char *
     882: xxlast(char *s, char c)
     883: #else
     884: static char *
     885: xxlast(s,c) char *s; char c;
     886: #endif /* CK_ANSIC */
     887: /* xxlast */ {      /*  Last occurrence of character c in string s. */
     888:     int i;
     889:     for (i = (int)strlen(s); i > 0; i--)
     890:         if ( s[i-1] == c ) return( s + (i - 1) );
     891:     return(NULL);
     892: }
     893:
     894: /* Timeout handler for communication line input functions */
     895:
     896: SIGTYP
     897: timerh(foo) int foo; {
     898:     ttimoff();
     899:     longjmp(sjbuf,1);
     900: }
     901:
     902: /* Control-C trap for communication line input functions */
     903:
     904: int cc_int;             /* Flag */
     905: SIGTYP (* occt)();          /* For saving old SIGINT handler */
     906:
     907: SIGTYP
     908: cctrap(foo) int foo; {          /* Needs arg for ANSI C */
     909:   cc_int = 1;               /* signal() prototype. */
     910:   return;
     911: }
     912:
     913: /*  S Y S I N I T  --  System-dependent program initialization.  */
     914:
     915: int
     916: sysinit() {
     917:     int x;
     918:
     919:     conbgt(0);              /* See if we're in the background */
     920: #ifndef __386BSD__
     921: /*
     922:   386BSD doesn't allow opening /dev/tty if Kermit is running setuid.
     923: */
     924:     congm();                /* Get console modes */
     925: #endif /* __386BSD__ */
     926:     signal(SIGALRM,SIG_IGN);        /* Ignore alarms */
     927:
     928: #ifdef ultrix
     929:     gtty(0,&vanilla);           /* Get sgtty info */
     930:     iniflags = fcntl(0,F_GETFL,0);  /* Get flags */
     931: #else
     932: #ifdef AUX
     933:     set42sig();             /* Don't ask! (hakanson@cs.orst.edu) */
     934: #endif /* AUX */
     935: #endif /* ultrix */
     936:
     937: /* Initialize the setuid package. */
     938: /* Change to the user's real user and group id. */
     939: /* If this can't be done, don't run at all. */
     940:
     941:     if (x = priv_ini()) {
     942:     if (x | 1) fprintf(stderr,"Fatal: setuid failure.\n");
     943:     if (x | 2) fprintf(stderr,"Fatal: setgid failure.\n");
     944:     if (x | 4) fprintf(stderr,"Fatal: C-Kermit setuid to root!\n");
     945:     exit(1);
     946:     }
     947: #ifdef __386BSD__
     948: /*
     949:   386BSD...  OK, now we have changed into ourselves, so can open /dev/tty.
     950: */
     951:     congm();                /* Get console modes */
     952: #endif /* __386BSD__ */
     953:     return(0);
     954: }
     955:
     956: /*  S Y S C L E A N U P  --  System-dependent program cleanup.  */
     957:
     958: int
     959: syscleanup() {
     960: #ifdef ultrix
     961:     stty(0,&vanilla);                   /* Get sgtty info */
     962:     fcntl(0,F_SETFL,iniflags);      /* Restore flags */
     963: #endif /* ultrix */
     964:     /* No need to call anything in the suid package here, right? */
     965:     return(0);
     966: }
     967:
     968: /*  T T O P E N  --  Open a tty for exclusive access.  */
     969:
     970: /*
     971:   Call with:
     972:     ttname: character string - device name or network host name.
     973:     lcl:
     974:   If called with lcl < 0, sets value of lcl as follows:
     975:   0: the terminal named by ttname is the job's controlling terminal.
     976:   1: the terminal named by ttname is not the job's controlling terminal.
     977:   But watch out: if a line is already open, or if requested line can't
     978:   be opened, then lcl remains (and is returned as) -1.
     979:     modem:
     980:   Less than zero: ttname is a network host name.
     981:   Zero or greater: ttname is a terminal device name.
     982:   Zero means a local connection (don't use modem signals).
     983:   Positive means use modem signals.
     984:    timo:
     985:   0 = no timer.
     986:   nonzero = number of seconds to wait for open() to return before timing out.
     987:
     988:   Returns:
     989:     0 on success
     990:    -5 if device is in use
     991:    -4 if access to device is denied
     992:    -3 if access to lock directory denied
     993:    -2 upon timeout waiting for device to open
     994:    -1 on other error
     995: */
     996: static int ttotmo = 0;          /* Timeout flag */
     997: /* Flag kept here to avoid being clobbered by longjmp.  */
     998:
     999: int
    1000: ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, timo; {
    1001:
    1002: #ifdef BSD44
    1003: #define ctermid(x) strcpy(x,"")
    1004: #else
    1005: #ifdef SVORPOSIX
    1006: #ifndef CIE
    1007:     extern char *ctermid();     /* Wish they all had this! */
    1008: #else                   /* CIE Regulus */
    1009: #define ctermid(x) strcpy(x,"")
    1010: #endif /* CIE */
    1011: #endif /* SVORPOSIX */
    1012: #endif /* BSD44 */
    1013:
    1014:     char *x;                /* what's this ? */
    1015:
    1016: #ifndef MINIX
    1017:     extern char* ttyname();
    1018: #endif /* MINIX */
    1019:     char cname[DEVNAMLEN+4];
    1020:
    1021: #ifndef pdp11
    1022: #define NAMEFD   /* Feature to allow name to be an open file descriptor */
    1023: #endif /* pdp11 */
    1024:
    1025: #ifdef NAMEFD
    1026:     char *p;
    1027:
    1028:     debug(F101,"ttopen telnetfd","",telnetfd);
    1029: #endif /* NAMEFD */
    1030:
    1031:     debug(F111,"ttopen entry modem",ttname,modem);
    1032:     debug(F101," ttyfd","",ttyfd);
    1033:     debug(F101," lcl","",*lcl);
    1034:
    1035: #ifdef MAXNAMLEN
    1036:     debug(F100,"ttopen MAXNAMLEN defined","",0);
    1037: #else
    1038:     debug(F100,"ttopen MAXNAMLEN *NOT* defined","",0);
    1039: #endif
    1040:
    1041: #ifdef BSD4
    1042:     debug(F100,"ttopen BSD4 defined","",0);
    1043: #else
    1044:     debug(F100,"ttopen BSD4 *NOT* defined","",0);
    1045: #endif
    1046:
    1047: #ifdef BSD42
    1048:     debug(F100,"ttopen BSD42 defined","",0);
    1049: #else
    1050:     debug(F100,"ttopen BSD42 *NOT* defined","",0);
    1051: #endif /* BSD42 */
    1052:
    1053: #ifdef MYREAD
    1054:     debug(F100,"ttopen MYREAD defined","",0);
    1055: #else
    1056:     debug(F100,"ttopen MYREAD *NOT* defined","",0);
    1057: #endif /* MYREAD */
    1058:
    1059:
    1060:     if (ttyfd > -1) {           /* if device already opened */
    1061:         if (strncmp(ttname,ttnmsv,DEVNAMLEN)) /* are new & old names equal? */
    1062:           ttclos(ttyfd);        /* no, close old ttname, open new */
    1063:         else                /* else same, ignore this call, */
    1064:       return(0);            /* and return. */
    1065:     }
    1066:
    1067: #ifdef  NETCONN
    1068:     if (modem < 0) {            /* modem < 0 = special code for net */
    1069:     int x;
    1070:     ttmdm = modem;
    1071:     modem = -modem;         /* Positive network type number */
    1072:     fdflag = 0;         /* Stdio not redirected. */
    1073:     netconn = 1;            /* And it's a network connection */
    1074:     debug(F111,"ttopen net",ttname,modem);
    1075: #ifdef NAMEFD
    1076:     for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */
    1077:     if (*p == '\0' && (telnetfd || x25fd)) { /* Avoid X.121 addresses */
    1078:         ttyfd = atoi(ttname);   /* Is there a way to test it's open? */
    1079:         ttfdflg = 1;        /* We got an open file descriptor */
    1080:         debug(F111,"ttopen got open network fd",ttname,ttyfd);
    1081:         strncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
    1082:         x = 1;          /* Return code is "good". */
    1083:         if (telnetfd) {
    1084:         ttnet = NET_TCPB;
    1085:         ttnproto = NP_TELNET;
    1086: #ifdef SUNX25
    1087:         } else if (x25fd) {
    1088:         ttnet = NET_SX25;
    1089:         ttnproto = NP_NONE;
    1090: #endif /* SUNX25 */
    1091:         }
    1092:     } else {            /* Host name or address given */
    1093: #endif /* NAMEFD */
    1094:         x = netopen(ttname, lcl, modem); /* (see ckcnet.h) */
    1095:         if (x > -1) {
    1096:         strncpy(ttnmsv,ttname,DEVNAMLEN);
    1097:         } else netconn = 0;
    1098: #ifdef NAMEFD
    1099:     }
    1100: #endif /* NAMEFD */
    1101:
    1102: #ifdef sony_news            /* Sony NEWS */
    1103:     if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get Kanji mode */
    1104:         perror("ttopen error getting Kanji mode (network)");
    1105:         debug(F111,"ttopen error getting Kanji mode","network",0);
    1106:         km_ext = -1;        /* Make sure this stays undefined. */
    1107:     }
    1108: #endif /* sony_news */
    1109:
    1110:     xlocal = *lcl = 1;      /* Network connections are local. */
    1111:     debug(F101,"ttopen net x","",x);
    1112:
    1113:     if (x > -1 && !x25fd)
    1114:       x = tn_ini();         /* Initialize TELNET protocol */
    1115:     return(x);
    1116:     } else {                /* Terminal device */
    1117: #endif	/* NETCONN */
    1118:
    1119: #ifdef NAMEFD
    1120: /*
    1121:   This code lets you give Kermit an open file descriptor for a serial
    1122:   communication device, rather than a device name.  Kermit assumes that the
    1123:   line is already open, locked, conditioned with the right parameters, etc.
    1124: */
    1125:     for (p = ttname; isdigit(*p); p++) ; /* Check for all digits */
    1126:     if (*p == '\0') {
    1127:         ttyfd = atoi(ttname);   /* Is there a way to test it's open? */
    1128:         debug(F111,"ttopen got open fd",ttname,ttyfd);
    1129:         strncpy(ttnmsv,ttname,DEVNAMLEN); /* Remember the "name". */
    1130:         xlocal = *lcl = 1;      /* Assume it's local. */
    1131:         netconn = 0;        /* Assume it's not a network. */
    1132:         tvtflg = 0;         /* Might need to initialize modes. */
    1133:         ttmdm = modem;      /* Remember modem type. */
    1134:         fdflag = 0;         /* Stdio not redirected. */
    1135:         ttfdflg = 1;        /* Flag we were opened this way. */
    1136:
    1137: #ifdef sony_news            /* Sony NEWS */
    1138:         /* Get device Kanji mode */
    1139:         if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) {
    1140:         perror("ttopen error getting Kanji mode");
    1141:         debug(F101,"ttopen error getting Kanji mode","",0);
    1142:         km_ext = -1;        /* Make sure this stays undefined. */
    1143:         }
    1144: #endif /* sony_news */
    1145:         return(0);          /* Return success */
    1146:     }
    1147: #endif /* NAMEFD */
    1148: #ifdef NETCONN
    1149:     }
    1150: #endif /* NETCONN */
    1151:
    1152: /* Here we have to open a serial device of the given name. */
    1153:
    1154:     occt = signal(SIGINT, cctrap);  /* Set Control-C trap, save old one */
    1155:
    1156:     tvtflg = 0;         /* Flag for use by ttvt(). */
    1157:                 /* 0 = ttvt not called yet for this device */
    1158:
    1159:     fdflag = (!isatty(0) || !isatty(1)); /* Flag for stdio redirected */
    1160:     debug(F101,"ttopen fdflag","",fdflag);
    1161:
    1162:     ttmdm = modem;                      /* Make this available to other fns */
    1163:     xlocal = *lcl;                      /* Make this available to other fns */
    1164:
    1165: /* Code for handling bidirectional tty lines goes here. */
    1166: /* Use specified method for turning off logins and suppressing getty. */
    1167:
    1168: #ifdef ACUCNTRL
    1169:     /* Should put call to priv_on() here, but that would be very risky! */
    1170:     acucntrl("disable",ttname);         /* acucntrl() program. */
    1171:     /* and priv_off() here... */
    1172: #else
    1173: #ifdef ATT7300
    1174:     if ((attmodem & DOGETY) == 0)       /* offgetty() program. */
    1175:       attmodem |= offgetty(ttname); /* Remember response.  */
    1176: #endif /* ATT7300 */
    1177: #endif /* ACUCNTRL */
    1178:
    1179: /*
    1180:  In the following section, we open the tty device for read/write.
    1181:  If a modem has been specified via "set modem" prior to "set line"
    1182:  then the O_NDELAY parameter is used in the open, provided this symbol
    1183:  is defined (e.g. in fcntl.h), so that the program does not hang waiting
    1184:  for carrier (which in most cases won't be present because a connection
    1185:  has not been dialed yet).  O_NDELAY is removed later on in ttopen().  It
    1186:  would make more sense to first determine if the line is local before
    1187:  doing this, but because ttyname() requires a file descriptor, we have
    1188:  to open it first.  See do_open().
    1189:
    1190:  Now open the device using the desired treatment of carrier.
    1191:  If carrier is REQUIRED, then open could hang forever, so an optional
    1192:  timer is provided.  If carrier is not required, the timer should never
    1193:  go off, and should do no harm...
    1194: */
    1195:     ttotmo = 0;             /* Flag no timeout */
    1196:     if (timo > 0) {
    1197:     int xx;
    1198:     saval = signal(SIGALRM,timerh); /* Timed, set up timer. */
    1199:     xx = alarm(timo);       /* Timed open() */
    1200:     debug(F101,"ttopen alarm","",xx);
    1201:     if (setjmp(sjbuf)) {
    1202:         ttotmo = 1;         /* Flag timeout. */
    1203:     } else ttyfd = do_open(ttname);
    1204:     ttimoff();
    1205:     debug(F111,"ttopen","modem",modem);
    1206:     debug(F101," ttyfd","",ttyfd);
    1207:     debug(F101," alarm return","",ttotmo);
    1208:     } else ttyfd = do_open(ttname);
    1209:     debug(F111,"ttopen ttyfd",ttname,ttyfd);
    1210:     if (ttyfd < 0) {            /* If couldn't open, fail. */
    1211: #ifdef ATT7300
    1212:     if (attmodem & DOGETY)      /* was getty(1m) running before us? */
    1213:       ongetty(ttnmsv);      /* yes, restart on tty line */
    1214:     attmodem &= ~DOGETY;        /* no phone in use, getty restored */
    1215: #else
    1216: #if ACUCNTRL
    1217:         /* Should put call to priv_on() here, but that would be risky! */
    1218:     acucntrl("enable",ttname);  /* acucntrl() program. */
    1219:     /* and priv_off() here... */
    1220: #endif /* ACUNTRL */
    1221: #endif /* ATT7300 */
    1222:
    1223:     signal(SIGINT,occt);        /* Put old Ctrl-C trap back. */
    1224:     if (errno == EACCES) {      /* Device is protected against user */
    1225:         perror(ttname);     /* Print message */
    1226:         debug(F111,"ttopen tty access denied",ttname,errno);
    1227:         return(-4);
    1228:     } else return(ttotmo ? -2 : -1);
    1229:     }
    1230:
    1231:     /* Make sure it's a real tty. */
    1232:     if (!isatty(ttyfd)) {
    1233:     fprintf(stderr,"%s is not a tty!\n",ttname);
    1234:     debug(F110,"ttopen not a tty",ttname,0);
    1235:     close(ttyfd);
    1236:     ttyfd = -1;
    1237:     signal(SIGINT,occt);
    1238:     return(-1);
    1239:     }
    1240:
    1241: #ifdef aegis
    1242:     /* Apollo C runtime claims that console pads are tty devices, which
    1243: 	 * is reasonable, but they aren't any good for packet transfer. */
    1244:     ios_$inq_type_uid((short)ttyfd, ttyuid, st);
    1245:     if (st.all != status_$ok) {
    1246:         fprintf(stderr, "problem getting tty object type: ");
    1247:         error_$print(st);
    1248:     } else if (ttyuid != sio_$uid) { /* reject non-SIO lines */
    1249:         close(ttyfd); ttyfd = -1;
    1250:         errno = ENOTTY; perror(ttname);
    1251:         signal(SIGINT,occt);
    1252:         return(-1);
    1253:     }
    1254: #endif /* aegis */
    1255:
    1256:     strncpy(ttnmsv,ttname,DEVNAMLEN);   /*  Keep copy of name locally. */
    1257:
    1258: /* Caller wants us to figure out if line is controlling tty */
    1259:
    1260:     if (*lcl < 0) {
    1261:     int x0 = 0, x1 = 0;
    1262:         if (strcmp(ttname,CTTNAM) == 0) {   /* "/dev/tty" always remote */
    1263:             xlocal = 0;
    1264:         debug(F111," ttname=CTTNAM",ttname,xlocal);
    1265:
    1266:     /* If any of 0, 1, or 2 not redirected, we can use ttyname() to get */
    1267:     /* the name of the controlling terminal... */
    1268:
    1269: /*
    1270:   Warning: on some UNIX systems (SVR4?), ttyname() reportedly opens /dev but
    1271:   never closes it.  If it is called often enough, we run out of file
    1272:   descriptors and subsequent open()'s of other devices or files can fail.
    1273: */
    1274:
    1275:         } else if ((x0 = isatty(0)) || (x1 = isatty(1)) || isatty(2)) {
    1276: #ifndef MINIX
    1277:         if (x0)
    1278:           x = ttyname(0);       /* and compare it with the */
    1279:         else if (x1)        /* tty device name. */
    1280:           x = ttyname(1);
    1281:         else x = ttyname(2);
    1282:             strncpy(cname,x,DEVNAMLEN); /* (copy from internal static buf) */
    1283:         debug(F110," cname",x,0);
    1284:             x = ttyname(ttyfd);         /* Gat real name of ttname. */
    1285:             xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1; /* Compare. */
    1286:         debug(F111," ttyname",x,xlocal);
    1287: #else
    1288:         xlocal = 1;         /* Can't do this test in MINIX */
    1289: #endif /* MINIX */
    1290:         } else {                        /* Else, if stdin redirected... */
    1291: #ifdef SVORPOSIX
    1292: /* System V provides nice ctermid() function to get name of controlling tty */
    1293:             ctermid(cname);             /* Get name of controlling terminal */
    1294:             debug(F110," ctermid",cname,0);
    1295:             x = ttyname(ttyfd);         /* Compare with name of comm line. */
    1296:             xlocal = (strncmp(x,cname,DEVNAMLEN) == 0) ? 0 : 1;
    1297:             debug(F111," ttyname",x,xlocal);
    1298: #else
    1299: /* Just assume local */
    1300:             xlocal = 1;
    1301: #endif /* SVORPOSIX */
    1302:             debug(F101," redirected stdin","",xlocal);
    1303:         }
    1304:     }
    1305:
    1306: #ifndef NOFDZERO
    1307: /* Note, the following code was added so that Unix "idle-line" snoopers */
    1308: /* would not think Kermit was idle when it was transferring files, and */
    1309: /* maybe log people out. */
    1310:     if (xlocal == 0) {          /* Remote mode */
    1311:     if (fdflag == 0) {      /* Standard i/o is not redirected */
    1312:         debug(F100,"ttopen setting ttyfd = 0","",0);
    1313:         close(ttyfd);       /* Use file descriptor 0 */
    1314:         ttyfd = 0;
    1315:     } else {            /* Standard i/o is redirected */
    1316:         debug(F101,"ttopen stdio redirected","",ttyfd);
    1317:     }
    1318:     }
    1319: #endif /* NOFDZERO */
    1320:
    1321: /* Now check if line is locked -- if so fail, else lock for ourselves */
    1322: /* Note: After having done this, don't forget to delete the lock if you */
    1323: /* leave ttopen() with an error condition. */
    1324:
    1325:     lkf = 0;                            /* Check lock */
    1326:     if (xlocal > 0) {
    1327:     int xx; int xpid;
    1328:         if ((xx = ttlock(ttname)) < 0) { /* Can't lock it. */
    1329:             debug(F111,"ttopen ttlock fails",ttname,xx);
    1330:             close(ttyfd);       /* Close the device. */
    1331:         ttyfd = -1;         /* Erase its file descriptor. */
    1332:         signal(SIGINT,occt);    /* Put old SIGINT back. */
    1333:         if (xx == -2) {     /* If lockfile says tty is in use, */
    1334:         char *p = malloc(200);  /* print an ls -l listing */
    1335:         if (p) {        /* if we can get space... */
    1336:             sprintf(p,"/bin/ls -l %s",flfnam);
    1337:             zsyscmd(p);     /* Get listing. */
    1338:             free(p);        /* free the space */
    1339:             xpid = ttrpid(flfnam); /* Try to read pid from lockfile */
    1340:             priv_off();     /* Turn privs back off. */
    1341:             if (xpid > -1) printf("pid = %d\n",xpid); /* show pid */
    1342:         }
    1343:         return(-5);     /* Code for device in use */
    1344:         } else return(-3);      /* Access denied */
    1345:         } else lkf = 1;
    1346:     }
    1347:
    1348: /* Got the line, now set the desired value for local. */
    1349:
    1350:     if (*lcl != 0) *lcl = xlocal;
    1351:
    1352: /* Some special stuff for v7... */
    1353:
    1354: #ifdef  V7
    1355: #ifndef MINIX
    1356:     if (kmem[TTY] < 0) {        /*  If open, then skip this.  */
    1357:     qaddr[TTY] = initrawq(ttyfd);   /* Init the queue. */
    1358:     if ((kmem[TTY] = open("/dev/kmem", 0)) < 0) {
    1359:         fprintf(stderr, "Can't read /dev/kmem in ttopen.\n");
    1360:         perror("/dev/kmem");
    1361:         exit(1);
    1362:     }
    1363:     }
    1364: #endif /* !MINIX */
    1365: #endif /* V7 */
    1366:
    1367: /* No failure returns after this point */
    1368:
    1369: #ifdef ultrix
    1370: #ifdef TIOCSINUSE
    1371:     if (xlocal && ioctl(ttyfd, TIOCSINUSE, NULL) < 0) {
    1372:     fprintf(stderr, "Can't set in-use flag on modem.\n");
    1373:     perror("TIOCSINUSE");
    1374:     }
    1375: #endif /* TIOCSINUSE */
    1376: #endif /* ultrix */
    1377:
    1378: /* Get tty device settings */
    1379:
    1380: #ifdef BSD44ORPOSIX         /* POSIX */
    1381:     tcgetattr(ttyfd,&ttold);
    1382:     debug(F101,"ttopen tcgetattr ttold.c_lflag","",ttold.c_lflag);
    1383:     tcgetattr(ttyfd,&ttraw);
    1384:     tcgetattr(ttyfd,&tttvt);
    1385: #else                   /* BSD, V7, and all others */
    1386: #ifdef ATTSV                /* AT&T UNIX */
    1387:     ioctl(ttyfd,TCGETA,&ttold);
    1388:     debug(F101,"ttopen ioctl TCGETA ttold.c_lflag","",ttold.c_lflag);
    1389:     ioctl(ttyfd,TCGETA,&ttraw);
    1390:     ioctl(ttyfd,TCGETA,&tttvt);
    1391: #else
    1392:     gtty(ttyfd,&ttold);
    1393:     debug(F101,"ttopen gtty ttold.sg_flags","",ttold.sg_flags);
    1394:
    1395: #ifdef sony_news            /* Sony NEWS */
    1396:     if (ioctl(ttyfd,TIOCKGET,&km_ext) < 0) { /* Get console Kanji mode */
    1397:     perror("ttopen error getting Kanji mode");
    1398:     debug(F101,"ttopen error getting Kanji mode","",0);
    1399:     km_ext = -1;            /* Make sure this stays undefined. */
    1400:     }
    1401: #endif /* sony_news */
    1402:
    1403: #ifdef TIOCGETC
    1404:     tcharf = 0;             /* In remote mode, also get */
    1405:     if (xlocal == 0) {          /* special characters */
    1406:     if (ioctl(ttyfd,TIOCGETC,&tchold) < 0) {
    1407:         debug(F100,"ttopen TIOCGETC failed","",0);
    1408:     } else {
    1409:         tcharf = 1;         /* It worked. */
    1410:         ioctl(ttyfd,TIOCGETC,&tchnoi); /* Get another copy */
    1411:         debug(F100,"ttopen TIOCGETC ok","",0);
    1412:     }
    1413:     }
    1414: #else
    1415:     debug(F100,"ttopen TIOCGETC not defined","",0);
    1416: #endif /* TIOCGETC */
    1417:
    1418: #ifdef TIOCGLTC
    1419:     ltcharf = 0;            /* In remote mode, also get */
    1420:     if (xlocal == 0) {          /* local special characters */
    1421:     if (ioctl(ttyfd,TIOCGLTC,&ltchold) < 0) {
    1422:         debug(F100,"ttopen TIOCGLTC failed","",0);
    1423:     } else {
    1424:         ltcharf = 1;        /* It worked. */
    1425:         ioctl(ttyfd,TIOCGLTC,&ltchnoi); /* Get another copy */
    1426:         debug(F100,"ttopen TIOCGLTC ok","",0);
    1427:     }
    1428:     }
    1429: #else
    1430:     debug(F100,"ttopen TIOCGLTC not defined","",0);
    1431: #endif /* TIOCGLTC */
    1432:
    1433: #ifdef TIOCLGET
    1434:     lmodef = 0;
    1435:     if (ioctl(ttyfd,TIOCLGET,&lmode) < 0) {
    1436:     debug(F100,"ttopen TIOCLGET failed","",0);
    1437:     } else {
    1438:     lmodef = 1;
    1439:     debug(F100,"ttopen TIOCLGET ok","",0);
    1440:     }
    1441: #endif /* TIOCLGET */
    1442:
    1443:     gtty(ttyfd,&ttraw);                 /* And a copy of it for packets*/
    1444:     gtty(ttyfd,&tttvt);                 /* And one for virtual tty service */
    1445:
    1446: #endif /* ATTSV */
    1447: #endif /* BSD44ORPOSIX */
    1448:
    1449:
    1450: /* Section for changing line discipline.  It's restored in ttres(). */
    1451:
    1452: #ifdef BSD41
    1453: /* For 4.1BSD only, force "old" tty driver, new one botches TANDEM. */
    1454:     { int k;
    1455:       ioctl(ttyfd, TIOCGETD, &ttld);    /* Get and save line discipline */
    1456:       debug(F101,"4.1bsd line discipline","",ttld);
    1457:       k = OTTYDISC;         /* Switch to "old" discipline */
    1458:       k = ioctl(ttyfd, TIOCSETD, &k);
    1459:       debug(F101,"4.1bsd tiocsetd","",k);
    1460:     }
    1461: #endif /* BSD41 */
    1462:
    1463: #ifdef aegis
    1464:     /* This was previously done before the last two TCGETA or gtty above,
    1465:      * in both the ATTSV and not-ATTSV case.  If it is not okay to have only
    1466:      * one copy if it here instead, give us a shout!
    1467:      */
    1468:     sio_$control((short)ttyfd, sio_$raw_nl, false, st);
    1469:     if (xlocal) {       /* ignore breaks from local line */
    1470:         sio_$control((short)ttyfd, sio_$int_enable, false, st);
    1471:         sio_$control((short)ttyfd, sio_$quit_enable, false, st);
    1472:     }
    1473: #endif /* aegis */
    1474:
    1475: #ifdef VXVE
    1476:     ttraw.c_line = 0;                   /* STTY line 0 for VX/VE */
    1477:     tttvt.c_line = 0;                   /* STTY line 0 for VX/VE */
    1478:     ioctl(ttyfd,TCSETA,&ttraw);
    1479: #endif /* vxve */
    1480:
    1481: /* If O_NDELAY was used during open(), then remove it now. */
    1482:
    1483: #ifdef O_NDELAY
    1484:     if (fcntl(ttyfd, F_GETFL, 0) & O_NDELAY) {
    1485:
    1486: #ifndef aegis
    1487:     if (fcntl(ttyfd,F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY) < 0 )
    1488:         perror("Can't unset O_NDELAY");
    1489: #endif /* aegis */
    1490:     /* Some systems, notably Xenix (don't know how common this is in
    1491: 	 * other systems), need special treatment to get rid of the O_NDELAY
    1492: 	 * behaviour on read() with respect to carrier presence (i.e. read()
    1493: 	 * returning 0 when carrier absent), even though the above fcntl()
    1494: 	 * is enough to make read() wait for input when carrier is present.
    1495: 	 * This magic, in turn, requires CLOCAL for working when the carrier
    1496: 	 * is absent. But if xlocal == 0, presumably you already have CLOCAL
    1497: 	 * or you have a carrier, otherwise you wouldn't be running this.
    1498: 	 */
    1499: #ifdef ATTSV
    1500: #ifdef BSD44
    1501:     tcsetattr(ttyfd, TCSADRAIN, &ttraw);
    1502: #else
    1503:     if (xlocal) {
    1504:         ttraw.c_cflag |= CLOCAL;
    1505:         ioctl(ttyfd, TCSETA, &ttraw);
    1506:     }
    1507: #endif /* BSD44 */
    1508: #endif /* ATTSV */
    1509: #ifndef SCO3R2
    1510: #ifndef OXOS
    1511: /* Reportedly lets uugetty grab the device in SCO UNIX 3.2 / XENIX 2.3 */
    1512:     close( priv_opn(ttname, O_RDWR) ); /* Magic to force change. */
    1513: #endif /* OXOS */
    1514: #endif /* SCO3R2 */
    1515:     }
    1516: #endif /* O_NDELAY */
    1517:
    1518: /* Instruct the system how to treat the carrier, and set a few other tty
    1519:  * parameters.
    1520:  *
    1521:  * This also undoes the temporary setting of CLOCAL that may have been done
    1522:  * for the close(open()) above (except in Xenix).  Also throw in ~ECHO, to
    1523:  * prevent the other end of the line from sitting there talking to itself,
    1524:  * producing garbage when the user performs a connect.
    1525:  *
    1526:  * SCO Xenix unfortunately seems to ignore the actual state of CLOCAL.
    1527:  * Now it thinks CLOCAL is always on. It seems the only real solution for
    1528:  * Xenix is to switch between the lower and upper case device names.
    1529:  *
    1530:  * This section may at some future time expand into setting a complete
    1531:  * collection of tty parameters, or call a function shared with ttpkt()/
    1532:  * ttvt() that does so.  On the other hand, the initial parameters are not
    1533:  * that important, since ttpkt() or ttvt() should always fix that before
    1534:  * any communication is done.  Well, we'll see...
    1535:  */
    1536:     if (xlocal) {
    1537:         curcarr = -2;
    1538:     carrctl(&ttraw, ttcarr == CAR_ON);
    1539:
    1540: #ifdef SVORPOSIX
    1541:     ttraw.c_lflag &= ~ECHO;
    1542:     ttold.c_lflag &= ~ECHO;
    1543: #ifdef BSD44ORPOSIX
    1544:     tcsetattr(ttyfd, TCSADRAIN, &ttraw);
    1545: #else
    1546:     ioctl(ttyfd, TCSETA, &ttraw);
    1547: #endif /* BSD44ORPOSIX */
    1548:
    1549: #else /* BSD, etc */
    1550:     ttraw.sg_flags &= ~ECHO;
    1551:     ttold.sg_flags &= ~ECHO;
    1552:     stty(ttyfd,&ttraw);
    1553: #endif /* SVORPOSIX */
    1554: /*	ttflui();  This fails for some reason  */
    1555:     }
    1556:
    1557:     /* Get current speed */
    1558:
    1559:     ttspeed = ttgspd();
    1560:     debug(F101,"ttopen ttspeed","",ttspeed);
    1561:
    1562:     /* Done, make entries in debug log, restore Ctrl-C trap, and return. */
    1563:
    1564:     debug(F101,"ttopen, ttyfd","",ttyfd);
    1565:     debug(F101," lcl","",*lcl);
    1566:     debug(F111," lock file",flfnam,lkf);
    1567:     signal(SIGINT,occt);
    1568:     return(0);
    1569: }
    1570:
    1571:
    1572: /*  D O _ O P E N  --  Do the right kind of open() call for the tty. */
    1573:
    1574: int
    1575: do_open(ttname) char *ttname; {
    1576:
    1577: #ifndef O_NDELAY            /* O_NDELAY not defined */
    1578:     return(priv_opn(ttname,2));
    1579: #else                   /* O_NDELAY defined */
    1580:
    1581: #ifdef ATT7300
    1582: /*
    1583:  Open comms line without waiting for carrier so initial call does not hang
    1584:  because state of "modem" is likely unknown at the initial call  -jrd.
    1585:  If this is needed for the getty stuff to work, and the open would not work
    1586:  without O_NDELAY when getty is still on, then this special case is ok.
    1587:  Otherwise, get rid of it. -ske
    1588: */
    1589:     return(priv_opn(ttname, O_RDWR | O_NDELAY));
    1590:
    1591: #else   /* !ATT7300 */
    1592:
    1593:     /* Normal case. Use O_NDELAY according to SET CARRIER. See ttscarr(). */
    1594:
    1595:     return(priv_opn(ttname, O_RDWR | ((ttcarr != CAR_ON) ? O_NDELAY : 0) ));
    1596:
    1597: #endif	/* !ATT7300 */
    1598: #endif	/* O_NDELAY */
    1599: }
    1600:
    1601: /*  T T C L O S  --  Close the TTY, releasing any lock.  */
    1602:
    1603: int
    1604: ttclos(foo) int foo; {          /* Arg req'd for signal() prototype */
    1605:     int x = 0;
    1606:
    1607:     debug(F101,"ttclos ttyfd","",ttyfd);
    1608:     if (ttyfd < 0) return(0);           /* Wasn't open. */
    1609:
    1610:     if (ttfdflg) return(0);     /* If we got ttyfd from another */
    1611:                     /* process, don't close it. */
    1612:     tvtflg = 0;
    1613: #ifdef  NETCONN
    1614:     if (netconn) {          /* Network connection. */
    1615:     debug(F100,"ttclos closing net","",0);
    1616:     netclos();          /* Close it. */
    1617:     netconn = 0;
    1618:     return(0);
    1619:     }
    1620: #endif	/* NETCONN */
    1621: #ifdef FT21
    1622:     if (xlocal) ioctl(ttyfd,TIOCHPCL, NULL);
    1623: #endif /* FT21 */
    1624: #ifdef ultrix
    1625:     if (xlocal) ioctl(ttyfd, TIOCNCAR, NULL);
    1626: #endif /* ultrix */
    1627:     if (xlocal) {
    1628:     debug(F100,"ttclos about to call ttunlck","",0);
    1629:         if (ttunlck())                  /* Release uucp-style lock */
    1630:       fprintf(stderr,"Warning, problem releasing lock\r\n");
    1631:     debug(F100,"ttclos about to call ttres","",0);
    1632:     }
    1633:     if (ttyfd > 0) {
    1634:     int xx;
    1635:     saval = signal(SIGALRM,timerh); /* Enable timer interrupt. */
    1636:     xx = alarm(5);          /* Allow 5 seconds for this. */
    1637:     debug(F101,"ttclos alarm","",xx);
    1638:     if (setjmp(sjbuf)) {        /* Timer went off? */
    1639:         x = -1;
    1640:     } else {            /* What we're really trying to do */
    1641:         if (xlocal) {
    1642:         tthang();       /* Hang up first, then... */
    1643:         ttres();        /* reset device modes. */
    1644:         }
    1645:         debug(F101,"ttclos about to call close","",ttyfd);
    1646:         close(ttyfd);       /* Close the device. */
    1647:         x = 1;
    1648:     }
    1649:     ttimoff();          /* Turn off timer. */
    1650:     if (x < 0) {
    1651:         fprintf(stderr,"?Timed out closing device: %s\n",ttnmsv);
    1652:         debug(F100,"ttclos timed out","",0);
    1653:     }
    1654:     }
    1655:     ttyfd = -1;                         /* Invalidate the file descriptor. */
    1656: #ifdef sony_news
    1657:     km_ext = -1;            /* Invalidate device's Kanji-mode */
    1658: #endif /* sony_news */
    1659:
    1660: /* For bidirectional lines, restore getty if it was there before. */
    1661:
    1662: #ifdef ACUCNTRL             /* 4.3BSD acucntrl() method. */
    1663:     acucntrl("enable",ttnmsv);      /* Enable getty on the device. */
    1664: #else
    1665: #ifdef ATT7300              /* ATT UNIX PC (3B1, 7300) method. */
    1666:     if (attmodem & DOGETY)              /* Was getty(1m) running before us? */
    1667:       ongetty(ttnmsv);          /* Yes, restart getty on tty line */
    1668:     attmodem &= ~DOGETY;                /* No phone in use, getty restored */
    1669: #endif /* ATT7300 */
    1670: #endif /* System-dependent getty-restoring methods */
    1671:
    1672:     debug(F100,"ttclos done","",0);
    1673:     return(0);
    1674: }
    1675:
    1676: /*  T T H A N G  --  Hangup phone line or network connection.  */
    1677: /*
    1678:   Returns:
    1679:   0 if it does nothing.
    1680:   1 if it believes that it hung up successfully.
    1681:  -1 if it believes that the hangup attempt failed.
    1682: */
    1683:
    1684: #define HUPTIME 500         /* Milliseconds for hangup */
    1685:
    1686: int
    1687: tthang() {
    1688:     int x = 0;              /* Sometimes used as return code. */
    1689: #ifndef POSIX
    1690:     int z;              /* worker */
    1691: #endif /* POSIX */
    1692:
    1693: #ifdef SVORPOSIX            /* AT&T, POSIX, HPUX declarations. */
    1694:     int spdsav;             /* for saving speed */
    1695:     int spdsavi;
    1696: #ifdef HPUX
    1697:     mflag dtr_down = 00000000000,
    1698:     modem_rtn;
    1699:     mflag modem_sav;
    1700:     char modem_state[64];
    1701: #endif /* HPUX */
    1702:     int flags;              /* fcntl flags */
    1703:     unsigned short ttc_save;
    1704: #endif /* SVORPOSIX */
    1705:
    1706:     if (ttyfd < 0) return(0);           /* Don't do this if not open  */
    1707:     if (xlocal < 1) return(0);      /* Don't do this if not local */
    1708:
    1709: #ifdef NETCONN
    1710:     if (netconn)            /* Network connection. */
    1711:       return((netclos() < 0) ? -1 : 1); /* Just close it. */
    1712: #endif /* NETCONN */
    1713:
    1714: /* From here down, we handle real tty devices. */
    1715:
    1716: #ifdef BSD44ORPOSIX
    1717: /* Should add some error checking here... */
    1718:     debug(F100,"tthang POSIX style","",0);
    1719:     spdsav = cfgetospeed(&ttcur);   /* Get current speed */
    1720:     spdsavi = cfgetispeed(&ttcur);  /* Get current speed */
    1721:     cfsetospeed(&ttcur,B0);     /* Replace by 0 */
    1722:     cfsetispeed(&ttcur,B0);
    1723:     if (tcsetattr(ttyfd,TCSADRAIN,&ttcur) == -1)
    1724:       debug(F100,"tthang tcsetattr fails","",errno);
    1725:     msleep(HUPTIME);            /* Sleep */
    1726:     cfsetospeed(&ttcur,spdsav);     /* Restore previous speed */
    1727:     cfsetispeed(&ttcur,spdsavi);
    1728:     tcsetattr(ttyfd,TCSADRAIN,&ttcur);
    1729:     return(1);
    1730:
    1731: #else /* BSD44ORPOSIX */
    1732:
    1733: #ifdef aegis                /* Apollo Aegis */
    1734:     sio_$control((short)ttyfd, sio_$dtr, false, st);    /* DTR down */
    1735:     msleep(HUPTIME);                    /* pause */
    1736:     sio_$control((short)ttyfd, sio_$dtr, true,  st);    /* DTR up */
    1737:     return(1);
    1738: #endif /* aegis */
    1739:
    1740: #ifdef ANYBSD               /* Any BSD version. */
    1741:     debug(F100,"tthang BSD style","",0);
    1742:     if (ioctl(ttyfd,TIOCCDTR,0) < 0) {  /* Clear DTR. */
    1743:     debug(F101,"tthang TIOCCDTR fails","",errno);
    1744:     return(-1);
    1745:     }
    1746:     msleep(HUPTIME);            /* For about 1/2 sec */
    1747:     errno = 0;
    1748:     x = ioctl(ttyfd,TIOCSDTR,0);    /* Restore DTR */
    1749:     if (x < 0) {
    1750:     /*
    1751: 	  For some reason, this tends to fail with "no such device or address"
    1752: 	  but the operation still works, probably because of the close/open
    1753: 	  later on.  So let's not scare the user unnecessarily here.
    1754: 	*/
    1755:     debug(F101,"tthang TIOCSDTR errno","",errno); /* Log the error */
    1756:     x = 1;              /* Pretend we succeeded */
    1757:     } else if (x == 0) x = 1;       /* Success */
    1758: #ifdef COMMENT
    1759: #ifdef FT21
    1760:     ioctl(ttyfd, TIOCSAVEMODES, 0);
    1761:     ioctl(ttyfd, TIOCHPCL, 0);
    1762:     close(ttyfd);           /* Yes, must do this twice */
    1763:     if ((ttyfd = open(ttnmsv,2)) < 0)   /* on Fortune computers... */
    1764:       return(-1);           /* (but why?) */
    1765:     else x = 1;
    1766: #endif /* FT21 */
    1767: #endif /* COMMENT */
    1768:     close(do_open(ttnmsv));     /* Clear i/o error condition */
    1769:     errno = 0;
    1770: #ifdef COMMENT
    1771: /* This is definitely dangerous.  Why was it here? */
    1772:     z = ttvt(ttspeed,ttflow);       /* Restore modes. */
    1773:     debug(F101,"tthang ttvt returns","",z);
    1774:     return(z < 0 ? -1 : 1);
    1775: #else
    1776:     return(x);
    1777: #endif /* COMMENT */
    1778: #endif /* ANYBSD */
    1779:
    1780: #ifdef ATTSV
    1781: /* AT&T UNIX section, includes HP-UX and generic AT&T System III/V... */
    1782:
    1783: #ifdef HPUX
    1784: /* Hewlett Packard allows explicit manipulation of modem signals. */
    1785:
    1786: #ifdef COMMENT
    1787: /* Old way... */
    1788:     debug(F100,"tthang HP-UX style","",0);
    1789:     if (ioctl(ttyfd,MCSETAF,&dtr_down) < 0)        /* lower DTR */
    1790:       return(-1);                          /* oops, can't. */
    1791:     msleep(HUPTIME);                       /* Pause half a second. */
    1792:     x = 1;                         /* Set return code */
    1793:     if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) {     /* Get line status. */
    1794:     if ((modem_rtn & MDCD) != 0)           /* Check if CD is low. */
    1795:       x = -1;                                  /* CD didn't drop, fail. */
    1796:     } else x = -1;
    1797:
    1798:     /* Even if above calls fail, RTS & DTR should be turned back on. */
    1799:     modem_rtn = MRTS | MDTR;
    1800:     if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) x = -1;
    1801:     return(x);
    1802: #else
    1803: /* New way, from Hellmuth Michaelis */
    1804:     debug(F100,"tthang HP-UX style, HPUXDEBUG","",0);
    1805:     if (ioctl(ttyfd,MCGETA,&modem_rtn) == -1) { /* Get current status. */
    1806:     debug(F100,"tthang HP-UX: can't get modem lines, NO HANGUP!","",0);
    1807:     return(-1);
    1808:     }
    1809:     sprintf(modem_state,"%#lx",modem_rtn);
    1810:     debug(F110,"tthang HP-UX: modem lines got = ",modem_state,0);
    1811:     modem_sav = modem_rtn;      /* save line status */
    1812:     modem_rtn &= ~MDTR;         /* DTR bit down */
    1813:     sprintf(modem_state,"%#lx",modem_rtn);
    1814:     debug(F110,"tthang HP-UX: modem lines lowered DTR = ",modem_state,0);
    1815:     if (ioctl(ttyfd,MCSETAF,&modem_rtn) < 0) { /* lower DTR */
    1816:     debug(F100,"tthang HP-UX: can't lower DTR!","",0);
    1817:     return(-1);         /* oops, can't. */
    1818:     }
    1819:     msleep(HUPTIME);            /* Pause half a second. */
    1820:     x = 1;              /* Set return code */
    1821:     if (ioctl(ttyfd,MCGETA,&modem_rtn) > -1) { /* Get line status. */
    1822:     sprintf(modem_state,"%#lx",modem_rtn);
    1823:     debug(F110,"tthang HP-UX: modem lines got = ",modem_state,0);
    1824:     if ((modem_rtn & MDCD) != 0) {  /* Check if CD is low. */
    1825:         debug(F100,"tthang HP-UX: DCD didn't get down!","",0);
    1826:         x = -1;         /* CD didn't drop, fail. */
    1827:     } else {
    1828:         debug(F100,"tthang HP-UX: DCD down!","",0);
    1829:     }
    1830:     } else {
    1831:     x = -1;
    1832:     debug(F100,"tthang HP-UX: can't get DCD status !","",0);
    1833:     }
    1834:
    1835:     /* Even if above calls fail, RTS & DTR should be turned back on. */
    1836:
    1837:     modem_sav |= (MRTS | MDTR);
    1838:     if (ioctl(ttyfd,MCSETAF,&modem_sav) < 0) {
    1839:     x = -1;
    1840:     debug(F100,"tthang HP-UX: can't set saved state |=(RTS | DTR)","",0);
    1841:     } else {
    1842:     sprintf(modem_state,"%#lx",modem_sav);
    1843:     debug(F110,"tthang HP-UX: final modem lines = ",modem_state,0);
    1844:     }
    1845:     return(x);
    1846: #endif /* COMMENT */
    1847:
    1848: #else /* AT&T but not HP-UX */
    1849:
    1850: /* SVID for AT&T System V R3 defines ioctl's for handling modem signals. */
    1851: /* It is not known how many, if any, systems actually implement them, */
    1852: /* so we include them here in ifdef's. */
    1853:
    1854: #ifndef _IBMR2
    1855: /*
    1856:   No modem-signal twiddling for IBM RT PC or RS/6000.
    1857:   In AIX 3.1 and earlier, the ioctl() call is broken.
    1858:   This code could be activated for AIX 3.1 with PTF 2006 or later
    1859:   (e.g. AIX 3.2), but close/open does the job too, so why bother.
    1860: */
    1861: #ifdef TIOCMBIS             /* Bit Set */
    1862: #ifdef TIOCMBIC             /* Bit Clear */
    1863: #ifdef TIOCM_DTR            /* DTR */
    1864:
    1865: /* Clear DTR, sleep 300 msec, turn it back on. */
    1866: /* If any of the ioctl's return failure, go on to the next section. */
    1867:
    1868:     z = TIOCM_DTR;          /* Code for DTR. */
    1869: #ifdef TIOCM_RTS            /* Lower RTS too if symbol is known. */
    1870:     z |= TIOCM_RTS;
    1871: #endif /* TIOCM_RTS */
    1872:
    1873:     debug(F101,"tthang TIOCM signal mask","",z);
    1874:     if (ioctl(ttyfd,TIOCMBIC,&z) > -1) {   /* Try to lower DTR. */
    1875:     debug(F100,"tthang TIOCMBIC ok","",0);
    1876:     msleep(HUPTIME);           /* Pause half a second. */
    1877:     if (ioctl(ttyfd,TIOCMBIS,&z) > -1) { /* Try to turn it back on. */
    1878:         debug(F100,"tthang TIOCMBIS ok","",0);
    1879: #ifndef CLSOPN
    1880:         return(1);          /* Success, done. */
    1881: #endif /* CLSOPN */
    1882:     } else {            /* Couldn't raise, continue. */
    1883:         debug(F101,"tthang TIOCMBIS errno","",errno);
    1884:     }
    1885:     } else {                /* Couldn't lower, continue. */
    1886:     debug(F101,"tthang TIOCMBIC errno","",errno);
    1887:     }
    1888: #endif /* TIOCM_DTR */
    1889: #endif /* TIOCMBIC */
    1890: #endif /* TIOCMBIS */
    1891: #endif /* _IBMR2 */
    1892: /*
    1893:   General AT&T UNIX case, not HPUX.  The following code is highly suspect.  No
    1894:   two AT&T-based systems seem to do this the same way.  The object is simply
    1895:   to turn off DTR and then turn it back on.  SVID says the universal method
    1896:   for turning off DTR is to set the speed to zero, and this does seem to do
    1897:   the trick in all cases.  But neither SVID nor any known man pages say how to
    1898:   turn DTR back on again.  Some variants, like most Xenix implementations,
    1899:   raise DTR again when the speed is restored to a nonzero value.  Others
    1900:   require the device to be closed and opened again, but this is risky because
    1901:   getty could seize the device during the instant it is closed.
    1902: */
    1903:
    1904: /* Return code for ioctl failures... */
    1905: #ifdef ATT6300
    1906:     x = 1;              /* ATT6300 doesn't want to fail... */
    1907: #else
    1908:     x = -1;
    1909: #endif /* ATT6300 */
    1910:
    1911:     debug(F100,"tthang get settings","",0);
    1912:     if (ioctl(ttyfd,TCGETA,&ttcur) < 0) /* Get current settings. */
    1913:       return(x);            /* Fail if this doesn't work. */
    1914:     if ((flags = fcntl(ttyfd,F_GETFL,0)) < 0) /* Get device flags. */
    1915:       return(x);
    1916:     ttc_save = ttcur.c_cflag;       /* Remember current speed. */
    1917:     spdsav = ttc_save & CBAUD;
    1918:     debug(F101,"tthang speed","",spdsav);
    1919:
    1920: #ifdef O_NDELAY
    1921:     debug(F100,"tthang turning O_NDELAY on","",0);
    1922:     fcntl(ttyfd, F_SETFL, flags | O_NDELAY); /* Activate O_NDELAY */
    1923: #endif /* O_NDELAY */
    1924:
    1925: #ifdef ATT7300 /* This is the way it is SUPPOSED to work */
    1926:     ttcur.c_cflag &= ~CBAUD;        /* Change the speed to zero.  */
    1927: #else
    1928: #ifdef RTAIX
    1929:     ttcur.c_cflag &= ~CBAUD;        /* Change the speed to zero.  */
    1930: #else          /* This way really works but may be dangerous */
    1931: #ifdef u3b2
    1932:     ttcur.c_cflag = ~(CBAUD|CLOCAL);    /* Special for AT&T 3B2s */
    1933:                     /* (CLOCAL must be OFF) */
    1934: #else
    1935: #ifdef SCO3R2               /* SCO UNIX 3.2 */
    1936: /*
    1937:   This is complete nonsense, but an SCO user claimed this change made
    1938:   hanging up work.  Comments from other SCO UNIX 3.2 users would be
    1939:   appreciated.
    1940: */
    1941:     ttcur.c_cflag = CBAUD|B0;
    1942: #else                   /* None of the above. */
    1943:     ttcur.c_cflag = CLOCAL|HUPCL;   /* Change all but these to zero */
    1944:                     /* (CLOCAL must be ON) */
    1945: #endif /* SCO3R2 */
    1946: #endif /* u3b2 */
    1947: #endif /* RTAIX */
    1948: #endif /* ATT7300 */
    1949:
    1950: #ifdef COMMENT
    1951:     /* and if none of those work, try one of these... */
    1952:     ttcur.c_cflag = 0;
    1953:     ttcur.c_cflag = CLOCAL;
    1954:     ttcur.c_cflag &= ~(CBAUD|HUPCL);
    1955:     ttcur.c_cflag &= ~(CBAUD|CREAD);
    1956:     ttcur.c_cflag &= ~(CBAUD|CREAD|HUPCL);
    1957:     /* or other combinations */
    1958: #endif /* COMMENT */
    1959:
    1960: #ifdef TCXONC
    1961:     debug(F100,"tthang TCXONC","",0);
    1962:     ioctl(ttyfd, TCXONC, 1);
    1963: #endif /* TCXONC */
    1964:
    1965: #ifdef TIOCSTART
    1966:     debug(F100,"tthang TIOCSTART","",0);
    1967:     ioctl(ttyfd, TIOCSTART, 0);
    1968: #endif /* TIOCSTART */
    1969:
    1970:     if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) { /* Fail if we can't. */
    1971:     fcntl(ttyfd, F_SETFL, flags);   /* Restore flags */
    1972:     return(-1);         /* before returning. */
    1973:     }
    1974:     msleep(300);            /* Give modem time to notice. */
    1975:
    1976: /* Now, even though it doesn't say this in SVID or any man page, we have */
    1977: /* to close and reopen the device.  This is not necessary for all systems, */
    1978: /* but it's impossible to predict which ones need it and which ones don't. */
    1979:
    1980: #ifdef ATT7300
    1981: /*
    1982:   Special handling for ATT 7300 UNIX PC and 3B1, which have "phone"
    1983:   related ioctl's for their internal modems.  attmodem has getty status and
    1984:   modem-in-use bit.  Reportedly the ATT7300/3B1 PIOCDISC call is necessary,
    1985:   but also ruins the file descriptor, and no other phone(7) ioctl call can fix
    1986:   it.  Whateverit does, it seems to escape detection with PIOCGETA and TCGETA.
    1987:   The only way to undo the damage is to close the fd and then reopen it.
    1988: */
    1989:     if (attmodem & ISMODEM) {
    1990:     debug(F100,"tthang attmodem close/open","",0);
    1991:     ioctl(ttyfd,PIOCUNHOLD,&dialer); /* Return call to handset. */
    1992:     ioctl(ttyfd,PIOCDISC,&dialer);  /* Disconnect phone. */
    1993:     close(ttyfd);           /* Close and reopen the fd. */
    1994:     ttyfd = priv_opn(ttnmsv, O_RDWR | O_NDELAY);
    1995:     attmodem &= ~ISMODEM;       /* Phone no longer in use. */
    1996:     }
    1997: #else /* !ATT7300 */
    1998: /* It seems we have to close and open the device for other AT&T systems */
    1999: /* too, and this is the place to do it.  The following code does the */
    2000: /* famous close(open(...)) magic by default.  If that doesn't work for you, */
    2001: /* then try uncommenting the following statement or putting -DCLSOPN in */
    2002: /* the makefile CFLAGS. */
    2003:
    2004: /* #define CLSOPN */
    2005:
    2006: #ifndef SCO32 /* Not needed by, and harmful to, SCO UNIX 3.2 / Xenix 2.3 */
    2007:
    2008: #ifdef O_NDELAY
    2009: #define OPENFLGS O_RDWR | O_NDELAY
    2010: #else
    2011: #define OPENFLGS O_RDWR
    2012: #endif
    2013:
    2014: #ifndef CLSOPN
    2015: /* This method is used by default, i.e. unless CLSOPN is defined. */
    2016: /* It is thought to be safer because there is no window where getty */
    2017: /* can seize control of the device.  The drawback is that it might not work. */
    2018:
    2019:     debug(F101,"tthang close(open()), OPENFLGS","",OPENFLGS);
    2020:     close(priv_opn(ttnmsv, OPENFLGS));
    2021:
    2022: #else
    2023: /* This method is used if you #define CLSOPN.  It is more likely to work */
    2024: /* than the previous method, but it's also more dangerous. */
    2025:
    2026:     debug(F101,"tthang close/open, OPENFLGS","",OPENFLGS);
    2027:     close(ttyfd);
    2028:     msleep(10);
    2029:     ttyfd = priv_opn(ttnmsv, OPENFLGS); /* Open it again */
    2030: #endif /* CLSOPN */
    2031: #undef OPENFLGS
    2032:
    2033: #endif /* SCO32 */
    2034: #endif /* ATT7300 */
    2035:
    2036: /* Now put all flags & modes back the way we found them. */
    2037: /* (Does the order of ioctl & fcntl matter ? ) */
    2038:
    2039:     debug(F100,"tthang restore settings","",0);
    2040:     ttcur.c_cflag = ttc_save;       /* Get old speed back. */
    2041:     if (ioctl(ttyfd,TCSETAF,&ttcur) < 0) /* ioctl parameters. */
    2042:       return(-1);
    2043: #ifdef O_NDELAY
    2044: /*
    2045:   This is required for IBM RT and RS/6000, probably helps elsewhere too (?).
    2046:   After closing a modem line, the modem will probably not be asserting
    2047:   carrier any more, so we should not require carrier any more.  If this
    2048:   causes trouble on non-IBM UNIXes, change the #ifdef to use _IBMR2 rather
    2049:   than O_NDELAY.
    2050: */
    2051:     flags &= ~O_NDELAY;         /* Don't require carrier on reopen */
    2052: #endif /* O_NDELAY */
    2053:     if (fcntl(ttyfd,F_SETFL,flags) < 0) /* fcntl parameters */
    2054:       return(-1);
    2055:
    2056:     return(1);
    2057: #endif /* not HPUX */
    2058: #endif /* ATTSV */
    2059: #endif /* BSD44ORPOSIX */
    2060: }
    2061:
    2062: /*
    2063:   Major change in 5A(174).  We used to use LPASS8, if it was defined, to
    2064:   allow 8-bit data and Xon/Xoff flow control at the same time.  But this
    2065:   LPASS8 business seems to have been causing trouble for everybody but me!
    2066:   For example, Annex terminal servers, commonly used with Encore computers,
    2067:   do not support LPASS8 even though the Encore itself does.  Ditto for many
    2068:   other terminal servers, TELNET connections, rlogin connections, etc etc.
    2069:   Now, reportedly, even vanilla 4.3 BSD systems can't do this right on their
    2070:   serial lines, even though LPASS8 is a feature of 4.3BSD.  So let's turn it
    2071:   off for everybody.  That means we goes back to using raw mode, with no
    2072:   flow control.  Phooey.
    2073:
    2074:   NOTE: This must be done before the first reference to LPASS8 in this file,
    2075:   and after the last #include statment.
    2076: */
    2077: #ifdef LPASS8
    2078: #undef LPASS8
    2079: #endif /* LPASS8 */
    2080:
    2081: /*  T T R E S  --  Restore terminal to "normal" mode.  */
    2082:
    2083: /* ske@pkmab.se: There are two choices for what this function should do.
    2084:  * (1) Restore the tty to current "normal" mode, with carrier treatment
    2085:  * according to ttcarr, to be used after every kermit command. (2) Restore
    2086:  * the tty to the state it was in before kermit opened it. These choices
    2087:  * conflict, since ttold can't hold both choices of tty parameters.  ttres()
    2088:  * is currently being called as in choice (1), but ttold basically holds
    2089:  * the initial parameters, as in (2), and the description at the beginning
    2090:  * of this file says (2).
    2091:  *
    2092:  * I don't think restoring tty parameters after all kermit commands makes
    2093:  * much of a difference.  Restoring them upon exit from kermit may be of
    2094:  * some use in some cases (when the line is not restored automatically on
    2095:  * close, by the operating system).
    2096:  *
    2097:  * I can't choose which one it should be, so I haven't changed it. It
    2098:  * probably works as it is, too. It would probably even work even with
    2099:  * ttres() entirely deleted...
    2100:  *
    2101:  * (from fdc: Actually, this function operates in remote mode too, so
    2102:  * it restores the console (command) terminal to whatever mode it was
    2103:  * in before packet operations began, so that commands work right again.)
    2104:  */
    2105: int
    2106: ttres() {                               /* Restore the tty to normal. */
    2107:     int x;
    2108:
    2109:     if (ttyfd < 0) return(-1);          /* Not open. */
    2110:
    2111:     if (ttfdflg) return(0);     /* Don't mess with terminal modes if */
    2112:                     /* we got ttyfd from another process */
    2113: #ifdef  NETCONN
    2114:     if (netconn) return (0);        /* Network connection, do nothing */
    2115: #endif	/* NETCONN */
    2116:
    2117: /* Real terminal device, so restore its original modes */
    2118:
    2119: #ifdef BSD44ORPOSIX         /* For POSIX like this */
    2120:     x = tcsetattr(ttyfd,TCSADRAIN,&ttold);
    2121: #else                   /* For all others... */
    2122: #ifdef ATTSV                            /* For AT&T versions... */
    2123:     x = ioctl(ttyfd,TCSETAW,&ttold);    /* Restore tty modes this way. */
    2124: #else
    2125:     msleep(HUPTIME);            /* This replaces sleep(1)... */
    2126:                     /* Put back sleep(1) if tty is */
    2127:                     /* messed up after close. */
    2128:
    2129: /* Here we restore the modes for BSD */
    2130:
    2131: #ifdef LPASS8               /* Undo "pass8" if it were done */
    2132:     if (lmodef) {
    2133:     if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
    2134:       debug(F100,"ttres TIOCLSET failed","",0);
    2135:     else
    2136:       debug(F100,"ttres TIOCLSET ok","",0);
    2137:     }
    2138: #endif /* LPASS8 */
    2139:
    2140: #ifdef CK_DTRCTS           /* Undo hardware flow if it were done */
    2141:     if (lmodef) {
    2142:     if (ioctl(ttyfd,TIOCLSET,&lmode) < 0)
    2143:       debug(F100,"ttres TIOCLSET failed","",0);
    2144:     else
    2145:       debug(F100,"ttres TIOCLSET ok","",0);
    2146:     }
    2147: #endif /* CK_DTRCTS */
    2148:
    2149: #ifdef TIOCGETC             /* Put back special characters */
    2150:     if (tcharf && (xlocal == 0)) {
    2151:     if (ioctl(ttyfd,TIOCSETC,&tchold) < 0)
    2152:       debug(F100,"ttres TIOCSETC failed","",0);
    2153:     else
    2154:       debug(F100,"ttres TIOCSETC ok","",0);
    2155:     }
    2156: #endif /* TIOCGETC */
    2157:
    2158: #ifdef TIOCGLTC             /* Put back local special characters */
    2159:     if (ltcharf && (xlocal == 0)) {
    2160:     if (ioctl(ttyfd,TIOCSLTC,&ltchold) < 0)
    2161:       debug(F100,"ttres TIOCSLTC failed","",0);
    2162:     else
    2163:       debug(F100,"ttres TIOCSLTC ok","",0);
    2164:     }
    2165: #endif /* TIOCGLTC */
    2166:
    2167:     x = stty(ttyfd,&ttold);             /* restore tty modes the old way. */
    2168:
    2169: #endif /* ATTSV */
    2170: #endif /* BSD44ORPOSIX */
    2171:
    2172:     debug(F101,"ttres tty modes restore","",x);
    2173:     if (x < 0) debug(F101,"ttres errno","",errno);
    2174:
    2175: #ifdef BSD41
    2176:     if (ttld > -1) {            /* Put back line discipline */
    2177:     x = ioctl(ttyfd, TIOCSETD, &ttld);
    2178:     debug(F101,"ttres line discipline restore","",x);
    2179:     if (x < 0) debug(F101,"...ioctl errno","",errno);
    2180:     ttld = -1;
    2181:     }
    2182: #endif /* BSD41 */
    2183:
    2184: #ifdef sony_news
    2185:     x = xlocal ? km_ext : km_con;   /* Restore Kanji mode. */
    2186:     if (x != -1) {          /* Make sure we know original modes. */
    2187:     if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
    2188:         perror("ttres can't set Kanji mode");
    2189:         debug(F101,"ttres error setting Kanji mode","",x);
    2190:         return(-1);
    2191:     }
    2192:     }
    2193:     debug(F100,"ttres set Kanji mode ok","",0);
    2194: #endif /* sony_news */
    2195:
    2196:     tvtflg = 0;             /* Invalidate terminal mode settings */
    2197:     return(x);
    2198: }
    2199:
    2200: /*  T T R P I D  --  Read pid from lockfile "name" (used by ttlock) */
    2201:
    2202: int
    2203: ttrpid(name) char *name; {
    2204:     int x, fd, pid;
    2205:
    2206:     fd = open(name,O_RDONLY);       /* Try to open lockfile. */
    2207:     if (fd > 0) {
    2208:
    2209: #ifdef PIDSTRING
    2210:     char buf[12];
    2211:     x = read(fd, buf, 11);      /* For HDP UUCP, read pid string */
    2212:     if (x < 0) return(-1);
    2213:     buf[11] = '\0';
    2214:     if (x == 11)
    2215:       x = sscanf(buf,"%d",&pid);    /* Get the integer pid from it. */
    2216: #else
    2217:     x = read(fd, (char *)&pid, sizeof(pid)); /* Else read integer pid */
    2218: #endif /* PIDSTRING */
    2219:
    2220:     if (x < 0) pid = -1;        /* Return any errors. */
    2221:     close(fd);          /* Close the lockfile. */
    2222:     } else pid = -1;
    2223:     return(pid);
    2224: }
    2225:
    2226: /*  T T L O C K  */
    2227:
    2228: /*
    2229:   This function attempts to coordinate use of the communication device with
    2230:   other copies of Kermit and any other program that follows the UUCP
    2231:   device-locking conventions, which, unfortunately, vary among different UNIX
    2232:   implementations.  The idea is to look for a file of a certain name, the
    2233:   "lockfile", in a certain directory.  If such a file is found, then the line
    2234:   is presumed to be in use, and Kermit should not use it.  If no such file is
    2235:   found, Kermit attempts to create one so that other programs will not use the
    2236:   same line at the same time.  Because the lockfile and/or the directory it's
    2237:   in might lack write permission for the person running Kermit, Kermit could
    2238:   find itself running setuid to uucp or other user that does have the
    2239:   necessary permissions.  At startup, Kermit has changed its effective uid to
    2240:   the user's real uid, and so ttlock() must switch back to the original
    2241:   effective uid in order to create the lockfile, and then back again to the
    2242:   real uid to prevent unauthorized access to other directories or files owned
    2243:   by the user the program is setuid to.
    2244:
    2245:   Totally rewritten for C-Kermit 5A to eliminate windows of vulnerability,
    2246:   based on suggestions from Warren Tucker.  Call with pointer to name of
    2247:   tty device.  Returns:
    2248:
    2249:    0 on success
    2250:   -1 on failure
    2251:
    2252:   Note: Once privileges are turned on using priv_on(), it is essential that
    2253:   they are turned off again before this function returns.
    2254: */
    2255: #ifdef SVR4             /* Lockfile uses device numbers. */
    2256: #ifndef LFDEVNO             /* Define this for SVR4 */
    2257: #ifndef AIXRS               /* But not for RS/6000 AIX 3.2 */
    2258: #define LFDEVNO             /* If anybody else needs it, */
    2259: #endif /* AIXRS */
    2260: #endif /* LFDEVNO */			/* define it here or on CC */
    2261: #endif /* SVR4 */			/* command line. */
    2262:
    2263: #ifdef LFDEVNO
    2264: #include <sys/stat.h>           /* For major() & minor() macros. */
    2265:                     /* Should be in <sys/types.h>. */
    2266: #ifndef major               /* If we didn't find it */
    2267: #ifdef SVR4             /* then for Sys V R4 */
    2268: #include <sys/mkdev.h>          /* look here */
    2269: #else                   /* or for Sunos versions */
    2270: #ifdef SUNOS4               /* ... */
    2271: #include <sys/sysmacros.h>      /* look here */
    2272: #else                   /* Otherwise take a chance: */
    2273: #define major(dev) ( (int) ( ((unsigned)(dev) >> 8) & 0xff))
    2274: #define minor(dev) ( (int) ( (dev) & 0xff))
    2275: #endif /* SUNOS4 */
    2276: #endif /* SVR4 */
    2277: #endif /* major */
    2278: #endif /* LFDEVNO */
    2279: /*
    2280:   Note for RS/6000: routines ttylock(devicename), ttyunlock(devicename),
    2281:   and ttylocked(devicename) from the standard library (libc.a) could be
    2282:   used here instead.  It's not clear whether there is any advantage in this.
    2283: */
    2284: static int
    2285: ttlock(ttdev) char *ttdev; {
    2286:     int x;
    2287:
    2288: #ifdef MINIX
    2289:     char *buf;
    2290: #endif /* MINIX */
    2291:
    2292: #ifdef NOUUCP
    2293:     strcpy(flfnam,"NOLOCK");
    2294:     haslock = 1;
    2295:     return(0);
    2296: #else /* !NOUUCP */
    2297:     int lockfd;             /* File descriptor for lock file. */
    2298:     PID_T pid;              /* Process id of this process. */
    2299:     int fpid;               /* pid found in existing lockfile. */
    2300:     int tries;              /* How many times we've tried... */
    2301: #ifdef LFDEVNO
    2302:     struct stat devbuf;         /* For device numbers (SVR4). */
    2303: #endif /* LFDEVNO */
    2304:
    2305: #ifdef PIDSTRING
    2306:     char pid_str[12];           /* My pid in string format. */
    2307: #endif /* PIDSTRING */
    2308:
    2309:     char *device, *devname;
    2310:
    2311: #define LFNAML 50           /* Max length for lock file name. */
    2312:     char lockfil[LFNAML];       /* Lock file name */
    2313: #ifdef RTAIX
    2314:     char lklockf[LFNAML];       /* Name for link to lock file  */
    2315: #endif /* RTAIX */
    2316:     char tmpnam[LFNAML+30];     /* Temporary lockfile name. */
    2317:     char *lockdir = LOCK_DIR;       /* Defined near top of this file, */
    2318:                     /* or on cc command line. */
    2319:
    2320:     haslock = 0;                        /* Not locked yet. */
    2321:     *flfnam = '\0';         /* Lockfile name is empty. */
    2322:     pid = getpid();         /* Get id of this process. */
    2323:
    2324: /*  Construct name of lockfile and temporary file */
    2325:
    2326: /*  device  = name of tty device without the path, e.g. "ttyh8" */
    2327: /*  lockfil = name of lock file, without path, e.g. "LCK..ttyh8" */
    2328:
    2329:     device = ((devname = xxlast(ttdev,'/')) != NULL ? devname+1 : ttdev);
    2330:
    2331: #ifdef ISIII                /* Interactive System III, PC/IX */
    2332:     strcpy(lockfil, device);
    2333: #else
    2334: #ifdef LFDEVNO              /* Lockfilename has device numbers. */
    2335:     if (stat(ttdev,&devbuf) < 0)
    2336:       return(-1);
    2337:     sprintf(lockfil,"LK.%03d.%03d.%03d",
    2338:         major(devbuf.st_dev),   /* inode */
    2339:         major(devbuf.st_rdev),  /* major device number */
    2340:         minor(devbuf.st_rdev)); /* minor device number */
    2341:
    2342: #else                   /* Others... */
    2343: #ifdef PTX              /* Dynix PTX */
    2344:     if (device != &ttdev[5] && strncmp(ttdev,"/dev/",5)==0) {
    2345:     sprintf(lockfil,"LCK..%.3s%s", &ttdev[5], device);
    2346:     } else
    2347: #endif /* PTX */
    2348:     sprintf(lockfil,"LCK..%s", device);
    2349: #ifdef M_XENIX              /* SCO Xenix */
    2350:     { int x; char c;
    2351:       x = (int)strlen(lockfil) - 1; /* Get last letter of device name. */
    2352:       if (x > 0) {          /* If it's uppercase, lower it. */
    2353:       c = lockfil[x];
    2354:       if (c >= 'A' && c <= 'Z') lockfil[x] += ('a' - 'A');
    2355:       }
    2356:     }
    2357: #endif /* M_XENIX */
    2358: #ifdef RTAIX
    2359:     strcpy(lklockf,device);
    2360: #endif /* RTAIX */
    2361: #endif /* LFDEVNO */
    2362: #endif /* ISIII */
    2363:
    2364: /*  flfnam = full lockfile pathname, e.g. "/usr/spool/uucp/LCK..ttyh8" */
    2365: /*  tmpnam = temporary unique, e.g. "/usr/spool/uucp/LTMP..pid" */
    2366:
    2367:     sprintf(flfnam,"%s/%s",lockdir,lockfil);
    2368: #ifdef RTAIX
    2369:     sprintf(lkflfn,"%s/%s",lockdir,lklockf);
    2370: #endif /* RTAIX */
    2371:     sprintf(tmpnam,"%s/LTMP.%05d",lockdir,(int) pid);
    2372:     debug(F110,"ttlock flfnam",flfnam,0);
    2373:     debug(F110,"ttlock tmpnam",tmpnam,0);
    2374:
    2375:     priv_on();              /* Turn on privileges if possible. */
    2376:     lockfd = creat(tmpnam, 0444);   /* Try to create temp lock file. */
    2377:     if (lockfd < 0) {           /* Create failed. */
    2378:     debug(F111,"ttlock creat failed",tmpnam,errno);
    2379:     if (errno == ENOENT) {
    2380:         perror(lockdir);
    2381:         printf("UUCP not installed or Kermit misconfigured\n");
    2382:     } else {
    2383:         perror(lockdir);
    2384:         unlink(tmpnam);     /* Get rid of the temporary file. */
    2385:     }
    2386:     priv_off();         /* Turn off privileges!!! */
    2387:     return(-1);         /* Return failure code. */
    2388:     }
    2389: /* Now write the pid into the temp lockfile in the appropriate format */
    2390:
    2391: #ifdef PIDSTRING            /* For Honey DanBer UUCP, */
    2392:     sprintf(pid_str,"%10d\n", (int) pid); /* Write pid as decimal string. */
    2393:     write(lockfd, pid_str, 11);
    2394:     debug(F111,"ttlock hdb pid string",pid_str,(int) pid);
    2395: #else                   /* Others use integer pid */
    2396:     write(lockfd, (char *)&pid, sizeof(pid) );
    2397:     debug(F111,"ttlock pid","",(int) pid);
    2398: #endif /* PIDSTRING */
    2399:
    2400: /* Now try to rename the temp file to the real lock file name. */
    2401: /* This will fail if a lock file of that name already exists.  */
    2402:
    2403:     close(lockfd);          /* Close the temp lockfile. */
    2404:     chmod(tmpnam,0444);         /* Permission for a valid lock. */
    2405:     tries = 0;
    2406:     while (!haslock && tries++ < 2) {
    2407:     haslock = (link(tmpnam,flfnam) == 0); /* Create a link to it. */
    2408:     if (haslock) {                /* If we got the lockfile */
    2409: #ifdef RTAIX
    2410:         link(flfnam,lkflfn);
    2411: #endif /* RTAIX */
    2412: #ifdef LOCKF
    2413: /*
    2414:   Advisory file locking works on SVR4, so we use it.  In fact, it is
    2415:   necessary in some cases, e.g. when SLIP is involved.
    2416: */
    2417:             while ( lockf(ttyfd, F_TLOCK, 0L) != 0 ) {
    2418:                 debug(F111, "ttlock: lockf returns errno", "", errno);
    2419:                 if ( (++tries >= 3) || (errno != EAGAIN) ) {
    2420:                     x = unlink(flfnam); /* remove the lockfile */
    2421:                     debug(F111,"ttlock unlink",flfnam,x);
    2422:                     haslock = 0;
    2423:             break;
    2424:         }
    2425:                 sleep(2);
    2426:         }
    2427:         if (haslock)        /* If we got an advisory lock */
    2428: #endif /* LOCKF */
    2429:           break;            /* We're done. */
    2430:
    2431:     } else {            /* We didn't create a new lockfile. */
    2432:         if ((fpid = ttrpid(flfnam)) > -1) { /* Read pid from old one. */
    2433:         if (fpid > 0) {
    2434:             debug(F101,"ttlock fpid","",fpid);
    2435:             errno = 0;      /* See if process still exists. */
    2436:             x = kill((PID_T) fpid,0);
    2437:             debug(F101,"ttlock kill","",x);
    2438:             debug(F101,"ttlock kill errno","",errno);
    2439:             if (x < 0 && errno == ESRCH) { /* pid is invalid */
    2440:             debug(F111,"ttlock removing stale lock",flfnam,
    2441:                   fpid);
    2442:             if (!backgrd)
    2443:               printf(
    2444:                 "Removing stale lock %s (pid %d terminated)\n",
    2445:                  flfnam,fpid);
    2446:             x = unlink(flfnam); /* remove the lockfile. */
    2447:             debug(F111,"ttlock unlink",flfnam,x);
    2448:             continue;   /* and go back and try again. */
    2449:             } else if ((x < 0 && errno == EPERM) || x == 0) {
    2450:             unlink(tmpnam); /* Delete the tempfile */
    2451:             debug(F101,"ttlock found tty locked","",fpid);
    2452:             priv_off(); /* Turn off privs */
    2453:             return(-2); /* Code for device is in use. */
    2454:             }
    2455:         } else {
    2456:             debug(F101,"ttlock can't get fpid","",fpid);
    2457:             break;
    2458:         }
    2459:         } else break;       /* Couldn't read pid from old file */
    2460:     }
    2461:     }
    2462:     unlink(tmpnam);         /* Unlink (remove) the temp file. */
    2463:     priv_off();             /* Turn off privs */
    2464:     return(haslock ? 0 : -1);       /* Return link's return code. */
    2465: #endif /* !NOUUCP */
    2466: }
    2467:
    2468: /*  T T U N L O C K  */
    2469:
    2470: static int
    2471: ttunlck() {                             /* Remove UUCP lockfile. */
    2472: #ifndef NOUUCP
    2473:     if (haslock && *flfnam) {
    2474:     priv_on();          /* Turn privileges on.  */
    2475:     unlink(flfnam);         /* Remove the lockfile. */
    2476: #ifdef RTAIX
    2477:     unlink(lkflfn);         /* Remove other lockfile */
    2478: #endif /* RTAIX */
    2479: #ifdef LOCKF
    2480:         (void) lockf(ttyfd, F_ULOCK, 0L); /* Remove advisory lock */
    2481: #endif /* LOCKF */
    2482:     *flfnam = '\0';         /* Erase the name. */
    2483:     priv_off();         /* Turn privileges off. */
    2484:     }
    2485: #endif /* !NOUUCP */
    2486:     return(0);
    2487: }
    2488:
    2489: /* 4.3BSD-style UUCP line direction control (Stan Barber, Rice U) */
    2490:
    2491: #ifdef ACUCNTRL
    2492: VOID
    2493: acucntrl(flag,ttname) char *flag, *ttname; {
    2494:     char x[DEVNAMLEN+32], *device, *devname;
    2495:
    2496:     if (strcmp(ttname,CTTNAM) == 0 || xlocal == 0) /* If not local, */
    2497:       return;               /* just return. */
    2498:     device = ((devname = xxlast(ttname,'/')) != NULL ? devname+1 : ttname);
    2499:     if (strncmp(device,"LCK..",4) == 0) device += 5;
    2500:     sprintf(x,"/usr/lib/uucp/acucntrl %s %s",flag,device);
    2501:     debug(F110,"called ",x,0);
    2502:     zsyscmd(x);
    2503: }
    2504: #endif /* ACUCNTRL */
    2505:
    2506: /*
    2507:   T T H F L O W  --  Set hardware flow control.
    2508: */
    2509: static int
    2510: tthflow(flow) int flow; {
    2511:     int x = 0;              /* Return code */
    2512:
    2513: /* There is no hardware flow control in POSIX. */
    2514:
    2515: /*
    2516:   For SunOS 4.0 and later in the BSD environment ...
    2517:
    2518:   The declarations are copied and interpreted from the System V header files,
    2519:   so we don't actually have to pull in all the System V junk when building
    2520:   C-Kermit for SunOS in the BSD environment, which would be dangerous because
    2521:   having those symbols defined would cause us to take the wrong paths through
    2522:   the code.  The code in this section is used in both the BSD and Sys V SunOS
    2523:   versions.
    2524: */
    2525: #ifdef SUNOS41
    2526: /*
    2527:   In SunOS 4.1 and later, we use the POSIX calls rather than ioctl calls
    2528:   because GNU CC uses different formats for the _IOxxx macros than regular CC;
    2529:   the POSIX forms work for both.  But the POSIX calls are not available in
    2530:   SunOS 4.0.
    2531: */
    2532: #define CRTSCTS 0x80000000      /* RTS/CTS flow control */
    2533: #define TCSANOW 0           /* Do it now */
    2534:
    2535:     struct termios {
    2536:     unsigned long c_iflag;      /* Input modes */
    2537:     unsigned long c_oflag;      /* Output modes */
    2538:     unsigned long c_cflag;      /* Control modes */
    2539:     unsigned long c_lflag;      /* Line discipline modes */
    2540:     char c_line;
    2541:     CHAR c_cc[17];
    2542:     };
    2543:     struct termios temp;
    2544:
    2545: _PROTOTYP( int tcgetattr, (int, struct termios *) );
    2546: _PROTOTYP( int tcsetattr, (int, int, struct termios *) );
    2547:
    2548: /*
    2549:   When CRTSCTS is set, SunOS won't do output unless both CTS and CD are
    2550:   asserted.  So we don't set CRTSCTS unless CD is up.  This should be OK,
    2551:   since we don't need RTS/CTS during dialing, and after dialing is complete,
    2552:   we should have CD.  If not, we still communicate, but without RTS/CTS.
    2553: */
    2554:       int mflags;                   /* Modem signal flags */
    2555:       if (ioctl(ttyfd,TIOCMGET,&mflags) > -1 && /* Get modem signals */
    2556:           (mflags & TIOCM_CAR)) {           /* Check for CD */
    2557:           debug(F100,"tthflow SunOS has CD","",0);
    2558:           if (tcgetattr(ttyfd, &temp) > -1 &&   /* Get device attributes */
    2559:           !(temp.c_cflag & CRTSCTS)) {      /* Check for RTS/CTS */
    2560:           temp.c_cflag |= CRTSCTS;      /* Not there, add it */
    2561:           x = tcsetattr(ttyfd,TCSANOW,&temp);
    2562:           }
    2563:       } else debug(F100,"tthflow SunOS no CD","",0);
    2564: #else
    2565: #ifdef SUNOS4
    2566: /*
    2567:   SunOS 4.0 (and maybe earlier?).  This code is dangerous because it
    2568:   prevents compilation with GNU gcc, which uses different formats for the
    2569:   _IORxxx macros than regular cc.  SunOS 4.1 and later can use the POSIX
    2570:   routines in the #else part of this clause, which work for both cc and gcc.
    2571: */
    2572: #define TCGETS _IOR(T, 8, struct termios) /* Get modes into termios struct */
    2573: #define TCSETS _IOW(T, 9, struct termios) /* Set modes from termios struct */
    2574: #define CRTSCTS 0x80000000        /* RTS/CTS flow control */
    2575:
    2576:     struct termios {
    2577:     unsigned long c_iflag;      /* Input modes */
    2578:     unsigned long c_oflag;      /* Output modes */
    2579:     unsigned long c_cflag;      /* Control modes */
    2580:     unsigned long c_lflag;      /* Line discipline modes */
    2581:     char c_line;
    2582:     CHAR c_cc[17];
    2583:     };
    2584:     struct termios temp;
    2585:
    2586:     if (ioctl(ttyfd,TCGETS,&temp) > -1) { /* Get current terminal modes. */
    2587:     temp.c_cflag |= CRTSCTS;    /* Add RTS/CTS to them. */
    2588:     x = ioctl(ttyfd,TCSETS,&temp);  /* Set them again. */
    2589:     }
    2590: #else                   /* Not SunOS 4.0 or later */
    2591: #ifdef ATTSV
    2592:     if (flow == FLO_RTSC) {
    2593:     /* RTS/CTS Flow control... */
    2594: #ifdef RTSXOFF
    2595:     /* This is the preferred way, according to SVID R4 */
    2596:     if (ioctl(ttyfd,TCGETX,&rctsx) > -1) {
    2597:         rctsx.x_hflag |= RTSXOFF | CTSXON;
    2598:         x = ioctl(ttyfd,TCSETX,&rctsx);
    2599:     }
    2600: #endif /* RTSXOFF */
    2601:     }
    2602:     if (flow == FLO_DTRC) {
    2603:     /* DTR/CD Flow control... */
    2604: #ifdef DTRXOFF
    2605:     /* This is straight out of SVID R4 */
    2606:     if (ioctl(ttyfd,TCGETX,&rctsx) > -1) {
    2607:         rctsx.x_hflag |= DTRXOFF | CDXON;
    2608:         x = ioctl(ttyfd,TCSETX,&rctsx);
    2609:     }
    2610: #endif /* DTRXOFF */
    2611:     }
    2612: #else /* not System V */
    2613: #ifdef CK_DTRCTS
    2614:     x = LDODTR | LDOCTS;        /* Found only on UTEK? */
    2615:     if (flow == FLO_DTRT) {     /* Use hardware flow control */
    2616:     if (lmodef) {
    2617:         x = ioctl(ttyfd,TIOCLBIS,&x);
    2618:         if (x < 0) {
    2619:             debug(F100,"hardflow TIOCLBIS error","",0);
    2620:         } else {
    2621:         lmodef++;
    2622:         debug(F100,"hardflow TIOCLBIS ok","",0);
    2623:         }
    2624:     }
    2625:     } else {
    2626:     if (lmodef) {
    2627:         x = ioctl(ttyfd,TIOCLBIC,&x);
    2628:         if (x < 0) {
    2629:             debug(F100,"hardflow TIOCLBIC error","",0);
    2630:         } else {
    2631:         lmodef++;
    2632:         debug(F100,"hardflow TIOCLBIC ok","",0);
    2633:         }
    2634:     }
    2635:     }
    2636: #endif /* CK_DTRCTS */
    2637: #endif /* ATTSV */
    2638: #endif /* SUNOS4 */
    2639: #endif /* SUNOS41 */
    2640:     return(x);
    2641: }
    2642:
    2643: /*  T T P K T  --  Condition the communication line for packets */
    2644: /*                 or for modem dialing */
    2645:
    2646: /*
    2647:   If called with speed > -1, also set the speed.
    2648:   Returns 0 on success, -1 on failure.
    2649:
    2650:   NOTE: the "xflow" parameter is supposed to be the currently selected
    2651:   type of flow control, but for historical reasons, this parameter is also
    2652:   used to indicate that we are dialing.  Therefore, when the true flow
    2653:   control setting is needed, we access the external variable "flow", rather
    2654:   than trusting our "xflow" argument.
    2655: */
    2656: int
    2657: #ifdef CK_ANSIC
    2658: ttpkt(long speed, int xflow, int parity)
    2659: #else
    2660: ttpkt(speed,xflow,parity) long speed; int xflow, parity;
    2661: #endif /* CK_ANSIC */
    2662: /* ttpkt */ {
    2663:     int s2;
    2664:     int s = -1;
    2665: #ifndef SVORPOSIX
    2666:     int x;
    2667: #endif /* SVORPOSIX */
    2668:     extern int flow;            /* REAL flow-control setting */
    2669:
    2670:     if (ttyfd < 0) return(-1);          /* Not open. */
    2671:
    2672:     debug(F101,"ttpkt parity","",parity);
    2673:     debug(F101,"ttpkt xflow","",xflow);
    2674:     debug(F101,"ttpkt speed","",(int) speed);
    2675:
    2676:     ttprty = parity;                    /* Let other tt functions see these. */
    2677:     ttpflg = 0;             /* Parity not sensed yet */
    2678:     ttpmsk = ttprty ? 0177 : 0377;  /* Parity stripping mask */
    2679:     ttspeed = speed;            /* Make global copy for this module */
    2680:
    2681: #ifdef NETCONN              /* Nothing to do for telnet */
    2682:     if (netconn) return (0);
    2683: #endif /* NETCONN */
    2684:
    2685:     if (ttfdflg && !isatty(ttyfd)) return(0);
    2686:
    2687: #ifndef SVORPOSIX           /* Berkeley, V7, etc. */
    2688: #ifdef LPASS8
    2689: /*
    2690:  For some reason, with BSD terminal drivers, you can't set FLOW to XON/XOFF
    2691:  after having previously set it to NONE without closing and reopening the
    2692:  device.  Unless there's something I overlooked below...
    2693: */
    2694:     if (ttflow == FLO_NONE && flow == FLO_XONX && xlocal == 0) {
    2695:     debug(F101,"ttpkt executing horrible flow kludge","",0);
    2696:     ttclos(0);          /* Close it */
    2697:     x = 0;
    2698:     ttopen(ttnmsv,&x,ttmdm,0);  /* Open it again */
    2699:     }
    2700: #endif /* LPASS8 */
    2701: #endif /* SVORPOSIX */
    2702:
    2703:     if (xflow != FLO_DIAL && xflow != FLO_DIAX)
    2704:       ttflow = xflow;           /* Now make this available too. */
    2705:
    2706:     if (xlocal) {
    2707:     s2 = (int) (speed / 10L);   /* Convert bps to cps */
    2708:     s = ttsspd(s2);         /* Check and set the speed */
    2709:     debug(F101,"ttpkt carrier","",xflow);
    2710:     carrctl(&ttraw, xflow != FLO_DIAL /* Carrier control */
    2711:         && (ttcarr == CAR_ON));
    2712:     tvtflg = 0;         /* So ttvt() will work next time */
    2713:     }
    2714:
    2715: #ifndef SVORPOSIX           /* BSD section */
    2716:     if (flow == FLO_RTSC ||     /* Hardware flow control */
    2717:     flow == FLO_DTRC ||
    2718:     flow == FLO_DTRT) {
    2719:     tthflow(flow);
    2720:     debug(F100,"ttpkt hard flow, TANDEM off, RAW on","",0);
    2721:     ttraw.sg_flags &= ~TANDEM;  /* Don't ask for it. */
    2722:     ttraw.sg_flags |= RAW;
    2723:     } else if (flow == FLO_NONE) {  /* No Xon/Xoff flow control */
    2724:     debug(F100,"ttpkt no flow, TANDEM off, RAW on","",0);
    2725:     ttraw.sg_flags &= ~TANDEM;  /* Don't ask for it. */
    2726:     ttraw.sg_flags |= RAW;
    2727: /* NOTE: We should also turn off hardware flow control here! */
    2728:     } else if (flow == FLO_KEEP) {  /* Keep device's original setting */
    2729:     debug(F100,"ttpkt keeping original TANDEM","",0);
    2730:     ttraw.sg_flags &= ~TANDEM;
    2731:     ttraw.sg_flags |= (ttold.sg_flags & TANDEM);
    2732: /* NOTE: We should also handle hardware flow control here! */
    2733:     }
    2734:
    2735: /* SET FLOW XON/XOFF is in effect, or SET FLOW KEEP resulted in Xon/Xoff */
    2736:
    2737:     if ((flow == FLO_XONX) || (ttraw.sg_flags & TANDEM)) {
    2738:     debug(F100,"ttpkt turning on TANDEM","",0);
    2739:     ttraw.sg_flags |= TANDEM;   /* So ask for it. */
    2740:
    2741: #ifdef LPASS8               /* Can pass 8-bit data through? */
    2742: /* If the LPASS8 local mode is available, then flow control can always  */
    2743: /* be used, even if parity is none and we are transferring 8-bit data.  */
    2744: /* But we only need to do all this if Xon/Xoff is requested. */
    2745: /* BUT... this tends not to work through IP or LAT connections, terminal */
    2746: /* servers, telnet, rlogin, etc, so it is currently disabled. */
    2747:     x = LPASS8;         /* If LPASS8 defined, then */
    2748:     debug(F100,"ttpkt executing LPASS8 code","",0);
    2749:     if (lmodef) {           /* TIOCLBIS must be too. */
    2750:         x = ioctl(ttyfd,TIOCLBIS,&x); /* Try to set LPASS8. */
    2751:         if (x < 0) {
    2752:         debug(F100,"ttpkt TIOCLBIS error","",0);
    2753:         } else {
    2754:         lmodef++;
    2755:         debug(F100,"ttpkt TIOCLBIS ok","",0);
    2756:         }
    2757:     }
    2758: /*
    2759:  But if we use LPASS8 mode, we must explicitly turn off
    2760:  terminal interrupts of all kinds.
    2761: */
    2762: #ifdef TIOCGETC             /* Not rawmode, */
    2763:     if (tcharf && (xlocal == 0)) {  /* must turn off */
    2764:         tchnoi.t_intrc = -1;    /* interrupt character */
    2765:         tchnoi.t_quitc = -1;    /* and quit character. */
    2766:         tchnoi.t_startc = 17;   /* Make sure xon */
    2767:         tchnoi.t_stopc = 19;    /* and xoff not ignored. */
    2768: #ifndef NOBRKC
    2769:         tchnoi.t_eofc = -1;     /* eof character. */
    2770:         tchnoi.t_brkc = -1;     /* brk character. */
    2771: #endif /* NOBRKC */
    2772:         if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
    2773:         debug(F100,"ttpkt TIOCSETC failed","",0);
    2774:         } else {
    2775:         tcharf = 1;
    2776:         debug(F100,"ttpkt TIOCSETC ok","",0);
    2777:         }
    2778: #ifdef COMMENT
    2779: /* only for paranoid debugging */
    2780:         if (tcharf) {
    2781:         struct tchars foo;
    2782:         char tchbuf[100];
    2783:         ioctl(0,TIOCGETC,&foo);
    2784:         sprintf(tchbuf,
    2785:             "intr=%d,quit=%d, start=%d, stop=%d, eof=%d, brk=%d",
    2786:             foo.t_intrc, foo.t_quitc, foo.t_startc,
    2787:             foo.t_stopc, foo.t_eofc,  foo.t_brkc);
    2788:         debug(F110,"ttpkt chars",tchbuf,0);
    2789:         }
    2790: #endif /* COMMENT */
    2791:     }
    2792:     ttraw.sg_flags |= CBREAK;   /* Needed for unknown reason */
    2793: #endif /* TIOCGETC */
    2794:
    2795: /* Prevent suspend during packet mode */
    2796: #ifdef TIOCGLTC             /* Not rawmode, */
    2797:     if (ltcharf && (xlocal == 0)) { /* must turn off */
    2798:         ltchnoi.t_suspc = -1;   /* suspend character */
    2799:         ltchnoi.t_dsuspc = -1;  /* and delayed suspend character */
    2800:         if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
    2801:         debug(F100,"ttpkt TIOCSLTC failed","",0);
    2802:         } else {
    2803:         ltcharf = 1;
    2804:         debug(F100,"ttpkt TIOCSLTC ok","",0);
    2805:         }
    2806:     }
    2807: #endif /* TIOCGLTC */
    2808:
    2809: #else /* LPASS8 not defined */
    2810:
    2811: /* Previously, BSD-based implementations always */
    2812: /* used rawmode for packets.  Now, we use rawmode only if parity is NONE. */
    2813: /* This allows the flow control requested above to actually work, but only */
    2814: /* if the user asks for parity (which also means they get 8th-bit quoting). */
    2815:
    2816:     if (parity) {           /* If parity, */
    2817:         ttraw.sg_flags &= ~RAW; /* use cooked mode */
    2818: #ifdef COMMENT
    2819: /* WHY??? */
    2820:         if (xlocal)
    2821: #endif /* COMMENT */
    2822:           ttraw.sg_flags |= CBREAK;
    2823:         debug(F101,"ttpkt cooked, cbreak, parity","",parity);
    2824: #ifdef TIOCGETC             /* Not rawmode, */
    2825:         if (tcharf && (xlocal == 0)) { /* must turn off */
    2826:         tchnoi.t_intrc = -1;    /* interrupt character */
    2827:         tchnoi.t_quitc = -1;    /* and quit character. */
    2828:         tchnoi.t_startc = 17;   /* Make sure xon */
    2829:         tchnoi.t_stopc = 19;    /* and xoff not ignored. */
    2830: #ifndef NOBRKC
    2831:         tchnoi.t_eofc = -1; /* eof character. */
    2832:         tchnoi.t_brkc = -1; /* brk character. */
    2833: #endif /* NOBRKC */
    2834:         if (ioctl(ttyfd,TIOCSETC,&tchnoi) < 0) {
    2835:             debug(F100,"ttpkt TIOCSETC failed","",0);
    2836:         } else {
    2837:             tcharf = 1;
    2838:             debug(F100,"ttpkt TIOCSETC ok","",0);
    2839:         }
    2840:         }
    2841: #endif /* TIOCGETC */
    2842: #ifdef TIOCGLTC             /* Not rawmode, */
    2843: /* Prevent suspend during packet mode */
    2844:         if (ltcharf && (xlocal == 0)) { /* must turn off */
    2845:         ltchnoi.t_suspc = -1;   /* suspend character */
    2846:         ltchnoi.t_dsuspc = -1;  /* and delayed suspend character */
    2847:         if (ioctl(ttyfd,TIOCSLTC,&tchnoi) < 0) {
    2848:             debug(F100,"ttpkt TIOCSLTC failed","",0);
    2849:         } else {
    2850:             ltcharf = 1;
    2851:             debug(F100,"ttpkt TIOCSLTC ok","",0);
    2852:         }
    2853:         }
    2854: #endif /* TIOCGLTC */
    2855:     } else {            /* If no parity, */
    2856:         ttraw.sg_flags |= RAW;  /* must use 8-bit raw mode. */
    2857:         debug(F101,"ttpkt setting rawmode, parity","",parity);
    2858:     }
    2859: #endif /* LPASS8 */
    2860:     } /* End of Xon/Xoff section */
    2861:
    2862:     /* Don't echo, don't map CR to CRLF on output, don't fool with case */
    2863: #ifdef LCASE
    2864:     ttraw.sg_flags &= ~(ECHO|CRMOD|LCASE);
    2865: #else
    2866:     ttraw.sg_flags &= ~(ECHO|CRMOD);
    2867: #endif /* LCASE */
    2868:
    2869: #ifdef TOWER1
    2870:     ttraw.sg_flags &= ~ANYP;            /* Must set this on old Towers */
    2871: #endif /* TOWER1 */
    2872:
    2873:     if (stty(ttyfd,&ttraw) < 0) return(-1); /* Set the new modes. */
    2874:     debug(F100,"ttpkt stty ok","",0);
    2875:
    2876: #ifdef sony_news
    2877:     x = xlocal ? km_ext : km_con;   /* Put line in ASCII mode. */
    2878:     if (x != -1) {          /* Make sure we know original modes. */
    2879:     x &= ~KM_TTYPE;
    2880:     x |= KM_ASCII;
    2881:     if (ioctl(ttyfd,TIOCKSET, &x) < 0) {
    2882:         perror("ttpkt can't set ASCII mode");
    2883:         debug(F101,"ttpkt error setting ASCII mode","",x);
    2884:         return(-1);
    2885:     }
    2886:     }
    2887:     debug(F100,"ttpkt set ASCII mode ok","",0);
    2888: #endif /* sony_news */
    2889:
    2890:     if (xlocal == 0)            /* Turn this off so we can read */
    2891:       signal(SIGINT,SIG_IGN);       /* Ctrl-C chars typed at console */
    2892:
    2893:     tvtflg = 0;             /* So ttvt() will work next time */
    2894:     return(0);
    2895:
    2896: #endif /* Not ATTSV or POSIX */
    2897:
    2898: /* AT&T UNIX and POSIX */
    2899:
    2900: #ifdef SVORPOSIX
    2901:     if (flow == FLO_XONX)       /* Xon/Xoff */
    2902:       ttraw.c_iflag |= (IXON|IXOFF);
    2903:     else if (flow == FLO_NONE)      /* None */
    2904:       /* NOTE: We should also turn off hardware flow control here! */
    2905:       ttraw.c_iflag &= ~(IXON|IXOFF);
    2906:     else if (flow == FLO_KEEP) {    /* Keep */
    2907:     ttraw.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
    2908:     ttraw.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
    2909:     /* NOTE: We should also handle hardware flow control here! */
    2910:     } else if (flow == FLO_RTSC ||  /* Hardware */
    2911:     flow == FLO_DTRC ||
    2912:     flow == FLO_DTRT)
    2913:       tthflow(flow);
    2914:
    2915:     ttraw.c_lflag &= ~(ICANON|ECHO);
    2916:     ttraw.c_lflag &= ~ISIG;     /* Do NOT check for interrupt chars */
    2917:     ttraw.c_lflag &= ~IEXTEN;       /* Turn off ^O/^V processing */
    2918:     ttraw.c_lflag |= NOFLSH;        /* Don't flush */
    2919:     ttraw.c_iflag |= (BRKINT|IGNPAR);
    2920: #ifdef ATTSV
    2921: #ifdef BSD44
    2922:     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP|IXANY);
    2923: #else
    2924:     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|INPCK|ISTRIP|IXANY);
    2925: #endif /* BSD44 */
    2926: #else /* POSIX */
    2927:     ttraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|INPCK|ISTRIP);
    2928: #endif /* ATTSV */
    2929:     ttraw.c_oflag &= ~OPOST;
    2930:     ttraw.c_cflag &= ~(CSIZE|PARENB);
    2931:     ttraw.c_cflag |= (CS8|CREAD|HUPCL);
    2932: #ifdef IX370
    2933:     ttraw.c_cc[4] = 48;  /* So Series/1 doesn't interrupt on every char */
    2934:     ttraw.c_cc[5] = 1;
    2935: #else
    2936: #ifndef VEOF    /* for DGUX this is VEOF, not VMIN */
    2937:     ttraw.c_cc[4] = 1;   /* [VMIN]  return max of this many characters or */
    2938: #else
    2939: #ifdef VMIN
    2940:     ttraw.c_cc[VMIN] = 1;
    2941: #endif /* VMIN */
    2942: #endif /* VEOF */
    2943: #ifndef VEOL    /* for DGUX this is VEOL, not VTIME */
    2944:     ttraw.c_cc[5] = 0;   /* [VTIME] when this many secs/10 expire w/no input */
    2945: #else
    2946: #ifdef VTIME
    2947:     ttraw.c_cc[VTIME] = 0;
    2948: #endif /* VTIME */
    2949: #endif /* VEOL */
    2950: #endif /* IX370 */
    2951:
    2952: #ifdef VINTR                /* Turn off interrupt character */
    2953:     if (xlocal == 0)            /* so ^C^C can break us out of */
    2954:       ttraw.c_cc[VINTR] = 0;        /* packet mode. */
    2955: #endif /* VINTR */
    2956:
    2957: #ifdef BSD44ORPOSIX
    2958:     if (xlocal && (s > 0)) {
    2959:     cfsetispeed(&ttraw,s);
    2960:     cfsetospeed(&ttraw,s);
    2961:     }
    2962:     if (tcsetattr(ttyfd,TCSADRAIN,&ttraw) < 0) return(-1);
    2963: #else /* ATTSV */
    2964:     if (xlocal && (s > 0)) {        /* set speed */
    2965:         ttraw.c_cflag &= ~CBAUD;
    2966:         ttraw.c_cflag |= s;
    2967:     }
    2968:     if (ioctl(ttyfd,TCSETAW,&ttraw) < 0) return(-1);  /* set new modes . */
    2969: #endif /* BSD44ORPOSIX */
    2970:     tvtflg = 0;
    2971:     return(0);
    2972: #endif /* ATTSV */
    2973: }
    2974:
    2975: /*  T T V T -- Condition communication line for use as virtual terminal  */
    2976:
    2977: int
    2978: #ifdef CK_ANSIC
    2979: ttvt(long speed, int flow)
    2980: #else
    2981: ttvt(speed,flow) long speed; int flow;
    2982: #endif /* CK_ANSIC */
    2983: /* ttvt */ {
    2984:     int s, s2;
    2985:
    2986:     debug(F101,"ttvt ttyfd","",ttyfd);
    2987:     debug(F101,"ttvt tvtflg","",tvtflg);
    2988:     debug(F101,"ttvt speed","",speed);
    2989:     if (ttyfd < 0) return(-1);          /* Not open. */
    2990: #ifdef NETCONN
    2991:     if (netconn) {
    2992:     tvtflg = 1;         /* Network connections */
    2993:     return(0);          /* require no special setup */
    2994:     }
    2995: #endif /* NETCONN */
    2996:
    2997:     if (tvtflg != 0 && speed == ttspeed && flow == ttflow && ttcarr == curcarr)
    2998:       return(0);            /* Already been called. */
    2999:
    3000:     if (ttfdflg && !isatty(ttyfd)) return(0);
    3001:
    3002:     if (xlocal) {           /* For external lines... */
    3003:     s2 = (int) (speed / 10L);
    3004:     s = ttsspd(s2);         /* Check/set the speed */
    3005:     carrctl(&tttvt, flow != FLO_DIAL /* Do carrier control */
    3006:         && (ttcarr == CAR_ON || (ttcarr == CAR_AUT && ttmdm != 0)));
    3007:     } else s = s2 = -1;
    3008:
    3009: #ifndef SVORPOSIX
    3010:     /* Berkeley, V7, etc */
    3011:     if (flow == FLO_RTSC ||     /* Hardware flow control */
    3012:     flow == FLO_DTRC ||
    3013:     flow == FLO_DTRT)
    3014:       tthflow(flow);
    3015:     if (flow == FLO_XONX) {     /* No Xon/Xoff flow control */
    3016:     tttvt.sg_flags |= TANDEM;   /* Ask for it. */
    3017:     } else if (flow == FLO_KEEP) {
    3018:     tttvt.sg_flags &= ~TANDEM;
    3019:     tttvt.sg_flags |= (ttold.sg_flags & TANDEM);
    3020: /* NOTE: We should also handle hardware flow control here! */
    3021:     } else if (flow == FLO_NONE) {
    3022:     tttvt.sg_flags &= ~TANDEM;  /* Don't ask for it. */
    3023: /* NOTE: We should also turn off hardware flow control here! */
    3024:     }
    3025:     tttvt.sg_flags |= RAW;              /* Raw mode in all cases */
    3026: #ifdef TOWER1
    3027:     tttvt.sg_flags &= ~(ECHO|ANYP);     /* No echo or parity */
    3028: #else
    3029:     tttvt.sg_flags &= ~ECHO;            /* No echo */
    3030: #endif /* TOWER1 */
    3031:
    3032:     if (stty(ttyfd,&tttvt) < 0)     /* Set the new modes */
    3033:       return(-1);
    3034:
    3035: #else /* It is ATTSV or POSIX */
    3036:
    3037:     if (flow == FLO_RTSC ||     /* Hardware flow control */
    3038:     flow == FLO_DTRC ||
    3039:     flow == FLO_DTRT)
    3040:       tthflow(flow);
    3041:     else if (flow == FLO_XONX)      /* Software flow control */
    3042:       tttvt.c_iflag |= (IXON|IXOFF);    /* On if requested. */
    3043:     else if (flow == FLO_KEEP) {
    3044:     tttvt.c_iflag &= ~(IXON|IXOFF); /* Turn off Xon/Xoff flags */
    3045:     tttvt.c_iflag |= (ttold.c_iflag & (IXON|IXOFF)); /* OR in old ones */
    3046:     /* NOTE: We should also handle hardware flow control here! */
    3047:     } else if (flow == FLO_NONE)    /* Off if NONE or hardware */
    3048:       tttvt.c_iflag &= ~(IXON|IXOFF);   /* requested. */
    3049:
    3050:     tttvt.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
    3051:     tttvt.c_iflag |= (IGNBRK|IGNPAR);
    3052: #ifdef ATTSV
    3053: #ifdef BSD44
    3054:     tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|BRKINT|INPCK|ISTRIP|IXANY);
    3055: #else
    3056:     tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|IUCLC|BRKINT|INPCK|ISTRIP|IXANY);
    3057: #endif /* BSD44 */
    3058: #else /* POSIX */
    3059:     tttvt.c_iflag &= ~(INLCR|IGNCR|ICRNL|BRKINT|INPCK|ISTRIP);
    3060: #endif /* ATTSV */
    3061:     tttvt.c_oflag &= ~OPOST;
    3062:     tttvt.c_cflag &= ~(CSIZE|PARENB);
    3063:     tttvt.c_cflag |= (CS8|CREAD|HUPCL);
    3064: #ifndef VEOF    /* DGUX termio has VEOF at entry 4, see comment above */
    3065:     tttvt.c_cc[4] = 1;
    3066: #else
    3067: #ifdef VMIN
    3068:     tttvt.c_cc[VMIN] = 1;
    3069: #endif /* VMIN */
    3070: #endif /* VEOF */
    3071: #ifndef VEOL    /* DGUX termio has VEOL at entry 5, see comment above */
    3072:     tttvt.c_cc[5] = 0;
    3073: #else
    3074: #ifdef VTIME
    3075:     tttvt.c_cc[VTIME] = 0;
    3076: #endif /* VTIME */
    3077: #endif /* VEOL */
    3078:
    3079: #ifdef BSD44ORPOSIX
    3080:     if (xlocal && (s > 0)) {
    3081:     cfsetispeed(&tttvt,s);
    3082:     cfsetospeed(&tttvt,s);
    3083:     }
    3084:     if (tcsetattr(ttyfd,TCSADRAIN,&tttvt) < 0) return(-1);
    3085: #else /* ATTSV */
    3086:     if (s > 0) {            /* Set speed */
    3087:         tttvt.c_cflag &= ~CBAUD;
    3088:         tttvt.c_cflag |= s;
    3089:     }
    3090:     if (ioctl(ttyfd,TCSETAW,&tttvt) < 0) return(-1);  /* set new modes . */
    3091: #endif /* BSD44ORPOSIX */
    3092: #endif /* ATTSV */
    3093:
    3094:     ttspeed = speed;            /* Done, remember how we were */
    3095:     ttflow = flow;          /* called, so we can decide how to */
    3096:     tvtflg = 1;             /* respond next time. */
    3097:
    3098:     debug(F101,"ttvt done","",tvtflg);
    3099:     return(0);
    3100: }
    3101:
    3102: /*  T T S S P D  --  Checks and sets transmission rate.  */
    3103:
    3104: /*  Call with speed in characters (not bits!) per second. */
    3105: /*  Returns internal speed code if successful, -1 otherwise. */
    3106:
    3107: int
    3108: ttsspd(cps) int cps; {
    3109:     int s, s2;
    3110:
    3111:     debug(F101,"ttsspd","",cps);
    3112:
    3113: #ifdef  NETCONN
    3114:     if (netconn) return (0);
    3115: #endif	/* NETCONN */
    3116:
    3117:     if (cps < 0) return(-1);
    3118:     s = s2 = -1;
    3119:
    3120:     /* First check that the given speed is valid. */
    3121:
    3122:     switch (cps) {
    3123: #ifndef MINIX
    3124:       case 0:   s = B0;    break;
    3125:       case 5:   s = B50;   break;
    3126:       case 7:   s = B75;   break;
    3127: #endif
    3128:       case 11:  s = B110;  break;
    3129: #ifndef MINIX
    3130:       case 15:  s = B150;  break;
    3131:       case 20:  s = B200;  break;
    3132: #endif
    3133:       case 30:  s = B300;  break;
    3134: #ifndef MINIX
    3135:       case 60:  s = B600;  break;
    3136: #endif
    3137:       case 120: s = B1200; break;
    3138: #ifndef MINIX
    3139:       case 180: s = B1800; break;
    3140: #endif
    3141:       case 240: s = B2400; break;
    3142:       case 480: s = B4800; break;
    3143: #ifndef MINIX
    3144:       case 888: s = B75; s2 = B1200; break; /* 888 = 75/1200 split speed */
    3145: #endif
    3146:       case 960: s = B9600; break;
    3147: #ifdef B19200
    3148:       case 1920: s = B19200; break;
    3149: #else
    3150: #ifdef EXTA
    3151:       case 1920: s = EXTA; break;
    3152: #endif
    3153: #endif
    3154: #ifdef B38400
    3155:       case 3840: s = B38400; break;
    3156: #else
    3157: #ifdef EXTB
    3158:       case 3840:   s = EXTB; break;
    3159: #endif
    3160: #endif
    3161:       default:
    3162:     return(-1);
    3163:     }
    3164:     /* Actually set the speed */
    3165:
    3166:     if (ttyfd > -1 && s > -1 && xlocal != 0) {
    3167:     if (s2 == -1) s2 = s;
    3168:
    3169: #ifdef BSD44ORPOSIX
    3170:     if (tcgetattr(ttyfd,&ttcur) < 0) return(-1);
    3171:     cfsetospeed(&ttcur,s);
    3172:     cfsetispeed(&ttcur,s2);
    3173:     cfsetospeed(&ttraw,s);
    3174:     cfsetispeed(&ttraw,s2);
    3175:     cfsetospeed(&tttvt,s);
    3176:     cfsetispeed(&tttvt,s2);
    3177:     cfsetospeed(&ttold,s);
    3178:     cfsetispeed(&ttold,s2);
    3179:     if (tcsetattr(ttyfd,TCSADRAIN,&ttcur) < 0) return(-1);
    3180: #else
    3181: #ifdef ATTSV
    3182:     if (cps == 888) return(-1); /* No split speeds, sorry. */
    3183:     if (ioctl(ttyfd,TCGETA,&ttcur) < 0) return(-1);
    3184:     ttcur.c_cflag &= ~CBAUD;
    3185:     ttcur.c_cflag |= s;
    3186:     tttvt.c_cflag &= ~CBAUD;
    3187:     tttvt.c_cflag |= s;
    3188:     ttraw.c_cflag &= ~CBAUD;
    3189:     ttraw.c_cflag |= s;
    3190:     ttold.c_cflag &= ~CBAUD;
    3191:     ttold.c_cflag |= s;
    3192:     if (ioctl(ttyfd,TCSETAW,&ttcur) < 0) return(-1);
    3193: #else
    3194:     if (gtty(ttyfd,&ttcur) < 0) return(-1);
    3195:     ttcur.sg_ospeed = s; ttcur.sg_ispeed = s2;
    3196:     tttvt.sg_ospeed = s; tttvt.sg_ispeed = s2;
    3197:     ttraw.sg_ospeed = s; ttraw.sg_ispeed = s2;
    3198:     ttold.sg_ospeed = s; ttold.sg_ispeed = s2;
    3199:     if (stty(ttyfd,&ttcur) < 0) return(-1);
    3200: #endif /* ATTSV */
    3201: #endif /* BSD44ORPOSIX */
    3202:     }
    3203:     return(s);
    3204: }
    3205:
    3206: /* T T G S P D  -  Get speed of currently selected tty line  */
    3207:
    3208: /*
    3209:   Unreliable.  After SET LINE, it returns an actual speed, but not the real
    3210:   speed.  Apparently it always returns the line's nominal speed, from
    3211:   /etc/ttytab.  Even if you SET SPEED to something else, this function might
    3212:   not notice.
    3213: */
    3214: long
    3215: ttgspd() {              /* Get current tty speed */
    3216:     int s; long ss;
    3217:     char temp[12];
    3218:
    3219: #ifdef NETCONN
    3220:     if (netconn) return(-1);        /* -1 if network connection */
    3221: #endif /* NETCONN */
    3222:
    3223:     if (ttyfd < 0) {
    3224: #ifdef BSD44ORPOSIX
    3225:     s = cfgetospeed(&ccold);
    3226: #else
    3227: #ifdef ATTSV
    3228:     s = ccold.c_cflag & CBAUD;
    3229: #else
    3230:     s = ccold.sg_ospeed;        /* (obtained by congm()) */
    3231: #endif /* ATTSV */
    3232: #endif /* BSD44ORPOSIX */
    3233:
    3234:     } else {
    3235: #ifdef BSD44ORPOSIX
    3236:     if (tcgetattr(ttyfd,&ttcur) < 0) return(-1);
    3237:     s = cfgetospeed(&ttcur);
    3238: #else
    3239: #ifdef ATTSV
    3240:     if (ioctl(ttyfd,TCGETA,&ttcur) < 0) return(-1);
    3241:     s = ttcur.c_cflag & CBAUD;
    3242: #else
    3243:     if (gtty(ttyfd,&ttcur) < 0) return(-1);
    3244:     s = ttcur.sg_ospeed;
    3245: #endif /* ATTSV */
    3246: #endif /* BSD44ORPOSIX */
    3247:     }
    3248:     debug(F101,"ttgspd ttyfd","",ttyfd);
    3249:     debug(F101,"ttgspd code","",s);
    3250:     switch (s) {
    3251: #ifdef B0
    3252:       case B0:    ss = 0L; break;
    3253: #endif /* B0 */
    3254:
    3255: #ifndef MINIX
    3256: /*
    3257:  MINIX defines the Bxx symbols to be bps/100, so B50==B75, B110==B134==B150,
    3258:  etc, making for many "duplicate case in switch" errors, which are fatal.
    3259: */
    3260: #ifdef B50
    3261:       case B50:   ss = 50L; break;
    3262: #endif
    3263: #ifdef B75
    3264:       case B75:   ss = 75L; break;
    3265: #endif
    3266: #endif /* MINIX */
    3267:
    3268: #ifdef B110
    3269:       case B110:  ss = 110L; break;
    3270: #endif
    3271:
    3272: #ifndef MINIX
    3273: #ifdef B134
    3274:       case B134:  ss = 134L; break;
    3275: #endif
    3276: #ifdef B150
    3277:       case B150:  ss = 150L; break;
    3278: #endif
    3279: #endif /* MINIX */
    3280:
    3281: #ifdef B200
    3282:       case B200:  ss = 200L; break;
    3283: #endif
    3284:
    3285: #ifdef B300
    3286:       case B300:  ss = 300L; break;
    3287: #endif
    3288: #ifdef B600
    3289:       case B600:  ss = 600L; break;
    3290: #endif
    3291: #ifdef B1200
    3292:       case B1200: ss = 1200L; break;
    3293: #endif
    3294: #ifdef B1800
    3295:       case B1800: ss = 1800L; break;
    3296: #endif
    3297: #ifdef B2400
    3298:       case B2400: ss = 2400L; break;
    3299: #endif
    3300: #ifdef B4800
    3301:       case B4800: ss = 4800L; break;
    3302: #endif
    3303: #ifdef B9600
    3304:       case B9600: ss = 9600L; break;
    3305: #endif
    3306: #ifdef B19200
    3307:       case B19200: ss = 19200L; break;
    3308: #else
    3309: #ifdef EXTA
    3310:       case EXTA: ss = 19200L; break;
    3311: #endif
    3312: #endif
    3313:
    3314: #ifndef MINIX
    3315: #ifdef B38400
    3316:       case B38400: ss = 38400L; break;
    3317: #else
    3318: #ifdef EXTB
    3319:       case EXTB: ss = 38400L; break;
    3320: #endif
    3321: #endif
    3322: #endif /* MINIX */
    3323:
    3324:       default:
    3325:     ss = -1; break;
    3326:     }
    3327:     sprintf(temp,"%ld",ss);
    3328:     debug(F110,"speed",temp,0);
    3329:     return(ss);
    3330: }
    3331:
    3332: /* ckumyr.c by Kristoffer Eriksson, ske@pkmab.se, 15 Mar 1990. */
    3333:
    3334: #ifdef COHERENT
    3335: #ifdef FIONREAD
    3336: #undef FIONREAD
    3337: #endif
    3338: #define FIONREAD TIOCQUERY
    3339: #define PEEKTYPE int
    3340: #else
    3341: #define PEEKTYPE long
    3342: #endif /* COHERENT */
    3343:
    3344: #ifdef MYREAD
    3345:
    3346: /* Private buffer for myread() and its companions.  Not for use by anything
    3347:  * else.  ttflui() is allowed to reset them to initial values.  ttchk() is
    3348:  * allowed to read my_count.
    3349:  *
    3350:  * my_item is an index into mybuf[].  Increment it *before* reading mybuf[].
    3351:  *
    3352:  * A global parity mask variable could be useful too.  We could use it to
    3353:  * let myread() strip the parity on its own, instead of stripping sign
    3354:  * bits as it does now.
    3355:  */
    3356: #define MYBUFLEN 256
    3357: #ifdef SUNX25
    3358: /*
    3359:   On X.25 connections, there is an extra control byte at the beginning.
    3360: */
    3361: static CHAR x25buf[MYBUFLEN+1];     /* Communication device input buffer */
    3362: static CHAR  *mybuf = x25buf+1;
    3363: #else
    3364: static CHAR mybuf[MYBUFLEN];
    3365: #endif /* SUNX25 */
    3366:
    3367: static int my_count = 0;        /* Number of chars still in mybuf */
    3368: static int my_item = -1;        /* Last index read from mybuf[] */
    3369:
    3370: /* myread() -- Efficient read of one character from communications line.
    3371:  *
    3372:  * Uses a private buffer to minimize the number of expensive read() system
    3373:  * calls.  Essentially performs the equivalent of read() of 1 character, which
    3374:  * is then returned.  By reading all available input from the system buffers
    3375:  * to the private buffer in one chunk, and then working from this buffer, the
    3376:  * number of system calls is reduced in any case where more than one character
    3377:  * arrives during the processing of the previous chunk, for instance high
    3378:  * baud rates or network type connections where input arrives in packets.
    3379:  * If the time needed for a read() system call approaches the time for more
    3380:  * than one character to arrive, then this mechanism automatically compensates
    3381:  * for that by performing bigger read()s less frequently.  If the system load
    3382:  * is high, the same mechanism compensates for that too.
    3383:  *
    3384:  * myread() is a macro that returns the next character from the buffer.  If the
    3385:  * buffer is empty, mygetbuf() is called.  See mygetbuf() for possible error
    3386:  * returns.
    3387:  *
    3388:  * This should be efficient enough for any one-character-at-a-time loops.
    3389:  * For even better efficiency you might use memcpy()/bcopy() or such between
    3390:  * buffers (since they are often better optimized for copying), but it may not
    3391:  * be worth it if you have to take an extra pass over the buffer to strip
    3392:  * parity and check for CTRL-C anyway.
    3393:  *
    3394:  * Note that if you have been using myread() from another program module, you
    3395:  * may have some trouble accessing this macro version and the private variables
    3396:  * it uses.  In that case, just add a function in this module, that invokes the
    3397:  * macro.
    3398:  */
    3399: #define myread()  (--my_count < 0 ? mygetbuf() : 255 & (int)mybuf[++my_item])
    3400:
    3401: /* Specification: Push back up to one character onto myread()'s queue.
    3402:  *
    3403:  * This implementation: Push back characters into mybuf. At least one character
    3404:  * must have been read through myread() before myunrd() may be used.  After
    3405:  * EOF or read error, again, myunrd() can not be used.  Sometimes more than
    3406:  * one character can be pushed back, but only one character is guaranteed.
    3407:  * Since a previous myread() must have read its character out of mybuf[],
    3408:  * that guarantees that there is space for at least one character.  If push
    3409:  * back was really needed after EOF, a small addition could provide that.
    3410:  *
    3411:  * myunrd() is currently not called from anywhere inside kermit...
    3412:  */
    3413: #ifdef NOTUSED
    3414: myunrd(ch) CHAR ch; {
    3415:     if (my_item >= 0) {
    3416:     mybuf[my_item--] = ch;
    3417:     ++my_count;
    3418:     }
    3419: }
    3420: #endif
    3421:
    3422: /* mygetbuf() -- Fill buffer for myread() and return first character.
    3423:  *
    3424:  * This function is what myread() uses when it can't get the next character
    3425:  * directly from its buffer.  First, it calls a system dependent myfillbuf()
    3426:  * to read at least one new character into the buffer, and then it returns
    3427:  * the first character just as myread() would have done.  This function also
    3428:  * is responsible for all error conditions that myread() can indicate.
    3429:  *
    3430:  * Returns: When OK	=> a positive character, 0 or greater.
    3431:  *	    When EOF	=> -2.
    3432:  *	    When error	=> -3, error code in errno.
    3433:  *
    3434:  * Older myread()s additionally returned -1 to indicate that there was nothing
    3435:  * to read, upon which the caller would call myread() again until it got
    3436:  * something.  The new myread()/mygetbuf() always gets something.  If it
    3437:  * doesn't, then make it do so!  Any program that actually depends on the old
    3438:  * behaviour will break.
    3439:  *
    3440:  * The older version also used to return -2 both for EOF and other errors,
    3441:  * and used to set errno to 9999 on EOF.  The errno stuff is gone, EOF and
    3442:  * other errors now return different results, although Kermit currently never
    3443:  * checks to see which it was.  It just disconnects in both cases.
    3444:  *
    3445:  * Kermit lets the user use the quit key to perform some special commands
    3446:  * during file transfer.  This causes read(), and thus also mygetbuf(), to
    3447:  * finish without reading anything and return the EINTR error.  This should
    3448:  * be checked by the caller.  Mygetbuf() could retry the read() on EINTR,
    3449:  * but if there is nothing to read, this could delay Kermit's reaction to
    3450:  * the command, and make Kermit appear unresponsive.
    3451:  *
    3452:  * The debug() call should be removed for optimum performance.
    3453:  */
    3454: int
    3455: mygetbuf() {
    3456:     my_count = myfillbuf();
    3457:     debug(F101, "myfillbuf read", "", my_count);
    3458:     if (my_count <= 0)
    3459:       return(my_count < 0 ? -3 : -2);
    3460:     --my_count;
    3461:     return(255 & (int)mybuf[my_item = 0]);
    3462: }
    3463:
    3464: /* myfillbuf():
    3465:  * System-dependent read() into mybuf[], as many characters as possible.
    3466:  *
    3467:  * Returns: OK => number of characters read, always more than zero.
    3468:  *          EOF => 0
    3469:  *          Error => -1, error code in errno.
    3470:  *
    3471:  * If there is input available in the system's buffers, all of it should be
    3472:  * read into mybuf[] and the function return immediately.  If no input is
    3473:  * available, it should wait for a character to arrive, and return with that
    3474:  * one in mybuf[] as soon as possible.  It may wait somewhat past the first
    3475:  * character, but be aware that any such delay lengthens the packet turnaround
    3476:  * time during kermit file transfers.  Should never return with zero characters
    3477:  * unless EOF or irrecoverable read error.
    3478:  *
    3479:  * Correct functioning depends on the correct tty parameters being used.
    3480:  * Better control of current parameters is required than may have been the
    3481:  * case in older Kermit releases.  For instance, O_NDELAY (or equivalent) can
    3482:  * no longer be sometimes off and sometimes on like it used to, unless a
    3483:  * special myfillbuf() is written to handle that.  Otherwise the ordinary
    3484:  * myfillbuf()s may think they have come to EOF.
    3485:  *
    3486:  * If your system has a facility to directly perform the functioning of
    3487:  * myfillbuf(), then use it.  If the system can tell you how many characters
    3488:  * are available in its buffers, then read that amount (but not less than 1).
    3489:  * If the system can return a special indication when you try to read without
    3490:  * anything to read, while allowing you to read all there is when there is
    3491:  * something, you may loop until there is something to read, but probably that
    3492:  * is not good for the system load.
    3493:  */
    3494:
    3495: #ifdef SVORPOSIX
    3496:     /* This is for System III/V with VMIN>0, VTIME=0 and O_NDELAY off,
    3497: 	 * and CLOCAL set any way you like.  This way, read() will do exactly
    3498: 	 * what is required by myfillbuf(): If there is data in the buffers
    3499: 	 * of the O.S., all available data is read into mybuf, up to the size
    3500: 	 * of mybuf.  If there is none, the first character to arrive is
    3501: 	 * awaited and returned.
    3502: 	 */
    3503: int
    3504: myfillbuf() {
    3505: #ifdef sxaE50
    3506:     /* From S. Dezawa at Fujifilm in Japan.  I don't know why this is */
    3507:     /* necessary for the sxa E50, but it is. */
    3508:     return read(ttyfd, mybuf, 255);
    3509: #else
    3510:     /* sizeof(mybuf) should be MYBUFL == 256 */
    3511:     return read(ttyfd, mybuf, sizeof(mybuf));
    3512: #endif /* sxaE50 */
    3513: }
    3514:
    3515: #else /* not AT&T or POSIX */
    3516:
    3517: #ifdef aegis
    3518:     /* This is quoted from the old myread().  The semantics seem to be
    3519: 	 * alright, but maybe errno would not need to be set even when
    3520: 	 * there is no error?  I don't know aegis.
    3521: 	 */
    3522: int
    3523: myfillbuf() {
    3524:     int count;
    3525:
    3526:     count = ios_$get((short)ttyfd, ios_$cond_opt, mybuf, 256L, st);
    3527:     errno = EIO;
    3528:     if (st.all == ios_$get_conditional_failed) /* get at least one */
    3529:       inbufc = ios_$get((short)ttyfd, 0, mybuf, 1L, st);
    3530:     if (st.all == ios_$end_of_file)
    3531:       return(0);
    3532:     else if (st.all != status_$ok) {
    3533:     errno = EIO;
    3534:     return(-1);
    3535:     }
    3536:     return(count);
    3537: }
    3538: #else /* !aegis */
    3539:
    3540: #ifdef FIONREAD
    3541:     /* This is for systems with FIONREAD.  FIONREAD returns the number
    3542: 	 * of characters available for reading. If none are available, wait
    3543: 	 * until something arrives, otherwise return all there is.
    3544: 	 */
    3545: int
    3546: myfillbuf() {
    3547:     PEEKTYPE avail;
    3548:     int x;
    3549:
    3550: #ifdef SUNX25
    3551: /*
    3552:   SunLink X.25 support in this routine from Stefaan A. Eeckels, Eurostat (CEC).
    3553:   Depends on SunOS having FIONREAD, not because we use it, but just so this
    3554:   code is grouped correctly within the #ifdefs.  Let's hope Solaris keeps it.
    3555:
    3556:   We call x25xin() instead of read() so that Q-Bit packets, which contain
    3557:   X.25 service-level information (e.g. PAD parameter changes), can be processed
    3558:   transparently to the upper-level code.  This is a blocking read, and so
    3559:   we depend on higher-level code (such as ttinc()) to set any necessary alarms.
    3560: */
    3561:     extern int nettype;
    3562:     if (netconn && nettype == NET_SX25) {
    3563:     while ((x = x25xin(sizeof(x25buf), x25buf)) < 1) ;
    3564:     return(x - 1);          /* "-1" compensates for extra status byte */
    3565:     }
    3566: #endif /* SUNX25 */
    3567:
    3568:     x = ioctl(ttyfd, FIONREAD, &avail);
    3569:     if (x < 0) {
    3570:     debug(F101,"myfillbuf FIONREAD","",x);
    3571:     debug(F101,"myfillbuf errno","",errno);
    3572:     }
    3573:     if (x < 0 || avail == 0)
    3574:       avail = 1;
    3575:
    3576:     if (avail > MYBUFLEN)
    3577:       avail = MYBUFLEN;
    3578:
    3579:     return(read(ttyfd, mybuf, (int) avail));
    3580: }
    3581:
    3582: #else /* !FIONREAD */
    3583: /* Add other systems here, between #ifdef and #else, e.g. NETCONN. */
    3584: /* When there is no other possibility, read 1 character at a time. */
    3585: int
    3586: myfillbuf() {
    3587:     return read(ttyfd, mybuf, 1);
    3588: }
    3589:
    3590: #endif /* !FIONREAD */
    3591: #endif /* !aegis */
    3592: #endif /* !ATTSV */
    3593:
    3594: #endif /* MYREAD */
    3595:
    3596: /*  T T F L U I  --  Flush tty input buffer */
    3597:
    3598: int
    3599: ttflui() {
    3600: #ifdef BSD44
    3601:     int n;
    3602: #endif /* BSD44 */
    3603: #ifndef SVORPOSIX
    3604:     int n;
    3605: #endif /* SVORPOSIX */
    3606:
    3607: #ifdef MYREAD
    3608: /*
    3609:   Flush internal MYREAD buffer *FIRST*, in all cases.
    3610: */
    3611:     my_count = 0;           /* Reset count to zero */
    3612:     my_item = -1;           /* And buffer index to -1 */
    3613: #endif /* MYREAD */
    3614:
    3615: #ifdef NETCONN
    3616: /*
    3617:   Network flush is done specially, in the network support module.
    3618: */
    3619:     if (netconn) return(netflui());
    3620: #endif /* NETCONN */
    3621:
    3622:     debug(F101,"ttflui ttyfd","",ttyfd);
    3623:     if (ttyfd < 0) return(-1);
    3624:
    3625: #ifdef aegis
    3626:     sio_$control((short)ttyfd, sio_$flush_in, true, st);
    3627:     if (st.all != status_$ok) {
    3628:     fprintf(stderr, "flush failed: "); error_$print(st);
    3629:     } else {      /* sometimes the flush doesn't work */
    3630:         for (;;) {
    3631:         char buf[256];
    3632:             /* eat all the characters that shouldn't be available */
    3633:             ios_$get((short)ttyfd, ios_$cond_opt, buf, 256L, st); /* (void) */
    3634:             if (st.all == ios_$get_conditional_failed) break;
    3635:             fprintf(stderr, "flush failed(2): "); error_$print(st);
    3636:         }
    3637:     }
    3638: #else
    3639: #ifdef BSD44                /* 4.4 BSD */
    3640:     n = FREAD;                          /* Specify read queue */
    3641:     debug(F101,"ttflui BSD44 flush","",ttyfd);
    3642:     ioctl(ttyfd,TIOCFLUSH,&n);
    3643:     ioctl(ttyfd,TCSAFLUSH,&n);
    3644: #else
    3645: #ifdef POSIX                /* POSIX */
    3646:     tcflush(ttyfd,TCIFLUSH);
    3647: #else
    3648: #ifdef ATTSV                /* System V */
    3649: #ifndef VXVE
    3650:     ioctl(ttyfd,TCFLSH,0);
    3651: #endif /* VXVE */
    3652: #else                   /* Not BSD44, POSIX, or Sys V */
    3653: #ifdef TIOCFLUSH            /* Those with TIOCFLUSH defined */
    3654: #ifdef ANYBSD               /* Berkeley */
    3655:     n = FREAD;                          /* Specify read queue */
    3656:     debug(F101,"ttflui anybsd flush","",ttyfd);
    3657:     ioctl(ttyfd,TIOCFLUSH,&n);
    3658: #else                   /* Others (V7, etc) */
    3659:     ioctl(ttyfd,TIOCFLUSH,0);
    3660: #endif /* ANYBSD */
    3661: #else                   /* All others... */
    3662: /*
    3663:   No system call (that we know about) for input buffer flushing.
    3664:   So see how many there are and read them in a loop, using ttinc().
    3665:   ttinc() is buffered, so we're not getting charged with a system call
    3666:   per character, just a function call.
    3667: */
    3668:     if ((n = ttchk()) > 0) {
    3669:     debug(F101,"ttflui reading","",n);
    3670:     while ((n--) && ttinc(0) > 1) ;
    3671:     }
    3672: #endif /* TIOCFLUSH */
    3673: #endif /* ATTSV */
    3674: #endif /* POSIX */
    3675: #endif /* BSD44 */
    3676: #endif /* aegis */
    3677:     return(0);
    3678: }
    3679:
    3680: int
    3681: ttfluo() {              /* Flush output buffer */
    3682: #ifdef POSIX
    3683:     return(tcflush(ttyfd,TCOFLUSH));
    3684: #else
    3685:     return(0);              /* (dummy for now) */
    3686: #endif /* POSIX */
    3687:
    3688: }
    3689:
    3690: /* Interrupt Functions */
    3691:
    3692: /* Set up terminal interrupts on console terminal */
    3693:
    3694: #ifdef SVORPOSIX
    3695: SIGTYP
    3696: esctrp(foo) int foo; {          /* trap console escapes (^\) */
    3697:     signal(SIGQUIT,SIG_IGN);            /* ignore until trapped */
    3698:     conesc = 1;
    3699:     debug(F101,"esctrp caught SIGQUIT","",conesc);
    3700: }
    3701: #endif /* SVORPOSIX */
    3702:
    3703: #ifdef V7
    3704: SIGTYP
    3705: esctrp(foo) int foo; {          /* trap console escapes (^\) */
    3706:     signal(SIGQUIT,SIG_IGN);            /* ignore until trapped */
    3707:     conesc = 1;
    3708:     debug(F101,"esctrp caught SIGQUIT","",conesc);
    3709: }
    3710: #endif
    3711:
    3712: #ifdef C70
    3713: SIGTYP
    3714: esctrp(foo) int foo; {          /* trap console escapes (^\) */
    3715:     conesc = 1;
    3716:     signal(SIGQUIT,SIG_IGN);            /* ignore until trapped */
    3717: }
    3718: #endif
    3719:
    3720: /*  C O N B G T  --  Background Test  */
    3721:
    3722: static int jc = 0;          /* 0 = no job control */
    3723:
    3724: /*
    3725:   Call with flag == 1 to prevent signal test, which can not be expected
    3726:   to work during file transfer, when SIGINT probably *is* set to SIG_IGN.
    3727:
    3728:   Call with flag == 0 to use the signal test, but only if the process-group
    3729:   test fails, as it does on some UNIX systems, where getpgrp() is buggy,
    3730:   requires an argument when the man page says it doesn't, or vice versa.
    3731:
    3732:   If flag == 0 and the process-group test fails, then we determine background
    3733:   status simply (but not necessarily reliably) from isatty().
    3734:
    3735:   conbgt() sets the global backgrd = 1 if we appear to be in the background,
    3736:   and to 0 if we seem to be in the foreground.  conbgt() is highly prone to
    3737:   misbehavior.
    3738: */
    3739: VOID
    3740: conbgt(flag) int flag; {
    3741:     int x = -1,             /* process group or SIGINT test */
    3742:         y = 0;              /* isatty() test */
    3743: /*
    3744:   Check for background operation, even if not running on real tty, so that
    3745:   background flag can be set correctly.  If background status is detected,
    3746:   then Kermit will not issue its interactive prompt or most messages.
    3747:   If your prompt goes away, you can blame (and fix?) this function.
    3748: */
    3749:
    3750: /* Use process-group test if possible. */
    3751:
    3752: #ifdef POSIX                /* We can do it in POSIX */
    3753: #define PGROUP_T
    3754: #else
    3755: #ifdef BSD4             /* and in BSD 4.x. */
    3756: #define PGROUP_T
    3757: #else
    3758: #ifdef HPUXJOBCTL           /* and in most HP-UX's */
    3759: #define PGROUP_T
    3760: #else
    3761: #ifdef TIOCGPGRP            /* and anyplace that has this ioctl. */
    3762: #define PGROUP_T
    3763: #endif /* TIOCGPGRP */
    3764: #endif /* HPUXJOBCTL */
    3765: #endif /* BSD4 */
    3766: #endif /* POSIX */
    3767:
    3768: #ifdef MIPS             /* Except if it doesn't work... */
    3769: #undef PGROUP_T
    3770: #endif /* MIPS */
    3771:
    3772: #ifdef PGROUP_T
    3773: /*
    3774:   Semi-reliable process-group test.  Check whether this process's group is
    3775:   the same as the controlling terminal's process group.  This works if the
    3776:   getpgrp() call doesn't lie (as it does in the SUNOS System V environment).
    3777: */
    3778:     PID_T mypgrp = (PID_T)0;        /* Kermit's process group */
    3779:     PID_T ctpgrp = (PID_T)0;        /* The terminal's process group */
    3780: #ifndef _POSIX_SOURCE
    3781: /*
    3782:   The getpgrp() prototype is obtained from system header files for POSIX
    3783:   and Sys V R4 compilations.  Other systems, who knows.  Some complain about
    3784:   a duplicate declaration here, others don't, so it's safer to leave it in
    3785:   if we don't know for certain.
    3786: */
    3787: #ifndef SVR4
    3788: #ifndef PS2AIX10
    3789:     extern PID_T getpgrp();
    3790: #endif /* PS2AIX10 */
    3791: #endif /* SVR4 */
    3792: #endif /* _POSIX_SOURCE */
    3793:
    3794: /* Get my process group. */
    3795:
    3796: #ifdef SVR3 /* Maybe this should be ATTSV? */
    3797: /* This function is not described in SVID R2 */
    3798:     mypgrp = getpgrp();
    3799:     debug(F101,"ATTSV conbgt process group","",(int) mypgrp);
    3800: #else
    3801: #ifdef POSIX
    3802:     mypgrp = getpgrp();
    3803:     debug(F101,"POSIX conbgt process group","",(int) mypgrp);
    3804: #else /* BSD, V7, etc */
    3805:     mypgrp = getpgrp(0);
    3806:     debug(F101,"BSD conbgt process group","",(int) mypgrp);
    3807: #endif /* POSIX */
    3808: #endif /* SVR3 */
    3809:
    3810: /* Now get controlling tty's process group */
    3811: #ifdef BSD44ORPOSIX
    3812:     ctpgrp = tcgetpgrp(1);      /* The POSIX way */
    3813:     debug(F101,"POSIX conbgt terminal process group","",(int) ctpgrp);
    3814: #else
    3815:     ioctl(1, TIOCGPGRP, &ctpgrp);   /* Or the BSD way */
    3816:     debug(F101,"non-POSIX conbgt terminal process group","",(int) ctpgrp);
    3817: #endif /* BSD44ORPOSIX */
    3818:
    3819:     if ((mypgrp > (PID_T) 0) && (ctpgrp > (PID_T) 0))
    3820:       x = (mypgrp == ctpgrp) ? 0 : 1;   /* If they differ, then background. */
    3821:     else x = -1;            /* If error, remember. */
    3822:     debug(F101,"conbgt process group test","",x);
    3823: #endif /* PGROUP_T */
    3824:
    3825: /* Try to see if job control is available */
    3826:
    3827: #ifdef NOJC             /* User override */
    3828:     jc = 0;             /* No job control allowed */
    3829:     debug(F111,"NOJC","jc",jc);
    3830: #else
    3831: #ifdef BSD44
    3832:     jc = 1;
    3833: #else
    3834: #ifdef SVR4ORPOSIX          /* POSIX actually tells us */
    3835:     debug(F100,"SVR4ORPOSIX jc test...","",0);
    3836: #ifdef _SC_JOB_CONTROL
    3837: #ifdef bsdi
    3838:     jc = 1;
    3839: #else
    3840: #ifdef __386BSD__
    3841:     jc = 1;
    3842: #else
    3843:     jc = sysconf(_SC_JOB_CONTROL);  /* Whatever system says */
    3844:     debug(F111,"sysconf(_SC_JOB_CONTROL)","jc",jc);
    3845: #endif /* __386BSD__ */
    3846: #endif /* bsdi */
    3847: #else
    3848: #ifdef _POSIX_JOB_CONTROL
    3849:     jc = 1;             /* By definition */
    3850:     debug(F111,"_POSIX_JOB_CONTROL is defined","jc",jc);
    3851: #else
    3852:     jc = 0;             /* Assume job control not allowed */
    3853:     debug(F111,"SVR4ORPOSIX _SC/POSIX_JOB_CONTROL not defined","jc",jc);
    3854: #endif /* _POSIX_JOB_CONTROL */
    3855: #endif /* _SC_JOB_CONTROL */
    3856: #else
    3857: #ifdef BSD4
    3858:     jc = 1;             /* Job control allowed */
    3859:     debug(F111,"BSD job control","jc",jc);
    3860: #else
    3861: #ifdef SVR3JC
    3862:     jc = 1;             /* JC allowed */
    3863:     debug(F111,"SVR3 job control","jc",jc);
    3864: #else
    3865:     jc = 0;             /* JC not allowed */
    3866:     debug(F111,"job control catch-all","jc",jc);
    3867: #endif /* SVR3JC */
    3868: #endif /* BSD4 */
    3869: #endif /* SVR4ORPOSIX */
    3870: #endif /* BSD44 */
    3871: #endif /* NOJC */
    3872:     debug(F101,"conbgt jc","",jc);
    3873:
    3874: /*
    3875:   Another background test.
    3876:   Test if SIGINT (terminal interrupt) is set to SIG_IGN (ignore),
    3877:   which is done by the shell (sh) if the program is started with '&'.
    3878:   Unfortunately, this is NOT done by csh or ksh so watch out!
    3879:   Note, it's safe to set SIGINT to SIG_IGN here, because further down
    3880:   we always set it to something else.
    3881: */
    3882:     if (x < 0 && !flag) {       /* Didn't get good results above... */
    3883:
    3884:     SIGTYP (*osigint)();
    3885:
    3886:     osigint = signal(SIGINT,SIG_IGN);   /* What is SIGINT set to? */
    3887:     x = (osigint == SIG_IGN) ? 1 : 0;   /* SIG_IGN? */
    3888:     debug(F101,"conbgt osigint","",(int) osigint);
    3889:     debug(F101,"conbgt signal test","",x);
    3890:     }
    3891:
    3892: /* Also check to see if we're running with redirected stdio. */
    3893: /* This is not really background operation, but we want to act as though */
    3894: /* it were. */
    3895:
    3896:     y = (isatty(0) && isatty(1)) ? 1 : 0;
    3897:     debug(F101,"conbgt isatty test","",y);
    3898:
    3899: #ifdef BSD29
    3900: /* The process group and/or signal test doesn't work under these... */
    3901:     backgrd = !y;
    3902: #else
    3903: #ifdef sxaE50
    3904:     backgrd = !y;
    3905: #else
    3906: #ifdef MINIX
    3907:     backgrd = !y;
    3908: #else
    3909:     if (x > -1)
    3910:       backgrd = (x || !y) ? 1 : 0;
    3911:     else backgrd = !y;
    3912: #endif /* BSD29 */
    3913: #endif /* sxaE50 */
    3914: #endif /* MINIX */
    3915:     debug(F101,"conbgt backgrd","",backgrd);
    3916: }
    3917:
    3918: /*  C O N I N T  --  Console Interrupt setter  */
    3919:
    3920: /*
    3921:   First arg is pointer to function to handle SIGTERM & SIGINT (like Ctrl-C).
    3922:   Second arg is pointer to function to handle SIGTSTP (suspend).
    3923: */
    3924:
    3925: VOID                    /* Set terminal interrupt traps. */
    3926: #ifdef CK_ANSIC
    3927: #ifdef apollo
    3928: conint(f,s) SIGTYP (*f)(), (*s)();
    3929: #else
    3930: conint(SIGTYP (*f)(int), SIGTYP (*s)(int))
    3931: #endif /* apollo */
    3932: #else
    3933: conint(f,s) SIGTYP (*f)(), (*s)();
    3934: #endif /* CK_ANSIC */
    3935: /* conint */ {
    3936:
    3937:     conbgt(0);              /* Do background test. */
    3938:
    3939: /* Set the desired handlers for hangup and software termination. */
    3940:
    3941:     signal(SIGTERM,f);                  /* Software termination */
    3942:
    3943: #ifdef COMMENT
    3944: /*
    3945:   Prior to edit 184, we used to trap SIGHUP here.  That is clearly wrong;
    3946:   on some systems, it would leave the user's process on the terminal after
    3947:   the phone hung up.  But the trap was here for a reason: most likely some
    3948:   UNIX systems (init, getty, or login) fail to properly restore the terminal
    3949:   modes after regaining control of a hung-up-upon login terminal.  Therefore
    3950:   removing this trap is likely to cause problems too.  A more sensible
    3951:   approach would be to use a special handler for HANGUP, which would restore
    3952:   the terminal modes and then exit().  But that could leave zombie processes
    3953:   around (like the lower CONNECT fork, or any fork started by zxcmd()), but
    3954:   there is probably no clean, portable, reliable way for Kermit to kill all
    3955:   its forks.  So we just exit() and hope that UNIX fixes the terminal modes
    3956:   before the next person tries to log in.
    3957: */
    3958:     signal(SIGHUP,f);                   /* Hangup */
    3959: #endif /* COMMENT */
    3960:
    3961: /* Now handle keyboard stop, quit, and interrupt signals. */
    3962: /* Check if invoked in background -- if so signals set to be ignored. */
    3963: /* However, if running under a job control shell, don't ignore them. */
    3964: /* We won't be getting any, as we aren't in the terminal's process group. */
    3965:
    3966:     debug(F101,"conint backgrd","",backgrd);
    3967:     debug(F101,"conint jc","",jc);
    3968:
    3969:     if (backgrd && !jc) {       /* In background, ignore signals */
    3970:     debug(F101,"conint background ignoring signals, jc","",jc);
    3971: #ifdef SIGTSTP
    3972:         signal(SIGTSTP,SIG_IGN);        /* Keyboard stop */
    3973: #endif /* SIGTSTP */
    3974:         signal(SIGQUIT,SIG_IGN);        /* Keyboard quit */
    3975:         signal(SIGINT,SIG_IGN);         /* Keyboard interrupt */
    3976:     } else {                /* Else in foreground or suspended */
    3977:     debug(F101,"conint foreground catching signals, jc","",jc);
    3978:         signal(SIGINT,f);               /* Catch terminal interrupt */
    3979:
    3980: #ifdef SIGTSTP              /* Keyboard stop (suspend) */
    3981:     debug(F101,"conint SIGSTSTP","",(int) s);
    3982:     if (s == NULL) s = SIG_DFL;
    3983: #ifdef NOJC             /* No job control allowed. */
    3984:     signal(SIGTSTP,SIG_IGN);
    3985: #else                   /* Job control allowed */
    3986:     if (jc)             /* if available. */
    3987:       signal(SIGTSTP,s);
    3988:     else
    3989:       signal(SIGTSTP,SIG_IGN);
    3990: #endif /* NOJC */
    3991: #endif /* SIGTSTP */
    3992:
    3993: #ifdef SVORPOSIX
    3994:         signal(SIGQUIT,esctrp);         /* Quit signal, Sys III/V. */
    3995:         if (conesc) conesc = 0;         /* Clear out pending escapes */
    3996: #else
    3997: #ifdef V7
    3998:         signal(SIGQUIT,esctrp);         /* V7 like Sys III/V */
    3999:         if (conesc) conesc = 0;
    4000: #else
    4001: #ifdef aegis
    4002:         signal(SIGQUIT,f);              /* Apollo, catch it like others. */
    4003: #else
    4004:         signal(SIGQUIT,SIG_IGN);        /* Others, ignore like 4D & earlier. */
    4005: #endif /* aegis */
    4006: #endif /* V7 */
    4007: #endif /* SVORPOSIX */
    4008:     }
    4009: }
    4010:
    4011:
    4012: /*  C O N N O I  --  Reset console terminal interrupts */
    4013:
    4014: SIGTYP                  /* Dummy function to ignore signals */
    4015: #ifdef CK_ANSIC
    4016: sig_ign(int foo)
    4017: #else
    4018: sig_ign(foo) int foo;
    4019: #endif /* CK_ANSIC */
    4020: /* sig_IGN */ {             /* Just like the real one, but has  */
    4021: }                   /* different address. */
    4022:
    4023: VOID
    4024: connoi() {                              /* Console-no-interrupts */
    4025:
    4026:     debug(F100,"connoi","",0);
    4027: #ifdef SIGTSTP
    4028:     signal(SIGTSTP,SIG_DFL);
    4029: #endif /* SIGTSTP */
    4030:     /* Note the locally defined replacement for SIG_IGN that is used here */
    4031:     /* for the SIGINT setting.  This is done so that the Sys V background */
    4032:     /* test -- (signal(SIGINT,SIG_IGN) == SIG_IGN) -- can work.  If we use */
    4033:     /* the real SIG_IGN here, then conint will always decide that this */
    4034:     /* program is running in the background! */
    4035:
    4036:     signal(SIGINT,sig_ign);     /* <--- note! */
    4037:
    4038:     signal(SIGHUP,SIG_DFL);
    4039:     signal(SIGQUIT,SIG_IGN);
    4040:     signal(SIGTERM,SIG_IGN);
    4041: }
    4042:
    4043: /*  I N I T R A W Q  --  Set up to read /dev/kmem for character count.  */
    4044:
    4045: #ifdef  V7
    4046: /*
    4047:  Used in Version 7 to simulate Berkeley's FIONREAD ioctl call.  This
    4048:  eliminates blocking on a read, because we can read /dev/kmem to get the
    4049:  number of characters available for raw input.  If your system can't
    4050:  or you won't let the world read /dev/kmem then you must figure out a
    4051:  different way to do the counting of characters available, or else replace
    4052:  this by a dummy function that always returns 0.
    4053: */
    4054: /*
    4055:  * Call this routine as: initrawq(tty)
    4056:  * where tty is the file descriptor of a terminal.  It will return
    4057:  * (as a char *) the kernel-mode memory address of the rawq character
    4058:  * count, which may then be read.  It has the side-effect of flushing
    4059:  * input on the terminal.
    4060:  */
    4061: /*
    4062:  * John Mackin, Physiology Dept., University of Sydney (Australia)
    4063:  * ...!decvax!mulga!physiol.su.oz!john
    4064:  *
    4065:  * Permission is hereby granted to do anything with this code, as
    4066:  * long as this comment is retained unmodified and no commercial
    4067:  * advantage is gained.
    4068:  */
    4069: #ifndef MINIX
    4070: #ifndef COHERENT
    4071: #include <a.out.h>
    4072: #include <sys/proc.h>
    4073: #endif /* COHERENT */
    4074: #endif /* MINIX */
    4075:
    4076: #ifdef COHERENT
    4077: #include <l.out.h>
    4078: #include <sys/proc.h>
    4079: #endif /* COHERENT */
    4080:
    4081: char *
    4082: initrawq(tty) int tty; {
    4083: #ifdef MINIX
    4084:     return(0);
    4085: #else
    4086: #ifdef UTS24
    4087:     return(0);
    4088: #else
    4089: #ifdef BSD29
    4090:     return(0);
    4091: #else
    4092:     long lseek();
    4093:     static struct nlist nl[] = {
    4094:         {PROCNAME},
    4095:         {NPROCNAME},
    4096:         {""}
    4097:     };
    4098:     static struct proc *pp;
    4099:     char *qaddr, *p, c;
    4100:     int m;
    4101:     PID_T pid, me;
    4102:     NPTYPE xproc;                       /* Its type is defined in makefile. */
    4103:     int catch();
    4104:
    4105:     me = getpid();
    4106:     if ((m = open("/dev/kmem", 0)) < 0) err("kmem");
    4107:     nlist(BOOTNAME, nl);
    4108:     if (nl[0].n_type == 0) err("proc array");
    4109:
    4110:     if (nl[1].n_type == 0) err("nproc");
    4111:
    4112:     lseek(m, (long)(nl[1].n_value), 0);
    4113:     read (m, &xproc, sizeof(xproc));
    4114:     saval = signal(SIGALRM, catch);
    4115:     if ((pid = fork()) == 0) {
    4116:         while(1)
    4117:             read(tty, &c, 1);
    4118:     }
    4119:     alarm(2);
    4120:
    4121:     if(setjmp(jjbuf) == 0) {
    4122:         while(1)
    4123:       read(tty, &c, 1);
    4124:     }
    4125:     signal(SIGALRM, SIG_DFL);
    4126:
    4127: #ifdef DIRECT
    4128:     pp = (struct proc *) nl[0].n_value;
    4129: #else
    4130:     if (lseek(m, (long)(nl[0].n_value), 0) < 0L) err("seek");
    4131:     if (read(m, &pp, sizeof(pp)) != sizeof(pp))  err("no read of proc ptr");
    4132: #endif
    4133:     lseek(m, (long)(nl[1].n_value), 0);
    4134:     read(m, &xproc, sizeof(xproc));
    4135:
    4136:     if (lseek(m, (long)pp, 0) < 0L) err("Can't seek to proc");
    4137:     if ((p = malloc(xproc * sizeof(struct proc))) == NULL) err("malloc");
    4138:     if (read(m,p,xproc * sizeof(struct proc)) != xproc*sizeof(struct proc))
    4139:         err("read proc table");
    4140:     for (pp = (struct proc *)p; xproc > 0; --xproc, ++pp) {
    4141:         if (pp -> p_pid == (short) pid) goto iout;
    4142:     }
    4143:     err("no such proc");
    4144:
    4145: iout:
    4146:     close(m);
    4147:     qaddr = (char *)(pp -> p_wchan);
    4148:     free (p);
    4149:     kill(pid, SIGKILL);
    4150:     wait((WAIT_T)0);             /* Destroy the ZOMBIEs! */
    4151:     return (qaddr);
    4152: #endif
    4153: #endif
    4154: #endif
    4155: }
    4156:
    4157: /*  More V7-support functions...  */
    4158:
    4159: static VOID
    4160: err(s) char *s; {
    4161:     char buf[200];
    4162:
    4163:     sprintf(buf, "fatal error in initrawq: %s", s);
    4164:     perror(buf);
    4165:     doexit(1,-1);
    4166: }
    4167:
    4168: static VOID
    4169: catch(foo) int foo; {
    4170:     longjmp(jjbuf, -1);
    4171: }
    4172:
    4173:
    4174: /*  G E N B R K  --  Simulate a modem break.  */
    4175:
    4176: #ifdef MINIX
    4177: #define BSPEED B110
    4178: #else
    4179: #define BSPEED B150
    4180: #endif /* MINIX */
    4181:
    4182: VOID
    4183: genbrk(fn,msec) int fn, msec; {
    4184:     struct sgttyb ttbuf;
    4185:     int ret, sospeed, x, y;
    4186:
    4187:     ret = ioctl(fn, TIOCGETP, &ttbuf);
    4188:     sospeed = ttbuf.sg_ospeed;
    4189:     ttbuf.sg_ospeed = BSPEED;
    4190:     ret = ioctl(fn, TIOCSETP, &ttbuf);
    4191:     y = (int)strlen(brnuls);
    4192:     x = ( BSPEED * 100 ) / msec;
    4193:     if (x > y) x = y;
    4194:     ret = write(fn, brnuls, (( BSPEED * 100 ) / msec ));
    4195:     ttbuf.sg_ospeed = sospeed;
    4196:     ret = ioctl(fn, TIOCSETP, &ttbuf);
    4197:     ret = write(fn, "@", 1);
    4198:     return;
    4199: }
    4200: #endif /* V7 */
    4201:
    4202: /*  T T C H K  --  Tell how many characters are waiting in tty input buffer  */
    4203:
    4204: /*  Some callers of this want to know whether there is something to read
    4205:  *  either in the system buffers or in our private buffers (and mostly don't
    4206:  *  care how many characters, just whether it's more than zero or not), while
    4207:  *  some others would be better off with the number of characters in our
    4208:  *  private buffers only.
    4209:  *
    4210:  *  Some systems can say how many characters there are in the system buffers.
    4211:  *  Others can not. For those that can't, the number in the private buffers
    4212:  *  will have to do (or should we put the tty into O_NDELAY-mode and try to
    4213:  *  read one character?). If the system can tell whether there is zero or
    4214:  *  more than zero characters, we can return 1 in the latter case even if the
    4215:  *  private buffer is empty. (That is good for sliding windows.)
    4216:  */
    4217: int
    4218: ttchk() {
    4219:     int x;
    4220:     PEEKTYPE n = 0;
    4221:
    4222: #ifdef COMMENT
    4223: /*
    4224:   This was REALLY slowing TELNET connections down!  Just do the regular
    4225:   ttyfd-based stuff here.  Let the VMS version call nettchk if it has to...
    4226:   FIONREAD definitely works for TELNET, at least on the NeXT and SUNOS.
    4227: */
    4228: #ifdef NETCONN
    4229:     if (netconn) return(nettchk());
    4230: #endif /* NETCONN */
    4231: #endif /* COMMENT */
    4232:
    4233: #ifdef FIONREAD
    4234:     x = ioctl(ttyfd, FIONREAD, &n);     /* Berkeley and maybe some others */
    4235:     debug(F101,"ttchk FIONREAD return code","",x);
    4236:     debug(F101,"ttchk FIONREAD count","",n);
    4237:     if (x < 0) n = 0;
    4238: #else
    4239: #ifdef  V7
    4240: #ifdef MINIX
    4241:     return(0);
    4242: #else
    4243:     lseek(kmem[TTY], (long) qaddr[TTY], 0); /* 7th Edition Unix */
    4244:     x = read(kmem[TTY], &n, sizeof(int));
    4245:     if (x != sizeof(int)) n = 0;
    4246: #endif /* MINIX */
    4247: #else
    4248: #ifdef PROVX1
    4249:     x = ioctl(ttyfd, TIOCQCNT, &ttbuf); /* Pro/3xx Venix V.1 */
    4250:     n = ttbuf.sg_ispeed & 0377;
    4251:     if (x < 0) n = 0;
    4252: #else
    4253: #ifdef RDCHK
    4254: /*
    4255:   Last resort for systems without FIONREAD or equivalent, but with
    4256:   something like rdchk(), like XENIX.
    4257: */
    4258:     if (my_count == 0 && rdchk(ttyfd) > 0) n = 1;
    4259:     debug(F101,"ttchk rdchk","",n);
    4260: #endif /* RDCHK */
    4261: #endif /* PROVX1 */
    4262: #endif /* V7 */
    4263: #endif /* FIONREAD */
    4264:
    4265: #ifdef MYREAD
    4266: /*
    4267:   For myread() users, add the contents of myread()'s private buffer.
    4268:   Sometimes, this is all there is to construct a result of ttchk() on.
    4269: */
    4270:     if (my_count > 0)
    4271:     n += my_count;
    4272: #endif /* MYREAD */
    4273:
    4274:     debug(F101,"ttchk returns","",n);
    4275:     return(n);
    4276: }
    4277:
    4278: /*  T T X I N  --  Get n characters from tty input buffer  */
    4279:
    4280: /*  Returns number of characters actually gotten, or -1 on failure  */
    4281:
    4282: /*  Intended for use only when it is known that n characters are actually */
    4283: /*  Available in the input buffer.  */
    4284:
    4285: int
    4286: ttxin(n,buf) int n; CHAR *buf; {
    4287:     register int x, c;
    4288:
    4289:     debug(F101,"ttxin n","",n);
    4290:     if (n < 1) return(0);
    4291:     ttpmsk = (ttprty) ? 0177 : 0377;    /* Parity stripping mask. */
    4292:
    4293: #ifdef SUNX25
    4294:     if (netconn && (ttnet == NET_SX25)) /* X.25 connection */
    4295:       return(x25xin(n,buf));
    4296: #endif /* SUNX25 */
    4297:
    4298: #ifdef MYREAD
    4299:     debug(F101,"ttxin MYREAD","",0);
    4300:     c = -2;
    4301:     for( x = 0; (x > -1) && (x < n) && (c = myread()) >= 0; )
    4302:       buf[x++] = c & ttpmsk;
    4303:     if (c < 0) {
    4304:     debug(F101,"ttxin myread returns","",c);
    4305:     if (c == -3) x = -1;
    4306:     }
    4307: #else
    4308:     x = read(ttyfd,buf,n);
    4309:     for (c = 0; c < n; c++) buf[c] &= ttpmsk;
    4310:     debug(F101," x","",x);
    4311: #endif /* MYREAD */
    4312:     if (x > 0) buf[x] = '\0';
    4313:     if (x < 0) x = -1;
    4314:     return(x);
    4315: }
    4316:
    4317: /*  T T O L  --  Write string s, length n, to communication device.  */
    4318: /*
    4319:   Returns:
    4320:    >= 0 on success, number of characters actually written.
    4321:    -1 on failure.
    4322: */
    4323: #define TTOLMAXT 5
    4324: int
    4325: ttol(s,n) int n; CHAR *s; {
    4326:     int x, len, tries;
    4327:
    4328:     if (ttyfd < 0) return(-1);          /* Not open? */
    4329:     debug(F101,"ttol n","",n);
    4330:     tries = TTOLMAXT;           /* Allow up to this many tries */
    4331:     len = n;                /* Remember original length */
    4332:
    4333:     while (n > 0 && tries-- > 0) {  /* Be persistent */
    4334:     debug(F101,"ttol try","",TTOLMAXT - tries);
    4335:     x = write(ttyfd,s,n);       /* Write string to device */
    4336:     if (x == n) {           /* Worked? */
    4337:         debug(F101,"ttol ok","",x); /* OK */
    4338:         return(len);        /* Done */
    4339:     } else if (x < 0) {     /* No, got error? */
    4340:         debug(F101,"ttol failed","",errno);
    4341:         return(-1);
    4342:     } else {            /* No error, so partial success */
    4343:         debug(F101,"ttol partial","",x);
    4344:         s += x;         /* Point to part not written yet */
    4345:         n -= x;         /* Adjust length */
    4346:         if (x > 0) msleep(100); /* Wait 100 msec */
    4347:     }               /* Go back and try again */
    4348:     }
    4349:     return(n < 1 ? len : -1);       /* Too many tries */
    4350: }
    4351:
    4352:
    4353:
    4354: /*  T T O C  --  Output a character to the communication line  */
    4355:
    4356: /*
    4357:  This function should only be used for interactive, character-mode operations,
    4358:  like terminal connection, script execution, dialer i/o, where the overhead
    4359:  of the signals and alarms does not create a bottleneck.
    4360: */
    4361: int
    4362: #ifdef CK_ANSIC
    4363: ttoc(char c)
    4364: #else
    4365: ttoc(c) char c;
    4366: #endif /* CK_ANSIC */
    4367: /* ttoc */ {
    4368: #define TTOC_TMO 15         /* Timeout in case we get stuck */
    4369:     int xx;
    4370:     c &= 0xff;
    4371:     /* debug(F101,"ttoc","",(CHAR) c); */
    4372:     if (ttyfd < 0) return(-1);          /* Check for not open. */
    4373:     saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
    4374:     xx = alarm(TTOC_TMO);       /* for this many seconds. */
    4375:     if (xx < 0) xx = 0;         /* Save old alarm value. */
    4376:     /* debug(F101,"ttoc alarm","",xx); */
    4377:     if (setjmp(sjbuf)) {        /* Timer went off? */
    4378:     ttimoff();          /* Yes, cancel this alarm. */
    4379:     if (xx - TTOC_TMO > 0) alarm(xx - TTOC_TMO); /* Restore previous one */
    4380:         /* debug(F100,"ttoc timeout","",0); */
    4381: #ifdef NETCONN
    4382:     if (!netconn) {
    4383: #endif /* NETCONN */
    4384:         debug(F101,"ttoc timeout","",c);
    4385:         if (ttflow == FLO_XONX) {
    4386:         int x = 0, y;
    4387:         debug(F101,"ttoc flow","",ttflow); /* Maybe we're xoff'd */
    4388: #ifdef POSIX
    4389:         y = tcflow(ttyfd,TCOON); /* POSIX way to unstick. */
    4390:         debug(F100,"ttoc tcflow","",y);
    4391: #else
    4392: #ifdef BSD4             /* Berkeley way to do it. */
    4393: #ifdef TIOCSTART
    4394: /* .... Used to be "ioctl(ttyfd, TIOCSTART, 0);".  Who knows? */
    4395:         y = ioctl(ttyfd, TIOCSTART, &x);
    4396:         debug(F101,"ttoc TIOCSTART","",y);
    4397: #endif /* TIOCSTART */
    4398: #endif /* BSD4 */
    4399:                     /* Is there a Sys V way to do this? */
    4400: #endif /* POSIX */
    4401:         }
    4402: #ifdef NETCONN
    4403:         }
    4404: #endif /* NETCONN */
    4405:     return(-1);         /* Return failure code. */
    4406:     } else {
    4407:     if (write(ttyfd,&c,1) < 1) {    /* Try to write the character. */
    4408:         ttimoff();          /* Failed, turn off the alarm. */
    4409:         alarm(xx);          /* Restore previous alarm. */
    4410:         debug(F101,"ttoc error","",errno); /* Log the error, */
    4411:         return(-1);         /* and return the error code. */
    4412:     }
    4413:     }
    4414:     ttimoff();              /* Success, turn off the alarm. */
    4415:     alarm(xx);              /* Restore previous alarm. */
    4416:     return(0);              /* Return good code. */
    4417: }
    4418:
    4419: /*  T T I N L  --  Read a record (up to break character) from comm line.  */
    4420: /*
    4421:   Reads up to "max" characters from the communication line, terminating on:
    4422:
    4423:     (a) the packet length field if the "turn" argument is zero, or
    4424:     (b) on the packet-end character (eol) if the "turn" argument is nonzero
    4425:     (c) two Ctrl-C's in a row
    4426:
    4427:   and returns the number of characters read upon success, or if "max" was
    4428:   exceeded or the timeout interval expired before (a) or (b), returns -1.
    4429:
    4430:   The characters that were input are copied into "dest" with their parity bits
    4431:   stripped if parity was selected.  Returns the number of characters read.
    4432:   Characters after the eol are available upon the next call to this function.
    4433:
    4434:   The idea is to minimize the number of system calls per packet, and also to
    4435:   minimize timeouts.  This function is the inner loop of the program and must
    4436:   be as efficient as possible.  The current strategy is to use myread().
    4437:
    4438:   WARNING: this function calls parchk(), which is defined in another module.
    4439:   Normally, ckutio.c does not depend on code from any other module, but there
    4440:   is an exception in this case because all the other ck?tio.c modules also
    4441:   need to call parchk(), so it's better to have it defined in a common place.
    4442:
    4443:   Since this function has grown to have its fingers so deeply into the
    4444:   protocol, it is slated for removal: rpack() will take care of everything.
    4445: */
    4446: #ifdef CTRLC
    4447: #undef CTRLC
    4448: #endif /* CTRLC */
    4449: #define CTRLC '\03'
    4450: /*
    4451:   We have four different declarations here because:
    4452:   (a) to allow Kermit to be built without the automatic parity sensing feature
    4453:   (b) one of each type for ANSI C, one for non-ANSI.
    4454: */
    4455: int
    4456: #ifdef PARSENSE
    4457: #ifdef CK_ANSIC
    4458: ttinl(CHAR *dest, int max,int timo, CHAR eol, CHAR start, int turn)
    4459: #else
    4460: ttinl(dest,max,timo,eol,start,turn) int max,timo,turn; CHAR *dest, eol, start;
    4461: #endif /* CK_ANSIC */
    4462: #else /* not PARSENSE */
    4463: #ifdef CK_ANSIC
    4464: ttinl(CHAR *dest, int max,int timo, CHAR eol)
    4465: #else
    4466: ttinl(dest,max,timo,eol) int max,timo; CHAR *dest, eol;
    4467: #endif /* __SDTC__ */
    4468: #endif /* PARSENSE */
    4469: /* ttinl */ {
    4470:
    4471: #ifndef MYREAD
    4472:     CHAR ch;
    4473: #endif /* MYREAD */
    4474: #ifdef PARSENSE
    4475:     int pktlen = -1;
    4476:     int lplen = 0;
    4477:     int havelen = 0;
    4478: #endif /* PARSENSE */
    4479:
    4480:     if (ttyfd < 0) return(-1);          /* Not open. */
    4481:
    4482:     debug(F101,"ttinl max","",max);
    4483:     debug(F101,"ttinl timo","",timo);
    4484:
    4485:     *dest = '\0';                       /* Clear destination buffer */
    4486:     if (timo < 0) timo = 0;     /* Safety */
    4487:     if (timo) {             /* Don't time out if timo == 0 */
    4488:     int xx;
    4489:     saval = signal(SIGALRM,timerh); /* Enable timer interrupt */
    4490:     xx = alarm(timo);       /* Set it. */
    4491:     debug(F101,"ttinl alarm","",xx);
    4492:     }
    4493:     if (setjmp(sjbuf)) {                /* Timer went off? */
    4494:     debug(F100,"ttinl timout","",0); /* Get here on timeout. */
    4495:     /* debug(F110," with",(char *) dest,0); */
    4496:     ttimoff();          /* Turn off timer */
    4497:     return(-1);         /* and return error code. */
    4498:     } else {
    4499:     register int i, m, n;       /* local variables */
    4500:     int ccn = 0;
    4501: #ifdef PARSENSE
    4502:     int flag = 0;
    4503:
    4504:     debug(F000,"ttinl start","",start);
    4505:     flag = 0;           /* Start of packet flag */
    4506: #endif /* PARSENSE */
    4507:
    4508:     ttpmsk = m = (ttprty) ? 0177 : 0377; /* Set parity stripping mask. */
    4509:
    4510: #ifdef COMMENT
    4511: /*
    4512:   No longer needed.
    4513: */
    4514: #ifdef SUNX25
    4515:         if (netconn && (ttnet == NET_SX25))
    4516: #ifdef PARSENSE
    4517:       return(x25inl(dest,max,timo,eol,start));
    4518: #else
    4519:       return(x25inl(dest,max,timo,eol));
    4520: #endif /* PARSENSE */
    4521: #endif /* SUNX25 */
    4522: #endif /* COMMENT */
    4523:
    4524: /* Now read into destination, stripping parity and looking for the */
    4525: /* the packet terminator, and also for two Ctrl-C's typed in a row. */
    4526:
    4527:     i = 0;              /* Destination index */
    4528:     debug(F101,"ttinl eol","",eol);
    4529:
    4530: #ifdef MYREAD
    4531:     while (i < max-1) {
    4532:         /* debug(F101,"ttinl i","",i); */
    4533:         if ((n = myread()) < 0) {
    4534:         debug(F101,"ttinl myread failure, n","",n);
    4535:         debug(F101,"ttinl myread errno,","",errno);
    4536:         /* Don't let EINTR break packets. */
    4537:         if (n == -3 && errno == EINTR && i > 0) {
    4538:             debug(F101,"ttinl myread i","",i);
    4539:             continue;
    4540:         }
    4541:         break;
    4542:         }
    4543: #else
    4544:     while ((i < max-1)  &&  (n = read(ttyfd, &ch, 1)) > 0) {
    4545:         n = ch;
    4546: #endif /* MYREAD */
    4547:
    4548:         /* debug(F101,"ttinl char","", (n & ttpmsk)); */
    4549:
    4550: #ifdef PARSENSE
    4551: /*
    4552:   Figure out what the length is supposed to be in case the packet
    4553:   has no terminator (as with Honeywell GCOS-8 Kermit).
    4554: */
    4555: #ifndef xunchar
    4556: #define xunchar(ch) (((ch) - 32 ) & 0xFF )  /* Character to number */
    4557: #endif /* xunchar */
    4558:         if ((flag == 0) && ((n & 0x7f) == start)) flag = 1;
    4559:         if (flag) dest[i++] = n & ttpmsk;
    4560: /*
    4561:   If we have not been instructed to wait for a turnaround character, we
    4562:   can go by the packet length field.  If turn != 0, we must wait for the
    4563:   end of line (eol) character before returning.
    4564: */
    4565:         if (i == 2) {
    4566:         pktlen = xunchar(dest[1]);
    4567:         havelen = (pktlen > 1);
    4568:         debug(F101,"ttinl length","",pktlen);
    4569:         } else if (i == 5 && pktlen == 0) {
    4570:         lplen = xunchar(dest[4]);
    4571:         } else if (i == 6 && pktlen == 0) {
    4572:         pktlen = lplen * 95 + xunchar(dest[5]) + 5;
    4573:         havelen = 1;
    4574:         debug(F101,"ttinl length","",pktlen);
    4575:         }
    4576: #else
    4577:         dest[i++] = n & ttpmsk;
    4578: #endif /* PARSENSE */
    4579:         if ((n & 0x7f) == CTRLC) {  /* Check for ^C^C */
    4580:         if (++ccn > 1) {    /* If we got 2 in a row, bail out. */
    4581:             if (timo) {     /* Clear timer. */
    4582:             ttimoff();
    4583:             }
    4584:             fprintf(stderr,"^C...\r\n"); /* Echo Ctrl-C */
    4585:             return(-2);
    4586:         }
    4587:         } else ccn = 0;     /* Not ^C, so reset ^C counter, */
    4588:
    4589: #ifdef PARSENSE
    4590:         if (flag == 0) {
    4591:         debug(F101,"ttinl skipping","",n);
    4592:         continue;
    4593:         }
    4594: #endif /* PARSENSE */
    4595:
    4596:     /* Check for end of packet */
    4597:
    4598:         if (((n & 0x7f) == eol)
    4599: #ifdef PARSENSE
    4600:         || (!turn && havelen && (i > pktlen+1))
    4601: #endif /* PARSENSE */
    4602:         ) {
    4603: #ifndef PARSENSE
    4604:         debug(F101,"ttinl got eol","",eol);
    4605:         dest[i] = '\0'; /* Yes, terminate the string, */
    4606:         /* debug(F101,"ttinl i","",i); */
    4607: #else
    4608:         if ((n & 0x7f) != eol) {
    4609:             debug(F101,"ttinl EOP length","",pktlen);
    4610:             debug(F101,"ttinl i","",i);
    4611:         } else debug(F101,"ttinl got eol","",eol);
    4612:         dest[i] = '\0';     /* Terminate the string, */
    4613:         /* Parity checked yet? */
    4614:             if (ttpflg++ == 0 && ttprty == 0) {
    4615:             if ((ttprty = parchk(dest,start,i)) > 0) { /* No, check. */
    4616:             int j;
    4617:             debug(F101,"ttinl senses parity","",ttprty);
    4618:             debug(F110,"ttinl packet before",dest,0);
    4619:             ttpmsk = 0x7f;
    4620:             for (j = 0; j < i; j++)
    4621:               dest[j] &= 0x7f;  /* Strip parity from packet */
    4622:             debug(F110,"ttinl packet after ",dest,0);
    4623:             } else ttprty = 0;  /* restore if parchk error */
    4624:         }
    4625: #endif /* PARSENSE */
    4626:         if (timo) {         /* Turn off timer. */
    4627:             ttimoff();
    4628:         }
    4629:         debug(F111,"ttinl got", dest,i);
    4630:         return(i);
    4631:         }
    4632:     }               /* end of while() */
    4633:     ttimoff();
    4634:     return(-1);
    4635:     }
    4636: }
    4637:
    4638: /*  T T I N C --  Read a character from the communication line  */
    4639: /*
    4640:  On success, returns the character that was read, >= 0.
    4641:  On failure, returns -1 or other negative myread error code.
    4642: */
    4643: int
    4644: ttinc(timo) int timo; {
    4645:
    4646:     int n = 0;
    4647: #ifndef MYREAD
    4648:     CHAR ch = 0;
    4649: #endif /* MYREAD */
    4650:
    4651:     if (ttyfd < 0) return(-1);          /* Not open. */
    4652:     if (timo <= 0) {                    /* Untimed. */
    4653: #ifdef MYREAD
    4654:         /* comm line failure returns -1 thru myread, so no &= 0377 */
    4655:     n = myread();           /* Wait for a character... */
    4656:     /* debug(F101,"ttinc MYREAD n","",n); */
    4657:     return(n < 0 ? n : n & ttpmsk);
    4658: #else
    4659:         while ((n = read(ttyfd,&ch,1)) == 0) /* Wait for a character. */
    4660:         /* Shouldn't have to loop in ver 5A. */
    4661: #ifdef NETCONN
    4662:       if (netconn) {        /* Special handling for net */
    4663:           netclos();        /* If read() returns 0 it means */
    4664:           netconn = 0;      /* the connection has dropped. */
    4665:           errno = ENOTCONN;
    4666:           return(-2);
    4667:       }
    4668: #endif /* NETCONN */
    4669:       ;
    4670:      /* debug(F000,"ttinc","",ch); */
    4671:         return( (n < 1) ? -3 : (ch & ttpmsk) );
    4672: #endif /* MYREAD */
    4673:     } else {                /* Timed read */
    4674:     int xx;
    4675:     saval = signal(SIGALRM,timerh); /* Set up handler, save old one. */
    4676:     xx = alarm(timo);       /* Set alarm, save old one. */
    4677:     /* debug(F101,"ttinc alarm","",xx); */
    4678:     if (setjmp(sjbuf)) {        /* Timer expired */
    4679:         n = -1;         /* set flag */
    4680:     } else {
    4681: #ifdef MYREAD
    4682:         n = myread();       /* If managing own buffer... */
    4683:         /* debug(F101,"ttinc myread","",n); */
    4684: #else
    4685:         n = read(ttyfd,&ch,1);  /* Otherwise call the system. */
    4686:         /* debug(F101,"ttinc read","",n); */
    4687:         if (n > 0)
    4688:           n = ch & 255;
    4689:         else
    4690:           n = (n < 0) ? -3 : -2;    /* Special return codes. */
    4691: #endif /* MYREAD */
    4692:     }
    4693:     ttimoff();          /* Turn off the timer */
    4694: /* #ifdef COMMENT */
    4695:     if (n == -1) xx -= timo;    /* and restore any previous alarm */
    4696:     if (xx < 0) xx = 0;     /* adjusted by timeout interval */
    4697:     alarm(xx);          /* if timer expired. */
    4698: /* #endif */ /* COMMENT */
    4699: #ifdef NETCONN
    4700:     if (netconn) {
    4701:         if (n == -2) {      /* read() returns 0 */
    4702:         netclos();      /* on network read failure */
    4703:         netconn = 0;
    4704:         errno = ENOTCONN;
    4705:         }
    4706:     }
    4707: #endif	/* NETCONN */
    4708:     return( (n < 0) ? n : (n & ttpmsk) ); /* Return masked char or neg. */
    4709:     }
    4710: }
    4711:
    4712: /*  S N D B R K  --  Send a BREAK signal of the given duration  */
    4713:
    4714: static int
    4715: #ifdef CK_ANSIC
    4716: sndbrk(int msec) {          /* Argument is milliseconds */
    4717: #else
    4718: sndbrk(msec) int msec; {
    4719: #endif /* CK_ANSIC */
    4720: #ifndef POSIX
    4721:     int x, n;
    4722: #endif /* POSIX */
    4723:
    4724: #ifdef ANYBSD
    4725: #define BSDBREAK
    4726: #endif /* ANYBSD */
    4727:
    4728: #ifdef BSD44
    4729: #define BSDBREAK
    4730: #endif /* BSD44 */
    4731:
    4732: #ifdef COHERENT
    4733: #define BSDBREAK
    4734: #endif /* COHERENT */
    4735:
    4736: #ifdef PROVX1
    4737:     char spd;
    4738: #endif /* PROVX1 */
    4739:
    4740:     debug(F101,"ttsndb ttyfd","",ttyfd);
    4741:     if (ttyfd < 0) return(-1);          /* Not open. */
    4742:
    4743: #ifdef NETCONN
    4744:     if (netconn)            /* Send network BREAK */
    4745:       return(netbreak());
    4746: #endif /* NETCONN */
    4747:
    4748:     if (msec < 1 || msec > 5000) return(-1); /* Bad argument */
    4749:
    4750: #ifdef POSIX                /* Easy in POSIX */
    4751:     return(tcsendbreak(ttyfd,msec / 375));
    4752: #else
    4753: #ifdef PROVX1
    4754:     gtty(ttyfd,&ttbuf);                 /* Get current tty flags */
    4755:     spd = ttbuf.sg_ospeed;              /* Save speed */
    4756:     ttbuf.sg_ospeed = B50;              /* Change to 50 baud */
    4757:     stty(ttyfd,&ttbuf);                 /*  ... */
    4758:     n = (int)strlen(brnuls);        /* Send the right number of nulls */
    4759:     x = msec / 91;
    4760:     if (x > n) x = n;
    4761:     write(ttyfd,brnuls,n);
    4762:     ttbuf.sg_ospeed = spd;              /* Restore speed */
    4763:     stty(ttyfd,&ttbuf);                 /*  ... */
    4764:     return(0);
    4765: #else
    4766: #ifdef aegis
    4767:     sio_$control((short)ttyfd, sio_$send_break, msec, st);
    4768:     return(0);
    4769: #else
    4770: #ifdef BSDBREAK
    4771:     n = FWRITE;                         /* Flush output queue. */
    4772: /* Watch out for int vs long problems in &n arg! */
    4773:     ioctl(ttyfd,TIOCFLUSH,&n);          /* Ignore any errors.. */
    4774:     if (ioctl(ttyfd,TIOCSBRK,(char *)0) < 0) {  /* Turn on BREAK */
    4775:         perror("Can't send BREAK");
    4776:         return(-1);
    4777:     }
    4778:     x = msleep(msec);                    /* Sleep for so many milliseconds */
    4779:     if (ioctl(ttyfd,TIOCCBRK,(char *)0) < 0) {  /* Turn off BREAK */
    4780:         perror("BREAK stuck!!!");
    4781:         doexit(BAD_EXIT,-1);        /* Get out, closing the line. */
    4782:                                         /*   with bad exit status */
    4783:     }
    4784:     return(x);
    4785: #else
    4786: #ifdef ATTSV
    4787: /*
    4788:   No way to send a long BREAK in Sys V, so send a bunch of regular ones.
    4789:   (Actually, Sys V R4 is *supposed* to have the POSIX tcsendbreak() function,
    4790:   but there's no way for this code to know for sure.)
    4791: */
    4792:     x = msec / 275;
    4793:     for (n = 0; n < x; n++) {
    4794:     if (ioctl(ttyfd,TCSBRK,(char *)0) < 0) {
    4795:         perror("Can't send BREAK");
    4796:         return(-1);
    4797:     }
    4798:     }
    4799:     return(0);
    4800: #else
    4801: #ifdef  V7
    4802:     return(genbrk(ttyfd,250));      /* Simulate a BREAK */
    4803: #endif /* V7 */
    4804: #endif /* BSDBREAK */
    4805: #endif /* ATTSV */
    4806: #endif /* aegis */
    4807: #endif /* PROVX1 */
    4808: #endif /* POSIX */
    4809: }
    4810:
    4811: /*  T T S N D B  --  Send a BREAK signal  */
    4812:
    4813: int
    4814: ttsndb() {
    4815:     return(sndbrk(275));
    4816: }
    4817:
    4818: /*  T T S N D L B  --  Send a Long BREAK signal  */
    4819:
    4820: int
    4821: ttsndlb() {
    4822:     return(sndbrk(1500));
    4823: }
    4824:
    4825: /*  M S L E E P  --  Millisecond version of sleep().  */
    4826:
    4827: /*
    4828:   Call with number of milliseconds (thousandths of seconds) to sleep.
    4829:   Intended only for small intervals.  For big ones, just use sleep().
    4830:   Highly system-dependent.
    4831:   Returns 0 always, even if it didn't work.
    4832: */
    4833:
    4834: /* Define MSLFTIME for systems that must use an ftime() loop. */
    4835: #ifdef ANYBSD               /* For pre-4.2 BSD versions */
    4836: #ifndef BSD4
    4837: #define MSLFTIME
    4838: #endif /* BSD4 */
    4839: #endif /* ANYBSD */
    4840:
    4841: #ifdef TOWER1               /* NCR Tower OS 1.0 */
    4842: #define MSLFTIME
    4843: #endif /* TOWER1 */
    4844:
    4845: #ifdef COHERENT             /* Coherent */
    4846: #ifndef _I386
    4847: #define MSLFTIME
    4848: #endif /* _I386 */
    4849: #endif /* COHERENT */
    4850:
    4851: int
    4852: msleep(m) int m; {
    4853:
    4854: #ifndef USLEEP
    4855: #ifdef SUNOS4               /* Systems that have usleep() */
    4856: #define USLEEP
    4857: #endif /* SUNOS4 */
    4858: #ifdef SUN4S5
    4859: #define USLEEP
    4860: #endif /* SUN4S5 */
    4861: #ifdef NEXT
    4862: #define USLEEP
    4863: #endif /* NEXT*/
    4864: #endif /* USLEEP */
    4865:
    4866: #ifdef AIXRS                /* RS/6000 can do select() */
    4867: #define BSD42
    4868: #endif /* AIXRS */
    4869:
    4870: #ifndef SELECT
    4871: #ifdef BSD44
    4872: #define SELECT
    4873: #endif /* BSD44 */
    4874: #ifdef BSD42
    4875: #define SELECT
    4876: #endif /* BSD42 */
    4877: #endif /* SELECT */
    4878:
    4879: #ifdef SELECT
    4880: /* BSD 4.2 & above can do it with select()... */
    4881:     int t1;
    4882:     if (m <= 0) return(0);
    4883:     if (m >= 1000) {            /* Catch big arguments. */
    4884:     sleep(m/1000);
    4885:     m = m % 1000;
    4886:     if (m < 10) return(0);
    4887:     }
    4888:     if (gettimeofday(&tv, &tz) < 0) return(-1); /* Get current time. */
    4889:     t1 = tv.tv_sec;                     /* Seconds */
    4890:     tv.tv_sec = 0;                      /* Use select() */
    4891:     tv.tv_usec = m * 1000L;
    4892: #ifdef BSD44
    4893:     select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
    4894: #else
    4895: #ifdef BSD43
    4896:     select( 0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
    4897: #else
    4898:     select( 0, (int *)0, (int *)0, (int *)0, &tv );
    4899: #endif /* BSD43 */
    4900: #endif /* BSD44 */
    4901:     return(0);
    4902:
    4903: #else                   /* Not SELECT */
    4904:
    4905: #ifdef USLEEP
    4906: /*
    4907:   "This routine is implemented using setitimer(2); it requires eight
    4908:   system calls...".  In other words, it might take 5 minutes to sleep
    4909:   for 100 milliseconds...
    4910: */
    4911:     if (m >= 1000) {            /* Catch big arguments. */
    4912:     sleep(m/1000);
    4913:     m = m % 1000;
    4914:     if (m < 10) return(0);
    4915:     }
    4916:     usleep((unsigned int)(m * 1000));
    4917:     return(0);
    4918: #else
    4919: #ifdef aegis
    4920:     time_$clock_t dur;
    4921:
    4922:     dur.c2.high16 = 0;
    4923:     dur.c2.low32  = 250 * m; /* one millisecond = 250 four microsecond ticks */
    4924:     time_$wait(time_$relative, dur, st);
    4925:     return(0);
    4926: #else
    4927: #ifdef PROVX1
    4928:     if (m <= 0) return(0);
    4929:     sleep(-((m * 60 + 500) / 1000));
    4930:     return(0);
    4931: #else
    4932: #ifdef NAP
    4933:     nap((long)m);
    4934:     return(0);
    4935: #else
    4936: #ifdef ATTSV
    4937: #ifndef BSD44
    4938:     extern long times();        /* Or #include <times.h> ? */
    4939: #endif /* BSD44 */
    4940:     long t1, t2, tarray[4];
    4941:     int t3;
    4942:
    4943: #ifdef COMMENT
    4944: /* This better be picked up in ckcdeb.h... */
    4945:     char *getenv();
    4946: #endif /* COMMENT */
    4947:     char *cp = getenv("HZ");
    4948:     int CLOCK_TICK;
    4949:     int hertz;
    4950:
    4951:     if (cp && (hertz = atoi(cp))) {
    4952:         CLOCK_TICK  = 1000 / hertz;
    4953:     } else {                /* probably single user mode */
    4954: #ifdef HZ
    4955:         CLOCK_TICK  = 1000 / HZ;
    4956: #else
    4957:     static warned = 0;
    4958:     /* HZ always exists in, for instance, SCO Xenix, so you don't have to
    4959: 	 * make special #ifdefs for XENIX here, like in ver 4F. Also, if you
    4960: 	 * have Xenix, you have should have nap(), so the best is to use -DNAP
    4961: 	 * in the makefile. Most systems have HZ.
    4962: 	 */
    4963:     CLOCK_TICK = 17;        /* 1/60 sec */
    4964:     if (!warned) {
    4965:           printf("warning: environment variable HZ bad... using HZ=%d\r\n",
    4966:          1000 / CLOCK_TICK);
    4967:           warned = 1;
    4968:     }
    4969: #endif /* !HZ */
    4970:     }
    4971:
    4972:     if (m <= 0) return(0);
    4973:     if (m >= 1000) {            /* Catch big arguments. */
    4974:     sleep(m/1000);
    4975:     m = m % 1000;
    4976:     if (m < 10) return(0);
    4977:     }
    4978:     if ((t1 = times(tarray)) < 0) return(-1);
    4979:     while (1) {
    4980:         if ((t2 = times(tarray)) < 0) return(-1);
    4981:         t3 = ((int)(t2 - t1)) * CLOCK_TICK;
    4982:         if (t3 > m) return(t3);
    4983:     }
    4984: #else /* Not ATTSV */
    4985: #ifdef MSLFTIME             /* Use ftime() loop... */
    4986:     int t1, t3 = 0;
    4987:     if (m <= 0) return(0);
    4988:     if (m >= 1000) {            /* Catch big arguments. */
    4989:     sleep(m/1000);
    4990:     m = m % 1000;
    4991:     if (m < 10) return(0);
    4992:     }
    4993:     if (ftime(&ftp) < 0) return(-1);    /* Get base time. */
    4994:     t1 = ((ftp.time & 0xff) * 1000) + ftp.millitm;
    4995:     while (1) {
    4996:         ftime(&ftp);            /* Get current time and compare. */
    4997:         t3 = (((ftp.time & 0xff) * 1000) + ftp.millitm) - t1;
    4998:         if (t3 > m) return(0);
    4999:     }
    5000: #else
    5001: /* This includes true POSIX, which has no way to do this. */
    5002:     if (m >= 1000) {            /* Catch big arguments. */
    5003:     sleep(m/1000);
    5004:     m = m % 1000;
    5005:     if (m < 10) return(0);
    5006:     }
    5007:     if (m > 0) while (m > 0) m--;   /* Just a dumb busy loop */
    5008:     return(0);
    5009: #endif /* MSLFTIME */
    5010: #endif /* ATTSV */
    5011: #endif /* NAP */
    5012: #endif /* PROVX1 */
    5013: #endif /* aegis */
    5014: #endif /* SELECT */
    5015: #endif /* USLEEP */
    5016: }
    5017:
    5018: /*  R T I M E R --  Reset elapsed time counter  */
    5019:
    5020: VOID
    5021: rtimer() {
    5022:     tcount = time( (time_t *) 0 );
    5023: }
    5024:
    5025:
    5026: /*  G T I M E R --  Get current value of elapsed time counter in seconds  */
    5027:
    5028: int
    5029: gtimer() {
    5030:     int x;
    5031:     x = (int) (time( (time_t *) 0 ) - tcount);
    5032:     debug(F101,"gtimer","",x);
    5033:     return( (x < 0) ? 0 : x );
    5034: }
    5035:
    5036:
    5037: /*  Z T I M E  --  Return date/time string  */
    5038:
    5039: VOID
    5040: ztime(s) char **s; {
    5041:
    5042: #undef ZTIMEV7              /* Which systems need to use */
    5043: #ifdef COHERENT             /* old UNIX Version 7 way... */
    5044: #define ZTIMEV7
    5045: #endif /* COHERENT */
    5046: #ifdef TOWER1
    5047: #define ZTIMEV7
    5048: #endif /* TOWER1 */
    5049: #ifdef ANYBSD
    5050: #ifndef BSD42
    5051: #define ZTIMEV7
    5052: #endif /* BSD42 */
    5053: #endif /* ANYBSD */
    5054: #ifdef V7
    5055: #ifndef MINIX
    5056: #define ZTIMEV7
    5057: #endif /* MINIX */
    5058: #endif /* V7 */
    5059: #ifdef POSIX
    5060: #define ZTIMEV7
    5061: #endif /* POSIX */
    5062:
    5063: #ifdef ATTSV                /* AT&T way */
    5064: /*  extern long time(); */      /* Theoretically these should */
    5065:     char *ctime();          /* already been dcl'd in <time.h> */
    5066:     long clock_storage;
    5067:     clock_storage = time( (long *) 0 );
    5068:     *s = ctime( &clock_storage );
    5069: #else
    5070: #ifdef PROVX1               /* Venix 1.0 way */
    5071:     int utime[2];
    5072:     time(utime);
    5073:     *s = ctime(utime);
    5074: #else
    5075: #ifdef BSD42                /* 4.2BSD way */
    5076:     char *asctime();
    5077:     struct tm *localtime();
    5078:     struct tm *tp;
    5079:     gettimeofday(&tv, &tz);
    5080:     time(&tv.tv_sec);
    5081:     tp = localtime(&tv.tv_sec);
    5082:     *s = asctime(tp);
    5083: #else
    5084: #ifdef MINIX                /* MINIX way */
    5085: #ifdef COMMENT
    5086:     extern long time();         /* Already got these from <time.h> */
    5087:     extern char *ctime();
    5088: #endif /* COMMENT */
    5089:     time_t utime[2];
    5090:     time(utime);
    5091:     *s = ctime(utime);
    5092: #else
    5093: #ifdef ZTIMEV7              /* The regular way */
    5094:     char *asctime();
    5095:     struct tm *localtime();
    5096:     struct tm *tp;
    5097:     long xclock;
    5098:     time(&xclock);
    5099:     tp = localtime(&xclock);
    5100:     *s = asctime(tp);
    5101: #else                   /* Catch-all for others... */
    5102:     *s = "Ddd Mmm 00 00:00:00 0000\n"   /* Return dummy in asctime() format */
    5103: #endif /* ZTIMEV7 */
    5104: #endif /* MINIX */
    5105: #endif /* BSD42 */
    5106: #endif /* PROVX1 */
    5107: #endif /* SVORPOSIX */
    5108: }
    5109:
    5110: /*  C O N G M  --  Get console terminal modes.  */
    5111:
    5112: /*
    5113:   Saves initial console mode, and establishes variables for switching
    5114:   between current (presumably normal) mode and other modes.
    5115:   Should be called when program starts, but only after establishing
    5116:   whether program is in the foreground or background.
    5117:   Returns 1 if it got the modes OK, 0 if it did nothing, -1 on error.
    5118: */
    5119: int
    5120: congm() {
    5121:     int fd;
    5122:     if (backgrd || !isatty(0)) {    /* If in background. */
    5123:     cgmf = -1;          /* Don't bother, modes are garbage. */
    5124:     return(-1);
    5125:     }
    5126:     if (cgmf > 0) return(0);        /* Already did this. */
    5127:     debug(F100,"congm getting modes","",0); /* Need to do it. */
    5128: #ifdef aegis
    5129:     ios_$inq_type_uid(ios_$stdin, conuid, st);
    5130:     if (st.all != status_$ok) {
    5131:     fprintf(stderr, "problem getting stdin objtype: ");
    5132:     error_$print(st);
    5133:     }
    5134:     concrp = (conuid == mbx_$uid);
    5135:     conbufn = 0;
    5136: #endif /* aegis */
    5137:
    5138:     if ((fd = open(CTTNAM,2)) < 0) {    /* Open controlling terminal */
    5139:     fprintf(stderr,"Error opening %s\n", CTTNAM);
    5140:     perror("congm");
    5141:     return(-1);
    5142:     }
    5143: #ifdef BSD44ORPOSIX
    5144:     if (tcgetattr(fd,&ccold) < 0) return(-1);
    5145:     if (tcgetattr(fd,&cccbrk) < 0) return(-1);
    5146:     if (tcgetattr(fd,&ccraw) < 0) return(-1);
    5147: #else
    5148: #ifdef ATTSV
    5149:     if (ioctl(fd,TCGETA,&ccold)  < 0) return(-1);
    5150:     if (ioctl(fd,TCGETA,&cccbrk) < 0) return(-1);
    5151:     if (ioctl(fd,TCGETA,&ccraw)  < 0) return(-1);
    5152: #ifdef VXVE
    5153:     cccbrk.c_line = 0;          /* STTY line 0 for CDC VX/VE */
    5154:     if (ioctl(fd,TCSETA,&cccbrk) < 0) return(-1);
    5155:     ccraw.c_line = 0;           /* STTY line 0 for CDC VX/VE */
    5156:     if (ioctl(fd,TCSETA,&ccraw) < 0) return(-1);
    5157: #endif /* VXVE */
    5158: #else
    5159:     if (gtty(fd,&ccold) < 0) return(-1);
    5160:     if (gtty(fd,&cccbrk) < 0) return(-1);
    5161:     if (gtty(fd,&ccraw) < 0) return(-1);
    5162: #endif /* ATTSV */
    5163: #endif /* BSD44ORPOSIX */
    5164: #ifdef sony_news            /* Sony NEWS */
    5165:     if (ioctl(fd,TIOCKGET,&km_con) < 0) { /* Get console Kanji mode */
    5166:     perror("congm error getting Kanji mode");
    5167:     debug(F101,"congm error getting Kanji mode","",0);
    5168:     km_con = -1;            /* Make sure this stays undefined. */
    5169:     return(-1);
    5170:     }
    5171: #endif /* sony_news */
    5172:     close(fd);
    5173:     cgmf = 1;               /* Flag that we got them. */
    5174:     return(1);
    5175: }
    5176:
    5177:
    5178: /*  C O N C B --  Put console in cbreak mode.  */
    5179:
    5180: /*  Returns 0 if ok, -1 if not  */
    5181:
    5182: int
    5183: #ifdef CK_ANSIC
    5184: concb(char esc)
    5185: #else
    5186: concb(esc) char esc;
    5187: #endif /* CK_ANSIC */
    5188: /* concb */ {
    5189:     int x;
    5190:     if (cgmf < 1) return(0);        /* Console modes not available yet */
    5191:     if (ttfdflg && ttyfd >= 0 && ttyfd < 3)
    5192:       return(0);
    5193:     debug(F101,"concb backgrd","",backgrd);
    5194:     if (!isatty(0)) return(0);          /* Only for real ttys */
    5195:     debug(F100,"concb isatty","",0);
    5196:     if (backgrd) return(0);     /* Do nothing if in background. */
    5197:     escchr = esc;                       /* Make this available to other fns */
    5198:     ckxech = 1;                         /* Program can echo characters */
    5199: #ifdef aegis
    5200:     conbufn = 0;
    5201:     if (concrp) return(write(1, "\035\002", 2));
    5202:     if (conuid == input_pad_$uid) {pad_$raw(ios_$stdin, st); return(0);}
    5203: #endif
    5204: #ifndef SVORPOSIX           /* BSD, V7, etc */
    5205:     cccbrk.sg_flags |= CBREAK;          /* Set to character wakeup, */
    5206:     cccbrk.sg_flags &= ~ECHO;           /* no echo. */
    5207:     x = stty(0,&cccbrk);
    5208: #else                   /* Sys V and POSIX */
    5209:     cccbrk.c_lflag &= ~(ICANON|ECHO|IEXTEN);
    5210: #ifndef VINTR
    5211:     cccbrk.c_cc[0] = 003;               /* interrupt char is control-c */
    5212: #else
    5213:     cccbrk.c_cc[VINTR] = 003;
    5214: #endif /* VINTR */
    5215: #ifndef VQUIT
    5216:     cccbrk.c_cc[1] = escchr;            /* escape during packet modes */
    5217: #else
    5218:     cccbrk.c_cc[VQUIT] = escchr;
    5219: #endif /* VQUIT */
    5220: #ifndef VEOF
    5221:     cccbrk.c_cc[4] = 1;
    5222: #else
    5223: #ifdef VMIN
    5224:     cccbrk.c_cc[VMIN] = 1;
    5225: #endif /* VMIN */
    5226: #endif /* VEOF */
    5227: #ifdef ZILOG
    5228:     cccbrk.c_cc[5] = 0;
    5229: #else
    5230: #ifndef VEOL
    5231:     cccbrk.c_cc[5] = 1;
    5232: #else
    5233: #ifdef VTIME
    5234:     cccbrk.c_cc[VTIME] = 1;
    5235: #endif /* VTIME */
    5236: #endif /* VEOL */
    5237: #endif /* ZILOG */
    5238: #ifdef BSD44ORPOSIX         /* Set new modes */
    5239:     x = tcsetattr(0,TCSADRAIN,&cccbrk);
    5240: #else /* ATTSV */               /* or the POSIX way */
    5241:     x = ioctl(0,TCSETAW,&cccbrk);   /* the Sys V way */
    5242: #endif /* BSD44ORPOSIX */
    5243: #endif /* SVORPOSIX */
    5244:
    5245: #ifndef aegis
    5246: #ifndef NOSETBUF
    5247:     if (x > -1) setbuf(stdout,NULL);    /* Make console unbuffered. */
    5248: #endif /* NOSETBUF */
    5249: #endif /* aegis */
    5250:
    5251: #ifdef  V7
    5252: #ifndef MINIX
    5253:     if (kmem[CON] < 0) {
    5254:         qaddr[CON] = initrawq(0);
    5255:         if((kmem[CON] = open("/dev/kmem", 0)) < 0) {
    5256:             fprintf(stderr, "Can't read /dev/kmem in concb.\n");
    5257:             perror("/dev/kmem");
    5258:             exit(1);
    5259:         }
    5260:     }
    5261: #endif /* MINIX */
    5262: #endif /* V7 */
    5263:     debug(F101,"concb returns","",x);
    5264:     return(x);
    5265: }
    5266:
    5267: /*  C O N B I N  --  Put console in binary mode  */
    5268:
    5269: /*  Returns 0 if ok, -1 if not  */
    5270:
    5271: int
    5272: #ifdef CK_ANSIC
    5273: conbin(char esc)
    5274: #else
    5275: conbin(esc) char esc;
    5276: #endif /* CK_ANSIC */
    5277: /* conbin */  {
    5278:     if (!isatty(0)) return(0);          /* only for real ttys */
    5279:     congm();                /* Get modes if necessary. */
    5280:     debug(F100,"conbin","",0);
    5281:     escchr = esc;                       /* Make this available to other fns */
    5282:     ckxech = 1;                         /* Program can echo characters */
    5283: #ifdef aegis
    5284:     conbufn = 0;
    5285:     if (concrp) return(write(1, "\035\002", 2));
    5286:     if (conuid == input_pad_$uid)
    5287:       pad_$raw(ios_$stdin, st);
    5288:     return(0)
    5289: #endif /* aegis */
    5290:
    5291: #ifdef SVORPOSIX
    5292:     ccraw.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
    5293:     ccraw.c_iflag |= (BRKINT|IGNPAR);
    5294: #ifdef ATTSV
    5295: #ifdef BSD44
    5296:     ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF
    5297:                         |INPCK|ISTRIP);
    5298: #else
    5299:     ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXANY|IXOFF
    5300:                         |INPCK|ISTRIP);
    5301: #endif /* BSD44 */
    5302: #else /* POSIX */
    5303:     ccraw.c_iflag &= ~(IGNBRK|INLCR|IGNCR|ICRNL|IXON|IXOFF|INPCK|ISTRIP);
    5304: #endif /* ATTSV */
    5305:     ccraw.c_oflag &= ~OPOST;
    5306: #ifdef ATT7300
    5307:     ccraw.c_cflag = CLOCAL | B9600 | CS8 | CREAD | HUPCL;
    5308: #endif /* ATT7300 */
    5309: /*** Kermit used to put the console in 8-bit raw mode, but some users have
    5310:  *** pointed out that this should not be done, since some sites actually
    5311:  *** use terminals with parity settings on their Unix systems, and if we
    5312:  *** override the current settings and stop doing parity, then their terminals
    5313:  *** will display blotches for characters whose parity is wrong.  Therefore,
    5314:  *** the following two lines are commented out (Larry Afrin, Clemson U):
    5315:  ***
    5316:  ***   ccraw.c_cflag &= ~(PARENB|CSIZE);
    5317:  ***   ccraw.c_cflag |= (CS8|CREAD);
    5318:  ***
    5319:  *** Sys III/V sites that have trouble with this can restore these lines.
    5320:  ***/
    5321: #ifndef VINTR
    5322:     ccraw.c_cc[0] = 003;        /* Interrupt char is Ctrl-C */
    5323: #else
    5324:     ccraw.c_cc[VINTR] = 003;
    5325: #endif /* VINTR */
    5326: #ifndef VQUIT
    5327:     ccraw.c_cc[1] = escchr;     /* Escape during packet mode */
    5328: #else
    5329:     ccraw.c_cc[VQUIT] = escchr;
    5330: #endif /* VQUIT */
    5331: #ifndef VEOF
    5332:     ccraw.c_cc[4] = 1;
    5333: #else
    5334: #ifdef VMIN
    5335:     ccraw.c_cc[VMIN] = 1;
    5336: #endif
    5337: #endif /* VEOF */
    5338:
    5339: #ifdef ZILOG
    5340:     ccraw.c_cc[5] = 0;
    5341: #else
    5342: #ifndef VEOL
    5343:     ccraw.c_cc[5] = 1;
    5344: #else
    5345: #ifdef VTIME
    5346:     ccraw.c_cc[VTIME] = 1;
    5347: #endif /* VTIME */
    5348: #endif /* VEOL */
    5349: #endif /* ZILOG */
    5350:
    5351: #ifdef BSD44ORPOSIX
    5352:     return(tcsetattr(0,TCSADRAIN,&ccraw));
    5353: #else
    5354:     return(ioctl(0,TCSETAW,&ccraw));    /* Set new modes. */
    5355: #endif /* BSD44ORPOSIX */
    5356:
    5357: #else /* Berkeley, etc. */
    5358:     ccraw.sg_flags |= (RAW|TANDEM);     /* Set rawmode, XON/XOFF (ha) */
    5359:     ccraw.sg_flags &= ~(ECHO|CRMOD);    /* Set char wakeup, no echo */
    5360:     return(stty(0,&ccraw));
    5361: #endif /* SVORPOSIX */
    5362: }
    5363:
    5364:
    5365: /*  C O N R E S  --  Restore the console terminal  */
    5366:
    5367: int
    5368: conres() {
    5369:     debug(F101,"conres cgmf","",cgmf);
    5370:     if (cgmf < 1) return(0);        /* Do nothing if modes unchanged */
    5371:     if (!isatty(0)) return(0);          /* only for real ttys */
    5372:     debug(F100,"conres isatty ok","",0);
    5373:     ckxech = 0;                         /* System should echo chars */
    5374:
    5375: #ifdef aegis
    5376:     conbufn = 0;
    5377:     if (concrp) return(write(1, "\035\001", 2));
    5378:     if (conuid == input_pad_$uid)
    5379:       pad_$cooked(ios_$stdin, st);
    5380:     return(0);
    5381: #endif /* aegis */
    5382:
    5383: #ifdef BSD44ORPOSIX
    5384:     debug(F100,"conres restoring tcsetattr","",0);
    5385:     return(tcsetattr(0,TCSADRAIN,&ccold));
    5386: #else
    5387: #ifdef ATTSV
    5388:     debug(F100,"conres restoring ioctl","",0);
    5389:     return(ioctl(0,TCSETAW,&ccold));
    5390: #else /* BSD, V7, and friends */
    5391: #ifdef sony_news            /* Sony NEWS */
    5392:     if (km_con != -1)
    5393:       ioctl(0,TIOCKSET,&km_con);    /* Restore console Kanji mode */
    5394: #endif /* sony_news */
    5395:     msleep(300);
    5396:     debug(F100,"conres restoring stty","",0);
    5397:     return(stty(0,&ccold));
    5398: #endif /* ATTSV */
    5399: #endif /* BSD44ORPOSIX */
    5400: }
    5401:
    5402: /*  C O N O C  --  Output a character to the console terminal  */
    5403:
    5404: int
    5405: #ifdef CK_ANSIC
    5406: conoc(char c)
    5407: #else
    5408: conoc(c) char c;
    5409: #endif /* CK_ANSIC */
    5410: /* conoc */ {
    5411:     return(write(1,&c,1));
    5412: }
    5413:
    5414: /*  C O N X O  --  Write x characters to the console terminal  */
    5415:
    5416: int
    5417: conxo(x,s) int x; char *s; {
    5418:     return(write(1,s,x));
    5419: }
    5420:
    5421: /*  C O N O L  --  Write a line to the console terminal  */
    5422:
    5423: int
    5424: conol(s) char *s; {
    5425:     int len;
    5426:     len = (int)strlen(s);
    5427:     return(write(1,s,len));
    5428: }
    5429:
    5430: /*  C O N O L A  --  Write an array of lines to the console terminal */
    5431:
    5432: int
    5433: conola(s) char *s[]; {
    5434:     int i;
    5435:     for (i=0 ; *s[i] ; i++) if (conol(s[i]) < 0) return(-1);;
    5436:     return(0);
    5437: }
    5438:
    5439: /*  C O N O L L  --  Output a string followed by CRLF  */
    5440:
    5441: int
    5442: conoll(s) char *s; {
    5443:     conol(s);
    5444:     return(write(1,"\r\n",2));
    5445: }
    5446:
    5447: /*  C O N C H K  --  Return how many characters available at console  */
    5448:
    5449: int
    5450: conchk() {
    5451:     int x; PEEKTYPE n;
    5452:
    5453:     if (backgrd || !isatty(0)) return(0);
    5454: #ifdef PROVX1
    5455:     x = ioctl(0, TIOCQCNT, &ttbuf);
    5456:     n = ttbuf.sg_ispeed & 0377;
    5457:     return((x < 0) ? 0 : n);
    5458: #else
    5459: #ifdef aegis
    5460:     if (conbufn > 0) return(conbufn);   /* use old count if nonzero */
    5461:
    5462:     /* read in more characters */
    5463:     conbufn = ios_$get(ios_$stdin,
    5464:               ios_$cond_opt, conbuf, (long)sizeof(conbuf), st);
    5465:     if (st.all != status_$ok) conbufn = 0;
    5466:     conbufp = conbuf;
    5467:     return(conbufn);
    5468: #else
    5469: #ifdef V7
    5470: #ifdef MINIX
    5471:     return(0);
    5472: #else
    5473:     lseek(kmem[CON], (long) qaddr[CON], 0);
    5474:     x = read(kmem[CON], &n, sizeof(int));
    5475:     return((x == sizeof(int))? n: 0);
    5476: #endif /* MINIX */
    5477: #else
    5478: #ifdef SVORPOSIX
    5479:     if (conesc) {                       /* Escape typed */
    5480:         debug(F100,"conchk returns conesc","",conesc);
    5481:         conesc = 0;
    5482:         signal(SIGQUIT,esctrp);         /* Restore escape */
    5483:         return(1);
    5484:     }
    5485:     return(0);
    5486: #else
    5487: #ifdef C70
    5488:     if (conesc) {                       /* Escape typed */
    5489:         conesc = 0;
    5490:         signal(SIGQUIT,esctrp);         /* Restore escape */
    5491:         return(1);
    5492:     }
    5493:     return(0);
    5494: #else
    5495: #ifdef FIONREAD
    5496: /*
    5497:   Reportedly, this can cause C-Kermit to be suspended on certain OS's,
    5498:   such as Olivetti X/OS, when called if Kermit is really in the background.
    5499:   Hence the change at the top of this routine to return 0 if the backgrd
    5500:   flag is set.
    5501: */
    5502:     x = ioctl(0, FIONREAD, &n);         /* BSD and maybe some others */
    5503:     debug(F101,"conchk","",n);
    5504:     return((x < 0) ? 0 : n);
    5505: #else
    5506:     return(0);                          /* Others can't do. */
    5507: #endif
    5508: #endif
    5509: #endif
    5510: #endif
    5511: #endif
    5512: #endif
    5513: }
    5514:
    5515: /*  C O N I N C  --  Get a character from the console  */
    5516: /*
    5517:   Call with timo > 0 to do a timed read, timo == 0 to do an untimed blocking
    5518:   read.  Upon success, returns the character.  Upon failure, returns -1.
    5519:   A timed read that does not complete within the timeout period returns -1.
    5520: */
    5521: int
    5522: coninc(timo) int timo; {
    5523:     int n = 0; CHAR ch;
    5524:     int xx;
    5525: #ifdef aegis                /* Apollo Aegis only... */
    5526:     debug(F101,"coninc timo","",timo);
    5527:     fflush(stdout);
    5528:     if (conchk() > 0) {
    5529:     --conbufn;
    5530:     return(*conbufp++ & 0377);
    5531:     }
    5532: #endif /* aegis */
    5533:
    5534:     if (timo <= 0 ) {                   /* Untimed, blocking read. */
    5535:     while (1) {         /* Keep trying till we get one. */
    5536:         n = read(0, &ch, 1);    /* Read a character. */
    5537:         if (n == 0) continue;   /* Shouldn't happen. */
    5538:         if (n > 0)          /* If read was successful, */
    5539:           return(ch & 0377);    /* return the character. */
    5540:
    5541: /* Come here if read() returned an error. */
    5542:
    5543:         debug(F101, "coninc(0) errno","",errno); /* Log the error. */
    5544: #ifdef SVORPOSIX
    5545: #ifdef CIE                             /* CIE Regulus has no EINTR symbol? */
    5546: #ifndef EINTR
    5547: #define EINTR 4
    5548: #endif /* EINTR */
    5549: #endif /* CIE */
    5550: /*
    5551:   This routine is used for several different purposes.  In CONNECT mode, it is
    5552:   used to do an untimed, blocking read from the keyboard in the lower CONNECT
    5553:   fork.  During local-mode file transfer, it reads a character from the
    5554:   console to interrupt the file transfer (like A for a status report, X to
    5555:   cancel a file, etc).  Obviously, we don't want the reads in the latter case
    5556:   to be blocking, or the file transfer would stop until the user typed
    5557:   something.  Unfortunately, System V does not allow the console device input
    5558:   buffer to be sampled nondestructively (e.g. by conchk()), so a kludge is
    5559:   used instead.  During local-mode file transfer, the SIGQUIT signal is armed
    5560:   and trapped by esctrp(), and this routine pretends to have read the quit
    5561:   character from the keyboard normally.  But, kludge or no kludge, the read()
    5562:   issued by this command, under System V only, can fail if a signal -- ANY
    5563:   signal -- is caught while the read is pending.  This can occur not only when
    5564:   the user types the quit character, but also during telnet negotiations, when
    5565:   the lower CONNECT fork signals the upper one about an echoing mode change.
    5566:   When this happens, we have to post the read() again.  This is apparently not
    5567:   a problem in BSD-based UNIX versions.
    5568: */
    5569:         if (errno == EINTR)     /* Read interrupted. */
    5570:           if (conesc)  {        /* If by SIGQUIT, */
    5571:          conesc = 0;        /* the conesc variable is set, */
    5572:          return(escchr);    /* so return the escape character. */
    5573:          } else continue;       /* By other signal, try again. */
    5574: #else
    5575: /*
    5576:   This might be dangerous, but let's do this on non-System V versions too,
    5577:   since at least one SunOS 4.1.2 user complains of immediate disconnections
    5578:   upon first making a TELNET connection.
    5579: */
    5580:         if (errno == EINTR)     /* Read interrupted. */
    5581:           continue;
    5582: #endif /* SVORPOSIX */
    5583:         return(-1);         /* Error */
    5584:     }
    5585:     }
    5586:
    5587:     if (timo <= 0)
    5588:       /* This should never happen */
    5589:       debug(F100,"coninc HORRIBLE ERROR","",0);
    5590:
    5591: /* Timed read... */
    5592:
    5593:     saval = signal(SIGALRM,timerh); /* Set up timeout handler. */
    5594:     xx = alarm(timo);           /* Set the alarm. */
    5595:     debug(F101,"coninc alarm","",xx);
    5596:     if (setjmp(sjbuf))          /* The read() timed out. */
    5597:       n = -2;               /* Code for timeout. */
    5598:     else
    5599:       n = read(0, &ch, 1);
    5600:     ttimoff();              /* Turn off timer */
    5601:     if (n > 0)              /* Got character OK. */
    5602:       return(ch & 0377);        /* Return it. */
    5603:
    5604: /*
    5605:   Read returned an error.  Same deal as above, but without the loop.
    5606: */
    5607:     debug(F101, "coninc(timo) n","",n);
    5608:     debug(F101, "coninc(timo) errno","",errno);
    5609: #ifdef SVORPOSIX
    5610:     if (n == -1 && errno == EINTR && conesc != 0) {
    5611:     conesc = 0;
    5612:     return(escchr);         /* User entered escape character. */
    5613:     } else              /* n == 0 shouldn't happen. */
    5614: #endif /* SVORPOSIX */
    5615:       return(-1);
    5616: }
    5617:
    5618: /*  C O N G K S  --  Console Get Keyboard Scancode  */
    5619:
    5620: #ifndef congks
    5621: /*
    5622:   This function needs to be filled in with the various system-dependent
    5623:   system calls used by SUNOS, NeXT OS, Xenix, Aviion, etc, to read a full
    5624:   keyboard scan code.  For now, it's a dummy.
    5625: */
    5626: int
    5627: congks(timo) int timo; {
    5628:     return(coninc(timo));
    5629: }
    5630: #endif /* congks */
    5631:
    5632: #ifdef ATT7300
    5633:
    5634: /*  A T T D I A L  --  Dial up the remote system using internal modem
    5635:  * Purpose: to open and dial a number on the internal modem available on the
    5636:  * ATT7300 UNIX PC.  Written by Joe Doupnik. Superceeds version written by
    5637:  * Richard E. Hill, Dickinson, TX. which employed dial(3c).
    5638:  * Uses information in <sys/phone.h> and our status int attmodem.
    5639:  */
    5640: attdial(ttname,speed,telnbr) char *ttname,*telnbr; long speed; {
    5641:     char *telnum;
    5642:     int ttclos();
    5643:
    5644:     attmodem &= ~ISMODEM;                       /* modem not in use yet */
    5645:                     /* Ensure O_NDELAY is set, else i/o traffic hangs */
    5646:                     /* We turn this flag off once the dial is complete */
    5647:     fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) | O_NDELAY);
    5648:
    5649:     /* Condition line, check availability & DATA mode, turn on speaker */
    5650:     if (ioctl(ttyfd,PIOCOFFHOOK, &dialer) == -1) {
    5651:         printf("cannot access phone\n");
    5652:         ttclos(0);
    5653:         return (-2);
    5654:     }
    5655:     ioctl(ttyfd,PIOCGETP,&dialer);      /* get phone dialer parameters */
    5656:
    5657:     if (dialer.c_lineparam & VOICE) {   /* phone must be in DATA mode */
    5658:         printf(" Should not dial with modem in VOICE mode.\n");
    5659:         printf(" Exit Kermit, switch to DATA and retry call.\n");
    5660:         ttclos(0);
    5661:         return (-2);
    5662:     }
    5663: #ifdef ATTTONED             /* Old way, tone dialing only. */
    5664:     dialer.c_lineparam = DATA | DTMF;   /* Dial with tones, */
    5665:     dialer.c_lineparam &= ~PULSE;   /* not with pulses. */
    5666: #else
    5667:     /* Leave current pulse/tone state alone. */
    5668:     /* But what about DATA?  Add it back if you have trouble. */
    5669:     /* sys/phone says you get DATA automatically by opening device RDWR */
    5670: #endif
    5671:     dialer.c_waitdialtone = 5;                  /* wait 5 sec for dialtone */
    5672: #ifdef COMMENT
    5673:     dialer.c_feedback = SPEAKERON|NORMSPK|RINGON;  /* control speaker */
    5674: #else
    5675:     /* sys/phone says RINGON used only for incoming voice calls */
    5676:     dialer.c_feedback &= ~(SOFTSPK|LOUDSPK);
    5677:     dialer.c_feedback |= SPEAKERON|NORMSPK;
    5678: #endif
    5679:     dialer.c_waitflash = 500;                   /* 0.5 sec flash hook */
    5680:     if(ioctl(ttyfd,PIOCSETP,&dialer) == -1) {   /* set phone parameters */
    5681:         printf("Cannot set modem characteristics\n");
    5682:         ttclos(0);
    5683:         return (-2);
    5684:     }
    5685:     ioctl(ttyfd,PIOCRECONN,0);      /* Turns on speaker for pulse */
    5686:
    5687: #ifdef COMMENT
    5688:     fprintf(stderr,"Phone line status. line_par:%o dialtone_wait:%o \
    5689: line_status:%o feedback:%o\n",
    5690:     dialer.c_lineparam, dialer.c_waitdialtone,
    5691:     dialer.c_linestatus, dialer.c_feedback);
    5692: #endif
    5693:
    5694:     attmodem |= ISMODEM;                        /* modem is now in-use */
    5695:     sleep(1);
    5696:     for (telnum = telnbr; *telnum != '\0'; telnum++)    /* dial number */
    5697: #ifdef ATTTONED
    5698:       /* Tone dialing only */
    5699:       if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
    5700:       perror("Error in dialing");
    5701:       ttclos(0);
    5702:       return(-2);
    5703:       }
    5704: #else /* Allow Pulse or Tone dialing */
    5705:     switch (*telnum) {
    5706:       case 't': case 'T': case '%': /* Tone dialing requested */
    5707:     dialer.c_lineparam |= DTMF;
    5708:     dialer.c_lineparam &= ~PULSE;
    5709:     if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
    5710:         printf("Cannot set modem to tone dialing\n");
    5711:         ttclos(0);
    5712:         return(-2);
    5713:     }
    5714:     break;
    5715:       case 'd': case 'D': case 'p': case 'P': case '^':
    5716:     dialer.c_lineparam |= PULSE;
    5717:     dialer.c_lineparam &= ~DTMF;
    5718:     if (ioctl(ttyfd,PIOCSETP,&dialer) == -1) {
    5719:         printf("Cannot set modem to pulse dialing\n");
    5720:         ttclos(0);
    5721:         return(-2);
    5722:     }
    5723:     break;
    5724:       default:
    5725:         if (ioctl(ttyfd,PIOCDIAL,telnum) != 0) {
    5726:         perror("Dialing error");
    5727:         ttclos(0);
    5728:         return(-2);
    5729:     }
    5730:     break;
    5731:     }
    5732: #endif
    5733:
    5734:     ioctl(ttyfd,PIOCDIAL,"@");      /* terminator for data call */
    5735:     do {                /* wait for modems to Connect */
    5736:         if (ioctl(ttyfd,PIOCGETP,&dialer) != 0) { /* get params */
    5737:         perror("Cannot get modems to connect");
    5738:         ttclos(0);
    5739:         return(-2);
    5740:     }
    5741:     } while ((dialer.c_linestatus & MODEMCONNECTED) == 0);
    5742:     /* Turn off O_NDELAY flag now. */
    5743:     fcntl(ttyfd, F_SETFL, fcntl(ttyfd, F_GETFL, 0) & ~O_NDELAY);
    5744:     signal(SIGHUP, ttclos);             /* hangup on loss of carrier */
    5745:     return(0);                          /* return success */
    5746: }
    5747:
    5748: /*
    5749:   Offgetty, ongetty functions. These function get the 'getty(1m)' off
    5750:   and restore it to the indicated line.  Shell's return codes are:
    5751:     0: Can't do it.  Probably a user logged on.
    5752:     1: No need.  No getty on that line.
    5753:     2: Done, you should restore the getty when you're done.
    5754:   DOGETY System(3), however, returns them as 0, 256, 512, respectively.
    5755:   Thanks to Kevin O'Gorman, Anarm Software Systems.
    5756:
    5757:    getoff.sh looks like:   geton.sh looks like:
    5758:      setgetty $1 0           setgetty $1 1
    5759:      err=$?                  exit $?
    5760:      sleep 2
    5761:      exit $err
    5762: */
    5763:
    5764: /*  O F F G E T T Y  --  Turn off getty(1m) for the communications tty line
    5765:  * and get status so it can be restarted after the line is hung up.
    5766:  */
    5767: int
    5768: offgetty(ttname) char *ttname; {
    5769:     char temp[30];
    5770:     while (*ttname != '\0') ttname++;       /* seek terminator of path */
    5771:     ttname -= 3;                            /* get last 3 chars of name */
    5772:     sprintf(temp,"/usr/bin/getoff.sh %s",ttname);
    5773:     return(zsyscmd(temp));
    5774: }
    5775:
    5776: /*  O N G E T T Y  --  Turn on getty(1m) for the communications tty line */
    5777:
    5778: int
    5779: ongetty(ttname) char *ttname; {
    5780:     char temp[30];
    5781:     while (*ttname != '\0') ttname++;       /* comms tty path name */
    5782:     ttname -= 3;
    5783:     sprintf(temp,"/usr/bin/geton.sh %s",ttname);
    5784:     return(zsyscmd(temp));
    5785: }
    5786: #endif /* ATT7300 */
    5787:
    5788: /*  T T S C A R R  --  Set ttcarr variable, controlling carrier handling.
    5789:  *
    5790:  *  0 = Off: Always ignore carrier. E.g. you can connect without carrier.
    5791:  *  1 = On: Heed carrier, except during dialing. Carrier loss gives disconnect.
    5792:  *  2 = Auto: For "modem direct": The same as "Off".
    5793:  *            For real modem types: Heed carrier during connect, but ignore
    5794:  *                it anytime else.  Compatible with pre-5A C-Kermit versions.
    5795:  *
    5796:  * As you can see, this setting does not affect dialing, which always ignores
    5797:  * carrier (unless there is some special exception for some modem type).  It
    5798:  * does affect ttopen() if it is set before ttopen() is used.  This setting
    5799:  * takes effect on the next call to ttopen()/ttpkt()/ttvt().  And they are
    5800:  * (or should be) always called before any communications is tried, which
    5801:  * means that, practically speaking, the effect is immediate.
    5802:  *
    5803:  * Of course, nothing of this applies to remote mode (xlocal = 0).
    5804:  *
    5805:  * Someone has yet to uncover how to manipulate the carrier in the BSD
    5806:  * environment (or any non-termio using environment).  Until that time, this
    5807:  * will simply be a no-op for BSD.
    5808:  *
    5809:  * Note that in previous versions, the carrier was most often left unchanged
    5810:  * in ttpkt()/ttvt() unless they were called with FLO_DIAL or FLO_DIAX.  This
    5811:  * has changed.  Now it is controlled by ttcarr in conjunction with these
    5812:  * modes.
    5813:  */
    5814: int
    5815: ttscarr(carrier) int carrier; {
    5816:     ttcarr = carrier;
    5817:     debug(F101, "ttscarr","",ttcarr);
    5818:     return(ttcarr);
    5819: }
    5820:
    5821: /* C A R R C T L  --  Set tty modes for carrier treatment.
    5822:  *
    5823:  * Sets the appropriate bits in a termio or sgttyb struct for carrier control
    5824:  * (actually, there are no bits in sgttyb for that), or performs any other
    5825:  * operations needed to control this on the current system.  The function does
    5826:  * not do the actual TCSETA or stty, since often we want to set other bits too
    5827:  * first.  Don't call this function when xlocal is 0, or the tty is not opened.
    5828:  *
    5829:  * We don't know how to do anything like carrier control on non-ATTSV systems,
    5830:  * except, apparently, ultrix.  See above.  It is also known that this doesn't
    5831:  * have much effect on a Xenix system.  For Xenix, one should switch back and
    5832:  * forth between the upper and lower case device files.  Maybe later.
    5833:  * Presently, Xenix will stick to the mode it was opened with.
    5834:  *
    5835:  * carrier: 0 = ignore carrier, 1 = require carrier.
    5836:  * The current state is saved in curcarr, and checked to save labour.
    5837:  */
    5838: #ifdef SVORPOSIX
    5839: int
    5840: #ifdef BSD44ORPOSIX
    5841: carrctl(ttpar, carrier) struct termios *ttpar; int carrier;
    5842: #else /* ATTSV */
    5843: carrctl(ttpar, carrier) struct termio *ttpar; int carrier;
    5844: #endif /* BSD44ORPOSIX */
    5845: /* carrctl */ {
    5846:     debug(F101, "carrctl","",carrier);
    5847:     if (carrier)
    5848:       ttpar->c_cflag &= ~CLOCAL;
    5849:     else
    5850:       ttpar->c_cflag |= CLOCAL;
    5851:     return(0);
    5852: }
    5853: #else /* Berkeley, V7, et al... */
    5854: int
    5855: carrctl(ttpar, carrier) struct sgttyb *ttpar; int carrier; {
    5856: #ifdef ultrix
    5857:     int temp = 0;
    5858: #endif /* ultrix */
    5859: #ifdef OXOS
    5860:     int modem_status, lnohang = LNOHANG;
    5861: #endif /* OXOS */
    5862:     debug(F101, "carrctl","",carrier);
    5863:     if (carrier == curcarr)
    5864:       return(0);
    5865:     curcarr = carrier;
    5866: #ifdef ultrix
    5867:     if (carrier) {
    5868:     ioctl(ttyfd, TIOCMODEM, &temp);
    5869:     ioctl(ttyfd, TIOCHPCL, 0);
    5870:     } else {
    5871:     /* (According to the manuals, TIOCNCAR should be preferred */
    5872:     /* over TIOCNMODEM...) */
    5873:     ioctl(ttyfd, TIOCNMODEM, &temp);
    5874:     }
    5875: #endif /* ultrix */
    5876: #ifdef OXOS
    5877: /*
    5878:   From Fulvio Marino at Olivetti.  This code allows CONNECT to work even
    5879:   if DCD/RTS are down, if "carrier" is set appropriately.
    5880: */
    5881:     if (ioctl(ttyfd, TIOCMODG, &modem_status) == 0) {
    5882:     if (carrier) {
    5883:         /* enable carrier detect */
    5884:         modem_status |= TIOCM_CAR;
    5885:     } else {
    5886:         /* disable carrier detect */
    5887:         modem_status &= ~TIOCM_CAR;
    5888:     }
    5889:     (void)ioctl(ttyfd, TIOCMODS, &modem_status);
    5890:     }
    5891:     if (carrier) {
    5892:     /* Send hangup when carrier drops */
    5893:     (void)ioctl(ttyfd, TIOCLBIC, &lnohang);
    5894:     /* hang up the phone */
    5895:     (void)ioctl(ttyfd, TIOCHPCL, NULL);
    5896:     } else {
    5897:     /* Don't send hangup when carrier drops */
    5898:     (void)ioctl(ttyfd, TIOCLBIS, &lnohang);
    5899:     }
    5900: #endif /* OXOS */
    5901:     return(0);
    5902: }
    5903: #endif /* SVORPOSIX */
    5904:
    5905:
    5906: /*  T T G M D M  --  Get modem signals  */
    5907: /*
    5908:  Looks for RS-232 modem signals, and returns those that are on in as its
    5909:  return value, in a bit mask composed of the BM_xxx values defined in ckcdeb.h.
    5910:  Returns:
    5911:  -3 Not implemented
    5912:  -2 if the communication device does not have modem control (e.g. telnet)
    5913:  -1 on error.
    5914:  >= 0 on success, with a bit mask containing the modem signals that are on.
    5915: */
    5916:
    5917: /*
    5918:   Define the symbol K_MDMCTL if we have Sys V R3 / 4.3 BSD style
    5919:   modem control, namely the TIOCMGET ioctl.
    5920: */
    5921:
    5922: #ifdef BSD43
    5923: #define K_MDMCTL
    5924: #endif
    5925:
    5926: #ifdef SUNOS4
    5927: #define K_MDMCTL
    5928: #endif
    5929:
    5930: #ifdef TIOCMGET
    5931: #define K_MDMCTL
    5932: #endif
    5933:
    5934: int
    5935: ttgmdm() {
    5936:
    5937: #ifdef HPUX             /* HPUX has its own way */
    5938:
    5939: /*
    5940:   NOTE: I don't have an HPUX man page, and so I'm only guessing at the
    5941:   right names for these symbols.  Somebody with HPUX please let me know
    5942:   what corrections are needed.
    5943: */
    5944:
    5945:     int x, y, z;
    5946:
    5947:     if (netconn) return(-2);        /* No modem signals for network */
    5948:     if (xlocal)             /* Get modem signals */
    5949:       x = ioctl(ttyfd,MCGETA,&y);
    5950:     else
    5951:       x = ioctl(0,MCGETA,&y);
    5952:     if (x < 0) return(-1);
    5953:     debug(F101,"ttgmdm","",y);
    5954:
    5955:     z = 0;              /* Initialize return value */
    5956:
    5957: /* Now set bits for each modem signal that is reported to be on. */
    5958:
    5959: #ifdef MCTS
    5960:     /* Clear To Send */
    5961:     if (y & MCTS) z |= BM_CTS;
    5962: #endif
    5963: #ifdef MDSR
    5964:     /* Data Set Ready */
    5965:     if (y & MDSR) z |= BM_DSR;
    5966: #endif
    5967: #ifdef MDCD
    5968:     /* Carrier */
    5969:     if (y & MDCD) z |= BM_DCD;
    5970: #endif
    5971: #ifdef MRNG
    5972:     /* Ring Indicate */
    5973:     if (y & MRNG) z |= BM_RNG;
    5974: #endif
    5975: #ifdef MDTR
    5976:     /* Data Terminal Ready */
    5977:     if (y & MDTR) z |= BM_DTR;
    5978: #endif
    5979: #ifdef MRTS
    5980:     /* Request To Send */
    5981:     if (y & MRTS) z |= BM_RTS;
    5982: #endif
    5983:     return(z);
    5984:
    5985: #else /* ! HPUX */
    5986:
    5987: #ifdef K_MDMCTL
    5988: /*
    5989:   Note, <sys/ttycom> might have already been included by by <sys/ioctl.h>.
    5990:   Hence the following ifndef on a symbol which is defined there.
    5991: */
    5992: #ifndef TIOCMGET
    5993: #include <sys/ttycom.h>
    5994: #endif /* TIOCMGET */
    5995:
    5996:     int x, y, z;
    5997:
    5998:     if (netconn) return(-2);        /* Network, no modem signals. */
    5999:     if (xlocal)
    6000:       x = ioctl(ttyfd,TIOCMGET,&y); /* Get modem signals. */
    6001:     else
    6002:       x = ioctl(0,TIOCMGET,&y);
    6003:     if (x < 0) return(-1);
    6004:     debug(F101,"ttgmdm","",y);
    6005:
    6006:     z = 0;              /* Initialize return value. */
    6007: #ifdef TIOCM_CTS
    6008:     /* Clear To Send */
    6009:     if (y & TIOCM_CTS) z |= BM_CTS;
    6010: #endif
    6011: #ifdef TIOCM_DSR
    6012:     /* Data Set Ready */
    6013:     if (y & TIOCM_DSR) z |= BM_DSR;
    6014: #endif
    6015: #ifdef TIOCM_CAR
    6016:     /* Carrier */
    6017:     if (y & TIOCM_CAR) z |= BM_DCD;
    6018: #endif
    6019: #ifdef TIOCM_RNG
    6020:     /* Ring Indicate */
    6021:     if (y & TIOCM_RNG) z |= BM_RNG;
    6022: #endif
    6023: #ifdef TIOCM_DTR
    6024:     /* Data Terminal Ready */
    6025:     if (y & TIOCM_DTR) z |= BM_DTR;
    6026: #endif
    6027: #ifdef TIOCM_RTS
    6028:     /* Request To Send */
    6029:     if (y & TIOCM_RTS) z |= BM_RTS;
    6030: #endif
    6031:     return(z);
    6032: #else
    6033:     if (netconn) return(-2);
    6034:     return(-3);
    6035:
    6036: #endif /* K_MDMCTL */
    6037: #endif /* HPUX */
    6038: }
    6039:
    6040: /*  P S U S P E N D  --  Put this process in the background.  */
    6041:
    6042: /*
    6043:   Call with flag nonzero if suspending is allowed, zero if not allowed.
    6044:   Returns 0 on apparent success, -1 on failure (flag was zero, or
    6045:   kill() returned an error code.
    6046: */
    6047: int
    6048: psuspend(flag) int flag; {
    6049:
    6050: #ifdef RTU
    6051:     extern int rtu_bug;
    6052: #endif /* RTU */
    6053:
    6054:     if (flag == 0) return(-1);
    6055:
    6056: #ifdef NOJC
    6057:     return(-1);
    6058: #else
    6059: #ifdef SIGTSTP
    6060: /*
    6061:   The big question here is whether job control is *really* supported.
    6062:   There's no way Kermit can know for sure.  The fact that SIGTSTP is
    6063:   defined does not guarantee the Unix kernel supports it, and the fact
    6064:   that the Unix kernel supports it doesn't guarantee that the user's
    6065:   shell (or other process that invoked Kermit) supports it.
    6066: */
    6067: #ifdef RTU
    6068:     rtu_bug = 1;
    6069: #endif /* RTU */
    6070:     if (kill(0,SIGSTOP) < 0
    6071: #ifdef OXOS
    6072: /*
    6073:   Because "kill(myself,SIGSTOP)" can't be caught, blocked, or ignored..."
    6074: */
    6075:     && kill(getpid(),SIGSTOP) < 0
    6076: #else
    6077: #ifdef MIPS
    6078: /* Let's try this for MIPS too. */
    6079:     && kill(getpid(),SIGSTOP) < 0
    6080: #endif /* MIPS */
    6081: #endif /* OXOS */
    6082:     ) {             /* If job control, suspend the job */
    6083:     perror("suspend");
    6084:     debug(F101,"psuspend error","",errno);
    6085:     return(-1);
    6086:     }
    6087:     debug(F100,"psuspend ok","",0);
    6088:     return(0);
    6089: #else
    6090:     return(-1);
    6091: #endif /* SIGTSTP */
    6092: #endif /* NOJC */
    6093: }
    6094:
    6095: /*
    6096:   setuid package, by Kristoffer Eriksson, with contributions from Dean
    6097:   Long and fdc.
    6098: */
    6099:
    6100: #ifndef _POSIX_SOURCE
    6101: #ifndef SUNOS4
    6102: #ifndef NEXT
    6103: #ifndef PS2AIX10
    6104: extern UID_T getuid(), geteuid(), getreuid();
    6105: extern GID_T getgid(), getegid(), getregid();
    6106: #endif /* PS2AIX10 */
    6107: #endif /* NEXT */
    6108: #endif /* SUNOS4 */
    6109: #endif /* _POSIX_SOURCE */
    6110:
    6111: /*
    6112: Subject: Set-user-id
    6113: To: fdc@watsun.cc.columbia.edu (Frank da Cruz)
    6114: Date: Sat, 21 Apr 90 4:48:25 MES
    6115: From: Kristoffer Eriksson <ske@pkmab.se>
    6116:
    6117: This is a set of functions to be used in programs that may be run set-user-id
    6118: and/or set-group-id. They handle both the case where the program is not run
    6119: with such privileges (nothing special happens then), and the case where one
    6120: or both of these set-id modes are used.  The program is made to run with the
    6121: user's real user and group ids most of the time, except for when more
    6122: privileges are needed.  Don't set-user-id to "root".
    6123:
    6124: This works on System V and POSIX.  In BSD, it depends on the
    6125: "saved-set-user-id" feature.
    6126: */
    6127:
    6128: #define UID_ROOT 0          /* Root user and group ids */
    6129: #define GID_ROOT 0
    6130:
    6131: /*
    6132:   The following construction automatically defines the symbol SETREUID for
    6133:   Unix versions based on Berkeley Unix 4.2 or later.  If this symbol is
    6134:   defined, then this program will use getreuid() and getregid() calls in
    6135:   preference to getuid() and getgid(), which in Berkeley-based Unixes do
    6136:   not allow arbitrary switching back and forth of real & effective uid.
    6137:   This construction also allows -DSETREUID to be put on the cc command line
    6138:   for any system that has and wants to use setre[ug]id().  It also prevents
    6139:   automatic definition of SETREUID if -DNOSETREU is included on the cc
    6140:   command line (or otherwise defined).
    6141: */
    6142: #ifdef FT18             /* None of this for Fortune. */
    6143: #define NOSETREU
    6144: #endif /* FT18 */
    6145:
    6146: #ifdef ANYBSD
    6147: #ifndef BSD29
    6148: #ifndef BSD41
    6149: #ifndef SETREUID
    6150: #ifndef NOSETREU
    6151: #define SETREUID
    6152: #endif /* NOSETREU */
    6153: #endif /* SETREUID */
    6154: #endif /* !BSD41 */
    6155: #endif /* !BSD29 */
    6156: #endif /* ANYBSD */
    6157:
    6158: /* Variables for user and group IDs. */
    6159:
    6160: static UID_T realuid = (UID_T) -1, privuid = (UID_T) -1;
    6161: static GID_T realgid = (GID_T) -1, privgid = (GID_T) -1;
    6162:
    6163:
    6164: /* P R I V _ I N I  --  Initialize privileges package  */
    6165:
    6166: /* Called as early as possible in a set-uid or set-gid program to store the
    6167:  * set-to uid and/or gid and step down to the users real uid and gid. The
    6168:  * stored id's can be temporarily restored (allowed in System V) during
    6169:  * operations that require the privilege.  Most of the time, the program
    6170:  * should execute in unpriviliged state, to not impose any security threat.
    6171:  *
    6172:  * Note: Don't forget that access() always uses the real id:s to determine
    6173:  * file access, even with privileges restored.
    6174:  *
    6175:  * Returns an error mask, with error values or:ed together:
    6176:  *   1 if setuid() fails,
    6177:  *   2 if setgid() fails, and
    6178:  *   4 if the program is set-user-id to "root", which can't be handled.
    6179:  *
    6180:  * Only the return value 0 indicates real success. In case of failure,
    6181:  * those privileges that could be reduced have been, at least, but the
    6182:  * program should be aborted none-the-less.
    6183:  *
    6184:  * Also note that these functions do not expect the uid or gid to change
    6185:  * without their knowing. It may work if it is only done temporarily, but
    6186:  * you're on your own.
    6187:  */
    6188: int
    6189: priv_ini() {
    6190:     int err = 0;
    6191:
    6192:     /* Save real ID:s. */
    6193:     realuid = getuid();
    6194:     realgid = getgid();
    6195:
    6196:     /* Save current effective ID:s, those set to at program exec. */
    6197:     privuid = geteuid();
    6198:     privgid = getegid();
    6199:
    6200:     /* If running set-uid, go down to real uid, otherwise remember that
    6201:      * no privileged uid is available.
    6202:      *
    6203:      * Exceptions:
    6204:      *
    6205:      * 1) If the real uid is already "root" and the set-uid uid (the
    6206:      * initial effective uid) is not "root", then we would have trouble
    6207:      * if we went "down" to "root" here, and then temporarily back to the
    6208:      * set-uid uid (not "root") and then again tried to become "root". I
    6209:      * think the "saved set-uid" is lost when changing uid from effective
    6210:      * uid "root", which changes all uid, not only the effective uid. But
    6211:      * in this situation, we can simply go to "root" and stay there all
    6212:      * the time. That should give sufficient privilege (understatement!),
    6213:      * and give the right uids for subprocesses.
    6214:      *
    6215:      * 2) If the set-uid (the initial effective uid) is "root", and we
    6216:      * change uid to the real uid, we can't change it back to "root" when
    6217:      * we need the privilege, for the same reason as in 1). Thus, we can't
    6218:      * handle programs that are set-user-id to "root" at all. The program
    6219:      * should be aborted. Use some other uid. "root" is probably to
    6220:      * privileged for such things, anyway. (The uid is reverted to the
    6221:      * real uid until abortion.)
    6222:      *
    6223:      * These two exceptions have the effect that the "root" uid will never
    6224:      * be one of the two uids that are being switched between, which also
    6225:      * means we don't have to check for such cases in the switching
    6226:      * functions.
    6227:      *
    6228:      * Note that exception 1) is handled by these routines (by constantly
    6229:      * running with uid "root", while exception 2) is a serious error, and
    6230:      * is not provided for at all in the switching functions.
    6231:      */
    6232:     if (realuid == privuid)
    6233:     privuid = (UID_T) -1;       /* Not running set-user-id. */
    6234:
    6235:     /* If running set-gid, go down to real gid, otherwise remember that
    6236:      * no privileged gid is available.
    6237:      *
    6238:      * There are no exception like there is for the user id, since there
    6239:      * is no group id that is privileged in the manner of uid "root".
    6240:      * There could be equivalent problems for group changing if the
    6241:      * program sometimes ran with uid "root" and sometimes not, but
    6242:      * that is already avoided as explained above.
    6243:      *
    6244:      * Thus we can expect always to be able to switch to the "saved set-
    6245:      * gid" when we want, and back to the real gid again. You may also
    6246:      * draw the conclusion that set-gid provides for fewer hassles than
    6247:      * set-uid.
    6248:      */
    6249:
    6250:     if (realgid == privgid)     /* If not running set-user-id, */
    6251:       privgid = (GID_T) -1;     /*  remember it this way. */
    6252:
    6253:     err = priv_off();           /* Turn off setuid privilege. */
    6254:
    6255:     if (privuid == UID_ROOT)        /* If setuid to root, */
    6256:       err |= 4;             /* return this error. */
    6257:
    6258:     if (realuid == UID_ROOT)        /* If real id is root, */
    6259:       privuid = (UID_T) -1;     /* stay root at all times. */
    6260:
    6261:     return(err);
    6262: }
    6263:
    6264:
    6265: /* Macros for hiding the differences in UID/GID setting between various Unix
    6266:  * systems. These macros should always be called with both the privileged ID
    6267:  * and the non-privileged ID. The one in the second argument, will become the
    6268:  * effective ID. The one in the first argument will be retained for later
    6269:  * retrieval.
    6270:  */
    6271: #ifdef SETREUID
    6272: #ifdef SAVEDUID
    6273: /* On BSD systems with the saved-UID feature, we just juggle the effective
    6274:  * UID back and forth, and leave the real UID at its true value.  The kernel
    6275:  * allows switching to both the current real UID, the effective UID, and the
    6276:  * UID which the program is set-UID to.  The saved set-UID always holds the
    6277:  * privileged UID for us, and the real UID will always be the non-privileged,
    6278:  * and we can freely choose one of them for the effective UID at any time.
    6279:  */
    6280: #define switchuid(hidden,active) setreuid( (UID_T) -1, active)
    6281: #define switchgid(hidden,active) setregid( (GID_T) -1, active)
    6282:
    6283: #else   /* SETREUID,!SAVEDUID */
    6284:
    6285: /* On systems with setreXid() but without the saved-UID feature, notably
    6286:  * BSD 4.2, we swap the real and effective UIDs each time.  It's
    6287:  * the effective UID that we are interrested in, but we have to retain the
    6288:  * unused UID somewhere to enable us to restore it later, and that we do this
    6289:  * in the real UID.  The kernel only allows switching to either the current
    6290:  * real or the effective UID, unless you're "root".
    6291:  */
    6292: #define switchuid(hidden,active)    setreuid(hidden,active)
    6293: #define switchgid(hidden,active)    setregid(hidden,active)
    6294: #endif
    6295:
    6296: #else /* !SETREUID, !SAVEDUID */
    6297:
    6298: /* On System V and POSIX, the only thing we can change is the effective UID
    6299:  * (unless the current effective UID is "root", but initsuid() avoids that for
    6300:  * us).  The kernel allows switching to the current real UID or to the saved
    6301:  * set-UID.  These are always set to the non-privileged UID and the privileged
    6302:  * UID, respectively, and we only change the effective UID.  This breaks if
    6303:  * the current effective UID is "root", though, because for "root" setuid/gid
    6304:  * becomes more powerful, which is why initsuid() treats "root" specially.
    6305:  * Note: That special treatment maybe could be ignored for BSD?  Note: For
    6306:  * systems that don't fit any of these three cases, we simply can't support
    6307:  * set-UID.
    6308:  */
    6309: #define switchuid(hidden,active)    setuid(active)
    6310: #define switchgid(hidden,active)    setgid(active)
    6311: #endif /* SETREUID */
    6312:
    6313:
    6314: /* P R I V _ O N  --  Turn on the setuid and/or setgid */
    6315:
    6316: /* Go to the privileged uid (gid) that the program is set-user-id
    6317:  * (set-group-id) to, unless the program is running unprivileged.
    6318:  * If setuid() fails, return value will be 1. If getuid() fails it
    6319:  * will be 2.  Return immediately after first failure, and the function
    6320:  * tries to restore any partial work done.  Returns 0 on success.
    6321:  * Group id is changed first, since it is less serious than user id.
    6322:  */
    6323: int
    6324: priv_on() {
    6325:     if (privgid != (GID_T) -1)
    6326:       if (switchgid(realgid,privgid))
    6327:         return(2);
    6328:
    6329:     if (privuid != (UID_T) -1)
    6330:       if (switchuid(realuid,privuid)) {
    6331:       if (privgid != (GID_T) -1)
    6332:         switchgid(privgid,realgid);
    6333:       return(1);
    6334:       }
    6335:     return(0);
    6336: }
    6337:
    6338: /* P R I V _ O F F  --  Turn on the real uid and gid */
    6339:
    6340: /* Return to the unprivileged uid (gid) after an temporary visit to
    6341:  * privileged status, unless the program is running without set-user-id
    6342:  * (set-group-id). Returns 1 for failure in setuid() and 2 for failure
    6343:  * in setgid() or:ed together. The functions tries to return both uid
    6344:  * and gid to unprivileged state, regardless of errors. Returns 0 on
    6345:  * success.
    6346:  */
    6347: int
    6348: priv_off() {
    6349:     int err = 0;
    6350:
    6351:     if (privuid != (UID_T) -1)
    6352:        if (switchuid(privuid,realuid))
    6353:       err |= 1;
    6354:
    6355:     if (privgid != (GID_T) -1)
    6356:        if (switchgid(privgid,realgid))
    6357:     err |= 2;
    6358:
    6359:     return(err);
    6360: }
    6361:
    6362: /* Turn off privilege permanently.  No going back.  This is necessary before
    6363:  * a fork() on BSD43 machines that don't save the setUID or setGID, because
    6364:  * we swap the real and effective ids, and we don't want to let the forked
    6365:  * process swap them again and get the privilege back. It will work on other
    6366:  * machines too, such that you can rely on its effect always being the same,
    6367:  * for instance, even when you're in priv_on() state when this is called.
    6368:  * (Well, that part about "permanent" is on System V only true if you follow
    6369:  * this with a call to exec(), but that's what we want it for anyway.)
    6370:  * Added by Dean Long -- dlong@midgard.ucsc.edu
    6371:  */
    6372: int
    6373: priv_can() {
    6374:
    6375: #ifdef SETREUID
    6376:     int err = 0;
    6377:     if (privuid != (UID_T) -1)
    6378:        if (setreuid(realuid,realuid))
    6379:       err |= 1;
    6380:
    6381:     if (privgid != (GID_T) -1)
    6382:         if (setregid(realgid,realgid))
    6383:       err |= 2;
    6384:
    6385:     return(err);
    6386:
    6387: #else
    6388:     /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
    6389:     return(priv_off());
    6390:
    6391: #endif /* SETREUID */
    6392: }
    6393:
    6394: /* P R I V _ O P N  --  For opening protected files or devices. */
    6395:
    6396: int
    6397: priv_opn(name, modes) char *name; int modes; {
    6398:     int x;
    6399:     priv_on();              /* Turn privileges on */
    6400:     x = open(name, modes);      /* Try to open the device */
    6401:     priv_off();             /* Turn privileges off */
    6402:     return(x);              /* Return open's return code */
    6403: }
    6404:
    6405: /*  P R I V _ C H K  --  Check privileges.  */
    6406:
    6407: /*  Try to turn them off.  If turning them off did not succeed, cancel them */
    6408:
    6409: int
    6410: priv_chk() {
    6411:     int x, y = 0;
    6412:     x = priv_off();         /* Turn off privs. */
    6413:     if (x != 0 || getuid() == privuid || geteuid() == privuid)
    6414:       y = priv_can();
    6415:     if (x != 0 || getgid() == privgid || getegid() == privgid)
    6416:       y = y | priv_can();
    6417:     return(y);
    6418: }
    6419:
    6420: UID_T
    6421: real_uid() {
    6422:     return(realuid);
    6423: }
    6424:
    6425: VOID
    6426: ttimoff() {             /* Turn off any timer interrupts */
    6427:     int xx;
    6428: /*
    6429:   As of 5A(183), we set SIGALRM to SIG_IGN (to ignore alarms) rather than to
    6430:   SIG_DFL (to catch alarms, or if there is no handler, to exit).  This is to
    6431:   cure (mask, really) a deeper problem with stray alarms that occurs on some
    6432:   systems, possibly having to do with sleep(), that caused core dumps.  It
    6433:   should be OK to do this, because no code in this module uses nested alarms.
    6434:   (But we still have to watch out for SCRIPT and DIAL...)
    6435: */
    6436:     xx = alarm(0);
    6437:     /* debug(F101,"ttimoff alarm","",xx); */
    6438:     if (saval) {            /* Restore any previous */
    6439:     signal(SIGALRM,saval);      /* alarm handler. */
    6440:     /* debug(F101,"ttimoff alarm restoring saval","",saval); */
    6441:     saval = NULL;
    6442:     } else {
    6443:     signal(SIGALRM,SIG_IGN);    /* Used to be SIG_DFL */
    6444:     /* debug(F100,"ttimoff alarm SIG_IGN","",0); */
    6445:     }
    6446: }

#### Defined functions

SIGTYP defined in line 3930; never used
acucntrl defined in line 2492; used 4 times

- in line 861, 1170, 1218, 1663

attdial defined in line 5640; used 2 times

- in line 875
- in /usr/src/new/kermit5.188/ckudia.c line 1471

carrctl defined in line 5854; used 6 times

- in line 865-870(3), 1538, 2710, 3005

catch defined in line 4168; used 2 times

- in line 4103, 4114

cctrap defined in line 907; used 3 times

- in line 845-850(2), 1154

conbgt defined in line 3739; used 4 times

- in line 859, 919, 3937
- in /usr/src/new/kermit5.188/ckuusx.c line 974

conbin defined in line 5271; used 4 times

- in /usr/src/new/kermit5.188/ckucon.c line 510, 1282
- in /usr/src/new/kermit5.188/ckuus5.c line 2347
- in /usr/src/new/kermit5.188/ckuusx.c line 643

concb defined in line 5182; used 18 times

- in /usr/src/new/kermit5.188/ckcmai.c line 853
- in /usr/src/new/kermit5.188/ckuus4.c line 634, 716, 1527
- in /usr/src/new/kermit5.188/ckuus5.c line 381, 730, 771-773(2), 1480, 1497, 2349
- in /usr/src/new/kermit5.188/ckuus6.c line 304, 588
- in /usr/src/new/kermit5.188/ckuusr.c line 916, 1707
- in /usr/src/new/kermit5.188/ckuusx.c line 649, 659, 976

conchk defined in line 5449; used 5 times

- in line 5528
- in /usr/src/new/kermit5.188/ckuus4.c line 1587
- in /usr/src/new/kermit5.188/ckuus6.c line 923
- in /usr/src/new/kermit5.188/ckuusx.c line 694, 793

congks defined in line 5626; never used
congm defined in line 5119; used 3 times

- in line 924, 951, 5279

coninc defined in line 5521; used 12 times

- in line 5628
- in /usr/src/new/kermit5.188/ckucmd.c line 1881-1884(2)
- in /usr/src/new/kermit5.188/ckucmd.h line 32-37(2)
- in /usr/src/new/kermit5.188/ckuus4.c line 1589-1593(2)
- in /usr/src/new/kermit5.188/ckuus6.c line 924
- in /usr/src/new/kermit5.188/ckuus7.c line 1325
- in /usr/src/new/kermit5.188/ckuusx.c line 499, 688, 697

conint defined in line 3930; used 7 times

- in /usr/src/new/kermit5.188/ckuus5.c line 764, 1478, 1495
- in /usr/src/new/kermit5.188/ckuus6.c line 1361
- in /usr/src/new/kermit5.188/ckuusx.c line 639, 977, 1279

connoi defined in line 4023; used 4 times

- in /usr/src/new/kermit5.188/ckcmai.c line 761
- in /usr/src/new/kermit5.188/ckuus5.c line 1030
- in /usr/src/new/kermit5.188/ckuus6.c line 1350
- in /usr/src/new/kermit5.188/ckuusx.c line 1225

conoc defined in line 5404; used 38 times

- in /usr/src/new/kermit5.188/ckcfns.c line 282
- in /usr/src/new/kermit5.188/ckucmd.c line 94
- in /usr/src/new/kermit5.188/ckucon.c line 690-692(2), 768, 776, 827, 853, 991, 1192, 1206, 1306-1310(2)
- in /usr/src/new/kermit5.188/ckudia.c line 1078-1079(2), 1146-1147(2), 2768, 2792
- in /usr/src/new/kermit5.188/ckuscr.c line 214
- in /usr/src/new/kermit5.188/ckuus4.c line 519, 527, 604, 615, 679-680(2), 705, 1640
- in /usr/src/new/kermit5.188/ckuus5.c line 1048
- in /usr/src/new/kermit5.188/ckuusx.c line 939, 1001, 1039, 1100, 1107-1110(2), 1818, 2177, 2184

conol defined in line 5423; used 51 times

- in line 5435, 5443
- in /usr/src/new/kermit5.188/ckcnet.c line 1424
- in /usr/src/new/kermit5.188/ckucon.c line 763, 774, 790-799(5), 851, 954, 1132-1136(4), 1166, 1189, 1222, 1228-1240(4), 1251, 1263
- in /usr/src/new/kermit5.188/ckudia.c line 2666
- in /usr/src/new/kermit5.188/ckuscr.c line 254, 261
- in /usr/src/new/kermit5.188/ckuus2.c line 128-134(5)
- in /usr/src/new/kermit5.188/ckuusr.c line 1251-1252(2)
- in /usr/src/new/kermit5.188/ckuusx.c line 830-838(6), 926, 1001, 1011(2), 1056-1066(3), 1082, 1117-1120(2)

conola defined in line 5432; used 2 times

- in /usr/src/new/kermit5.188/ckucon.c line 1135
- in /usr/src/new/kermit5.188/ckuus2.c line 130

conoll defined in line 5441; used 61 times

- in /usr/src/new/kermit5.188/ckcmai.c line 865
- in /usr/src/new/kermit5.188/ckucon.c line 1140, 1245-1246(2), 1254-1263(7), 1329-1330(2)
- in /usr/src/new/kermit5.188/ckuus4.c line 589
- in /usr/src/new/kermit5.188/ckuusx.c line 254, 829-833(2), 842-848(4), 860-864(4), 936, 1001, 1010-1012(2), 1020, 1026(2), 1036-1037(2), 1045-1075(12), 1093, 1102-1128(11), 1134, 1818(2)

conres defined in line 5367; used 23 times

- in line 820
- in /usr/src/new/kermit5.188/ckucon.c line 532, 604, 887, 1280
- in /usr/src/new/kermit5.188/ckuus4.c line 478, 681, 1525
- in /usr/src/new/kermit5.188/ckuus5.c line 3607
- in /usr/src/new/kermit5.188/ckuus6.c line 581, 602, 723, 965, 1856
- in /usr/src/new/kermit5.188/ckuusr.c line 911, 1526, 1705
- in /usr/src/new/kermit5.188/ckuusx.c line 548-551(2), 571, 629, 796, 1221

conxo defined in line 5416; used 4 times

- in /usr/src/new/kermit5.188/ckucon.c line 340, 355, 997
- in /usr/src/new/kermit5.188/ckuscr.c line 268

do_open defined in line 1574; used 4 times

- in line 853, 1203-1208(2), 1768

err defined in line 4159; used 21 times

- in line 4106-4110(3), 4130-4143(6), 6190, 6253-6261(3), 6349-6359(4), 6376-6385(4)

esctrp defined in line 3713; used 6 times

- in line 846-851(2), 3994-3998(2), 5482, 5490

genbrk defined in line 4182; used 1 times

- in line 4802

gtimer defined in line 5028; used 8 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 1512-1514(2)
- in /usr/src/new/kermit5.188/ckcfns.c line 1199, 1356
- in /usr/src/new/kermit5.188/ckuus4.c line 1613, 1675
- in /usr/src/new/kermit5.188/ckuusx.c line 896, 2057

initrawq defined in line 4081; used 3 times

- in line 557, 1357, 5254

main defined in line 801; never used
msleep defined in line 4851; used 29 times

- in line 1725, 1735, 1746, 1791, 1819, 1876, 1974, 2028, 2125, 4346, 4778, 5395
- in /usr/src/new/kermit5.188/ckudia.c line 1059, 1280, 1369, 1625, 1693, 1749, 1919, 1994, 2024, 2686, 2912, 2925-2926(2)
- in /usr/src/new/kermit5.188/ckuscr.c line 285
- in /usr/src/new/kermit5.188/ckuus4.c line 516, 593
- in /usr/src/new/kermit5.188/ckuus6.c line 918

myfillbuf defined in line 3585; used 2 times

- in line 858, 3456

mygetbuf defined in line 3454; used 2 times

- in line 857, 3399

myunrd defined in line 3414; never used
offgetty defined in line 5767; used 2 times

- in line 876, 1175

ongetty defined in line 5778; used 3 times

- in line 877, 1213, 1667

priv_can defined in line 6372; used 7 times

- in line 6414-6416(2)
- in /usr/src/new/kermit5.188/ckucon.c line 922
- in /usr/src/new/kermit5.188/ckufio.c line 1379, 2847, 2897, 2906

priv_chk defined in line 6409; used 9 times

- in /usr/src/new/kermit5.188/ckufio.c line 1003, 1070, 1315-1318(2), 1351, 2831, 2872, 2879-2882(2)

priv_ini defined in line 6188; used 1 times

- in line 941

priv_off defined in line 6347; used 9 times

- in line 1340, 2386, 2452, 2463, 2483, 6253, 6389, 6401, 6412

priv_on defined in line 6323; used 5 times

- in line 2375, 2474, 6399
- in /usr/src/new/kermit5.188/ckufio.c line 999, 1062

priv_opn defined in line 6396; used 7 times

- in line 1512, 1578, 1589, 1595, 1994, 2020, 2029

psuspend defined in line 6047; used 1 times

- in /usr/src/new/kermit5.188/ckuusx.c line 635

real_uid defined in line 6420; used 4 times

- in /usr/src/new/kermit5.188/ckufio.c line 512, 1402, 2733, 2907

rtimer defined in line 5020; used 1 times

- in /usr/src/new/kermit5.188/ckuus4.c line 1580

sig_ign defined in line 4014; used 2 times

- in line 847, 4036

sndbrk defined in line 4714; used 2 times

- in line 4815, 4822

syscleanup defined in line 958; used 1 times

- in /usr/src/new/kermit5.188/ckuusx.c line 1228

sysinit defined in line 915; used 1 times

- in /usr/src/new/kermit5.188/ckcmai.c line 759

timerh defined in line 896; used 8 times

- in line 844-849(2), 1198, 1635, 4373, 4489, 4675, 5593

ttchk defined in line 4217; used 9 times

- in line 3668
- in /usr/src/new/kermit5.188/ckcfn2.c line 314
- in /usr/src/new/kermit5.188/ckcfns.c line 1431
- in /usr/src/new/kermit5.188/ckcnet.c line 866
- in /usr/src/new/kermit5.188/ckucon.c line 389
- in /usr/src/new/kermit5.188/ckudia.c line 2662
- in /usr/src/new/kermit5.188/ckuscr.c line 388
- in /usr/src/new/kermit5.188/ckuus4.c line 522, 608

ttclos defined in line 1603; used 20 times

- in line 1062, 2696, 5642, 5652, 5660, 5682, 5701, 5711, 5720, 5727, 5738, 5744
- in /usr/src/new/kermit5.188/ckcnet.c line 1570
- in /usr/src/new/kermit5.188/ckucon.c line 521, 878
- in /usr/src/new/kermit5.188/ckudia.c line 1267, 1359
- in /usr/src/new/kermit5.188/ckuus7.c line 1969, 2017
- in /usr/src/new/kermit5.188/ckuusx.c line 1216

ttflui defined in line 3598; used 28 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 558
- in /usr/src/new/kermit5.188/ckcfns.c line 1049
- in /usr/src/new/kermit5.188/ckudia.c line 1161, 1627, 1663, 1694, 1750, 1920, 2028, 2046, 2741, 2827, 2927
- in /usr/src/new/kermit5.188/ckuscr.c line 394
- in /usr/src/new/kermit5.188/ckuus4.c line 531, 617
- in /usr/src/new/kermit5.188/ckuus6.c line 1303
- in /usr/src/new/kermit5.188/ckuus7.c line 1365, 1373, 1511, 1968, 2016
- in /usr/src/new/kermit5.188/ckuusr.c line 1003, 1019, 1336, 1345, 1622, 1663

ttfluo defined in line 3680; never used
ttgmdm defined in line 5934; used 5 times

- in /usr/src/new/kermit5.188/ckudia.c line 2164, 2668, 2891
- in /usr/src/new/kermit5.188/ckuus6.c line 928
- in /usr/src/new/kermit5.188/ckuusx.c line 156

ttgspd defined in line 3214; used 15 times

- in line 1559
- in /usr/src/new/kermit5.188/ckcfn2.c line 678, 1548
- in /usr/src/new/kermit5.188/ckcmai.c line 782
- in /usr/src/new/kermit5.188/ckuscr.c line 302
- in /usr/src/new/kermit5.188/ckuus4.c line 1023, 1490, 2370
- in /usr/src/new/kermit5.188/ckuus5.c line 2720
- in /usr/src/new/kermit5.188/ckuus7.c line 1129, 2095, 2105
- in /usr/src/new/kermit5.188/ckuusx.c line 1892
- in /usr/src/new/kermit5.188/ckuusy.c line 38, 292

tthang defined in line 1686; used 6 times

- in line 1642
- in /usr/src/new/kermit5.188/ckucon.c line 520, 894, 1022
- in /usr/src/new/kermit5.188/ckudia.c line 2848
- in /usr/src/new/kermit5.188/ckuusr.c line 1424

tthflow defined in line 2509; used 4 times

- in line 2719, 2913, 3014, 3040

ttimoff defined in line 6425; used 19 times

- in line 898, 1204, 1649, 4378, 4408, 4414, 4496, 4582, 4627, 4633, 4693, 5600
- in /usr/src/new/kermit5.188/ckcnet.c line 773, 1680, 1695-1698(2)
- in /usr/src/new/kermit5.188/ckuusx.c line 570, 576-579(2)

ttinc defined in line 4643; used 13 times

- in line 3670
- in /usr/src/new/kermit5.188/ckcnet.c line 868
- in /usr/src/new/kermit5.188/ckucon.c line 378
- in /usr/src/new/kermit5.188/ckudia.c line 1038-1042(2), 1051
- in /usr/src/new/kermit5.188/ckuscr.c line 196, 205
- in /usr/src/new/kermit5.188/ckuus4.c line 524, 597, 609, 1585, 1600

ttinl defined in line 4464; used 5 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 1271-1279(4), 1286

ttlock defined in line 2284; used 2 times

- in line 855, 1328

ttoc defined in line 4361; used 19 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 1302
- in /usr/src/new/kermit5.188/ckcnet.c line 1420
- in /usr/src/new/kermit5.188/ckucon.c line 745-750(2), 826, 842, 848, 1158, 1272, 1303
- in /usr/src/new/kermit5.188/ckudia.c line 1058, 1404, 1417, 2047
- in /usr/src/new/kermit5.188/ckuscr.c line 253, 274
- in /usr/src/new/kermit5.188/ckuus4.c line 511, 625
- in /usr/src/new/kermit5.188/ckuus5.c line 1047

ttol defined in line 4324; used 20 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 833-836(2), 1191
- in /usr/src/new/kermit5.188/ckcnet.c line 942, 971, 1245, 1343, 1350-1352(2), 1361-1363(2), 1395, 1432
- in /usr/src/new/kermit5.188/ckucon.c line 807, 1183, 1205
- in /usr/src/new/kermit5.188/ckudia.c line 2916, 2932
- in /usr/src/new/kermit5.188/ckuscr.c line 267
- in /usr/src/new/kermit5.188/ckuus4.c line 573

ttopen defined in line 999; used 12 times

- in line 2698
- in /usr/src/new/kermit5.188/ckcmai.c line 777
- in /usr/src/new/kermit5.188/ckucon.c line 465, 522
- in /usr/src/new/kermit5.188/ckudia.c line 1254, 1268, 1360
- in /usr/src/new/kermit5.188/ckuscr.c line 303
- in /usr/src/new/kermit5.188/ckuus4.c line 426
- in /usr/src/new/kermit5.188/ckuus7.c line 2066
- in /usr/src/new/kermit5.188/ckuusy.c line 285, 306

ttpkt defined in line 2656; used 6 times

- in /usr/src/new/kermit5.188/ckudia.c line 1266, 1274, 1481, 2692, 2909
- in /usr/src/new/kermit5.188/ckuus4.c line 438

ttres defined in line 2105; used 2 times

- in line 1643
- in /usr/src/new/kermit5.188/ckuus6.c line 585

ttrpid defined in line 2202; used 3 times

- in line 854, 1339, 2432

ttscarr defined in line 5814; used 1 times

- in /usr/src/new/kermit5.188/ckuus3.c line 777

ttsndb defined in line 4813; used 6 times

- in /usr/src/new/kermit5.188/ckucon.c line 1170
- in /usr/src/new/kermit5.188/ckudia.c line 1356, 1621, 1971
- in /usr/src/new/kermit5.188/ckuscr.c line 260
- in /usr/src/new/kermit5.188/ckuus5.c line 1078

ttsndlb defined in line 4820; used 2 times

- in /usr/src/new/kermit5.188/ckucon.c line 1213
- in /usr/src/new/kermit5.188/ckuus5.c line 1084

ttsspd defined in line 3107; used 7 times

- in line 2708, 3004
- in /usr/src/new/kermit5.188/ckudia.c line 1125, 2300
- in /usr/src/new/kermit5.188/ckuus3.c line 1176
- in /usr/src/new/kermit5.188/ckuus6.c line 531
- in /usr/src/new/kermit5.188/ckuusy.c line 347

ttunlck defined in line 2470; used 2 times

- in line 856, 1629

ttvt defined in line 2977; used 7 times

- in line 1772
- in /usr/src/new/kermit5.188/ckucon.c line 517, 531
- in /usr/src/new/kermit5.188/ckuscr.c line 336
- in /usr/src/new/kermit5.188/ckuus4.c line 433, 1549
- in /usr/src/new/kermit5.188/ckuus5.c line 1058

ttxin defined in line 4285; used 4 times

- in /usr/src/new/kermit5.188/ckucon.c line 392, 941
- in /usr/src/new/kermit5.188/ckudia.c line 2665
- in /usr/src/new/kermit5.188/ckuscr.c line 391

xxlast defined in line 881; used 2 times

- in line 2329, 2498

ztime defined in line 5039; used 10 times

- in /usr/src/new/kermit5.188/ckcfn2.c line 1527
- in /usr/src/new/kermit5.188/ckcfns.c line 900, 1028
- in /usr/src/new/kermit5.188/ckuus4.c line 930, 980, 2226, 2241, 2317, 2326, 2423

#### Defined variables

UID_T defined in line 6420; never used
VOID defined in line 6425; never used
attmodem defined in line 762; used 10 times

- in line 1174-1175(2), 1212-1214(2), 1666-1668(2), 1989, 1995, 5644, 5694

backgrd defined in line 598; used 29 times

- in line 2442, 3901-3915(6), 3966-3969(2), 5122, 5193-5196(2), 5453
- in /usr/src/new/kermit5.188/ckudia.c line 1320, 1482, 2306, 2318, 2694
- in /usr/src/new/kermit5.188/ckuscr.c line 309
- in /usr/src/new/kermit5.188/ckuus3.c line 553
- in /usr/src/new/kermit5.188/ckuus5.c line 1122-1123(2)
- in /usr/src/new/kermit5.188/ckuus6.c line 499, 523
- in /usr/src/new/kermit5.188/ckuusx.c line 239, 973-975(2), 984, 1286

cc_int defined in line 904; used 1 times

- in line 909

cccbrk defined in line 730; used 21 times

- in line 717, 5145-5154(4), 5160, 5205-5241(15)

ccold defined in line 730; used 10 times

- in line 717, 3225-3230(3), 5144-5149(2), 5159, 5385-5389(2), 5397

ccraw defined in line 730; used 27 times

- in line 717, 5146-5161(5), 5292-5307(7), 5322-5346(9), 5352-5360(5)

ckxech defined in line 617; used 15 times

- in line 5198, 5282, 5373
- in /usr/src/new/kermit5.188/ckuus5.c line 796, 819, 836, 890, 1005, 1511
- in /usr/src/new/kermit5.188/ckuus6.c line 307, 318, 760, 1250, 1276, 1745

ckxsys defined in line 132; used 12 times

- in /usr/src/new/kermit5.188/ckuus4.c line 928, 978, 1451, 2310-2311(3)
- in /usr/src/new/kermit5.188/ckuus5.c line 1126-1128(2), 1592(2)
- in /usr/src/new/kermit5.188/ckuus6.c line 863
- in /usr/src/new/kermit5.188/ckuusr.c line 1955

ckxv defined in line 1; used 2 times

- in /usr/src/new/kermit5.188/ckuus5.c line 1592(2)

conbuf defined in line 790; used 3 times

- in line 5464-5466(3)

conbufn defined in line 791; used 10 times

- in line 5135, 5200, 5284, 5376, 5460-5467(5), 5529

conbufp defined in line 792; used 2 times

- in line 5466, 5530

concrp defined in line 788; used 4 times

- in line 5134, 5201, 5285, 5377

conesc defined in line 779; used 18 times

- in line 3698-3699(2), 3707-3708(2), 3715, 3995-3999(4), 5479-5481(3), 5488-5489(2), 5570-5571(2), 5610-5611(2)

dfflow defined in line 597; used 1 times

- in /usr/src/new/kermit5.188/ckcmai.c line 776

dfloc defined in line 584; used 6 times

- in /usr/src/new/kermit5.188/ckcmai.c line 774
- in /usr/src/new/kermit5.188/ckuus2.c line 1777
- in /usr/src/new/kermit5.188/ckuus7.c line 1984, 2022, 2091
- in /usr/src/new/kermit5.188/ckuusx.c line 1219

dfmdm defined in line 583; never used
dfprty defined in line 591; used 1 times

- in /usr/src/new/kermit5.188/ckcmai.c line 775

dftty defined in line 582; used 10 times

- in /usr/src/new/kermit5.188/ckcmai.c line 773
- in /usr/src/new/kermit5.188/ckuus2.c line 1776-1779(2)
- in /usr/src/new/kermit5.188/ckuus7.c line 1983, 2012, 2021, 2053, 2093
- in /usr/src/new/kermit5.188/ckuusx.c line 556, 1218

dialer defined in line 763; used 25 times

- in line 1991-1992(2), 5650-5657(3), 5664-5665(2), 5671-5680(6), 5690-5691(4), 5707-5709(3), 5716-5718(3), 5736-5741(2)

fdflag defined in line 602; used 5 times

- in line 1072, 1134, 1159-1160(2), 1311

flfnam defined in line 766; used 21 times

- in line 1336-1339(2), 1566, 2293, 2321, 2367-2372(2), 2407-2410(2), 2420-2421(2), 2432, 2440-2447(4), 2473-2475(2), 2482
- in /usr/src/new/kermit5.188/ckuus4.c line 1083-1084(2)

haslock defined in line 770; used 10 times

- in line 2294, 2320, 2406-2408(3), 2422-2427(2), 2464, 2473
- in /usr/src/new/kermit5.188/ckuus4.c line 1083

iniflags defined in line 600; used 2 times

- in line 930, 962

jc defined in line 3722; used 23 times

- in line 3828-3832(3), 3838-3866(14), 3872, 3967-3970(3), 3977, 3986

km_con defined in line 610; used 6 times

- in line 2185, 2877, 5165-5168(2), 5392-5393(2)

km_ext defined in line 611; used 9 times

- in line 1103-1106(2), 1139-1142(2), 1396-1399(2), 1657, 2185, 2877

kmem defined in line 556; used 8 times

- in line 1356-1358(2), 4243-4244(2), 5253-5255(2), 5473-5474(2)

lkflfn defined in line 768; used 3 times

- in line 2369, 2410, 2477

lmode defined in line 748; used 3 times

- in line 1435, 2133, 2142

lmodef defined in line 747; used 10 times

- in line 1434-1438(2), 2132, 2141, 2616-2631(4), 2749-2754(2)

ltcharf defined in line 745; used 7 times

- in line 1419-1424(2), 2159, 2797, 2803, 2844, 2850

ltchnoi defined in line 743; used 5 times

- in line 1425, 2798-2799(2), 2845-2846(2)

ltchold defined in line 743; used 2 times

- in line 1421, 2160

my_count defined in line 3367; used 11 times

- in line 3399, 3417, 3456-3460(5), 3611, 4258, 4270-4271(2)

my_item defined in line 3368; used 5 times

- in line 3399, 3415-3416(2), 3461, 3612

mybuf defined in line 3364; used 10 times

- in line 3399, 3416, 3461, 3508-3511(3), 3526-3529(2), 3579, 3587

qaddr defined in line 557; used 7 times

- in line 1357, 4099, 4147-4151(2), 4243, 5254, 5473

rctsx defined in line 370; used 6 times

- in line 2596-2598(3), 2606-2608(3)

rtu_bug defined in line 588; used 2 times

- in line 6051, 6068

tcharf defined in line 737; used 8 times

- in line 1404-1409(2), 2150, 2763, 2775-2780(2), 2825, 2837

tchnoi defined in line 735; used 17 times

- in line 1410, 2764-2772(7), 2800, 2826-2834(7), 2847

tchold defined in line 735; used 2 times

- in line 1406, 2151

tcount defined in line 621; used 2 times

- in line 5022, 5031

ttbuf defined in line 753; used 17 times

- in line 4184-4196(7), 4249-4250(2), 4754-4763(6), 5455-5456(2)

ttcarr defined in line 596; used 9 times

- in line 1538, 1595, 2711, 2997, 3006(2), 5816-5818(3)

ttcur defined in line 729; used 42 times

- in line 716, 1719-1728(8), 1912-1916(2), 1926-1932(3), 1941-1943(2), 1952-1956(5), 1970, 2040-2041(2), 3170-3172(3), 3179-3185(4), 3192-3199(5), 3236-3244(6)

ttfdflg defined in line 603; used 7 times

- in line 1079, 1135, 1610, 2111, 2685, 3000, 5191

ttflow defined in line 606; used 7 times

- in line 1772, 2694, 2704, 2997, 3095, 4385-4387(2)

ttld defined in line 607; used 5 times

- in line 1455-1456(2), 2176-2180(3)

ttmdm defined in line 595; used 5 times

- in line 1070, 1133, 1162, 2698, 3006

ttnmsv defined in line 784; used 15 times

- in line 1061, 1081, 1096, 1129, 1213, 1256, 1651, 1663-1667(2), 1763-1768(2), 1994, 2020, 2029, 2698

ttold defined in line 729; used 23 times

- in line 716-720(2), 1381-1393(6), 1542, 1551, 2120-2123(2), 2167, 2731, 2908, 3019, 3045, 3177-3178(2), 3190-3191(2), 3198(2)

ttotmo defined in line 996; used 4 times

- in line 1195, 1202-1207(2), 1228

ttpflg defined in line 593; used 2 times

- in line 2677, 4614

ttpmsk defined in line 594; used 11 times

- in line 2678, 4291, 4302, 4309, 4508, 4559, 4577, 4619, 4657, 4671, 4708

ttprty defined in line 592; used 10 times

- in line 2676-2678(2), 4291, 4508, 4614-4617(3), 4623
- in /usr/src/new/kermit5.188/ckcfn2.c line 1283-1284(2)

ttraw defined in line 729; used 66 times

- in line 716, 1383, 1389, 1443, 1476-1478(2), 1501-1505(3), 1538-1552(6), 2710, 2721-2731(6), 2737-2739(2), 2792, 2817-2822(2), 2856, 2864-2873(4), 2902-2908(4), 2915-2947(17), 2954-2968(7), 3173-3174(2), 3188-3189(2), 3197(2)

ttspeed defined in line 605; used 6 times

- in line 1559-1560(2), 1772, 2679, 2997, 3094

tttvt defined in line 729; used 42 times

- in line 716, 1384, 1390, 1444, 1477, 3005, 3016-3032(8), 3042-3075(16), 3081-3090(6), 3175-3176(2), 3186-3187(2), 3196(2)

tvtflg defined in line 604; used 12 times

- in line 1132, 1156, 1612, 2196, 2712, 2893, 2970, 2987-2997(3), 3096-3098(2)

vanilla defined in line 758; used 2 times

- in line 929, 961

x25buf defined in line 3361; used 3 times

- in line 3362, 3563(2)

#### Defined struct's

termios defined in line 2576; used 12 times

- in line 715, 865, 2543-2546(6), 2584(2), 5841(2)

#### Defined typedef's

mflag defined in line 441; used 2 times

- in line 1697-1699(2)

#### Defined macros

BREAKNULS defined in line 636; used 3 times

- in line 629, 635-640(2)

BSD42 defined in line 4867; used 6 times

- in line 217, 673, 1047, 4874, 5050, 5075

BSDBREAK defined in line 4733; used 1 times

- in line 4770

BSPEED defined in line 4179; used 3 times

- in line 4189-4194(3)

CON defined in line 558; used 6 times

- in line 5253-5255(3), 5473-5474(3)

CONBUFSIZ defined in line 789; used 1 times

- in line 790

CRTSCTS defined in line 2574; used 3 times

- in line 2559-2560(2), 2587

CTRLC defined in line 4449; used 3 times

- in line 4446-4447(2), 4579

DEVNAMLEN defined in line 101; used 13 times

- in line 95-100(2), 784, 1019, 1061, 1081, 1096, 1129, 1256, 1282-1285(2), 1296, 2494

DIRENT defined in line 34; used 1 times

- in line 46

DOGETY defined in line 214; used 5 times

- in line 1174, 1212-1214(2), 1666-1668(2)

EINTR defined in line 5547; used 5 times

- in line 4537, 5546, 5569, 5580, 5610

ENOTCONN defined in line 23; used 2 times

- in line 4665, 4704

FIONREAD defined in line 3338; used 10 times

- in line 513-517(2), 3335-3336(2), 3540, 3568, 4233-4234(2), 5495, 5502

FREAD defined in line 524; used 3 times

- in line 523, 3640, 3655

FWRITE defined in line 528; used 2 times

- in line 527, 4771

GID_ROOT defined in line 6129; never used
HPUXJOBCTL defined in line 434; used 4 times

- in line 437-443(3), 3758

HUPTIME defined in line 1684; used 7 times

- in line 1725, 1735, 1746, 1791, 1819, 1876, 2125

HZ defined in line 69; used 2 times

- in line 4954-4955(2)

IEXTEN defined in line 461; used 6 times

- in line 458-460(2), 2917, 3050, 5209, 5292

ISMODEM defined in line 213; used 4 times

- in line 1989, 1995, 5644, 5694

K_MDMCTL defined in line 5931; used 1 times

- in line 5987

LCKDIR defined in line 141; used 1 times

- in line 189

LFDEVNO defined in line 2258; used 4 times

- in line 2256, 2263, 2301, 2334

LFNAML defined in line 2311; used 3 times

- in line 2312-2316(3)

LOCKF defined in line 177; used 3 times

- in line 176, 2412, 2479

LOCK_DIR defined in line 192; used 2 times

- in line 148, 2317

MSLFTIME defined in line 4847; used 1 times

- in line 4985

MYBUFLEN defined in line 3356; used 4 times

- in line 3361-3364(2), 3576-3577(2)

MYREAD defined in line 222; used 11 times

- in line 209, 1053, 3344, 3607, 4265, 4298, 4471, 4530, 4647, 4653, 4681

NAMEFD defined in line 1022; used 4 times

- in line 1025, 1075, 1098, 1119

NAP defined in line 73; used 2 times

- in line 65, 4932

NCCS defined in line 346; used 1 times

- in line 345

NOFILEH defined in line 333; used 2 times

- in line 317, 336

NOSETREU defined in line 6143; used 1 times

- in line 6150

NOSYSIOCTLH defined in line 377; used 1 times

- in line 382

OPENFLGS defined in line 2011; used 5 times

- in line 2019-2020(2), 2026-2031(3)

O_RDONLY defined in line 532; used 2 times

- in line 531, 2206

PEEKTYPE defined in line 3341; used 3 times

- in line 3547, 4220, 5451

PGROUP_T defined in line 3762; used 2 times

- in line 3769-3772(2)

PIDSTRING defined in line 167; used 3 times

- in line 2209, 2305, 2391

SELECT defined in line 4875; used 2 times

- in line 4870, 4879

SETREUID defined in line 6151; used 3 times

- in line 6149, 6271, 6375

TANDEM defined in line 126; used 11 times

- in line 2721-2731(4), 2737-2739(2), 3016-3022(4), 5358

TCGETS defined in line 2572; used 1 times

- in line 2586

TCSANOW defined in line 2533; used 1 times

- in line 2561

TCSETS defined in line 2573; used 1 times

- in line 2588

TERMIOS defined in line 343; never used
TTOC_TMO defined in line 4368; used 3 times

- in line 4374-4379(3)

TTOLMAXT defined in line 4323; used 2 times

- in line 4330-4334(2)

TTY defined in line 559; used 6 times

- in line 1356-1358(3), 4243-4244(3)

UID_ROOT defined in line 6128; used 2 times

- in line 6255-6258(2)

USLEEP defined in line 4862; used 2 times

- in line 4854, 4905

ZTIMEV7 defined in line 5060; used 2 times

- in line 5042, 5093

ctermid defined in line 1009; used 2 times

- in line 1007, 1293

major defined in line 2273; used 3 times

- in line 2266, 2338-2339(2)

minor defined in line 2274; used 1 times

- in line 2340

myread defined in line 3399; used 4 times

- in line 4301, 4533, 4655, 4682

nap defined in line 72; used 1 times

- in line 4933

switchgid defined in line 6310; used 3 times

- in line 6326, 6332, 6356

switchuid defined in line 6309; used 2 times

- in line 6330, 6352

xunchar defined in line 4556; used 4 times

- in line 4555, 4566-4572(3)

Last modified: 1992-11-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 14888 |