home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / bts314b4 / zsend.c < prev   
C/C++ Source or Header  |  1994-08-16  |  41KB  |  1,092 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                    Zmodem file transmission module                       */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*    For complete  details  of the licensing restrictions, please refer    */
  17. /*    to the License  agreement,  which  is published in its entirety in    */
  18. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  19. /*                                                                          */
  20. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  21. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  22. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  23. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  24. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  25. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  26. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  27. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  28. /*                                                                          */
  29. /*                                                                          */
  30. /* You can contact Bit Bucket Software Co. at any one of the following      */
  31. /* addresses:                                                               */
  32. /*                                                                          */
  33. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  34. /* P.O. Box 460398                AlterNet 7:491/0                          */
  35. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  36. /*                                Internet f491.n132.z1.fidonet.org         */
  37. /*                                                                          */
  38. /* Please feel free to contact us at any time to share your comments about  */
  39. /* our software and/or licensing policies.                                  */
  40. /*                                                                          */
  41. /*                                                                          */
  42. /*  This module is based largely on a similar module in OPUS-CBCS V1.03b.   */
  43. /*  The original work is (C) Copyright 1986, Wynn Wagner III. The original  */
  44. /*  authors have graciously allowed us to use their code in this work.      */
  45. /*                                                                          */
  46. /*--------------------------------------------------------------------------*/
  47.  
  48.  
  49. #include <stdio.h>
  50. #ifdef __TOS__
  51. #include <ext.h>
  52. #else
  53. #include <sys\types.h>
  54. #include <sys\stat.h>
  55. #include <fcntl.h>
  56. #endif
  57. #include <ctype.h>
  58. #include <time.h>
  59. #ifdef LATTICE
  60. #define ultoa(v,s,r) (stcul_d(s,v),s)
  61. #include <errno.h>
  62. #else
  63. #include <io.h>
  64. #endif
  65. #include <stdlib.h>
  66. #include <conio.h>
  67. #include <string.h>
  68.  
  69. #include "bink.h"
  70. #include "msgs.h"
  71. #include "sbuf.h"
  72. #include "zmodem.h"
  73. #include "com.h"
  74. #include "vfossil.h"
  75. #include "session.h"
  76. #include "wazoo.h"
  77.  
  78. /*--------------------------------------------------------------------------*/
  79. /* Private routines                                                         */
  80. /*--------------------------------------------------------------------------*/
  81. static void ZS_SendBinaryHeader (unsigned short, byte *);
  82. static void ZS_32SendBinaryHeader (unsigned short, byte *);
  83. static void ZS_SendData (register byte *, size_t, unsigned short);
  84. static void ZS_32SendData (byte *, size_t, unsigned short);
  85. static void ZS_SendByte (byte);
  86. static int ZS_GetReceiverInfo (void);
  87. static int ZS_SendFile (size_t, int);
  88. static int ZS_SendFileData (int);
  89. static int ZS_SyncWithReceiver (int);
  90. static void ZS_EndSend (void);
  91.  
  92. /*--------------------------------------------------------------------------*/
  93. /* Private data                                                             */
  94. /*--------------------------------------------------------------------------*/
  95. static FILE *Infile;                             /* Handle of file being sent */
  96. static long Strtpos;                             /* Starting byte position of */
  97.  
  98.  /* download                 */
  99. static long LastZRpos;                           /* Last error location      */
  100. static long ZRPosCount;                          /* ZRPOS repeat count       */
  101. static long Txpos;                               /* Transmitted file position */
  102. static int Rxbuflen;                             /* Receiver's max buffer    */
  103.  
  104.  /* length                   */
  105. static int Rxflags;                              /* Receiver's flags         */
  106.  
  107. /*--------------------------------------------------------------------------*/
  108. /* SEND ZMODEM (send a file)                                                */
  109. /*   returns TRUE (1) for good xfer, FALSE (0) for bad                      */
  110. /*   sends one file per call; 'fsent' flags start and end of batch          */
  111. /*--------------------------------------------------------------------------*/
  112. int Send_Zmodem (char *fname, char *alias, int fsent, int wazoo)
  113.         {       register byte *p;
  114.                 register byte *q;
  115.                 struct stat f;
  116.                 int i;
  117.         int rc = TRUE;
  118.         char j[100];
  119.  
  120. #ifdef ZDEBUG
  121.                 if(debugging_log)
  122.                         show_debug_name ("send_Zmodem");
  123. #endif
  124. #ifdef DEBUG
  125.                 if(debugging_log)
  126.                 status_line(">send_Zmodem(%s,%s,%d,%d)",
  127.                         fname ? fname : "NULL",
  128.                         alias ? alias : "NULL",
  129.                         fsent, wazoo);
  130. #endif
  131.  
  132. /*                _BRK_DISABLE ();    Like PC*/
  133.         IN_XON_ENABLE ();
  134.  
  135.         z_size = 0;
  136.         Infile = NULL;
  137. /*        rc = TRUE;   Like PC */
  138.  
  139.  
  140.         if (fname && !(fullscreen && un_attended))
  141.       /*set_xy ("")*/;
  142.         switch (fsent)
  143.                         {  
  144. /*     case 0: Z_PutString ("rz\r");  Like PC */
  145.             case 0: Z_PutString ((byte *)"rz\r");
  146.  
  147. #ifdef NEW
  148.                           case EMPTY_BATCH:
  149. #endif
  150.                                         Z_PutLongIntoHeader (0L);
  151. /*                                   Z_SendHexHeader (ZRQINIT, Txhdr);  Like PC */
  152.                                    Z_SendHexHeader (ZRQINIT, (byte *)Txhdr);
  153.  
  154.                                   /* Fall through */
  155.  
  156.         case NOTHING_TO_DO:
  157.                                         Rxtimeout = 200;
  158.                                         if (ZS_GetReceiverInfo () == ERROR)
  159.                                                 {       XON_DISABLE ();
  160.                                             XON_ENABLE ();
  161. #ifdef DEBUG
  162.                                                                                 if(debugging_log)
  163.                                                                                         status_line(">GetReceiver returned ERROR");
  164. #endif
  165.                                         return FALSE;
  166.                                           }
  167. #ifdef NEW
  168.                                                                 CLEAR_OUTBOUND();
  169.                                                                 CLEAR_INBOUND();
  170. #endif
  171.             
  172.             }
  173.  
  174.                 Rxtimeout = (int) (614400L / (long) cur_baud);
  175.  
  176.         if (Rxtimeout < 100)
  177.       Rxtimeout = 100;
  178.  
  179.         if (fname == NULL)
  180.       goto Done;
  181.  
  182.    /*--------------------------------------------------------------------*/
  183.    /* Prepare the file for transmission.  Just ignore file open errors   */
  184.    /* because there may be other files that can be sent.                 */
  185.    /*--------------------------------------------------------------------*/
  186.         Filename = fname;
  187.         CLEAR_IOERR ();
  188.         if ((Infile = fopen (Filename, read_binary)) == NULL)
  189.       { (void) got_error (msgtxt[M_OPEN_MSG], Filename);
  190.         XON_DISABLE ();
  191.         XON_ENABLE ();
  192.         return OK;
  193.       }
  194.                 if (isatty (fileno (Infile)))
  195.       { errno = 1;
  196.         (void) got_error (msgtxt[M_DEVICE_MSG], Filename);
  197.         fclose (Infile);
  198.         XON_DISABLE ();
  199.         XON_ENABLE ();
  200.               return OK;
  201.       }
  202.  
  203.    /*--------------------------------------------------------------------*/
  204.    /* Send the file                                                      */
  205.    /*--------------------------------------------------------------------*/
  206.                 rc = TRUE;
  207.  
  208.    /*--------------------------------------------------------------------*/
  209.    /* Display outbound filename, size, and ETA for sysop                 */
  210.    /*--------------------------------------------------------------------*/
  211.  
  212. #ifdef ATARIST
  213.         stat(Filename, &f);
  214. #else
  215.         fstat (fileno (Infile), &f);
  216. #endif   
  217.  
  218.         i = (int) (f.st_size * 10 / cur_baud + 53) / 54;
  219. #ifdef NEW
  220.                 if(alias)
  221.                         sprintf (j, "Z-Send %s (%s), %ldb, %d min.", Filename, alias, f.st_size, i);
  222.                 else
  223. #endif
  224.                 sprintf (j, "Z-Send %s, %ldb, %d min.", Filename, f.st_size, i);
  225.         file_length = f.st_size;
  226.  
  227.         if (un_attended && fullscreen)
  228.       { clear_filetransfer ();
  229.         sb_move (filewin, 1, 2);
  230.         sb_puts (filewin, j);
  231.               elapse_time ();
  232.             sb_move (filewin, 2, 69);
  233.           sprintf (j, "%3d min", i);
  234.         sb_puts (filewin, j);
  235.               sb_show ();
  236.       }
  237.         else
  238.       { printf ("%s", j);
  239.         set_xy (NULL);
  240.               locate_x += 2;
  241.       }
  242.  
  243.    /*--------------------------------------------------------------------*/
  244.    /* Get outgoing file name; no directory path, lower case              */
  245.    /*--------------------------------------------------------------------*/
  246.         for (p = (alias != NULL) ? alias : Filename, q = Txbuf; *p;)
  247.       { if ((*p == '/') || (*p == '\\') || (*p == ':'))
  248.                 q = Txbuf;
  249.               else *q++ = tolower (*p);
  250.         p++;
  251.       }
  252.  
  253.         *q++ = '\0';
  254.         p = q;
  255.  
  256.    /*--------------------------------------------------------------------*/
  257.    /* Zero out remainder of file header packet                           */
  258.    /*--------------------------------------------------------------------*/
  259.         while (q < (Txbuf + KSIZE))
  260.       *q++ = '\0';
  261.  
  262.    /*--------------------------------------------------------------------*/
  263.    /* Store filesize, time last modified, and file mode in header packet */
  264.    /*--------------------------------------------------------------------*/
  265.         sprintf (p, "%lu %lo %ho", f.st_size, f.st_mtime, f.st_mode);
  266.  
  267.    /*--------------------------------------------------------------------*/
  268.    /* Transmit the filename block and the download                 */
  269.    /*--------------------------------------------------------------------*/
  270.         throughput (0, 0L);
  271.  
  272.    /*--------------------------------------------------------------------*/
  273.    /* Check the results                                                  */
  274.    /*--------------------------------------------------------------------*/
  275.         switch (ZS_SendFile (1 + strlen (p) + (p - Txbuf), wazoo))
  276.       { case ERROR:
  277.          /*--------------------------------------------------*/
  278.          /* Something tragic happened                        */
  279.          /*--------------------------------------------------*/
  280. #ifdef DEBUG
  281.                                                                                 status_line("#Unknown Zmodem error");
  282. #endif
  283.                                                          goto Err_Out;
  284.  
  285.               case OK:
  286.          /*--------------------------------------------------*/
  287.          /* File was sent                                    */
  288.          /*--------------------------------------------------*/
  289.                                                         CLEAR_IOERR ();
  290.                                                         fclose (Infile);
  291.                                                         Infile = NULL;
  292.  
  293.                                                         status_line ("%s-Z%s %s", msgtxt[M_FILE_SENT], Crc32t ? "/32" : "", Filename);
  294.  
  295.                                                         update_files (1);
  296.                                                   goto Done;
  297.  
  298.         case ZSKIP:
  299.                                                         status_line (msgtxt[M_REMOTE_REFUSED], Filename);
  300.                                                         rc = SPEC_COND;
  301.                                                         goto Done;
  302.  
  303.               default:
  304.          /*--------------------------------------------------*/
  305.          /* Ignore the problem, get next file, trust other   */
  306.          /* error handling mechanisms to deal with problems  */
  307.          /*--------------------------------------------------*/
  308. #ifdef DEBUG
  309.                                                                                 if(debugging_log)
  310.                                                                                         status_line(">Default Zmodem error");
  311. #endif
  312.                                                         goto Done;
  313.                         }   /* switch */
  314.  
  315. Err_Out:
  316.         rc = FALSE;
  317.  
  318. Done:
  319.         if (Infile)
  320.       fclose (Infile);
  321.  
  322.         if (fsent < 0)
  323.       ZS_EndSend ();
  324.  
  325.         XON_DISABLE ();
  326.         XON_ENABLE ();
  327.         return rc;
  328.         }                                                /* send_Zmodem */
  329.  
  330. /*--------------------------------------------------------------------------*/
  331. /* ZS SEND BINARY HEADER                                                    */
  332. /* Send ZMODEM binary header hdr of type type                               */
  333. /*--------------------------------------------------------------------------*/
  334. static void ZS_SendBinaryHeader (unsigned short type,register byte *hdr)
  335. {  register unsigned short crc;
  336.    int n;
  337.  
  338. #ifdef ZDEBUG
  339.         if(debugging_log)
  340.                 show_debug_name ("ZS_SendBinaryHeader");
  341. #endif
  342.  
  343.    BUFFER_BYTE (ZPAD);
  344.    BUFFER_BYTE (ZDLE);
  345.  
  346.    if (Crc32t = Txfcs32)
  347.       ZS_32SendBinaryHeader (type, hdr);
  348.    else
  349.       {
  350.       BUFFER_BYTE (ZBIN);
  351.       ZS_SendByte ((byte) type);
  352.  
  353.       crc = Z_UpdateCRC (type, 0);
  354.  
  355.       for (n = 4; n-- ;)
  356.          {
  357.          ZS_SendByte (*hdr);
  358.          crc = Z_UpdateCRC (*hdr++, crc);
  359.          }
  360.       ZS_SendByte ((byte) (crc >> 8));
  361.       ZS_SendByte ((byte) crc);
  362.  
  363.       UNBUFFER_BYTES ();
  364.       }
  365.  
  366.    if (type != ZDATA)
  367.       {
  368.       while (CARRIER && !OUT_EMPTY ())
  369.          time_release ();
  370.       if (!CARRIER)
  371.          CLEAR_OUTBOUND ();
  372.       }
  373. }                                                /* ZS_SendBinaryHeader */
  374.  
  375. /*--------------------------------------------------------------------------*/
  376. /* ZS SEND BINARY HEADER                                                    */
  377. /* Send ZMODEM binary header hdr of type type                               */
  378. /*--------------------------------------------------------------------------*/
  379. static void ZS_32SendBinaryHeader (unsigned short type,register byte *hdr)
  380. {  unsigned long crc;
  381.    int n;
  382.  
  383. #ifdef ZDEBUG
  384.    if(debugging_log)
  385.                 show_debug_name ("ZS_32SendBinaryHeader");
  386. #endif
  387.  
  388.    BUFFER_BYTE (ZBIN32);
  389.    ZS_SendByte ((byte) type);
  390.  
  391.    crc = 0xFFFFFFFF;
  392.    crc = Z_32UpdateCRC (type, crc);
  393.  
  394.    for (n = 4; n--;)
  395.       {
  396.       ZS_SendByte (*hdr);
  397.       crc = Z_32UpdateCRC (((unsigned short) (*hdr++)), crc);
  398.       }
  399.  
  400.    crc = ~crc;
  401.    for (n = 4; n--;)
  402.       {
  403.       ZS_SendByte ((byte) crc);
  404.       crc >>= 8;
  405.       }
  406.  
  407.    UNBUFFER_BYTES ();
  408. }                                                /* ZS_SendBinaryHeader */
  409.  
  410. /*--------------------------------------------------------------------------*/
  411. /* ZS SEND DATA                                                             */
  412. /* Send binary array buf with ending ZDLE sequence frameend                 */
  413. /*--------------------------------------------------------------------------*/
  414. static void ZS_SendData (register byte *buf, size_t length, unsigned short frameend)
  415. {       register unsigned short crc;
  416.  
  417. #ifdef ZDEBUG
  418.    if(debugging_log)
  419.                 show_debug_name ("ZS_SendData");
  420. #endif
  421.  
  422.    if (Crc32t)
  423.       ZS_32SendData (buf, length, frameend);
  424.    else
  425.       {
  426.       crc = 0;
  427.       for (; length--;)
  428.          {
  429.          ZS_SendByte (*buf);
  430.          crc = Z_UpdateCRC (*buf++, crc);
  431.          }
  432.  
  433.       BUFFER_BYTE (ZDLE);
  434.       BUFFER_BYTE ((unsigned char) frameend);
  435.       crc = Z_UpdateCRC (frameend, crc);
  436.       ZS_SendByte ((byte) (crc >> 8));
  437.       ZS_SendByte ((byte) crc);
  438.  
  439.       UNBUFFER_BYTES ();
  440.  
  441.       }
  442.  
  443.    if (frameend == ZCRCW)
  444.       {
  445.       SENDBYTE (XON);
  446.       while (CARRIER && !OUT_EMPTY ())
  447.          time_release ();
  448.       if (!CARRIER)
  449.          CLEAR_OUTBOUND ();
  450.       }
  451. }                                                /* ZS_SendData */
  452.  
  453. /*--------------------------------------------------------------------------*/
  454. /* ZS SEND DATA with 32 bit CRC                                             */
  455. /* Send binary array buf with ending ZDLE sequence frameend                 */
  456. /*--------------------------------------------------------------------------*/
  457. static void ZS_32SendData (byte *buf, size_t length, unsigned short frameend)
  458. {       unsigned long crc;
  459.  
  460. #ifdef ZDEBUG
  461.    if(debugging_log)
  462.                 show_debug_name ("ZS_32SendData");
  463. #endif
  464.  
  465.    crc = 0xFFFFFFFF;
  466.    for (; length--; ++buf)
  467.       {
  468.       ZS_SendByte (*buf);
  469.       crc = Z_32UpdateCRC (*buf, crc);
  470.       }
  471.  
  472.    BUFFER_BYTE (ZDLE);
  473.    BUFFER_BYTE ((unsigned char) frameend);
  474.    crc = Z_32UpdateCRC (frameend, crc);
  475.  
  476.    crc = ~crc;
  477.    for (length = 4; length--;)
  478.       {
  479.       ZS_SendByte ((byte) crc);
  480.       crc >>= 8;
  481.       }
  482.  
  483.    UNBUFFER_BYTES ();
  484. }                                                /* ZS_SendData */
  485.  
  486. /*--------------------------------------------------------------------------*/
  487. /* ZS SEND BYTE                                                             */
  488. /* Send character c with ZMODEM escape sequence encoding.                   */
  489. /* Escape XON, XOFF. Escape CR following @ (Telenet net escape)             */
  490. /*--------------------------------------------------------------------------*/
  491. static void ZS_SendByte (register byte c)
  492. {  static byte lastsent;
  493.  
  494.    switch (c)
  495.       {
  496.       case 015:
  497.       case 0215:
  498.          if ((lastsent & 0x7F) != '@')
  499.             goto SendIt;
  500.       case 020:
  501.       case 021:
  502.       case 023:
  503.       case 0220:
  504.       case 0221:
  505.       case 0223:
  506.       case ZDLE:
  507.          /*--------------------------------------------------*/
  508.          /* Quoted characters                                */
  509.          /*--------------------------------------------------*/
  510.          BUFFER_BYTE (ZDLE);
  511.          c ^= 0x40;
  512.  
  513.       default:
  514.          /*--------------------------------------------------*/
  515.          /* Normal character output                          */
  516.          /*--------------------------------------------------*/
  517.    SendIt:
  518.          BUFFER_BYTE (lastsent = c);
  519.  
  520.       }                                          /* switch */
  521. }                                                /* ZS_SendByte */
  522.  
  523. /*--------------------------------------------------------------------------*/
  524. /* ZS GET RECEIVER INFO                                                     */
  525. /* Get the receiver's init parameters                                       */
  526. /*--------------------------------------------------------------------------*/
  527. static int ZS_GetReceiverInfo ()
  528. {  int n;
  529. #ifdef ZDEBUG
  530.    if(debugging_log)
  531.                 show_debug_name ("ZS_GetReceiverInfo");
  532. #endif
  533.  
  534.    for (n = 10; n--;)
  535.       {
  536. /*      switch (Z_GetHeader (Rxhdr))  Like PC */
  537.           switch (Z_GetHeader ((byte *)Rxhdr))
  538.          {
  539.          case ZCHALLENGE:
  540.             /*--------------------------------------*/
  541.             /* Echo receiver's challenge number     */
  542.             /*--------------------------------------*/
  543.             Z_PutLongIntoHeader (Rxpos);
  544. /*             Z_SendHexHeader (ZACK, Txhdr);  Like PC */
  545.             Z_SendHexHeader (ZACK, (byte *)Txhdr);
  546.             continue;
  547.  
  548.          case ZCOMMAND:
  549.             /*--------------------------------------*/
  550.             /* They didn't see our ZRQINIT          */
  551.             /*--------------------------------------*/
  552.             Z_PutLongIntoHeader (0L);
  553. /*            Z_SendHexHeader (ZRQINIT, Txhdr);   Like PC */
  554.             Z_SendHexHeader (ZRQINIT, (byte *)Txhdr);
  555.             continue;
  556.  
  557.          case ZRINIT:
  558.             /*--------------------------------------*/
  559.             /* */
  560.             /*--------------------------------------*/
  561.             Rxflags = 0377 & Rxhdr[ZF0];
  562.             Rxbuflen = ((word) Rxhdr[ZP1] << 8) | Rxhdr[ZP0];
  563.             Txfcs32 = Rxflags & CANFC32;
  564.             return OK;
  565.  
  566.          case ZCAN:
  567.          case RCDO:
  568.          case TIMEOUT:
  569.             return ERROR;
  570.  
  571.          case ZRQINIT:
  572.             if (Rxhdr[ZF0] == ZCOMMAND)
  573.                continue;
  574.  
  575.          default:
  576. /*            Z_SendHexHeader (ZNAK, Txhdr);  Like PC */
  577.             Z_SendHexHeader (ZNAK, (byte *)Txhdr);
  578.             continue;
  579.          }                                       /* switch */
  580.       }                                          /* for */
  581.  
  582.    return ERROR;
  583. }                                                /* ZS_GetReceiverInfo */
  584.  
  585. /*--------------------------------------------------------------------------*/
  586. /* ZS SEND FILE                                                             */
  587. /* Send ZFILE frame and begin sending ZDATA frame                           */
  588. /*--------------------------------------------------------------------------*/
  589. static int ZS_SendFile (size_t blen, int wazoo)
  590. {
  591.         register int c;
  592.         long t;
  593. int szmdm;
  594. /*,filepos,sendcrc;
  595.         int fileread;
  596. BS Don't need this now */
  597. #ifdef ZDEBUG
  598.         if(debugging_log)
  599.                 show_debug_name ("ZS_SendFile");
  600. #endif
  601.  
  602.         for(;;)
  603.         {
  604.                 if (got_ESC ())
  605.                 {
  606.                         CLEAR_OUTBOUND ();
  607.                         XON_DISABLE ();                         /* Make sure xmitter is unstuck */
  608.                         send_can ();                            /* transmit at least 10 cans    */
  609.                         t = timerset (200);                     /* wait no more than 3 seconds  */
  610.                         while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  611.                         time_release ();                                                /* Give up slice while waiting  */
  612.                         XON_ENABLE ();                          /* Turn XON/XOFF back on...     */
  613.                         z_log (msgtxt[M_KBD_MSG]);
  614.                         return ERROR;
  615.                 }
  616.                 else if (!CARRIER)
  617.                         return ERROR;
  618.  
  619.                 Txhdr[ZF0] = LZCONV;             /* Default file conversion */
  620.                 Txhdr[ZF1] = LZMANAG;            /* Default file management */
  621.                 Txhdr[ZF2] = LZTRANS;            /* Default file transport      */
  622.                 Txhdr[ZF3] = 0;
  623.  
  624. /*                ZS_SendBinaryHeader (ZFILE, Txhdr);  Like PC */
  625.                 ZS_SendBinaryHeader (ZFILE, (byte *)Txhdr);
  626.                 ZS_SendData (Txbuf, blen, ZCRCW);
  627.  
  628. Again:
  629.                 szmdm = 1;
  630.                 if (szmdm)
  631.                 SENDBYTE (021);
  632.                 switch (c = Z_GetHeader(Rxhdr) )
  633.                 {       
  634.                 
  635.                         /*
  636.                         **      Maybe this can fix problems with FD. The break only
  637.                         **  fixes the FD problem but causes a Resend on the first
  638.                         **  DATA block. The second (original) code doesn't have
  639.                         **  Resend problems but probably the ESC problem again.
  640.                         **  I set the timeout in the loop from 0,5sec to 2sec.
  641.                         **  Maybe this fixes the FD problem also.
  642.                         **
  643.                         
  644.                         case ZRINIT:
  645.                                 if (FDBugfix)
  646.                                         break;
  647.                                 else
  648.                                 {
  649.                                                 while ((c = Z_GetByte (200)) > 0)
  650.                                                 if (c == ZPAD)
  651.                                                         goto Again;
  652.                                 } BS now make it look like this*/
  653.  
  654.            case ZRINIT:
  655.             status_line ("!case is ZRINIT", c);
  656.             if (FDBugfix)
  657.                     break;
  658. /*              else
  659.               {  */
  660.               while ((c = Z_GetByte (50)) > 0)
  661.               if (c == ZPAD)
  662.             goto Again;
  663. /*               } */
  664.             status_line ("!Test C = %d", c);
  665.     
  666. /* BS do this  */
  667.             default :
  668.              status_line ("!Default C = %d", c);
  669.                continue;
  670.                                 
  671.                         case ZCAN:
  672.                         case RCDO:
  673.                         case TIMEOUT:
  674.                         case ZFIN:
  675.                         case ZABORT:
  676.                                 return ERROR;
  677.  
  678. /*                      case ZCRC: 
  679.                                 filepos = ftell(Infile);
  680.                                 status_line ("!Zmodem: Calculating CRC");
  681.                                 rewind(Infile);
  682.                                 sendcrc = 0xffffffffL;
  683.                                 while ( (fileread=getc(Infile))!=EOF )
  684.                                         Z_32UpdateCRC (fileread,sendcrc);
  685.                                 sendcrc = ~sendcrc;
  686.                                 Z_PutLongIntoHeader(sendcrc);
  687.                                 Z_SendHexHeader(ZCRC, Txhdr);
  688.                                 fseek(Infile,filepos,SEEK_SET);
  689.                                 status_line ("!Zmodem: CRC is sent");
  690.                                 goto Again;
  691. BS try taking this out... */                                                                  
  692.                         case ZSKIP:
  693.                                 return c;
  694.                                 
  695.                         case ZRPOS:
  696.                                 fseek (Infile, Rxpos, SEEK_SET);
  697.                                 if (Rxpos != 0L)
  698.                                 {
  699.                                         status_line (msgtxt[M_SYNCHRONIZING_OFFSET], Rxpos);
  700.                                         CLEAR_OUTBOUND ();                /* Get rid of queued data */
  701.                                         XON_DISABLE ();                   /* End XON/XOFF restraint */
  702.                                         SENDBYTE (XON);                   /* Send XON to remote     */
  703.                                         XON_ENABLE ();                    /* Start XON/XOFF again   */
  704.                                 }
  705.                                 LastZRpos = Strtpos = Txpos = Rxpos;
  706.                                 ZRPosCount = 10;
  707.                                 CLEAR_INBOUND ();
  708.                                 return ZS_SendFileData (wazoo);
  709. /*                              
  710.                         default:
  711.                                 status_line ("!Zmodem: Unknown Header error %u",c);
  712. BS did this earlier. */                              
  713.                 }                                                                               /* switch */
  714.         }                                                                                       /* for */
  715. }                                                                                               /* ZS_SendFile */
  716.  
  717. /*--------------------------------------------------------------------------*/
  718. /* ZS SEND FILE DATA                                                        */
  719. /* Send the data in the file                                                */
  720. /*--------------------------------------------------------------------------*/
  721. static int ZS_SendFileData (int wazoo)
  722. {  register int c, e;
  723.    size_t tsize;
  724.    int i;
  725.    char j[100];
  726.    word goodblks = 0, goodneeded = 1;
  727.    size_t newcnt, maxblklen;    
  728. #ifndef NEW
  729.         size_t blklen;
  730. #endif
  731.  
  732.    long t;
  733.  
  734. #ifdef ZDEBUG
  735.    if(debugging_log)
  736.                 show_debug_name ("ZS_SendFileData");
  737. #endif
  738.  
  739.   maxblklen = ((cur_baud >= 0) && (cur_baud < 300)) ? 128 : cur_baud / 300 * 256;
  740.  
  741.    if (maxblklen > WAZOOMAX)
  742.       maxblklen = WAZOOMAX;
  743.    if (!wazoo && maxblklen > KSIZE)
  744.       maxblklen = KSIZE;
  745.    if (Rxbuflen && maxblklen > Rxbuflen)
  746.       maxblklen = Rxbuflen;
  747.  
  748.    if (wazoo && (remote_capabilities & ZED_ZIPPER))
  749.       maxblklen = KSIZE;
  750.  
  751. #ifdef NEW /* ZMODEMBLOCKLEN */
  752.    if (!blklen)
  753.       {
  754.       if (small_window && (mdm_reliable[0]=='\0'))
  755.          {
  756.          blklen     = ((maxblklen >> 3) > 64) ? maxblklen >> 3 : 64;
  757.          goodneeded = 6;
  758.          }
  759.       else
  760.         {
  761. /*           blklen = maxblklen;   JS */
  762.            blklen = KSIZE;
  763.            goodneeded = 1;
  764.          }
  765.       }
  766. #else
  767.    blklen = maxblklen;
  768. #endif
  769.  
  770. SomeMore:
  771.    if (CHAR_AVAIL ())
  772.       {
  773. WaitAck:
  774.       switch (c = ZS_SyncWithReceiver (1))
  775.          {
  776.          case ZSKIP:
  777.             /*-----------------------------------------*/
  778.             /* Skip this file                          */
  779.             /*-----------------------------------------*/
  780.             return c;
  781.  
  782.          case ZACK:
  783.             break;
  784.  
  785.          case ZRPOS:
  786.             /*-----------------------------------------*/
  787.             /* Resume at this position                 */
  788.             /*-----------------------------------------*/
  789.             blklen = ((blklen >> 2) > 64) ? blklen >> 2 : 64;
  790.             goodblks = 0;
  791.             goodneeded = ((goodneeded << 1) > 16) ? 16 : goodneeded << 1;
  792.             break;
  793.  
  794.          case ZRINIT:
  795.             /*-----------------------------------------*/
  796.             /* Receive init                            */
  797.             /*-----------------------------------------*/
  798.             if (locate_y && !(fullscreen && un_attended))
  799.                gotoxy (2, (byte) locate_y - 1);
  800.             throughput (1, Txpos - Strtpos);
  801.             return OK;
  802.  
  803.          case TIMEOUT:
  804.             /*-----------------------------------------*/
  805.             /* Timed out on message from other side    */
  806.             /*-----------------------------------------*/
  807.             break;
  808.  
  809.          default:
  810.             z_log (msgtxt[M_CAN_MSG]);
  811.             fclose (Infile);
  812.             return ERROR;
  813.          }                                       /* switch */
  814.  
  815.       /*
  816.        * Noise probably got us here. Odds of surviving are not good. But we
  817.        * have to get unstuck in any event. 
  818.        *
  819.        */
  820.  
  821.       Z_UncorkTransmitter ();
  822.       SENDBYTE (XON);
  823.  
  824.       while (CHAR_AVAIL ())
  825.          {
  826.          switch (MODEM_IN ())
  827.             {
  828.             case CAN:
  829.             case RCDO:
  830.             case ZPAD:
  831.                goto WaitAck;
  832.             }                                    /* switch */
  833.          }                                       /* while */
  834.       }                                          /* while */
  835.  
  836.    newcnt = Rxbuflen;
  837.    Z_PutLongIntoHeader (Txpos);
  838.    ZS_SendBinaryHeader (ZDATA, Txhdr);
  839.  
  840.    do
  841.       {
  842.       if (got_ESC ())
  843.          {
  844.          CLEAR_OUTBOUND ();
  845.          XON_DISABLE ();                         /* Make sure xmitter is
  846.                                                   * unstuck */
  847.          send_can ();                            /* transmit at least 10 cans    */
  848.          t = timerset (200);                     /* wait no more than 2
  849.                                                   * seconds  */
  850.          while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  851.             time_release ();                     /* Give up slice while
  852.                                                   * waiting  */
  853.          XON_ENABLE ();                          /* Turn XON/XOFF back on...     */
  854.          z_log (msgtxt[M_KBD_MSG]);
  855.          goto oops;
  856.          }
  857.                         else if (!CARRIER)
  858.                                 goto oops;              /* ssl - St.Slabihoud */
  859.  
  860.       if ((tsize = fread (Txbuf, 1, (size_t) blklen, Infile)) != z_size)
  861.          {
  862.          if (fullscreen && un_attended)
  863.             {
  864.             sb_move (filewin, 2, 12);
  865.             sb_puts (filewin, ultoa (((unsigned long) (z_size = tsize)), e_input, 10));
  866.             sb_puts (filewin, "    ");
  867.             elapse_time ();
  868.             sb_show ();
  869.             }
  870.          else
  871.             {
  872.             gotoxy (locate_x + 10, locate_y);
  873.             cputs (ultoa (((unsigned long) (z_size = tsize)), e_input, 10));
  874.             putch (' ');
  875.             }
  876.          }
  877.  
  878.       if (tsize < blklen)
  879.          e = ZCRCE;
  880.       else if (Rxbuflen && (newcnt -= tsize) <= 0)
  881.          e = ZCRCW;
  882.       else e = ZCRCG;
  883.  
  884.       ZS_SendData (Txbuf, tsize, e);
  885.  
  886.       i = (int) ((file_length - Txpos) * 10 / cur_baud + 53) / 54;
  887.       sprintf (j, "%3d min", i);
  888.  
  889.       if (fullscreen && un_attended)
  890.          {
  891.          sb_move (filewin, 2, 2);
  892.          sb_puts (filewin, ultoa (((unsigned long) Txpos), e_input, 10));
  893.          sb_puts (filewin, "  ");
  894.          sb_move (filewin, 2, 69);
  895.          sb_puts (filewin, j);
  896.          elapse_time ();
  897.          sb_show ();
  898.          }
  899.       else
  900.          {
  901.          gotoxy (locate_x, locate_y);
  902.          cputs (ultoa (((unsigned long) Txpos), e_input, 10));
  903.          putch (' ');
  904.          putch (' ');
  905.          gotoxy (locate_x + 20, locate_y);
  906.          printf ("%s", j);
  907.          putch (' ');
  908.          }
  909.  
  910.       Txpos += tsize;
  911.       if (blklen < maxblklen && ++goodblks > goodneeded)
  912.          {
  913.          blklen = ((blklen << 1) < maxblklen) ? blklen << 1 : maxblklen;
  914.          goodblks = 0;
  915.          }
  916.  
  917.       if (e == ZCRCW)
  918.          goto WaitAck;
  919.  
  920.       while (CHAR_AVAIL ())
  921.          {
  922.          switch (MODEM_IN ())
  923.             {
  924.             case CAN:
  925.             case RCDO:
  926.             case ZPAD:
  927.                /*--------------------------------------*/
  928.                /* Interruption detected;               */
  929.                /* stop sending and process complaint   */
  930.                /*--------------------------------------*/
  931.                z_message (msgtxt[M_TROUBLE]);
  932.                CLEAR_OUTBOUND ();
  933.                ZS_SendData (Txbuf, 0, ZCRCE);
  934.                goto WaitAck;
  935.             }                                    /* switch */
  936.          }                                       /* while */
  937.  
  938.       }                                          /* do */
  939.    while (e == ZCRCG);
  940.  
  941.    while (1)
  942.       {
  943.       Z_PutLongIntoHeader (Txpos);
  944.       ZS_SendBinaryHeader (ZEOF, Txhdr);
  945.  
  946.       switch (c = ZS_SyncWithReceiver (7))
  947.          {
  948.          case ZACK:
  949.             continue;
  950.          case ZRPOS:
  951.             /*-----------------------------------------*/
  952.             /* Resume at this position...              */
  953.             /*-----------------------------------------*/
  954.             goto SomeMore;
  955.          case ZRINIT:
  956.             /*-----------------------------------------*/
  957.             /* Receive init                            */
  958.             /*-----------------------------------------*/
  959.             if (locate_y && !(fullscreen && un_attended))
  960.                gotoxy (2, (byte) locate_y - 1);
  961.             throughput (1, Txpos - Strtpos);
  962.             return OK;
  963.          case ZSKIP:
  964.             /*-----------------------------------------*/
  965.             /* Request to skip the current file        */
  966.             /*-----------------------------------------*/
  967.             z_log (msgtxt[M_SKIP_MSG]);
  968.             CLEAR_IOERR ();
  969.             fclose (Infile);
  970.             return c;
  971.          default:
  972.       oops:
  973.             z_log (msgtxt[M_CAN_MSG]);
  974.             fclose (Infile);
  975.             return ERROR;
  976.          }                                       /* switch */
  977.       }                                          /* while */
  978. }                                                /* ZS_SendFileData */
  979.  
  980. /*--------------------------------------------------------------------------*/
  981. /* ZS SYNC WITH RECEIVER                                                    */
  982. /* Respond to receiver's complaint, get back in sync with receiver          */
  983. /*--------------------------------------------------------------------------*/
  984. static int ZS_SyncWithReceiver (int num_errs)
  985. {  register int c;
  986.    char j[50];
  987.  
  988. #ifdef ZDEBUG
  989.    if(debugging_log)
  990.                 show_debug_name ("ZS_SyncWithReceiver");
  991. #endif
  992.  
  993.    while (1)
  994.       {
  995.       c = Z_GetHeader (Rxhdr);
  996.       CLEAR_INBOUND ();
  997.       switch (c)
  998.          {
  999.          case TIMEOUT:
  1000.             z_message (msgtxt[M_TIMEOUT]);
  1001.             if ((num_errs--) >= 0)
  1002.                break;
  1003.  
  1004.          case ZCAN:
  1005.          case ZABORT:
  1006.          case ZFIN:
  1007.          case RCDO:
  1008.             z_log (msgtxt[M_ERROR]);
  1009.             return ERROR;
  1010.  
  1011.          case ZRPOS:
  1012.             if (Rxpos == LastZRpos)              /* Same as last time?    */
  1013.                {
  1014.                if (!(--ZRPosCount))              /* Yup, 10 times yet?    */
  1015.                   return ERROR;                  /* Too many, get out     */
  1016.                }
  1017.             else ZRPosCount = 10;                /* Reset repeat count    */
  1018.             LastZRpos = Rxpos;                   /* Keep track of this    */
  1019.  
  1020.             rewind (Infile);                     /* In case file EOF seen */
  1021.             fseek (Infile, Rxpos, SEEK_SET);
  1022.             Txpos = Rxpos;
  1023.             sprintf (j, msgtxt[M_RESENDING_FROM],
  1024.                      ultoa (((unsigned long) (Txpos)), e_input, 10));
  1025.             z_message (j);
  1026.             return c;
  1027.  
  1028.          case ZSKIP:
  1029.             z_log (msgtxt[M_SKIP_MSG]);
  1030.  
  1031.          case ZRINIT:
  1032.             CLEAR_IOERR ();
  1033.             fclose (Infile);
  1034.             return c;
  1035.  
  1036.          case ZACK:
  1037.             z_message (NULL);
  1038.             return c;
  1039.  
  1040.          default:
  1041.             z_message (IDUNNO_msg);
  1042.             ZS_SendBinaryHeader (ZNAK, Txhdr);
  1043.             continue;
  1044.          }                                       /* switch */
  1045.       }                                          /* while */
  1046. }                                                /* ZS_SyncWithReceiver */
  1047.  
  1048.  
  1049.  
  1050.  
  1051. /*--------------------------------------------------------------------------*/
  1052. /* ZS END SEND                                                              */
  1053. /* Say BIBI to the receiver, try to do it cleanly                           */
  1054. /*--------------------------------------------------------------------------*/
  1055. static void ZS_EndSend ()
  1056. {
  1057. #ifdef ZDEBUG
  1058.     if(debugging_log)
  1059.         show_debug_name ("ZS_EndSend");
  1060. #endif
  1061.  
  1062.    while (1)
  1063.    {
  1064. #ifdef NEW
  1065.            CLEAR_OUTBOUND();
  1066.         CLEAR_INBOUND();
  1067. #endif
  1068.       Z_PutLongIntoHeader (0L);
  1069.       ZS_SendBinaryHeader (ZFIN, Txhdr);
  1070.  
  1071.       switch (Z_GetHeader (Rxhdr))
  1072.       {
  1073.       case ZFIN:
  1074.          SENDBYTE ('O');
  1075.          SENDBYTE ('O');
  1076.          while (CARRIER && !OUT_EMPTY ())
  1077.             time_release ();
  1078.          if (!CARRIER)
  1079.             CLEAR_OUTBOUND ();
  1080.          /* fallthrough... */
  1081.       case ZCAN:
  1082.       case RCDO:
  1083.       case TIMEOUT:
  1084.          return;
  1085.       }                                       /* switch */
  1086. #ifdef ZDEBUG
  1087.                 if(debugging_log)
  1088.                         show_debug_name("ZS_EndSend... looping");
  1089. #endif
  1090.    }                                          /* while */
  1091. }                                             /* ZS_EndSend */
  1092.