home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol158 / yam3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-29  |  13.5 KB  |  759 lines

  1. /*
  2. >>:yam3.c 8-12-83
  3.  *
  4.  * two-way conversation with remote -whatever.
  5.  * Printer is buffered such that it needn't be as fast as the baudrate
  6.  * as long as it eventually gets a chance to catch up.
  7.  * This buffering also allows one to write the received data out to disk
  8.  * after the conversation has started.
  9.  */
  10. #define EXTERN extern
  11. #include "yamc86.h"
  12.  
  13. #define SAYTERM 2    /* doykbd returns this if sayterm needed */
  14.  
  15. term()
  16. {
  17.     register c, cc;
  18.     unsigned charsent;
  19.  
  20.     Lskcnt=lkbufcq=0;
  21.     sayterm();
  22.     charsent=0;
  23. #ifdef SCREAMER
  24.     if (Baudrate>SCREAMER && !Tfile && !Rfile && !Ctlview && (abptr==0)) {
  25.         yterm(Sport, Dport, &Lskcnt, &bufcq, bufst, bufend, &Wrapped);
  26.         bufcdq=bufcq;
  27.         return;
  28.     }
  29. #endif
  30.     Waitecho=Txwait=FALSE;
  31.     for (;;) {
  32. #ifdef CDO
  33.         if (CDO) {
  34.             lprintf("\nCarrier Lost");
  35.             return ERROR;
  36.         }
  37. #endif
  38.         if (miready()) {
  39.             *bufcq = michar();
  40.             Timeout=0;
  41.             if (++bufcq >= bufend)
  42.                 Wrapped=bufcq=bufst;
  43.             if (!Jovemode) {
  44.                 if (--Nfree == LOWWATER)
  45.                     MODOUT(Xoffflg=XOFF);
  46.                 else if (Nfree==0)
  47.                     goto belch;
  48.             }
  49.             continue;
  50.         }
  51.         if (COREADY && bufcdq != bufcq) {
  52.             switch((cfast=(checksum= *bufcdq) & 0177)) {
  53. #ifdef EXPANDTABS
  54.             case '\t':
  55.                 TTYOUT(' ');
  56.                 if (++Ttycol & 07)
  57.                     continue;
  58.                 else
  59.                     goto chuckit;
  60. #endif
  61. #ifdef MYSYSTEM
  62.             case SI:
  63.                 if (Cis02) {
  64.  
  65.                     if (++bufcdq >= bufend)
  66.                         bufcdq=bufst;
  67.                     cispa(); sayterm(); continue;
  68.                 }
  69.                 else
  70.                     goto showcc;
  71.             case '\f':
  72.                 if (Cis02) {    /* clr screen on ff */
  73.                     lprintf(CLEARS);
  74.                     Ttycol=0; goto chuckit;
  75.                 }
  76.                 /* ####### FALL THRU TO ###### */
  77. #endif
  78.             case '\n':
  79.                 ++Lskcnt;
  80.                 /* ####### FALL THRU TO ###### */
  81.             case '\r':
  82.                 Ttycol=0; break;
  83.             case XON:
  84.                 Txgo=TRUE; 
  85.                 if (Tfile) {
  86.                     sayterm();
  87.                     goto chuckit;
  88.                 }
  89.                 goto showcc;
  90.             case XOFF:
  91.                 Txgo=FALSE;
  92.                 if (Tfile) {
  93.                     sayterm();
  94.                     goto chuckit;
  95.                 }
  96.                 goto showcc;
  97.             case ENQ:
  98.                 if (Twxmode)
  99.                     setab();
  100.                 goto showcc;
  101. #ifdef EXPANDTABS
  102.             case '\b':
  103.                 if (Ttycol)
  104.                     --Ttycol;
  105.                 break;
  106. #endif
  107. #ifdef XMODEM
  108.             case ETX:
  109.             case EOT:
  110.             case CPMEOF:
  111.                 if (++bufcdq >= bufend)    /* discard char */
  112.                     bufcdq=bufst;
  113.                 while (readline(3)!=TIMEOUT)
  114.                     ;    /* discard anything else */
  115.                 dumprxbuff(); closerx(TRUE);
  116.                 printf("%d bytes received\n", bufcdq-bufst);
  117.                 clearbuff();
  118.                 return OK;
  119.             case 007:
  120.                 break;
  121. #endif
  122. showcc:
  123.             default:
  124.                 if (Ctlview) {
  125.                     if (checksum & 0200) { /* 8th bit */
  126.                         if (Ctlview>1) {
  127.                             TTYOUT('~');
  128. #ifdef EXPANDTABS
  129.                             ++Ttycol;
  130. #endif
  131.                         }
  132.                     }
  133.                     if (cfast>='~') { /* for ~ and rub */
  134.                         TTYOUT('^');
  135.                         TTYOUT(cfast-0100);
  136. #ifdef EXPANDTABS
  137.                         Ttycol += 2;
  138. #endif
  139.                         goto chuckit;
  140.                     }
  141.                     else if (cfast<040) { /* control char */
  142.                         TTYOUT('^');
  143.                         TTYOUT(cfast|0100);
  144. #ifdef EXPANDTABS
  145.                         Ttycol += 2;
  146. #endif
  147.                         goto chuckit;
  148.                     }
  149.                 }
  150. #ifdef EXPANDTABS
  151.                 if (cfast>037)
  152.                     ++Ttycol;
  153. #endif
  154.                 break;
  155.             }
  156.             if (cfast==GOchar && Txeoln==EOL_CRPROMPT)
  157.                 Waitecho=FALSE;
  158.  
  159. #ifdef RXNONO
  160.             if ( !index(cfast, RXNONO))
  161. #endif
  162.                 TTYOUT(cfast);
  163.             if (Echo) {
  164.                 sendline(cfast);
  165.                 if (Chat && cfast== '\r') {
  166.                     TTYOUT('\n');
  167. #ifndef XMODEM
  168.                     sendline('\n');
  169. #endif
  170.                 }
  171.             }
  172. chuckit:
  173.             if (++bufcdq >= bufend)
  174.                 bufcdq=bufst;
  175. #ifndef KBDNOW
  176.             continue;
  177. #endif
  178.         }
  179.         if (CIREADY)
  180.             switch(doykbd(CICHAR)) {
  181.             case TRUE:
  182.                 return OK;
  183.             case SAYTERM:
  184.                 sayterm();
  185.             }
  186.         if (Pflag && bufpcdq!=bufcq && POREADY) {
  187.             LPOUT(*bufpcdq++ & 0177);
  188.             if (bufpcdq >= bufend)
  189.                 bufpcdq=bufst;
  190.         }
  191.         if (MOREADY) {
  192.             if (abptr && !Txwait && !Waitecho && (Txgo||Twxmode)) {
  193.                 if (abptr>=abend) {
  194.                     abptr=NULL;
  195.                     if (Exoneof && (!Twxmode))
  196.                         return OK;
  197.                 }
  198.                 else {
  199.                     c= *abptr++; goto offwithit;
  200.                 }
  201.             }
  202.             if (Tfile && !Txwait && !Waitecho && Txgo) {
  203.                 /*
  204.                  * If receiving an echo term would emit dc3
  205.                  * when the buffer fills up. Can't allow that.
  206.                  */
  207.                 if (Nfree < (LOWWATER+50))
  208.                     dumprxbuff();
  209.                 c= getc(fin);
  210. #ifdef CPM
  211.                 if (c==EOF || (c==CPMEOF && Txeoln != TX_BINARY))
  212. #else
  213.                 if (c==EOF)
  214. #endif
  215.                 {
  216.                     closetx(FALSE);
  217. #ifdef XMODEM
  218.                     pstat(" "); return OK;
  219. #else
  220.                     if (Exoneof)
  221.                         return OK;
  222.                     sayterm(); continue;
  223. #endif
  224.                 }
  225.                 if (Twxmode)
  226.                     switch(c) {
  227.                     case ACK:
  228.                         setab();
  229.                     case CPMEOF:
  230.                         continue;
  231.                     case XOFF:
  232.                         Txgo = FALSE; sayterm(); break;
  233.                     case ENQ:
  234.                         /* force wait for response */
  235.                         Txgo = FALSE; break;
  236.                     }
  237. offwithit:
  238.                 echochr(c);    /* handle local echo */
  239.                 if (Waitbunch && ++charsent==Waitnum) {
  240.                     charsent=0;
  241.                     if (Waitnum>1) {
  242.                         Waitecho=TRUE; Timeout=0;
  243.                     } else {
  244.                         Txwait=TRUE;
  245.                         Txtimeout=Throttle;
  246.                     }
  247.                 }
  248.  
  249.                 if (c=='\r') {    /* end of line processing */
  250.                     switch(Txeoln) {
  251.                     case EOL_NL:
  252.                         continue;
  253.                     case EOL_CRPROMPT:
  254.                     case EOL_CRWAIT:
  255.                         Waitecho=TRUE; Timeout=0;
  256.                     case EOL_CR:
  257.                         if ((cc=getc(fin))!='\n')
  258.                             ungetc(cc, fin);
  259.                         break;
  260.                     }
  261.                 }
  262.                 MODOUT(c);
  263.                 continue;
  264.             }
  265.         }
  266.         if (++Timeout == Tpause) {
  267.             Waitecho=FALSE;
  268. belch:
  269.             if (Xoffflg) {
  270.                 dumprxbuff();
  271.                 if (miready()) {
  272.                     lprintf("\n\007OVERRUN: DATA LOST");
  273.                     return ERROR;
  274.                 }
  275.                 if (bufcdq != bufcq)
  276.                     continue;
  277.                 if (Pflag && bufpcdq != bufcq)
  278.                     continue;
  279.                 Xoffflg=FALSE;
  280.                 MODOUT(XON);
  281.             }
  282.         }
  283.         if (--Txtimeout==0)
  284.             Txwait=FALSE;
  285.     }
  286. }
  287.  
  288.  
  289.  
  290. #ifdef LINKPORT
  291. /*
  292.  * The term function stripped down for top speed at max baudrate
  293.  *  to allow linking of two computers.
  294.  */
  295.  
  296. dolink()
  297. {
  298.     chngport(LHPORT);
  299.     lpstat("Linking 0%o to 0%o", Dport, LIDPORT);
  300.     for (;;) {
  301. #ifndef REALSLOWKB
  302.         if (CIREADY)
  303.             switch(doykbd(CICHAR)) {
  304.             case TRUE:
  305.                 return OK;
  306.             }
  307. #endif
  308. #ifdef LCDO
  309.         if (LCDO) {
  310.             purgeline(); LICHAR;
  311.             continue;
  312.         }
  313. #endif
  314. checkrx:
  315.         while (miready()) {
  316.             *bufcq = michar();
  317.             if (++bufcq >= bufend)
  318.                 Wrapped=bufcq=bufst;
  319.         }
  320.         if (LOREADY && bufcdq != bufcq) {
  321. #ifndef REALSLOWKB
  322.             TTYOUT(*bufcdq);
  323. #endif
  324.             LOUT(*bufcdq);
  325.             if (++bufcdq >= bufend)
  326.                 bufcdq=bufst;
  327.             goto checkrx;
  328.         }
  329.         if (LIBREAK) {
  330.             clearbuff();
  331.             sendbrk();
  332.             CLRLIBREAK;
  333.         }
  334.         if (LIREADY) {
  335.             sendline(cfast=LICHAR);
  336.             switch (cfast) {
  337.             case 0177:
  338.             case 003:
  339.                 clearbuff();
  340.             }
  341.         }
  342.     }
  343. }
  344. #endif
  345.  
  346. setab()
  347. {
  348.     abptr = ANSWERBACK;
  349.     abend = abptr + strlen(abptr);
  350.     Waitecho = Txwait = FALSE;
  351. }
  352.  
  353. /* display the appropriate status information */
  354. sayterm()
  355. {
  356.     termreset();
  357.     if (Tfile)
  358.         lpstat("Sending '%s' %s", Tname, Txgo?"":"Stopped by XOFF");
  359.     if (Rfile) {
  360.         pstat("Term Receiving '%s'", Rname); Jovemode=FALSE;
  361.     }
  362.     else if (Jovemode)
  363.         pstat("Term: Jove Mode");
  364.     else
  365.         pstat("Term Function  ");
  366. #ifdef XMODEM
  367.     if (Rfile) {
  368.         printf("Transmit File. Characters will NOT be echoed\n");
  369.         printf("When file has been sent, close it by typing ^Z\n");
  370.     }
  371. #endif
  372. }
  373.  
  374. /* open a capture file and set the removal pointer to get max goods */
  375. opencapt(name)
  376. char *name;
  377. {
  378.     if (Rfile) {
  379.         dumprxbuff(); closerx(TRUE);
  380.     }
  381.     if (openrx(name)==ERROR)
  382.         return ERROR;
  383.     if (buffcdq<bufst)
  384.         buffcdq=bufst;
  385.     if (Wrapped)
  386.         buffcdq=bufcq+1;
  387.     if (buffcdq >= bufend)
  388.         buffcdq=bufst;
  389. /*    dumprxbuff(); */
  390.     return OK;
  391. }
  392.  
  393.  
  394. /*
  395.  * Dump the contents of capture buffer to receive file (if any).
  396.  */
  397. dumprxbuff()
  398. {
  399.     Nfree=Bufsize-1;
  400.     if (!Rfile || buffcdq==NULL)
  401.         return OK;
  402.     while (buffcdq != bufcq) {
  403.         Lastrx= *buffcdq++;
  404.         if (buffcdq >= bufend)
  405.             buffcdq=bufst;
  406.         if (!Image) {
  407.             switch(Lastrx &= 0177) {
  408.             case 0:
  409.                 continue;
  410.             case '\n':
  411.                 putc( '\r', fout); break;
  412.             case '\r':
  413.                 continue;
  414.             case 032:        /* ^Z or CPMEOF */
  415.                 if (Zeof) {
  416.                     closerx(TRUE);
  417.                     return OK;
  418.                 }
  419.                 else
  420. #ifdef CPM
  421.                     continue;
  422. #else
  423.                     break;
  424. #endif
  425.             case 022:
  426.                 if (Squelch) {
  427.                     Dumping=TRUE;
  428.                     continue;
  429.                 }
  430.                 break;
  431.             case 024:
  432.                 if (Squelch) {
  433.                     Dumping=FALSE;
  434.                     continue;
  435.                 }
  436.                 break;
  437.             default:
  438.                 break;
  439.             }
  440.         }
  441.         if (Dumping || Image)
  442.             if (fputc(Lastrx, fout)==ERROR) {
  443.                 lprintf("\nDisk Full");
  444.                 closerx(FALSE);
  445.                 return ERROR;
  446.             }
  447.     }
  448.     return OK;
  449. }
  450.  
  451. rewindcb()
  452. {
  453.     bufcdq=buffcdq=bufpcdq=Wrapped?bufcq+1:bufst;
  454. }
  455.  
  456. /*
  457.  * replot redisplays the buffer contents thru putcty allowing XOFF
  458.  * number will represent how many lines to go back first 
  459.  */
  460. replot(number)
  461. {
  462.     char doexit;
  463.     int count, shorts;
  464.     char *smark, *p;
  465.  
  466.     doexit=FALSE;
  467.     termreplot();
  468.     if (lkbufcq && (Lskcnt >= (TLENGTH-2))) {
  469.         number=3; shorts=0; reptr=bufmark=lkbufcq; goto f2;
  470.     }
  471. fromtop:
  472.     smark=bufmark=Wrapped?bufcq+1:bufst;
  473.     shorts=0;
  474.  
  475.     if (number) {
  476.         reptr=bufcq;
  477. f2:
  478. backsome:
  479.         for (;;) {
  480.             --reptr;
  481.             if (reptr<bufst) {
  482.                 if (Wrapped)
  483.                     reptr= bufend-1;
  484.                 else {
  485.                     reptr=bufst;
  486.                     break;
  487.                 }
  488.             }
  489.             if (reptr==bufcq)
  490.                 break;
  491.             if (((cfast=(*reptr&0177))=='\n' || cfast==ESC)
  492.              && --number<=0)
  493.                 break;
  494.         }
  495.         bufmark=reptr;
  496.     }
  497.     reptr=bufmark;
  498.     /* backing up is confusing unless screen is cleared first */
  499.     termreplot();
  500. nextscreen:
  501. #ifdef T4014
  502.     /* Do the big flash on the 4014 or 4012 */
  503.     lputs("\033\014");
  504.     sleep(CLKMHZ * 5);
  505. #endif
  506.     count=TLENGTH - shorts -1;
  507.     shorts =0;
  508. nextline:
  509.     while (reptr != bufcq) {
  510.         if ((cfast=(*reptr & 0177))==ESC && --count<0 && !doexit)
  511.             break;
  512.         if (++reptr >= bufend)
  513.             reptr=bufst;
  514.         if (Lastrx=putcty(cfast))
  515.             goto choose;
  516.         if (cfast=='\n' && --count<=0 && !doexit)
  517.             break;
  518.     }
  519.  
  520.     if (doexit) {
  521. #ifdef STATLINE
  522.         return SAYTERM;
  523. #else
  524.         termreset();
  525.         return FALSE;
  526. #endif
  527.     }
  528. #ifdef STATLINE
  529.     pstat("%s Replot cmd? %s", INTOREV, OUTAREV);
  530. #else
  531. #ifdef INTOREV
  532.     lprintf("%s Replot cmd? %s", INTOREV, OUTAREV);
  533. #else
  534.     lputs("Replot cmd? ");
  535. #endif
  536. #endif
  537.     Lastrx=getcty();
  538. #ifdef STATLINE
  539.     pstat(" ");
  540. #else
  541.     lputs(CLEARL);
  542. #endif
  543. choose:
  544.     /* Treat Control chars and letters the same */
  545.     switch((Lastrx|0140)&0177) {
  546.     case 'x':
  547.         doexit=TRUE;
  548. #ifdef NOSCROLL
  549.         number=(TLENGTH+2);
  550. #else
  551.         number=(TLENGTH<<2);
  552. #endif
  553.         reptr=bufcq; goto backsome;
  554.     case 'v':    /* control-v or v */
  555.     case 'h':    /* backspace */
  556.         number=(TLENGTH-2); reptr=bufmark; goto backsome;
  557.     case 0140:        /* space bar */
  558.         shorts=2; bufmark=reptr; goto nextscreen;
  559.     case 'o':
  560.         pstat(" "); putcty('/'); smark=reptr;
  561.         gets(Utility.ubuf); uncaps(Utility.ubuf);
  562.         /* FALL THROUGH TO */
  563.     case 'n':
  564.         if ((p=cisubstr(smark, Utility.ubuf)) && p<bufend) {
  565.             smark = 1+ (bufmark=reptr=p);    /* +1 so n can work */
  566.             number=1;
  567.             goto backsome;
  568.         } else
  569.             putcty(007);
  570.         /* FALL THROUGH TO */
  571.     case 'b':
  572.         number=0; goto fromtop;
  573.     case 'p':
  574.         number=1; reptr=bufmark; goto backsome;
  575.     case 'k':
  576.         clearbuff(); lprintf(CLEARS); return SAYTERM;
  577.     case 'z':
  578.         /*
  579.          * kill the "rest" of the buffer
  580.          * N.B.: if buffcdq or bufpcdq is between reptr and bufcq,
  581.          * yam will try to output the whole memory space
  582.          * when use of these pointers resumes.
  583.          */
  584.         bufcdq=bufcq=reptr; return SAYTERM;
  585.     case 'j':    /* linefeed */
  586.         bufmark=reptr; count=1; goto nextline;
  587.     default:
  588.         return SAYTERM;
  589.     }
  590. }
  591.  
  592. /*
  593.  * moment waits a moment and returns FALSE, if no character keyboarded in
  594.  * the meantime, otherwise returns TRUE.
  595.  */
  596. moment()
  597. {
  598.     int c;
  599.     for (c=MOMCAL; --c>0;)
  600.         if (CIREADY) {
  601.             getcty(); return TRUE;
  602.         }
  603.     return FALSE;
  604. }
  605. dochat()
  606. {
  607. #ifdef XMODEM
  608.     printf("Ring My Chimes, Maybe I'll Come\n");
  609.     printf("Exit chat with ^Z\n");
  610. #endif
  611.     Chat=Ctlview=Hdx=Echo=TRUE;
  612.     term();
  613. }
  614.  
  615. echochr(c)
  616. {
  617.     if (Hdx) {
  618.         while (!COREADY)
  619.             ;
  620.         TTYOUT(c);
  621.     }
  622.     if (Twxmode && Hdx) {
  623.         if (Rfile) {
  624.             dumprxbuff();
  625.             if (fputc(c, fout)==ERROR) {
  626.                 lprintf("\nDisk Full");
  627.                 closerx(FALSE);
  628.             }
  629.         }
  630.         if (Pflag)
  631.             LPOUT(c);
  632.     }
  633. }
  634.  
  635. /*
  636.  * Handle keyboarded character. Returns TRUE iff caller should return to
  637.  *  command mode.
  638.  */
  639. doykbd(cf)
  640. {
  641.     cf &= KBMASK;
  642. #ifdef FNXEXT
  643.     switch (cf) {
  644.         case FNXEXT:
  645.             pstat(" "); return TRUE;
  646.         case FNXREP:
  647.             return replot((TLENGTH<<1)-1);
  648.     }
  649. #endif
  650.     if (Exitchar) {
  651.         if (Exitchar==cf)
  652.             return TRUE;
  653.         Lskcnt=0; lkbufcq=bufcq;
  654.     }
  655.     else switch (cf) {
  656. #ifdef ESCCAL
  657.         case ESC:        /* buffer rapid escape sequences */
  658.             abend = abptr = Utility.ubuf;
  659.             for (Lskcnt=ESCCAL; --Lskcnt;)
  660.                 if (CIREADY) {
  661.                     *abend++ = CICHAR;
  662.                     Lskcnt=ESCCAL;
  663.                 }
  664.             sendline(ESC);  return(Waitecho = Txwait = FALSE);
  665. #endif
  666.         case ENQ:
  667.             if (moment())    /* ^E exits [y]term */
  668.                 break;
  669.             pstat(" "); return TRUE;
  670.         case 026:
  671.             if (moment())
  672.                 break;
  673.             return replot((TLENGTH<<1)-1);
  674.         case BRKKEY:        /* BRK KEY sends break */
  675.             sendbrk();
  676.             while (CIREADY)
  677.                 getcty();    /* discard garbage */
  678.             return FALSE;
  679.         case ACK:
  680.             if (Twxmode) {
  681.                 setab(); return FALSE;
  682.             }
  683.             break;
  684.         case XON:
  685.             if (Tfile && !Txgo) {
  686.                 Txgo=TRUE; return SAYTERM;
  687.             }
  688.             break;
  689.         case XOFF:
  690.             if (Tfile && Txgo) {
  691.                 Txgo=FALSE; return SAYTERM;
  692.             }
  693.             break;
  694.         case '\r':
  695.             Lskcnt=0; lkbufcq=bufcq;
  696.             if (Txeoln==EOL_NL)
  697.                 cf = '\n';
  698.             else {
  699.                 echochr('\r');
  700.                 sendline('\r');
  701.                 echochr('\n');
  702.                 if (Chat)
  703.                     sendline('\n');
  704.                 return FALSE;
  705.             }
  706.             break;
  707.         case 0177:
  708.         case 003:
  709.             break;    /* don't set lkbufcq, etc. */
  710.         default:
  711.             Lskcnt=0; lkbufcq=bufcq; break;
  712.         }
  713.     sendline(cf);  echochr(cf);  return FALSE;
  714. }
  715.  
  716. /*
  717.  * send a file (ascii) waiting Throttle/10 seconds for an echo
  718.  *  to each character.  Useful for sending files to pip file=tty:
  719.  */
  720. sendecho()
  721. {
  722.     for (;;) {
  723.         purgeline();
  724.         switch (firstch=getc(fin)) {
  725.         case EOF:
  726.             closetx(FALSE);
  727.             return OK;
  728.         case '\r':
  729.             if (Txeoln == EOL_NL) {
  730.                 putcty('\r'); continue;
  731.             }
  732.             break;
  733.         case '\n':
  734.             if (Txeoln == EOL_CR) {
  735.                 putcty('\n'); continue;
  736.             }
  737.             break;
  738.         case CPMEOF:
  739.             if (Txeoln == TX_BINARY)
  740.                 break;
  741.             if (Txeoln != EOL_NL)
  742.                 sendline(CPMEOF);
  743.             return OK;
  744.         }
  745.         sendline(firstch);
  746.         while ((wcj=readline(Throttle)) != firstch) {
  747.             if (wcj == ' ' && firstch == '\t' ) {
  748.                 while (readline(1) != TIMEOUT)
  749.                     ;
  750.                 break;
  751.             }
  752.             if (CIREADY || wcj == TIMEOUT) {
  753.                 closetx(TRUE); return ERROR;
  754.             }
  755.         }
  756.         putcty(wcj);
  757.     }
  758. }
  759.