?? zreceive.c
字號:
/*--------------------------------------------------------------------------*/
/* FILE: zreceive.c (Opus zmodem receiver) */
/* */
/* */
/* 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"
/*--------------------------------------------------------------------------*/
/* External material */
/*--------------------------------------------------------------------------*/
extern int dexists(byte *);
/*--------------------------------------------------------------------------*/
/* Local routines */
/*--------------------------------------------------------------------------*/
int cdecl get_Zmodem(byte *,FILE *);
static int pascal RZ_ReceiveData(byte *,int );
static int pascal RZ_InitReceiver(void);
static int pascal RZ_ReceiveBatch(FILE *);
static int pascal RZ_ReceiveFile(FILE *);
static int pascal RZ_GetHeader(void);
static int pascal RZ_SaveToDisk(unsigned long *);
static void pascal RZ_AckBibi(void);
/*--------------------------------------------------------------------------*/
/* Private declarations */
/*--------------------------------------------------------------------------*/
static long DiskAvail;
/*--------------------------------------------------------------------------*/
/* Private data */
/*--------------------------------------------------------------------------*/
/* Parameters for ZSINIT frame */
#define ZATTNLEN 32 /* Max length of attention string */
static char Attn[ZATTNLEN+1]; /* String rx sends to tx on err */
static FILE *Outfile; /* Handle of file being received */
static byte *Secbuf; /* Pointer to receive buffer */
static int Tryzhdrtype; /* Hdr type to send for Last rx close */
static char isBinary; /* Current file is binary mode */
static char EOFseen; /* indicates cpm eof (^Z) was received */
static char Zconv; /* ZMODEM file conversion request */
static int RxCount; /* Count of data bytes received */
/*--------------------------------------------------------------------------*/
/* GET ZMODEM */
/* Receive a batch of files. */
/* returns TRUE (1) for good xfer, FALSE (0) for bad */
/* can be called from f_upload or to get mail from a WaZOO Opus */
/*--------------------------------------------------------------------------*/
int cdecl get_Zmodem(rcvpath, xferinfo)
byte *rcvpath;
FILE *xferinfo;
begin
byte namebuf[PATHLEN];
int i;
errno = 0;
_BRK_DISABLE();
XON_ENABLE();
n_disable();
Secbuf = NULL;
Outfile = NULL;
z_size = 0;
DiskAvail = freespace(toupper(sys.uppath[0])-'@');
Rxtimeout = 10;
Tryzhdrtype = ZRINIT;
Secbuf = zalloc();
strcpy(namebuf, rcvpath);
Filename = namebuf;
if (((i=RZ_InitReceiver())==ZCOMPL) or
((i==ZFILE) and ((RZ_ReceiveBatch(xferinfo))==OK)) )
begin
free(Secbuf);
return 1;
end
CLEAR_OUTBOUND();
send_can(); /* transmit at least 10 cans */
wait_for_clear();
if (Secbuf) free(Secbuf);
if (Outfile) fclose(Outfile);
return 0;
end /* get_Zmodem */
/*--------------------------------------------------------------------------*/
/* RZ RECEIVE DATA */
/* Receive array buf of max length with ending ZDLE sequence */
/* and CRC. Returns the ending character or error code. */
/*--------------------------------------------------------------------------*/
static int pascal RZ_ReceiveData(buf, length)
byte *buf;
int length;
begin
register int c;
register word crc;
int d;
crc = RxCount = 0;
while(1)
begin
if ((c = Z_GetZDL()) & ~0xFF)
begin
CRCfoo:
switch (c)
begin
case GOTCRCE:
case GOTCRCG:
case GOTCRCQ:
case GOTCRCW: /*-----------------------------------*/
/* C R C s */
/*-----------------------------------*/
crc = Z_UpdateCRC(((d=c)&0xFF), crc);
if ((c=Z_GetZDL()) & ~0xFF) goto CRCfoo;
crc = Z_UpdateCRC(c, crc);
if ((c=Z_GetZDL()) & ~0xFF) goto CRCfoo;
crc = Z_UpdateCRC(c, crc);
if (crc & 0xFFFF)
begin
z_message( CRC_msg );
return ERROR;
end
return d;
case GOTCAN: /*-----------------------------------*/
/* Cancel */
/*-----------------------------------*/
z_log(Cancelled_msg);
return ZCAN;
case TIMEOUT: /*-----------------------------------*/
/* Timeout */
/*-----------------------------------*/
z_message( TIME_msg );
return c;
case RCDO: /*-----------------------------------*/
/* No carrier */
/*-----------------------------------*/
z_log( CARRIER_msg );
return c;
default: /*-----------------------------------*/
/* Something bizarre */
/*-----------------------------------*/
z_message("Debris");
return c;
end /* switch */
end /* if */
if (--length < 0)
begin
z_message("Long pkt");
return ERROR;
end
++RxCount;
*buf++ = c;
crc = Z_UpdateCRC(c, crc);
continue;
end /* while(1) */
end /* RZ_ReceiveData */
/*--------------------------------------------------------------------------*/
/* RZ INIT RECEIVER */
/* Initialize for Zmodem receive attempt, try to activate Zmodem sender */
/* Handles ZSINIT, ZFREECNT, and ZCOMMAND frames */
/* */
/* Return codes: */
/* ZFILE .... Zmodem filename received */
/* ZCOMPL ... transaction finished */
/* ERROR .... any other condition */
/*--------------------------------------------------------------------------*/
static int pascal RZ_InitReceiver()
begin
register int n;
int errors = 0;
for (n=10; --n>=0; )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -