ZSEND.C
上传用户:haiyue
上传日期:2007-01-05
资源大小:21k
文件大小:34k
源码类别:

通讯/手机编程

开发平台:

C/C++

  1. /*--------------------------------------------------------------------------*/
  2. /* FILE: zsend.c    (Opus zmodem transmitter)                               */
  3. /*                                                                          */
  4. /*                                                                          */
  5. /*               The Opus Computer-Based Conversation System                */
  6. /*       (c) Copyright 1986, Wynn Wagner III, All Rights Reserved           */
  7. /*                                                                          */
  8. /*      This implementation of Chuck Forsberg's ZMODEM protocol was         */
  9. /*              for Opus by Rick Huebner and Wynn Wagner III                */
  10. /*                                                                          */
  11. /* (MSC/4 with /Zp /Ox)                                                     */
  12. /*                                                                          */
  13. /*                                                                          */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*  This module is similar to a routine used by Opus-Cbcs (1.00).  It is    */
  17. /*  provided for your information only.  You will find routines that need   */
  18. /*  to be coded and identifiers to be resolved.                             */
  19. /*                                                                          */
  20. /*  There is absolutely no guarantee that anything here will work.  If you  */
  21. /*  break this routine, you own both pieces.                                */
  22. /*                                                                          */
  23. /*  USAGE:  You may use this material in any program with no obligation     */
  24. /*          as long as there is no charge for your program.  For more       */
  25. /*          information about commercial use, contact the "OPUSinfo HERE"   */
  26. /*          BBS (124/111).                                                  */
  27. /*                                                                          */
  28. /*  NOTE:   There are a couple of things the Opus implementation does that  */
  29. /*          aren't part of the original ZModem protocol.  They all deal     */
  30. /*          with WaZOO type ("ZedZap") netmail and should only show up when */
  31. /*          used under that condition.                                      */
  32. /*                                                                          */
  33. /*             * The maximum packet size can grow larger than 1k.  It is    */
  34. /*               sensitive to the baud rate.  (2400b=2048k; 9600b=8192k)    */
  35. /*             * The sender must be able to send nothing.  In other words,  */
  36. /*               the sending system must be able to initiate and terminate  */
  37. /*               a zmodem send session without having to actually send a    */
  38. /*               file.  Normally this kind of thing would never happen in   */
  39. /*               zmodem.                                                    */
  40. /*                                                                          */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43. #include "zmodem.h"
  44. /*--------------------------------------------------------------------------*/
  45. /* Global routines                                                          */
  46. /*--------------------------------------------------------------------------*/
  47. int cdecl send_Zmodem(byte *,byte *,int,int,int);
  48. /*--------------------------------------------------------------------------*/
  49. /* Private routines                                                         */
  50. /*--------------------------------------------------------------------------*/
  51. static void pascal ZS_SendBinaryHeader(unsigned short ,byte *);
  52. static void pascal ZS_SendData(byte *,int,unsigned short);
  53. static void pascal ZS_SendByte(byte);
  54. static int  pascal ZS_GetReceiverInfo(void);
  55. static int  pascal ZS_SendFile(int,int);
  56. static int  pascal ZS_SendFileData(int);
  57. static int  pascal ZS_SyncWithReceiver(void);
  58. static void pascal ZS_EndSend(void);
  59. /*--------------------------------------------------------------------------*/
  60. /* Private data                                                             */
  61. /*--------------------------------------------------------------------------*/
  62. static FILE *Infile;             /* Handle of file being sent               */
  63. static byte *Txbuf;              /* Pointer to transmit buffer              */
  64. static long  Strtpos;            /* Starting byte position of download      */
  65. static long  Txpos;              /* Transmitted file position               */
  66. static int Rxbuflen;             /* Receiver's max buffer length            */
  67. /*--------------------------------------------------------------------------*/
  68. /* External data not otherwise declared                                     */
  69. /*--------------------------------------------------------------------------*/
  70. extern char *FLAGGING_msg;
  71. extern char *NOTSENT_msg;
  72. extern char *TRUNC_msg;
  73. extern char *KBD_msg;
  74. /*--------------------------------------------------------------------------*/
  75. /* SEND ZMODEM (send a file)                                                */
  76. /*   returns TRUE (1) for good xfer, FALSE (0) for bad                      */
  77. /*   sends one file per call; 'fsent' flags start and end of batch          */
  78. /*--------------------------------------------------------------------------*/
  79. int cdecl send_Zmodem(fname,alias,doafter,fsent,wazoo)
  80.    byte  *fname;
  81.    byte  *alias;
  82.    int   doafter;
  83.    int   fsent;
  84.    int   wazoo;
  85.    begin
  86.       register byte *p;
  87.       register byte *q;
  88.       struct stat    f;
  89.       int   i;
  90.       int   rc;
  91.       _BRK_DISABLE();
  92.       XON_ENABLE();
  93.       errno    =
  94.       z_size   = 0;
  95.       Infile   = NULL;
  96.       Txbuf    = NULL;
  97.       if (fname) set_xy("");
  98.       switch(fsent)
  99.          begin
  100.             case 0:
  101.             case NOTHING_TO_DO:  n_disable();
  102.                                  if (!wazoo)
  103.                                     begin
  104.                                        Z_PutString("rzr");
  105.                                        Z_PutLongIntoHeader(0L);
  106.                                        Z_SendHexHeader(ZRQINIT, Txhdr);
  107.                                     end
  108.                                  Rxtimeout   = 20;
  109.                                  if (ZS_GetReceiverInfo() == ERROR) return FALSE;
  110.          end
  111.       Rxtimeout   = (int )(614400L/(long )cur_baud);
  112.       Rxtimeout  /= 10;
  113.       if (Rxtimeout < 10) Rxtimeout = 10;
  114.       if (Rxtimeout > 58) Rxtimeout = 58;
  115.       if (fname == NULL) goto Done;
  116.       /*--------------------------------------------------------------------*/
  117.       /* Prepare the file for transmission.  Just ignore file open errors   */
  118.       /* because there may be other files that can be sent.                 */
  119.       /*--------------------------------------------------------------------*/
  120.       Filename = fname;
  121.       CLEAR_IOERR();
  122.       Infile   = fopen(Filename,read_binary);
  123.       if (had_error(OPEN_msg,Filename)) return OK;
  124.       
  125.       Txbuf    = zalloc();
  126.       /*--------------------------------------------------------------------*/
  127.       /* Send the file                                                      */
  128.       /*--------------------------------------------------------------------*/
  129.       rc       = TRUE;
  130.       /*--------------------------------------------------------------------*/
  131.       /* Display outbound filename, size, and ETA for sysop                 */
  132.       /*--------------------------------------------------------------------*/
  133.       fstat(fileno(Infile), &f);
  134.       message(NULL);
  135.       cprintf( "Z-Send %s, %ldb",Filename,f.st_size);
  136.       i  = (int)(f.st_size*10/cur_baud+27)/54;
  137.       if (i) cprintf(", %d min.",i);
  138.       set_xy(NULL);
  139.       /*--------------------------------------------------------------------*/
  140.       /* Get outgoing file name; no directory path, lower case              */
  141.       /*--------------------------------------------------------------------*/
  142.       for (p=(alias!=NULL)?alias:Filename, q=Txbuf ; *p; )
  143.          begin
  144.             if ((*q++ = tolower(*p)) == '\') q = Txbuf;
  145.             p++;
  146.          end
  147.       *q++  = '';
  148.       p     = q;
  149.       /*--------------------------------------------------------------------*/
  150.       /* Zero out remainder of file header packet                           */
  151.       /*--------------------------------------------------------------------*/
  152.       while (q < (Txbuf + KSIZE)) *q++ = '';
  153.       /*--------------------------------------------------------------------*/
  154.       /* Store filesize, time last modified, and file mode in header packet */
  155.       /*--------------------------------------------------------------------*/
  156.       sprintf(p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);
  157.       /*--------------------------------------------------------------------*/
  158.       /* Transmit the filename block and begin the download                 */
  159.       /*--------------------------------------------------------------------*/
  160.       throughput(0,0L);
  161.       /*--------------------------------------------------------------------*/
  162.       /* Check the results                                                  */
  163.       /*--------------------------------------------------------------------*/
  164.       switch( ZS_SendFile(1+strlen(p)+(p-Txbuf), wazoo) )
  165.          begin
  166.             case ERROR: /*--------------------------------------------------*/
  167.                         /* Something tragic happened                        */
  168.                         /*--------------------------------------------------*/
  169.                         if (wazoo)
  170.                            begin
  171.                               status_line( NOTSENT_msg );
  172.                               mdm_hangup();
  173.                            end
  174.                         goto Err_Out;
  175.             case OK:    /*--------------------------------------------------*/
  176.                         /* File was sent                                    */
  177.                         /*--------------------------------------------------*/
  178.                         CLEAR_IOERR();
  179.                         fclose(Infile);
  180.                         had_error(CLOSE_msg,Filename);
  181.                         Infile   = NULL;
  182.                         status_line( "=DL %s", Filename );
  183.                         /*--------------------------------------------------*/
  184.                         /* Special WaZOO file handling following a          */
  185.                         /* successful transmission.                         */
  186.                         /*--------------------------------------------------*/
  187.                         switch(doafter)
  188.                            begin
  189.                               case DELETE_AFTER:   /*-----------------------*/
  190.                                                    /* Delete File           */
  191.                                                    /*-----------------------*/
  192.                                                    CLEAR_IOERR();
  193.                                                    unlink(Filename);
  194.                                                    had_error(UNLINK_msg,Filename);
  195.                                                    break;
  196.    
  197.                               case TRUNC_AFTER:    /*-----------------------*/
  198.                                                    /* Truncate File         */
  199.                                                    /*-----------------------*/
  200.                                                    CLEAR_IOERR();
  201.                                                    i = open(Filename,O_TRUNC,S_IWRITE);
  202.                                                    had_error( TRUNC_msg, Filename );
  203.                                                    status_line(FLAGGING_msg,Filename);
  204.                                                    close(i);
  205.                                                    break;
  206.                            end /* switch */
  207.             default:    /*--------------------------------------------------*/
  208.                         /* Probably a ZSKIP                                 */
  209.                         /*--------------------------------------------------*/
  210.                         goto Done;
  211.          end /* switch */
  212. Err_Out:
  213.       rc = FALSE;
  214. Done:
  215.       if (Infile) fclose(Infile);
  216.       if (Txbuf)  free(Txbuf);
  217.       if (fsent < 0) ZS_EndSend();
  218.       return rc;
  219.    end /* send_Zmodem */
  220. /*--------------------------------------------------------------------------*/
  221. /* ZS SEND BINARY HEADER                                                    */
  222. /* Send ZMODEM binary header hdr of type type                               */
  223. /*--------------------------------------------------------------------------*/
  224. static void pascal ZS_SendBinaryHeader(type, hdr)
  225.    unsigned short type;
  226.    byte          *hdr;
  227.    begin
  228.       register byte          *hptr;
  229.       register unsigned short crc;
  230.       int                     n;
  231.       SENDBYTE(ZPAD);
  232.       SENDBYTE(ZDLE);
  233.       SENDBYTE(ZBIN);
  234.       ZS_SendByte(type);
  235.       crc = Z_UpdateCRC(type, 0);
  236.       hptr  = hdr;
  237.       for (n=4; --n >= 0;)
  238.          begin
  239.             ZS_SendByte(*hptr);
  240.             crc = Z_UpdateCRC(((unsigned short)(*hptr++)), crc);
  241.          end
  242.       crc = Z_UpdateCRC(0,crc);
  243.       crc = Z_UpdateCRC(0,crc);
  244.       ZS_SendByte(crc>>8);
  245.       ZS_SendByte(crc);
  246.       if (type != ZDATA) wait_for_clear();
  247.    end /* ZS_SendBinaryHeader */
  248. /*--------------------------------------------------------------------------*/
  249. /* ZS SEND DATA                                                             */
  250. /* Send binary array buf with ending ZDLE sequence frameend                 */
  251. /*--------------------------------------------------------------------------*/
  252. static void pascal ZS_SendData(buf, length, frameend)
  253.    byte          *buf;
  254.    int            length;
  255.    unsigned short frameend;
  256.    begin
  257.       register unsigned short crc;
  258.       int                     t;
  259.       crc = 0;
  260.       for (;--length >= 0;)
  261.          begin
  262.             ZS_SendByte(*buf);
  263.             crc = Z_UpdateCRC(((unsigned short)(*buf++)), crc);
  264.          end
  265.       SENDBYTE(ZDLE);
  266.       SENDBYTE(frameend);
  267.       crc = Z_UpdateCRC(frameend, crc);
  268.       crc = Z_UpdateCRC(0,crc);
  269.       crc = Z_UpdateCRC(0,crc);
  270.       ZS_SendByte(crc>>8);
  271.       ZS_SendByte(crc);
  272.       if (frameend == ZCRCW)
  273.          begin
  274.             SENDBYTE(XON);
  275.             wait_for_clear();
  276.          end
  277.    end /* ZS_SendData */
  278. /*--------------------------------------------------------------------------*/
  279. /* ZS SEND BYTE                                                             */
  280. /* Send character c with ZMODEM escape sequence encoding.                   */
  281. /* Escape XON, XOFF. Escape CR following @ (Telenet net escape)             */
  282. /*--------------------------------------------------------------------------*/
  283. static void pascal ZS_SendByte(c)
  284.    register byte c;
  285.    begin
  286.       static byte lastsent;
  287.       switch (c)
  288.          begin
  289.             case 015:
  290.             case 0215:  /*--------------------------------------------------*/
  291.                         /*                                                  */
  292.                         /*--------------------------------------------------*/
  293.                         if ((lastsent & 0x7F) != '@') goto SendIt;
  294.             case 020:
  295.             case 021:
  296.             case 023:
  297.             case 0220:
  298.             case 0221:
  299.             case 0223:
  300.             case ZDLE:  /*--------------------------------------------------*/
  301.                         /* Quoted characters                                */
  302.                         /*--------------------------------------------------*/
  303.                         SENDBYTE(ZDLE);
  304.                         c ^= 0x40;
  305.             default:    /*--------------------------------------------------*/
  306.                         /* Normal character output                          */
  307. SendIt:                 /*--------------------------------------------------*/
  308.                         SENDBYTE(lastsent = c);
  309.          end /* switch */
  310.    end /* ZS_SendByte */
  311. /*--------------------------------------------------------------------------*/
  312. /* ZS GET RECEIVER INFO                                                     */
  313. /* Get the receiver's init parameters                                       */
  314. /*--------------------------------------------------------------------------*/
  315. static int pascal ZS_GetReceiverInfo()
  316.    begin
  317.       int   n;
  318.       int   rxflags;
  319.       for (n=10; --n>=0; )
  320.          begin
  321.             switch ( Z_GetHeader(Rxhdr) )
  322.                begin
  323.                   case ZCHALLENGE:  /*--------------------------------------*/
  324.                                     /* Echo receiver's challenge number     */
  325.                                     /*--------------------------------------*/
  326.                                     Z_PutLongIntoHeader(Rxpos);
  327.                                     Z_SendHexHeader(ZACK, Txhdr);
  328.                                     continue;
  329.                   case ZCOMMAND:    /*--------------------------------------*/
  330.                                     /* They didn't see our ZRQINIT          */
  331.                                     /*--------------------------------------*/
  332.                                     Z_PutLongIntoHeader(0L);
  333.                                     Z_SendHexHeader(ZRQINIT, Txhdr);
  334.                                     continue;
  335.                   case ZRINIT:      /*--------------------------------------*/
  336.                                     /*                                      */
  337.                                     /*--------------------------------------*/
  338.                                     Rxbuflen = ((word )Rxhdr[ZP1]<<8)|Rxhdr[ZP0];
  339.                                     return OK;
  340.                   case ZCAN:
  341.                   case RCDO:
  342.                   case TIMEOUT:     /*--------------------------------------*/
  343.                                     /*                                      */
  344.                                     /*--------------------------------------*/
  345.                                     return ERROR;
  346.                   case ZRQINIT:     /*--------------------------------------*/
  347.                                     /*                                      */
  348.                                     /*--------------------------------------*/
  349.                                     if (Rxhdr[ZF0] == ZCOMMAND) continue;
  350.                   default:          /*--------------------------------------*/
  351.                                     /*                                      */
  352.                                     /*--------------------------------------*/
  353.                                     Z_SendHexHeader(ZNAK, Txhdr);
  354.                                     continue;
  355.                end /* switch */
  356.          end /* for */
  357.       return ERROR;
  358.    end /* ZS_GetReceiverInfo */
  359. /*--------------------------------------------------------------------------*/
  360. /* ZS SEND FILE                                                             */
  361. /* Send ZFILE frame and begin sending ZDATA frame                           */
  362. /*--------------------------------------------------------------------------*/
  363. static int pascal ZS_SendFile(blen, wazoo)
  364.    int blen;
  365.    int wazoo;
  366.    begin
  367.       register int c;
  368.       while(1)
  369.          begin
  370.             if (((KEYPRESS()) and (READKB()==27)))
  371.                begin
  372.                   send_can();
  373.                   z_log( KBD_msg );
  374.                   return ERROR;
  375.                end
  376.             else if (!CARRIER) return ERROR;
  377.    
  378.             Txhdr[ZF0] = LZCONV;    /* Default file conversion mode */
  379.             Txhdr[ZF1] = LZMANAG;   /* Default file management mode */
  380.             Txhdr[ZF2] = LZTRANS;   /* Default file transport mode */
  381.             Txhdr[ZF3] = 0;
  382.             ZS_SendBinaryHeader(ZFILE, Txhdr);
  383.             ZS_SendData(Txbuf, blen, ZCRCW);
  384.    
  385. Again:
  386.             switch (c = Z_GetHeader(Rxhdr))
  387.                begin
  388.                   case ZRINIT:   /*-----------------------------------------*/
  389.                                  /*                                         */
  390.                                  /*-----------------------------------------*/
  391.                                  goto Again;
  392.                   case ZCAN:     
  393.                   case ZCRC:     
  394.                   case RCDO:     
  395.                   case TIMEOUT:  
  396.                   case ZFIN:
  397.                   case ZABORT:   
  398.                                  /*-----------------------------------------*/
  399.                                  /*                                         */
  400.                                  /*-----------------------------------------*/
  401.                                  return ERROR;
  402.    
  403.                   case ZSKIP:    /*-----------------------------------------*/
  404.                                  /* Other system wants to skip this file    */
  405.                                  /*-----------------------------------------*/
  406.                                  return c;
  407.    
  408.                   case ZRPOS:    /*-----------------------------------------*/
  409.                                  /* Resend from this position...            */
  410.                                  /*-----------------------------------------*/
  411.                                  fseek(Infile, Rxpos, SEEK_SET);
  412.                                  Strtpos = Txpos = Rxpos;
  413.                                  CLEAR_INBOUND();
  414.                                  return ZS_SendFileData(wazoo);
  415.                end /* switch */
  416.          end /* while */
  417.    end /* ZS_SendFile */
  418. /*--------------------------------------------------------------------------*/
  419. /* ZS SEND FILE DATA                                                        */
  420. /* Send the data in the file                                                */
  421. /*--------------------------------------------------------------------------*/
  422. static int pascal ZS_SendFileData(wazoo)
  423.    int wazoo;
  424.    begin
  425.       register int c, e;
  426.       word         newcnt, blklen, maxblklen, goodblks, goodneeded = 1;
  427.       byte        *p;
  428.       maxblklen = (cur_baud<300) ? 128 : cur_baud/300*256;
  429.       if (maxblklen>WAZOOMAX)              maxblklen = WAZOOMAX;
  430.       if (!wazoo && maxblklen>KSIZE)       maxblklen = KSIZE;
  431.       if (Rxbuflen && maxblklen>Rxbuflen)  maxblklen = Rxbuflen;
  432.       blklen = maxblklen;
  433. SomeMore:
  434.       if (CHAR_AVAIL())
  435.          begin
  436. WaitAck:
  437.             switch (c = ZS_SyncWithReceiver())
  438.                begin
  439.                   default:       /*-----------------------------------------*/
  440.                                  /*                                         */
  441.                                  /*-----------------------------------------*/
  442.                                  z_log(Cancelled_msg);
  443.                                  errno = 0;
  444.                                  fclose(Infile);
  445.                                  had_error(CLOSE_msg,Filename);
  446.                                  return ERROR;
  447.                   case ZSKIP:    /*-----------------------------------------*/
  448.                                  /* Skip this file                          */
  449.                                  /*-----------------------------------------*/
  450.                                  return c;
  451.                   case ZACK:     /*-----------------------------------------*/
  452.                                  /*                                         */
  453.                                  /*-----------------------------------------*/
  454.                                  break;
  455.                   case ZRPOS:    /*-----------------------------------------*/
  456.                                  /* Resume at this position                 */
  457.                                  /*-----------------------------------------*/
  458.                                  blklen = (blklen>>2 > 64) ? blklen>>2 : 64;
  459.                                  goodblks = 0;
  460.                                  goodneeded = (goodneeded<<1) | 1;
  461.                                  break;
  462.                   case ZRINIT:   /*-----------------------------------------*/
  463.                                  /* Receive init                            */
  464.                                  /*-----------------------------------------*/
  465.                                  throughput(1,Txpos-Strtpos);
  466.                                  return OK;
  467.                end /* switch */
  468.             while (CHAR_AVAIL())
  469.                begin
  470.                   switch (MODEM_IN())
  471.                      begin
  472.                         case CAN:
  473.                         case RCDO:
  474.                         case ZPAD:  goto WaitAck;
  475.                      end /* switch */
  476.                end /* while */
  477.          end /* while */
  478.       newcnt = Rxbuflen;
  479.       Z_PutLongIntoHeader(Txpos);
  480.       ZS_SendBinaryHeader(ZDATA, Txhdr);
  481.       do
  482.          begin
  483.             if (((KEYPRESS()) and (READKB()==27)))
  484.                begin
  485.                   send_can();
  486.                   z_log( KBD_msg );
  487.                   goto oops;
  488.                end
  489.             if (!CARRIER) goto oops;
  490.             if ((c=fread(Txbuf,1,blklen,Infile))!=z_size)
  491.                begin
  492.                   gotoxy( locate_x+10, locate_y );
  493.                   cputs( ultoa(((unsigned long )(z_size=c)),e_input,10) );
  494.                   putch(' ');
  495.                end
  496.             if (c < blklen) e = ZCRCE;
  497.             else if (Rxbuflen && (newcnt -= c) <= 0) e = ZCRCW;
  498.             else e = ZCRCG;
  499.             ZS_SendData(Txbuf, c, e);
  500.             gotoxy( locate_x, locate_y );
  501.             cputs( ultoa(((unsigned long )Txpos),e_input,10) );
  502.             putch(' ');
  503.             Txpos += c;
  504.             if (blklen<maxblklen && ++goodblks>goodneeded)
  505.                begin
  506.                   blklen = (blklen<<1 < maxblklen) ? blklen<<1 : maxblklen;
  507.                   goodblks = 0;
  508.                end
  509.             if (e == ZCRCW) goto WaitAck;
  510.             while (CHAR_AVAIL())
  511.                begin
  512.                   switch (MODEM_IN())
  513.                      begin
  514.                         case CAN:
  515.                         case RCDO:
  516.                         case ZPAD:  /*--------------------------------------*/
  517.                                     /* Interruption detected;               */
  518.                                     /* stop sending and process complaint   */
  519.                                     /*--------------------------------------*/
  520.                                     z_message("Trouble?");
  521.                                     CLEAR_OUTBOUND();
  522.                                     ZS_SendData(Txbuf, 0, ZCRCE);
  523.                                     goto WaitAck;
  524.                      end /* switch */
  525.                end /* while */
  526.       
  527.          end /* do */
  528.       while (e == ZCRCG);
  529.       while(1)
  530.          begin
  531.             Z_PutLongIntoHeader(Txpos);
  532.             ZS_SendBinaryHeader(ZEOF, Txhdr);
  533.             switch (ZS_SyncWithReceiver())
  534.                begin
  535.                   case ZACK:     /*-----------------------------------------*/
  536.                                  /*                                         */
  537.                                  /*-----------------------------------------*/
  538.                                  continue;
  539.                   case ZRPOS:    /*-----------------------------------------*/
  540.                                  /* Resume at this position...              */
  541.                                  /*-----------------------------------------*/
  542.                                  goto SomeMore;
  543.                   case ZRINIT:   /*-----------------------------------------*/
  544.                                  /* Receive init                            */
  545.                                  /*-----------------------------------------*/
  546.                                  throughput(1,Txpos-Strtpos);
  547.                                  return OK;
  548.                   case ZSKIP:    /*-----------------------------------------*/
  549.                                  /* Request to skip the current file        */
  550.                                  /*-----------------------------------------*/
  551.                                  z_log(Skip_msg);
  552.                                  CLEAR_IOERR();
  553.                                  fclose(Infile);
  554.                                  had_error(CLOSE_msg,Filename);
  555.                                  return c;
  556.                   default:       /*-----------------------------------------*/
  557.                                  /*                                         */
  558.                                  /*-----------------------------------------*/
  559. oops:                            z_log(Cancelled_msg);
  560.                                  errno = 0;
  561.                                  fclose(Infile);
  562.                                  had_error(CLOSE_msg,Filename);
  563.                                  return ERROR;
  564.                end /* switch */
  565.          end /* while */
  566.    end /* ZS_SendFileData */
  567. /*--------------------------------------------------------------------------*/
  568. /* ZS SYNC WITH RECEIVER                                                    */
  569. /* Respond to receiver's complaint, get back in sync with receiver          */
  570. /*--------------------------------------------------------------------------*/
  571. static int pascal ZS_SyncWithReceiver()
  572.    begin
  573.       register int c;
  574.       int          num_errs   = 7;
  575.       while(1)
  576.          begin
  577.             c = Z_GetHeader(Rxhdr);
  578.             CLEAR_INBOUND();
  579.             switch (c)
  580.                begin
  581.                   case TIMEOUT:  z_message( TIME_msg );
  582.                                  if ((num_errs--) >= 0) break;
  583.                   case ZCAN:
  584.                   case ZABORT:
  585.                   case ZFIN:
  586.                   case RCDO:
  587.                                  /*-----------------------------------------*/
  588.                                  /*                                         */
  589.                                  /*-----------------------------------------*/
  590.                                  z_log("Err");
  591.                                  return ERROR;
  592.                   case ZRPOS:    /*-----------------------------------------*/
  593.                                  /*                                         */
  594.                                  /*-----------------------------------------*/
  595.                                  rewind(Infile);   /* In case file EOF seen */
  596.                                  fseek(Infile, Rxpos, SEEK_SET);
  597.                                  Txpos = Rxpos;
  598.                                  z_message(NULL);
  599.                                  cputs("Resending from ");
  600.                                  cputs( ultoa(((unsigned long )(Txpos)),e_input,10) );
  601.                                  return c;
  602.                   case ZSKIP:    /*-----------------------------------------*/
  603.                                  /*                                         */
  604.                                  /*-----------------------------------------*/
  605.                                  z_log(Skip_msg);
  606.                   case ZRINIT:   /*-----------------------------------------*/
  607.                                  /*                                         */
  608.                                  /*-----------------------------------------*/
  609.                                  CLEAR_IOERR();
  610.                                  fclose(Infile);
  611.                                  had_error(CLOSE_msg,Filename);
  612.                                  return c;
  613.                   case ZACK:     /*-----------------------------------------*/
  614.                                  /*                                         */
  615.                                  /*-----------------------------------------*/
  616.                                  z_message( NULL );
  617.                                  return c;
  618.                   default:       /*-----------------------------------------*/
  619.                                  /*                                         */
  620.                                  /*-----------------------------------------*/
  621.                                  z_message( IDUNNO_msg );
  622.                                  ZS_SendBinaryHeader(ZNAK, Txhdr);
  623.                                  continue;
  624.                end /* switch */
  625.          end /* while */
  626.    end /* ZS_SyncWithReceiver */
  627. /*--------------------------------------------------------------------------*/
  628. /* ZS END SEND                                                              */
  629. /* Say BIBI to the receiver, try to do it cleanly                           */
  630. /*--------------------------------------------------------------------------*/
  631. static void pascal ZS_EndSend()
  632.    begin
  633.       while(1)
  634.          begin
  635.             Z_PutLongIntoHeader(0L);
  636.             ZS_SendBinaryHeader(ZFIN, Txhdr);
  637.             switch (Z_GetHeader(Rxhdr))
  638.                begin
  639.                   case ZFIN:     /*-----------------------------------------*/
  640.                                  /*                                         */
  641.                                  /*-----------------------------------------*/
  642.                                  SENDBYTE('O');
  643.                                  SENDBYTE('O');
  644.                                  wait_for_clear();
  645.                                  /* fallthrough... */
  646.                   case ZCAN:
  647.                   case RCDO:
  648.                   case TIMEOUT:  /*-----------------------------------------*/
  649.                                  /*                                         */
  650.                                  /*-----------------------------------------*/
  651.                                  return;
  652.                end /* switch */
  653.          end /* while */
  654.    end /* ZS_EndSend */
  655. /* END OF FILE: z_send.c */