⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zsend.c

📁 zmodem文件传输协议的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*--------------------------------------------------------------------------*/
/* FILE: zsend.c    (Opus zmodem transmitter)                               */
/*                                                                          */
/*                                                                          */
/*               The Opus Computer-Based Conversation System                */
/*       (c) Copyright 1986, Wynn Wagner III, All Rights Reserved           */
/*                                                                          */
/*      This implementation of Chuck Forsberg's ZMODEM protocol was         */
/*              for Opus by Rick Huebner and Wynn Wagner III                */
/*                                                                          */
/* (MSC/4 with /Zp /Ox)                                                     */
/*                                                                          */
/*                                                                          */
/*                                                                          */
/*                                                                          */
/*  This module is similar to a routine used by Opus-Cbcs (1.00).  It is    */
/*  provided for your information only.  You will find routines that need   */
/*  to be coded and identifiers to be resolved.                             */
/*                                                                          */
/*  There is absolutely no guarantee that anything here will work.  If you  */
/*  break this routine, you own both pieces.                                */
/*                                                                          */
/*  USAGE:  You may use this material in any program with no obligation     */
/*          as long as there is no charge for your program.  For more       */
/*          information about commercial use, contact the "OPUSinfo HERE"   */
/*          BBS (124/111).                                                  */
/*                                                                          */
/*  NOTE:   There are a couple of things the Opus implementation does that  */
/*          aren't part of the original ZModem protocol.  They all deal     */
/*          with WaZOO type ("ZedZap") netmail and should only show up when */
/*          used under that condition.                                      */
/*                                                                          */
/*             * The maximum packet size can grow larger than 1k.  It is    */
/*               sensitive to the baud rate.  (2400b=2048k; 9600b=8192k)    */
/*             * The sender must be able to send nothing.  In other words,  */
/*               the sending system must be able to initiate and terminate  */
/*               a zmodem send session without having to actually send a    */
/*               file.  Normally this kind of thing would never happen in   */
/*               zmodem.                                                    */
/*                                                                          */
/*                                                                          */
/*--------------------------------------------------------------------------*/

#include "zmodem.h"


/*--------------------------------------------------------------------------*/
/* Global routines                                                          */
/*--------------------------------------------------------------------------*/
int cdecl send_Zmodem(byte *,byte *,int,int,int);


/*--------------------------------------------------------------------------*/
/* Private routines                                                         */
/*--------------------------------------------------------------------------*/
static void pascal ZS_SendBinaryHeader(unsigned short ,byte *);
static void pascal ZS_SendData(byte *,int,unsigned short);
static void pascal ZS_SendByte(byte);
static int  pascal ZS_GetReceiverInfo(void);
static int  pascal ZS_SendFile(int,int);
static int  pascal ZS_SendFileData(int);
static int  pascal ZS_SyncWithReceiver(void);
static void pascal ZS_EndSend(void);



/*--------------------------------------------------------------------------*/
/* Private data                                                             */
/*--------------------------------------------------------------------------*/
static FILE *Infile;             /* Handle of file being sent               */
static byte *Txbuf;              /* Pointer to transmit buffer              */
static long  Strtpos;            /* Starting byte position of download      */
static long  Txpos;              /* Transmitted file position               */
static int Rxbuflen;             /* Receiver's max buffer length            */


/*--------------------------------------------------------------------------*/
/* External data not otherwise declared                                     */
/*--------------------------------------------------------------------------*/
extern char *FLAGGING_msg;
extern char *NOTSENT_msg;
extern char *TRUNC_msg;
extern char *KBD_msg;






