home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_06_04 / v6n4072a.txt < prev   
Text File  |  1989-09-28  |  9KB  |  142 lines

  1. /* trmnl2.c */
  2. #include <stdio.h>
  3. #include "ibmint.dlc"    /* "trsifm.mxc" for trs-80 and CP/M.         */
  4. #define MSDOS 1          /* 0 for trs-80 and CP/M.                    */
  5. #define RXBUFSIZ 64      /* Sizes of buffers for sending              */
  6. #define TXBUFSIZ 64      /* and receiving.                            */
  7. #define COMCHAR '`'      /* Control-7 on the trs-80 keyboard.         */
  8. #define SEND "S"         /* Disk operations, send,                    */
  9. #define RECEIVE "R"      /*   and receive.                            */
  10. #define BITMASK 255      /* Admit all 8 bits of received byte.        */
  11. #define LINE_SIZ 256     /* Size of buffer for disk writes.           */
  12. #define XON 17           /* Control Q (XON).                          */
  13. #define ECHO_RX_TX 0     /* Echo back to remote? no.                  */
  14. #define ECHO_KB_SC 1     /* Echo kb to screen?  yes.                  */
  15. #define ECHO_FRX_SC 1    /* Echo file input to screen? yes.           */
  16. #define ECHO_FTX_SC 1    /* Echo file output to screen? yes.          */
  17. #define RXSC_CR_LF 1     /* CRLF to screen for recieved CR? yes.      */
  18. #define TX_WAIT 1        /* Wait for XON after sending a line? yes.   */
  19. #define RX_TRIG 1        /* Send XON     after disk write? yes.       */
  20.  
  21. FILE *stream ;           /* Just one channel, in or out.              */
  22. int diskop=0 ;           /* Disk ops: 0 (none), 1 (in), 2 (out).      */
  23. int line_wait=0 ;        /* Flag for CTRL-Q wait.                     */
  24. int eof_flag = 0 ;       /* EOF signal.                               */
  25. char rxbuf[RXBUFSIZ] ;   /* Input char buffer.                        */
  26. int txbuf[TXBUFSIZ] ;    /* Output char buffer, type int for EOF.     */
  27. int scptr,rxptr,txptr,kbptr ;       /* IO ring buffer pointers.       */
  28.  
  29. void getstr(s) char *s ; /****** Get string from keyboard,  ***********/
  30. { int c ;                /* terminated by space or newline.           */
  31.   for(c=getchar(); (c == ' ') || (c == '\t') ; c=getchar()) ;       /**/
  32.   for(; (c != ' ') && (c != '\n'); c=getchar() ) *s++ = toupper(c) ;
  33.   *s = '\0' ;                                                       /**/
  34. }
  35.                          /**** Line-buffered output to disk file. *****/
  36. void putcbuf(c,stream) int c ; FILE *stream ; /* Limited length.      */
  37. { static int ix = 0 ; static char buf[LINE_SIZ] ;                   /**/
  38.   if( c == '\n' ) return ;               /* Ignore linefeed.          */
  39.   if( MSDOS && (c == '\r') ) c = '\n' ;  /* CR->LF if MS-DOS.         */
  40.   if( c != EOF ) buf[ix++] = c ;         /* Insert byte, bump ptr.    */
  41.   if( ((c == EOF) || (c == '\n') ||                                 /**/
  42.             (c == '\r')) && (ix > 0) || (ix >= LINE_SIZ - 1)  )     /**/
  43.     { buf[ix] = '\0' ;                   /* If lineend or EOF or      */
  44.       fputs(buf,stream) ;                /* long line, write.         */
  45.       if( RX_TRIG && (ix < LINE_SIZ - 1))  /* If XON is in use,       */
  46.          { while( !txready() )     ;     /* send XON as soon as tx    */
  47.            txbyte(XON) ;                 /* register is empty.        */
  48.          }                                                          /**/
  49.       ix = 0 ;                           /* Reset buffer ptr.         */
  50.     }
  51. }
  52.  
  53. int dispatch()           /****** Keyboard command handler. ************/
  54. { char kbuf[80] ;        /* Returns 1 if command done right, else 0   */
  55.   if ( (diskop == 2) && RX_TRIG )      /* If disk output buffered,    */
  56.               putcbuf(EOF,stream) ;    /* purge buffer.               */
  57.   if( diskop )                         /* If file open, close it.     */
  58.     { diskop=line_wait= 0 ;                                         /**/
  59.       fclose(stream) ;                                              /**/
  60.       return(1) ;                                                   /**/
  61.     }                                                               /**/
  62.   fputs("\nDISK COMMAND->",stderr) ;   /* Display prompt.             */
  63.   getstr(kbuf) ;                       /* Get command string.         */
  64.   if( strcmp(kbuf,SEND) == 0 )         /* Test if Send.               */
  65.      { getstr(kbuf) ;                  /* Get file name.              */
  66.        if( (stream=fopen(kbuf,"r")) != NULL )   /* Try to open.       */
  67.          { diskop = 1 ;                /* Sending in progress.        */
  68.            eof_flag = 0 ;              /* Clear flags to start.       */
  69.            line_wait = 0 ;                                          /**/
  70.            return(1) ;                 /* Return success signal.      */
  71.          }                                                          /**/
  72.      }                                                              /**/
  73.   if( strcmp(kbuf,RECEIVE) != 0 ) return(0) ; /* Test if receive.     */
  74.   getstr(kbuf) ;                       /* Get file name.              */
  75.   if( (stream=fopen(kbuf,"w")) == NULL ) return(0) ; /* Failure.      */
  76.   diskop = 2 ;                         /* Receiving in progress.      */
  77.   return(1) ;                          /* Return success signal.      */
  78. }
  79.  
  80. void putch2(c) int c ;   /* putch ignoring LF, but CRLF for CR. ********/
  81. { if(c == '\n') return ; putch(c) ; if(c == '\r') putch('\n') ; }   /**/
  82.  
  83. void tx_insert(c) int c ; /**** FIFO buffer-access routines. **********/
  84. { txbuf[kbptr] = c ; kbptr = ++kbptr % TXBUFSIZ ; }                 /**/
  85.                                                                     /**/
  86. int tx_extract()                                                    /**/
  87. {int c; c = txbuf[txptr] ; txptr = ++txptr % TXBUFSIZ ; return(c) ; }
  88.                                                                     /**/
  89. void rx_insert(c) int c ;                                           /**/
  90. { rxbuf[rxptr] = c ; rxptr = ++rxptr % RXBUFSIZ ; }                 /**/
  91.                                                                     /**/
  92. int rx_extract()                                                    /**/
  93. {int c; c = rxbuf[scptr] ; scptr = ++scptr % RXBUFSIZ ; return(c) ; }
  94.  
  95. main()      /************* Initialization, and polling loop. **********/
  96. { int byte ;                           /* Use CTRL-C to exit.         */
  97.   setcom() ;                           /* Initialize communications.  */
  98.   scptr=rxptr=txptr=kbptr=diskop = 0 ; /* Zero pointers & flags.      */
  99.   while(1)                             /* Loop forever.               */
  100.     { if( rxready() )                  /***** Receive a byte?  ********/
  101.         { byte = rxbyte() & BITMASK ;                               /**/
  102.           if( byte == XON ) { line_wait = 0; continue ; }           /**/
  103.           if(ECHO_RX_TX) tx_insert(byte) ;                          /**/
  104.           rx_insert(byte) ;                                         /**/
  105.         }                                                           /**/
  106.       if( kbhit() )                    /***** Byte from kb? ***********/
  107.         { byte = getch() ;                                          /**/
  108.           if(byte == COMCHAR) { dispatch() ; continue ; }           /**/
  109.           if(ECHO_KB_SC) putch2(byte) ;                             /**/
  110.           tx_insert(byte) ;                                         /**/
  111.         }                                                           /**/
  112.       if( scptr != rxptr )             /***** Byte to screen? *********/
  113.         { byte = rx_extract() ;                                     /**/
  114.           if( diskop == 2 )            /* Byte to disk? */          /**/
  115.             { putcbuf(byte,stream) ;                                /**/
  116.               if(ECHO_FRX_SC) putch2(byte) ;                        /**/
  117.             }                                                       /**/
  118.           else if(RXSC_CR_LF) putch2(byte) ;                        /**/
  119.           else putch(byte) ;                                        /**/
  120.         }                                                           /**/
  121.                                       /****** Byte from disk? *********/
  122.       if( (diskop == 1) && !line_wait && !eof_flag && txready() )   /**/
  123.         { byte = getc(stream) ;                                     /**/
  124.           if(byte == EOF) eof_flag = 1 ;                            /**/
  125.           if(byte == '\n') byte = '\r' ;                            /**/
  126.           tx_insert(byte) ;                                         /**/
  127.           if(ECHO_FTX_SC) putch2(byte) ;                            /**/
  128.         }                                                           /**/
  129.                                       /***** Send a byte? *************/
  130.       if( (txptr != kbptr) && txready() )                           /**/
  131.        if( (diskop != 1) || !line_wait )                            /**/
  132.         { byte = tx_extract() ;                                     /**/
  133.           if((byte == EOF) && (diskop == 1)) {dispatch() ; continue ; }
  134.           txbyte(byte) ;                                            /**/
  135.           if((byte == '\r') && (diskop == 1) && TX_WAIT) line_wait = 1 ;
  136.         }                                                           /**/
  137.       if( comerror & 9 )      /**** Ring-buffer or overrun error? *****/
  138.         { fprintf(stderr,"\ncomerror %d\n",comerror) ; comerror = 0 ; }
  139.     }                                                               /**/
  140. }
  141.  
  142.