home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / convergent / ctxcto.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  22KB  |  847 lines

  1. char *ckxv = "Comm line I/O CTOS/BTOS Version-2.00, May 1992";
  2.  
  3. /* C-Kermit interrupt, terminal control & i/o functions for CTOS systems */
  4.  
  5. /* Joel Dunn, UNC-CH Administrative Data Processing */
  6. /* Modifications -        Joel Dunn 9/21/87
  7.             Set video pause off in ttpkt and on in ttres
  8.             to allow large files to be sent without
  9.             having to press next-page 
  10. -        Joel Dunn 12/8/87
  11.             Return 0 on erc 602 in coninc, otherwise
  12.             it streams <cr> when run under CM/VM 
  13.  
  14.         Doug Drury May 1991
  15.             Implemented HANGUP command in TTHANG
  16.             patterned after UNIX TTHANG
  17.                         Modified TTPKT to fix BTOS problem that
  18.                         occured when an erc was incorrectly detected
  19.                         during line conditioning
  20.  
  21.         Evan Arnerich - Mar 1992
  22.             Modified parity logic to set databits to 8
  23.             whenever parity is none, otherwise set databits
  24.             to 7 for all other parity settings.
  25.  
  26.         Evan Arnerich/Doug Drury - May 1992
  27.             Modified logic to set flow control according
  28.             to operator-set parameter.
  29. **/
  30.  
  31. char *ckxsys = " CTOS 11.2 Standard Software";
  32.  
  33. /*
  34.  Variables available to outside world:
  35.  
  36.    dftty  -- Pointer to default tty name string,
  37.              like "[comm]x".
  38.    dfloc  -- 0 if dftty is console, 1 if external line.
  39.    dfprty -- Default parity
  40.    dfflow -- Default flow control
  41.    ckxech -- Flag for who echoes console typein:
  42.      1 - The program (system echo is turned off)
  43.      0 - The system (or front end, or terminal).
  44.    functions that want to do their own echoing should check this flag
  45.    before doing so.
  46.  
  47.  Functions for assigned communication line (either external or console tty):
  48.  
  49.    ttopen(ttname,local,mdmtyp) -- Open the named tty for exclusive access.
  50.    ttclos()                -- Close & reset the tty
  51.    ttpkt(speed,flow)       -- Put the tty in packet mode and set the speed.
  52.    ttvt(speed,flow)        -- Put the tty in virtual terminal mode.
  53.                    or in DIALING or CONNECTED modem control state.
  54.    ttinl(dest,max,timo,eol)-- Timed read line from the tty.
  55.    ttinc(timo)             -- Timed read character from tty.
  56.    myread()                -- timed or untimed comm line read
  57.    ttol(string,length)     -- Write a string to the tty.
  58.    ttoc(c)                 -- Write a character to the tty.
  59.    ttflui()                -- Flush tty input buffer.
  60.    tthang()                -- Hangup line.
  61.  
  62. */
  63.  
  64. /*
  65. Functions for console terminal:
  66.  
  67.    congm()   -- Get console terminal modes.
  68.    concb(esc) -- Put the console in single-character wakeup mode with no echo.
  69.    conbin(esc) -- Put the console in binary (raw) mode.
  70.    conres()  -- Restore the console to mode obtained by congm().
  71.    conoc(c)  -- Unbuffered output, one character to console.
  72.    conol(s)  -- Unbuffered output, null-terminated string to the console.
  73.    conola(s) -- Unbuffered output, array of strings to the console.
  74.    conxo(n,s) -- Unbuffered output, n characters to the console.
  75.    conchk()  -- Check if characters available at console
  76.    coninc(timo)  -- Timed get a character from the console.
  77.    conint()  -- Enable terminal interrupts on the console if not background.
  78.    connoi()  -- Disable terminal interrupts on the console if not background.
  79.  
  80. Time functions
  81.  
  82.    msleep(m) -- Millisecond sleep
  83.    ztime(&s) -- Return pointer to date/time string
  84. */
  85.  
  86. /* Includes */
  87.  
  88. #include "ctermi.h"
  89.  
  90. #ifndef DIRSIZ
  91. #ifdef MAXNAMLEN
  92. #define DIRSIZ MAXNAMLEN
  93. #else
  94. #define DIRSIZ 14
  95. #endif
  96. #endif
  97.  
  98. /* Declarations */
  99.  
  100. /* dftty is the device name of the default device for file transfer */
  101. /* dfloc is 0 if dftty is the user's console terminal, 1 if an external line */
  102.  
  103.     struct configtype {        /* config area for acquirebytestreamc */
  104.         char cctype;        /* is a comm config area */
  105.         int cspeed;        /* baud rate*/
  106.         char cstop;        /* stop bits */
  107.         char cdummy1;
  108.         char cdatab;        /* data bits */
  109.         char cparity;        /* 1 = even parity, 0 = none, 2 = odd,
  110.                            3 = mark, 4 = space */
  111.         char clinec;        /* line control, 0 = none, 1 = xon,
  112.                            2 = cts, 3 = both */
  113.         int cdummy2;
  114.         char cnlmap;        /* new line mapping, 0 = binary, 1 = CR,
  115.                            2 = CR/LF */
  116.         char clfmap;        /* LF mapping, 0 = binary, 1 = CR/LF */
  117.         int ctrto;        /* transmit timeout */
  118.         int crecto;        /* receive timeout */
  119.         int ceofb;        /* EOF byte */
  120.         int cdummy3;
  121.         char cunknown1;
  122.         char cunknown2;
  123.         char cunknown3;
  124.         char cunknown4;
  125.         char cunknown5;
  126.         char cunknown6;
  127.         char cunknown7;
  128.         char cunknown8;
  129.         char cdummy4[34];
  130.         int cunknown9;
  131.         char cdummy5[448];
  132.         };
  133.  
  134.     static struct configtype configarea;
  135.     char *dftty = "[comm]x";
  136.     static char BSWA[130];
  137.     extern char bsvid[130];
  138.     int dfloc = 0;
  139.  
  140.     int dfprty = 'e';            /* Parity ('e' = even) */
  141.     int dfflow = 1;            /* Xon/Xoff flow control */
  142.  
  143. int ckxech = 0; /* 0 if system normally echoes console characters, else 1 */
  144. extern int parity; /* pick up parity for use in writebytestreamparamc */
  145.  
  146. /* Declarations of variables global within this module */
  147.  
  148. static
  149.     conif = 0,            /* Console interrupts on/off flag */
  150.     cgmf = 0,            /* Flag that console modes saved */
  151.     xlocal = 0,            /* Flag for tty local or remote */
  152.     ttyfd = -1;            /* TTY file descriptor */
  153. static char escchr;            /* Escape or attn character */
  154. static char commbuff[4096];        /* bytestream buffer area */
  155. static int erc;                /* CTOS error number */
  156. unsigned int ttsspd(); /* make sure baud rate is a "real word" */
  157.  
  158. /*  T T O P E N  --  Open a tty for exclusive access.  */
  159.  
  160. /*  Returns 0 on success, -1 on failure.  */
  161.  
  162. ttopen(ttname,lcl,modem) char *ttname; int lcl, modem; {
  163.  
  164.     int openmode=0x6d6d;
  165.     if (ttyfd > -1) return(0); /* If already open, ignore this call */
  166.     if (*ttname != '[') return(-1); /* ignore bad format */
  167.     configarea.cctype = 0x03;
  168.     configarea.cspeed = 0x4b0;
  169.     configarea.cstop = 0x01;
  170.     configarea.cdatab = 0x07;
  171.     switch(parity)
  172.         {
  173.         case 'e' : 
  174.             configarea.cparity = 0x01;
  175.             break;
  176.         case 'o' : 
  177.             configarea.cparity = 0x02;
  178.             break;
  179.         case 'm' : 
  180.             configarea.cparity = 0x03;
  181.             break;
  182.         case 's' : 
  183.             configarea.cparity = 0x04;
  184.             break;
  185.         case 0   : 
  186.             configarea.cdatab  = 0x08;
  187.             configarea.cparity = 0x00;
  188.             break;
  189.         default  :
  190.             parity = 'e';
  191.             configarea.cparity = 0x01;
  192.             break;
  193.         }
  194.     configarea.clinec = 0x01;
  195.     configarea.cnlmap = 0x00;
  196.     configarea.clfmap = 0x00;
  197.     configarea.ctrto = 0x00;
  198.     configarea.crecto = 0x00;
  199.     configarea.ceofb = 0x00;
  200.     configarea.cunknown1 = 0x01;
  201.     configarea.cunknown2 = 0x02;
  202.     configarea.cunknown3 = 0x02;
  203.     configarea.cunknown4 = 0x02;
  204.     configarea.cunknown5 = 0x01;
  205.     configarea.cunknown6 = 0x02;
  206.     configarea.cunknown7 = 0x02;
  207.     configarea.cunknown8 = 0x01;
  208.     configarea.cunknown9 = 0x5454;
  209.     erc = acquirebytestreamc(&BSWA[0], ttname, strlen(ttname), openmode, 
  210.                  &configarea, &commbuff[0], 1024,
  211.                  &commbuff[1024], 3072, 512, 0);
  212.     debug(F101,"ttopen, acquirebytestream erc","",erc);
  213.     if (erc > 0)
  214.         {
  215.         ttyfd = -1;
  216.         return(-1);
  217.         }
  218.     ttyfd = 0;
  219.     erc = setimagemodec(&BSWA[0], 2);
  220.     debug(F101,"ttopen, setimagemodec erc","",erc);
  221.     return(0);
  222. }
  223.  
  224. /*  T T C L O S  --  Close the TTY  */
  225.  
  226. ttclos() {
  227.     debug(F101,"ttclos, ttyfd","",ttyfd);
  228.     if (ttyfd < 0) return(0);        /* Wasn't open. */
  229.     ttres();                /* Reset modes. */
  230.     erc = closebytestream(&BSWA[0]);
  231.     debug(F101,"ttclos, closebytestream erc","",erc);
  232.     ttyfd = -1;                /* Mark it as closed. */
  233.     return(0);
  234. }
  235.  
  236. /*  T T R E S  --  Restore terminal to "normal" mode.  */
  237.  
  238. ttres() {                /* Restore the tty to normal. */
  239.     int cbwritten;              
  240.         char s[3] = {'\377','P','N'};
  241.     
  242.     if (ttyfd < 0) return(-1);        /* Not open. */
  243.     /* set video pause on */
  244.     erc = writebsrecord(&bsvid[0], s, 3, &cbwritten);
  245.     return(0);
  246. }
  247.  
  248. /*  T T P K T  --  Condition the communication line for packets. */
  249. /*        or for modem dialing */
  250.  
  251. /*  If called with speed > -1, also set the speed.  */
  252.  
  253. /*  Returns 0 on success, -1 on failure.  */
  254.  
  255. ttpkt(speed,flow) int speed, flow; {
  256.     extern char ttname[];
  257.     unsigned int s;
  258.     unsigned int p;
  259.     int parmno=2;
  260.     int b;
  261.     int cbwritten;
  262.         int x;                 
  263.     char v[3] = {'\377','P','F'};
  264.  
  265.     if (ttyfd < 0)  return(-1);        /* Not open. */
  266.     s = ttsspd(speed);            /* Check the speed */
  267.  
  268.   /* set speed */
  269.     debug(F101,"ttpkt, speed","",s);
  270.     if (s > 0)
  271.         { 
  272.  
  273. /* the following FOR loop was added because of a problem that sometimes
  274.    occures where the modem IS ready but still returns an ERC of 300 */      
  275.  
  276.                   for(x=0; x<5; x++) {
  277.                       erc = writebytestreamparameterc(&BSWA[0], parmno, s);
  278.                       if (erc == 0) break;
  279.                       delay (1);
  280.                   }                    
  281.                 x = erc;  /* save ERC so debug doesn't reset it */
  282.                 debug(F101,"ttpkt, speed erc","",erc);
  283.         if (x > 0) return(-1);
  284.         }
  285.  
  286.   /* set parity */
  287.     parmno = 1;
  288.     switch(parity)
  289.         {
  290.         case 'e' : p = 1; b = 7; break;
  291.         case 'o' : p = 2; b = 7; break;
  292.         case 'm' : p = 3; b = 7; break;
  293.         case 's' : p = 4; b = 7; break;
  294.         case 0 : p = 0; b = 8; break;
  295.         default : return(-1);
  296.         }
  297.     debug(F101,"ttpkt, parity","",p);
  298.  
  299. /* the following FOR loop was added because of a problem that sometimes
  300.    occures where the modem IS ready but still returns an ERC of 300 */      
  301.  
  302.         for(x=0; x<5; x++) {
  303.              erc = writebytestreamparameterc(&BSWA[0], parmno, p);
  304.              if (erc == 0) break; 
  305.              delay (1);
  306.         }
  307.         x = erc;            /* Save ERC so debug doesn't reset it */
  308.     debug(F101,"ttpkt, parity erc","",erc);
  309.     if (x > 0) return(-1);
  310.  
  311.   /* set data bits */
  312.     parmno = 0;
  313.     debug(F101,"ttpkt, data bits","",b);
  314.  
  315. /* the following FOR loop was added because of a problem that sometimes
  316.    occures where the modem IS ready but still returns an ERC of 300 */      
  317.  
  318.         for(x=0; x<5; x++) {
  319.              erc = writebytestreamparameterc(&BSWA[0], parmno, b);
  320.              if (erc == 0) break; 
  321.              delay (1);
  322.         }
  323.         x = erc;            /* Save ERC so debug doesn't reset it */
  324.     debug(F101,"ttpkt, data bits erc","",erc);
  325.     if (x > 0) return(-1);
  326.  
  327.   /* set flow control */
  328.     parmno = 8;
  329.     debug(F101,"ttpkt, flow control","",flow);
  330.  
  331. /* the following FOR loop was added because of a problem that sometimes
  332.    occures where the modem IS ready but still returns an ERC of 300 */      
  333.  
  334.         for(x=0; x<5; x++) {
  335.              erc = writebytestreamparameterc(&BSWA[0], parmno, flow);
  336.              if (erc == 0) break; 
  337.              delay (1);
  338.         }
  339.         x = erc;            /* Save ERC so debug doesn't reset it */
  340.     debug(F101,"ttpkt, flow control erc","",erc);
  341.     if (x > 0) return(-1);
  342.  
  343.     /* set video pause off */
  344.     erc = writebsrecord(&bsvid[0], v, 3, &cbwritten);
  345.  
  346.     ttflui();                /* Flush any pending input */
  347.     return(0);
  348. }
  349.  
  350. /*  T T V T -- Condition communication line for use as virtual terminal  */
  351.  
  352. ttvt(speed,flow) int speed, flow; {
  353.     extern char ttname[];
  354.     unsigned int s;
  355.     unsigned int p;
  356.     int parmno=2;
  357.     int b;
  358.     int settry=0;
  359.     if (ttyfd < 0) return(-1);        /* Not open. */
  360.     s = ttsspd(speed);            /* Check the speed */
  361.  
  362.   /* set speed */
  363.     debug(F101,"ttvt, speed","",s);
  364.     if (s > 0)
  365.         {
  366.         erc = writebytestreamparameterc(&BSWA[0], parmno, s);
  367.         debug(F101,"ttvt, speed erc","",erc);
  368.         while ((settry < 10) && (erc))
  369.             {
  370.             erc = writebytestreamparameterc(&BSWA[0], parmno, s);
  371.             debug(F101,"ttvt, speed erc (in loop)","",erc);
  372.             debug(F101,"ttvt, speed set try number","",settry);
  373.             if (erc) delay(10);
  374.         /* retry 10 times at 1 second inteveral, may get erc 300 if line 
  375.                 is active (this is defensive programming) */
  376.             settry++;
  377.             }
  378.         if (erc > 0) return(-1);
  379.         }
  380.  
  381.   /* set parity */
  382.     parmno = 1;
  383.     switch(parity)
  384.         {
  385.         case 'e' : p = 1; b = 7; break;
  386.         case 'o' : p = 2; b = 7; break;
  387.         case 'm' : p = 3; b = 7; break;
  388.         case 's' : p = 4; b = 7; break;
  389.         case 0 : p = 0; b = 8; break;
  390.         default : return(-1);
  391.         }
  392.     debug(F101,"ttvt, parity","",p);
  393.     erc = writebytestreamparameterc(&BSWA[0], parmno, p);
  394.     debug(F101,"ttvt, parity erc","",erc);
  395.     if (erc > 0) return(-1);
  396.  
  397.   /* set data bits */
  398.     parmno = 0;
  399.     debug(F101,"ttvt, parity","",b);
  400.     erc = writebytestreamparameterc(&BSWA[0], parmno, b);
  401.     debug(F101,"ttvt, data bits erc","",erc);
  402.     if (erc > 0) return(-1);
  403.  
  404.     ttflui();                /* Flush any pending input */
  405.     return(0);
  406. }
  407.  
  408. /*  T T S S P D  --  Return the internal baud rate code for 'speed'.  */
  409.  
  410. unsigned int ttsspd(speed) {
  411.     unsigned int s;
  412.     int spdok;
  413.  
  414.     if (speed < 0) return(-1);
  415.     spdok = 1;            /* Assume arg ok */
  416.     switch (speed) {
  417.         case 0:    s = 0;    break;    
  418.         case 300:  s = 300;  break;    
  419.         case 1200: s = 1200; break;
  420.         case 2400: s = 2400; break;
  421.         case 4800: s = 4800; break;
  422.         case 9600: s = 9600; break;
  423.         default:
  424.             spdok = 0;
  425.         fprintf(stderr,"Unsupported line speed - %d\n",speed);
  426.         fprintf(stderr,"Current speed not changed\n");
  427.         break;
  428.     }        
  429.     if (spdok) return(s); else return(-1);
  430.  }
  431.  
  432. /*  T T F L U I  --  Flush tty input buffer */
  433.  
  434. ttflui() {
  435.  
  436.     unsigned int cbdiscard=0;
  437.  
  438.     while (myread(0)) cbdiscard++;
  439.     debug(F101,"ttflui, input bytes discarded: ","",cbdiscard);
  440.     return(0);        
  441. }
  442.  
  443. /*  T T H A N G  --  Hangup the line */
  444.  
  445. tthang(){                     
  446.     int x,y;
  447.     y = 0x08;
  448.         erc = readstatusc(&BSWA[0], y, &x); /*just see if its active */
  449.     if (erc != 0)
  450.        return(0);        /* return success if can't access line */
  451.     x = 0;                        
  452.     y = 0x300;          
  453.         erc = writestatusc(&BSWA[0], y, x); /* drop DTR to hang up */
  454.         ttclos();
  455.         return(0);
  456. }
  457.  
  458. /* C O N I N T -- Console Interrupt setter */
  459. conint(f) int (*f) ();
  460.     {
  461.     return 0;
  462.     }
  463.  
  464. /* C O N N O I -- Reset console terminal interrupts */
  465. connoi () 
  466.     {
  467.     return 0;
  468.     }
  469.  
  470. /* M Y R E A D -- read a character, timed or untimed */
  471.  
  472. myread(timo) int timo; { /* return character or -1 if disconnected */
  473.  
  474.     unsigned char *pch;
  475.     unsigned int ch;
  476.     unsigned int badchar=0x04;
  477.     int cbreceived;
  478.     int exchwait;
  479.     int timerexit;
  480.     struct ctostimer trb1;
  481.     struct ctostimer *ptrb1;
  482.     
  483.     cbreceived = 0;
  484.     if (timo == 0)
  485.         {
  486.         erc = fillbufferasyncc(&BSWA[0], 0, 1, &pch,
  487.                        &cbreceived,0,0l,0);
  488.         if (erc) debug(F101,"myread, fillbuff erc: ","",erc);
  489.         if (erc)
  490.             {
  491.             switch(erc)
  492.                 {
  493.                 case 2340:
  494.                 case 2341:
  495.                 case 2342:
  496.                     cbreceived = 1;
  497.                     pch = &badchar;
  498.                     break;
  499.                 case 2349:
  500.                     break;
  501.                 default:
  502.                     return(-1);
  503.                 }
  504.             }
  505.             if (cbreceived) return(ch = (*pch & 0xff));
  506.         else return(0);
  507.         }
  508.     else
  509.         {
  510.         timerexit = 0;
  511.         allocexch(&exchwait);
  512.         trb1.ctt_counter = 10*timo;
  513.         trb1.ctt_reload = 0;
  514.         trb1.ctt_cevents = 0;
  515.         trb1.ctt_exchresp = exchwait;
  516.         trb1.ctt_ercret = 0;
  517.         trb1.ctt_rqcode = exchwait;
  518.         openrtclock(&trb1);
  519.         while (!timerexit)
  520.             {
  521.             erc = fillbufferasyncc(&BSWA[0], 0, 1, &pch,
  522.                            &cbreceived,0,0l,0);
  523.             if (erc) debug(F101,"myread(timo), fillbuff erc: ","",erc);
  524.             if (erc)
  525.                 {
  526.                 switch(erc)
  527.                     {
  528.                     case 2340:
  529.                     case 2341:
  530.                     case 2342:
  531.                         cbreceived = 1;
  532.                         pch = &badchar;
  533.                         break;
  534.                     case 2349:
  535.                         break;
  536.                     default:
  537.                         return(-1);
  538.                     }
  539.                 }
  540.             if (cbreceived) break;
  541.             if (!check(exchwait, &ptrb1))
  542.               if (ptrb1->ctt_rqcode == exchwait) timerexit = 1;
  543.             }
  544.         closertclock(&trb1);
  545.         deallocexch(exchwait);
  546.         if ((timerexit) && (!cbreceived)) return(-1);
  547.         if (cbreceived) return (ch = (*pch & 0xff));
  548.         else return(-1);
  549.         }
  550.     }
  551.  
  552. /*  T T O L  --  Similar to "ttinl", but for writing.  */
  553.  
  554. ttol(s,n) int n; char *s; {
  555.     int x=0;
  556.     int cbwritten;
  557.     char no=0;
  558.     if (ttyfd < 0) return(-1);        /* Not open. */
  559.     erc = flushbufferc(&BSWA[0], s, n, &cbwritten);
  560.     if (erc > 0) x = -1;
  561.     debug(F111,"ttol",s,n);
  562.     if (x < 0) debug(F101,"ttol failed","",erc);
  563.     checkpointbsc(&BSWA[0], no);
  564.     return(x);
  565. }
  566.  
  567. /*  T T O C  --  Output a character to the communication line  */
  568.  
  569. ttoc(c) char c; {
  570.     int x=0;
  571.     int cbwritten;
  572.     if (ttyfd < 0) return(-1);        /* Not open. */
  573.     erc = flushbufferc(&BSWA[0], &c, 1, &cbwritten);
  574.     if (erc > 0) x = -1;
  575.     return(x);
  576. }
  577.  
  578. /*  T T I N L  --  Read a record (up to break character) from comm line.  */
  579. /*
  580.   If no break character encountered within "max", return "max" characters,
  581.   with disposition of any remaining characters undefined.  Otherwise, return
  582.   the characters that were read, including the break character, in "dest" and
  583.   the number of characters read as the value of function, or 0 upon end of
  584.   file, or -1 if an error occurred.  Times out & returns error if not completed
  585.   within "timo" seconds.
  586. */
  587.  
  588. ttinl(dest,max,timo,eol) int max,timo; char *dest; char eol; {
  589.     int x, c;
  590.     int exchwait;
  591.     int timerexit;
  592.     struct ctostimer trb1;
  593.     struct ctostimer *ptrb1;
  594.  
  595.     if (ttyfd < 0) return(-1);        /* Not open. */
  596.     allocexch(&exchwait);
  597.     trb1.ctt_counter = 10*timo;
  598.     trb1.ctt_reload = 0;
  599.     trb1.ctt_cevents = 0;
  600.     trb1.ctt_exchresp = exchwait;
  601.     trb1.ctt_ercret = 0;
  602.     trb1.ctt_rqcode = exchwait;
  603.     openrtclock(&trb1);
  604.     x = c = 0;
  605.     timerexit = 0;
  606.     while ((x < max) && (c != eol) && (!timerexit))
  607.         {
  608.         c = myread(0); 
  609.         if (c > 0)
  610.             {
  611.             dest[x] = c;
  612.             x++;
  613.             }
  614.         if (!check(exchwait, &ptrb1))
  615.             if (ptrb1->ctt_rqcode == exchwait) timerexit = 1;
  616.         }
  617.     if (c > 0) x++;
  618.     else x = -1;
  619.     closertclock(&trb1);
  620.     deallocexch(exchwait);
  621.     return(x);                /* Return the count. */
  622. }
  623.  
  624. /*  T T I N C --  Read a character from the communication line  */
  625.  
  626. ttinc(timo) int timo; {
  627.     int ch;
  628.  
  629.     if (ttyfd < 0) return(-1);        /* Not open. */
  630.     if (timo <= 0) {            /* Untimed. */
  631.     /* comm line failure returns -1 thru myread, so don't &= 0377 */
  632.     return( myread(timo) );
  633.     }
  634.     ch = myread(timo);
  635.     if (ch > 0) return(ch & 0377); else return(ch);  /* Return char or -1. */
  636. }
  637.  
  638. /*  T T S N D B  --  Send a BREAK signal  */
  639.  
  640. ttsndb() {
  641.     int x;
  642.  
  643.     if (ttyfd < 0) return(-1);        /* Not open. */
  644.  
  645.     erc = sendbreakc(&BSWA[0]);
  646.     if (erc != 0) 
  647.         {
  648.             conol("Can't send BREAK");
  649.         return(-1);
  650.         }
  651.     return(0);
  652. }
  653.  
  654. /*  M S L E E P  --  Millisecond version of sleep().  */
  655.  
  656. /*
  657.  Intended only for small intervals.  For big ones, just use sleep().
  658. */
  659.  
  660. msleep(m) int m; {
  661.  
  662.     delay(m);
  663.     return(0);
  664.  
  665. }
  666.  
  667. /*  Z T I M E  --  Return date/time string  */
  668.  
  669. ztime(s) char **s; {
  670.     static char sbdatetimeret[32];
  671.     long int datetimeret;
  672.     unsigned char expdatetimeret[8];
  673.     int i;
  674.  
  675.     for (i = 0; i < 31; i++) sbdatetimeret[i] = '\0';
  676.     erc = getdatetime(&datetimeret);
  677.     if (!erc) erc = expanddatetime(datetimeret, &expdatetimeret[0]);
  678.     if (!erc) erc = formattime(&sbdatetimeret[0], &expdatetimeret[0]);
  679.  
  680.     *s = &sbdatetimeret[1];
  681.     return(0);
  682. }
  683.  
  684. /*  C O N G M  --  Get console terminal modes.  */
  685.  
  686. /*
  687.  Saves current console mode, and establishes variables for switching between 
  688.  current (presumably normal) mode and other modes.
  689. */
  690.  
  691. congm() {
  692.     /* don't know what will be needed under CTOS */
  693.      cgmf = 1;            
  694. }
  695.  
  696.  
  697. /*  C O N C B --  Put console in cbreak mode.  */
  698.  
  699. /*  Returns 0 if ok, -1 if not  */
  700.  
  701. concb(esc) char esc; {
  702.     /* don't know what will be needed under CTOS, this looks good */
  703.     if (cgmf == 0) congm();        /* Get modes if necessary. */
  704.     escchr = esc;            /* Make this available to other fns */
  705.     ckxech = 1;                /* Program can echo characters */
  706.     return(0);
  707. }
  708.  
  709. /*  C O N B I N  --  Put console in binary mode  */
  710.  
  711.  
  712. /*  Returns 0 if ok, -1 if not  */
  713.  
  714. conbin(esc) char esc; {
  715.     int cbwritten;
  716.     char s[3] = {'\377','P','F'};       /* set video pause off */
  717.     int x = 3;
  718.     if (cgmf == 0) congm();        /* Get modes if necessary. */
  719.     escchr = esc;            /* Make this available to other fns */
  720.     ckxech = 1;                /* Program can echo characters */
  721.     erc = writebsrecord(&bsvid[0], s, x, &cbwritten);
  722.     if (erc == 0) return(0);
  723.     else return(-1);
  724. }
  725.  
  726.  
  727. /*  C O N R E S  --  Restore the console terminal  */
  728.  
  729. conres() {
  730.     int cbwritten;
  731.     char s[3] = {'\377','P','F'};        /* set video pause back off */
  732.     int x = 3;        
  733.     
  734.     if (cgmf == 0) return(0);        /* Don't do anything if modes not saved */
  735.     cgmf = 0;
  736.     ckxech = 0;                /* System should echo chars */
  737.     erc = writebsrecord(&bsvid[0], s, x, &cbwritten);
  738.     if (erc == 0) return(0);
  739.     else return(-1);
  740. }
  741.  
  742. /*  C O N O C  --  Output a character to the console terminal  */
  743.  
  744. conoc(c) char c; {
  745.     erc = writebyte(&bsvid[0], c);
  746. }
  747.  
  748. /*  C O N X O  --  Write x characters to the console terminal  */
  749.  
  750. conxo(x,s) char *s; int x; {
  751.     int cbwritten;
  752.  
  753.     writebsrecord(&bsvid[0], s, x, &cbwritten);
  754. }
  755.  
  756. /*  C O N O L  --  Write a line to the console terminal  */
  757.  
  758. conol(s) char *s; {
  759.     int len;
  760.     int cbwritten;
  761.     len = strlen(s);
  762.     writebsrecord(&bsvid[0], s, len, &cbwritten);
  763. }
  764.  
  765. /*  C O N O L A  --  Write an array of lines to the console terminal */
  766.  
  767. conola(s) char *s[]; {
  768.     int i;
  769.     for (i=0 ; *s[i] ; i++) conol(s[i]);
  770. }
  771.  
  772. /*  C O N O L L  --  Output a string followed by CRLF  */
  773.  
  774. conoll(s) char *s; {
  775.     conol(s);
  776.     writebyte(&bsvid[0], 0x0d);
  777.     writebyte(&bsvid[0], 0x0a);
  778. }
  779.  
  780.  
  781. /*  C O N C H K  --  Check if characters available at console  */
  782.  
  783. conchk() {
  784.  
  785.     int ch;
  786.  
  787.     erc = readkbddirect(3, &ch);
  788.     if (erc) return(0);
  789.     else return(1);
  790.  
  791. }
  792.  
  793. /*  C O N I N C  --  Get a character from the console  */
  794.  
  795. coninc(timo) int timo; {
  796.     int exchwait;
  797.     int timerexit;
  798.     struct ctostimer trb1;
  799.     struct ctostimer *ptrb1;
  800.     int ch;
  801.     ch = 0;
  802.     if (timo <= 0 ) {            /* untimed */
  803.     erc = readkbddirect(1, &ch);        /* Read a character. */
  804.     if (ch == 0x0a) ch = 0x0d;
  805.     else if (ch == 0x0d) ch = 0x0a;
  806.     ch &= 0377;
  807.     if (erc == 602) return(0);    /* 602 means no char is available */
  808.     /* chg for CTOS/VM, was just erc = 0 on 602 */
  809.     if (erc == 0) return(ch);         /* Return the char if read */
  810.     else 
  811.         return(-1);          /* Return the char, or -1. */
  812.     }
  813.     if (timo = 9999 ) {            /* wait forever */
  814.     erc = readkbddirect(0, &ch);        /* Read a character. */
  815.     if (ch == 0x0a) ch = 0x0d;
  816.     else if (ch == 0x0d) ch = 0x0a;
  817.     ch &= 0377;
  818.     if (erc == 0) return(ch);         /* Return the char if read */
  819.     else 
  820.         return(-1);          /* Return the char, or -1. */
  821.     }
  822.     timerexit = 0;
  823.     allocexch(&exchwait);
  824.     trb1.ctt_counter = 10*timo;
  825.     trb1.ctt_reload = 0;
  826.     trb1.ctt_cevents = 0;
  827.     trb1.ctt_exchresp = exchwait;
  828.     trb1.ctt_ercret = 0;
  829.     trb1.ctt_rqcode = exchwait;
  830.     openrtclock(&trb1);
  831.     erc = 602;
  832.     while ((!timerexit) && (erc == 602))
  833.         {
  834.         erc = readkbddirect(1, &ch);        /* Read a character. */
  835.         if (!check(exchwait, &ptrb1))
  836.             if (ptrb1->ctt_rqcode == exchwait) timerexit = 1;
  837.         }
  838.     deallocexch(exchwait);
  839.     closertclock(&trb1);
  840.     if (ch == 0x0a) ch = 0x0d;
  841.     else if (ch == 0x0d) ch = 0x0a;
  842.     ch &= 0377;
  843.     if (erc == 0) return(ch);  
  844.     else
  845.     return(-1);
  846. }
  847.