/*--------------------------------------------------------------------------*/
/* SEND ZMODEM (send a file)                                                */
/*   returns TRUE (1) for good xfer, FALSE (0) for bad                      */
/*   sends one file per call; 'fsent' flags start and end of batch          */
/*--------------------------------------------------------------------------*/
int cdecl send_Zmodem(fname,alias,doafter,fsent,wazoo)
   byte  *fname;
   byte  *alias;
   int   doafter;
   int   fsent;
   int   wazoo;
   begin
      register byte *p;
      register byte *q;
      struct stat    f;

      int   i;
      int   rc;


      _BRK_DISABLE();
      XON_ENABLE();

      errno    =
      z_size   = 0;
      Infile   = NULL;
      Txbuf    = NULL;



      if (fname) set_xy("");

      switch(fsent)
         begin
            case 0:
            case NOTHING_TO_DO:  n_disable();
                                 if (!wazoo)
                                    begin
                                       Z_PutString("rz\r");
                                       Z_PutLongIntoHeader(0L);
                                       Z_SendHexHeader(ZRQINIT, Txhdr);
                                    end
                                 Rxtimeout   = 20;
                                 if (ZS_GetReceiverInfo() == ERROR) return FALSE;
         end


      Rxtimeout   = (int )(614400L/(long )cur_baud);
      Rxtimeout  /= 10;

      if (Rxtimeout < 10) Rxtimeout = 10;
      if (Rxtimeout > 58) Rxtimeout = 58;


      if (fname == NULL) goto Done;

      /*--------------------------------------------------------------------*/
      /* Prepare the file for transmission.  Just ignore file open errors   */
      /* because there may be other files that can be sent.                 */
      /*--------------------------------------------------------------------*/
      Filename = fname;
      CLEAR_IOERR();
      Infile   = fopen(Filename,read_binary);
      if (had_error(OPEN_msg,Filename)) return OK;
      
      Txbuf    = zalloc();

      /*--------------------------------------------------------------------*/
      /* Send the file                                                      */
      /*--------------------------------------------------------------------*/
      rc       = TRUE;


      /*--------------------------------------------------------------------*/
      /* Display outbound filename, size, and ETA for sysop                 */
      /*--------------------------------------------------------------------*/
      fstat(fileno(Infile), &f);

      message(NULL);
      cprintf( "Z-Send %s, %ldb",Filename,f.st_size);

      i  = (int)(f.st_size*10/cur_baud+27)/54;
      if (i) cprintf(", %d min.",i);

      set_xy(NULL);

      /*--------------------------------------------------------------------*/
      /* Get outgoing file name; no directory path, lower case              */
      /*--------------------------------------------------------------------*/
      for (p=(alias!=NULL)?alias:Filename, q=Txbuf ; *p; )
         begin
            if ((*q++ = tolower(*p)) == '\\') q = Txbuf;
            p++;
         end

      *q++  = '\0';
      p     = q;

      /*--------------------------------------------------------------------*/
      /* Zero out remainder of file header packet                           */
      /*--------------------------------------------------------------------*/
      while (q < (Txbuf + KSIZE)) *q++ = '\0';

      /*--------------------------------------------------------------------*/
      /* Store filesize, time last modified, and file mode in header packet */
      /*--------------------------------------------------------------------*/
      sprintf(p, "%lu %lo %o", f.st_size, f.st_mtime, f.st_mode);

      /*--------------------------------------------------------------------*/
      /* Transmit the filename block and begin the download                 */
      /*--------------------------------------------------------------------*/
      throughput(0,0L);


      /*--------------------------------------------------------------------*/
      /* Check the results                                                  */
      /*--------------------------------------------------------------------*/
      switch( ZS_SendFile(1+strlen(p)+(p-Txbuf), wazoo) )
         begin

            case ERROR: /*--------------------------------------------------*/
                        /* Something tragic happened                        */
                        /*--------------------------------------------------*/
                        if (wazoo)
                           begin
                              status_line( NOTSENT_msg );
                              mdm_hangup();
                           end
                        goto Err_Out;


            case OK:    /*--------------------------------------------------*/
                        /* File was sent                                    */
                        /*--------------------------------------------------*/
                        CLEAR_IOERR();
                        fclose(Infile);
                        had_error(CLOSE_msg,Filename);
                        Infile   = NULL;

                        status_line( "=DL %s", Filename );

                        /*--------------------------------------------------*/
                        /* Special WaZOO file handling following a          */
                        /* successful transmission.                         */
                        /*--------------------------------------------------*/
                        switch(doafter)
                           begin
                              case DELETE_AFTER:   /*-----------------------*/
                                                   /* Delete File           */
                                                   /*-----------------------*/
                                                   CLEAR_IOERR();
                                                   unlink(Filename);
                                                   had_error(UNLINK_msg,Filename);
                                                   break;
   
                              case TRUNC_AFTER:    /*-----------------------*/
                                                   /* Truncate File         */
                                                   /*-----------------------*/
                                                   CLEAR_IOERR();
                                                   i = open(Filename,O_TRUNC,S_IWRITE);
                                                   had_error( TRUNC_msg, Filename );
                                                   status_line(FLAGGING_msg,Filename);
                                                   close(i);
                                                   break;
                           end /* switch */


            default:    /*--------------------------------------------------*/
                        /* Probably a ZSKIP                                 */
                        /*--------------------------------------------------*/
                        goto Done;

         end /* switch */

Err_Out:
      rc = FALSE;

Done:
      if (Infile) fclose(Infile);
      if (Txbuf)  free(Txbuf);

      if (fsent < 0) ZS_EndSend();

      return rc;

   end /* send_Zmodem */



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -