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

📄 zmodemr.c

📁 Gcomm is a serial communications program similar to seyon, but more modern, and easier to use. Works
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic const char rcsid[] = "$Id: zmodemr.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;#endif/* * Copyright (c) 1995 by Edward A. Falk *//********** * * *	@@@@@  @   @   @@@   @@@@   @@@@@  @   @  @@@@    *	   @   @@ @@  @   @  @   @  @      @@ @@  @   @   *	  @    @ @ @  @   @  @   @  @@@    @ @ @  @@@@    *	 @     @ @ @  @   @  @   @  @      @ @ @  @  @    *	@@@@@  @ @ @   @@@   @@@@   @@@@@  @ @ @  @   @   * *	ZMODEMR - receive side of zmodem protocol * * receive side of zmodem protocol * * This code is designed to be called from inside a larger * program, so it is implemented as a state machine where * practical. * * functions: * *	ZmodemRInit(ZModem *info) *		Initiate a connection * *	ZmodemRAbort(ZModem *info) *		abort transfer * * all functions return 0 on success, 1 on failure * * *	Edward A. Falk * *	January, 1995 * * * **********/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include "zmodem.h"#include "crctab.h"extern	int	errno ;extern	int	ZWriteFile(u_char *buffer, int len, FILE *, ZModem *);extern	int	ZCloseFile(ZModem *info) ;extern	void	ZFlowControl(int onoff, ZModem *info) ;static	u_char	zeros[4] = {0,0,0,0} ;intZmodemRInit(ZModem *info){	info->packetCount = 0 ;	info->offset = 0 ;	info->errCount = 0 ;	info->escCtrl = info->escHibit = info->atSign = info->escape = 0 ;	info->InputState = Idle ;	info->canCount = info->chrCount = 0 ;	info->filename = NULL ;	info->interrupt = 0 ;	info->waitflag = 0 ;	info->attn = NULL ;	info->file = NULL ;	info->buffer = (u_char *)malloc(8192) ;	info->state = RStart ;	info->timeoutCount = 0 ;	ZIFlush(info) ;	/* Don't send ZRINIT right away, there might be a ZRQINIT in	 * the input buffer.  Instead, set timeout to zero and return.	 * This will allow ZmodemRcv() to check the input stream first.	 * If nothing found, a ZRINIT will be sent immediately.	 */	info->timeout = 0 ;	zmodemlog("ZmodemRInit[%s]: flush input, new state = RStart\n",	    sname(info)) ;	return 0 ;}intYmodemRInit(ZModem *info){	info->errCount = 0 ;	info->InputState = Yrcv ;	info->canCount = info->chrCount = 0 ;	info->noiseCount = 0 ;	info->filename = NULL ;	info->file = NULL ;	if( info->buffer == NULL )	  info->buffer = (u_char *)malloc(1024) ;	info->state = YRStart ;	info->packetCount = -1 ;	info->timeoutCount = 0 ;	info->timeout = 10 ;	info->offset = 0 ;	ZIFlush(info) ;	return ZXmitStr((u_char *)"C", 1, info) ;}extern	int	ZPF() ;extern	int	Ignore() ;extern	int	GotCommand() ;extern	int	GotStderr() ;	int	SendRinit() ;static	int	GotSinit() ;static	int	GotFile() ;static	int	GotFin() ;static	int	GotData() ;static	int	GotEof() ;static	int	GotFreecnt() ;static	int	GotFileCrc() ;	int	ResendCrcReq() ;	int	ResendRpos() ;		/* sent ZRINIT, waiting for ZSINIT or ZFILE */	StateTable	RStartOps[] = {	  {ZSINIT,GotSinit,0,1,RSinitWait},	/* SINIT, wait for attn str */	  {ZFILE,GotFile,0,0,RFileName},	/* FILE, wait for filename */	  {ZRQINIT,SendRinit,0,1,RStart},	/* sender confused, resend */	  {ZFIN,GotFin,1,0,RFinish},		/* sender shutting down */	  {ZNAK,SendRinit,1,0,RStart},		/* RINIT was bad, resend */#ifdef	TODO	  {ZCOMPL,f,1,1,s},#endif	/* TODO */	  {ZFREECNT,GotFreecnt,0,0,RStart},	/* sender wants free space */	  {ZCOMMAND,GotCommand,0,0,CommandData}, /* sender wants command */	  {ZSTDERR,GotStderr,0,0,StderrData},	/* sender wants to send msg */	  {99,ZPF,0,0,RStart},			/* anything else is an error */	} ;	StateTable	RSinitWaitOps[] = {	/* waiting for data */	  {99,ZPF,0,0,RSinitWait},	} ;	StateTable	RFileNameOps[] = {	/* waiting for file name */	  {99,ZPF,0,0,RFileName},	} ;	StateTable	RCrcOps[] = {		/* waiting for CRC */	  {ZCRC,GotFileCrc,0,0,RFile},		  /* sender sent it */	  {ZNAK,ResendCrcReq,0,0,RCrc},		  /* ZCRC was bad, resend */	  {ZRQINIT,SendRinit,1,1,RStart},	  /* sender confused, restart */	  {ZFIN,GotFin,1,1,RFinish},		  /* sender signing off */	  {99,ZPF,0,0,RCrc},	} ;	StateTable	RFileOps[] = {		/* waiting for ZDATA */	  {ZDATA,GotData,0,0,RData},		  /* got it */	  {ZNAK,ResendRpos,0,0,RFile},		  /* ZRPOS was bad, resend */	  {ZEOF,GotEof,0,0,RStart},		  /* end of file */	  {ZRQINIT,SendRinit,1,1,RStart},	  /* sender confused, restart */	  {ZFILE,ResendRpos,0,0,RFile},		  /* ZRPOS was bad, resend */	  {ZFIN,GotFin,1,1,RFinish},		  /* sender signing off */	  {99,ZPF,0,0,RFile},	} ;	/* waiting for data, but a packet could possibly arrive due	 * to error recovery or something	 */	StateTable	RDataOps[] = {	  {ZRQINIT,SendRinit,1,1,RStart},	/* sender confused, restart */	  {ZFILE,GotFile,0,1,RFileName},	/* start a new file (??) */	  {ZNAK,ResendRpos,1,1,RFile},		/* ZRPOS was bad, resend */	  {ZFIN,GotFin,1,1,RFinish},		/* sender signing off */	  {ZDATA,GotData,0,1,RData},		/* file data follows */	  {ZEOF,GotEof,1,1,RStart},		/* end of file */	  {99,ZPF,0,0,RData},	} ;	/* here if we've sent ZFERR or ZABORT.  Waiting for ZFIN */	StateTable	RFinishOps[] = {	  {ZRQINIT,SendRinit,1,1,RStart},	/* sender confused, restart */	  {ZFILE,GotFile,1,1,RFileName},	/* start a new file */	  {ZNAK,GotFin,1,1,RFinish},		/* resend ZFIN */	  {ZFIN,GotFin,1,1,RFinish},		/* sender signing off */	  {99,ZPF,0,0,RFinish},	} ;extern	char	*hdrnames[] ;extern	int	dataSetup() ;	/* RECEIVE-RELATED STUFF BELOW HERE */	/* resend ZRINIT header in response to ZRQINIT or ZNAK header */intSendRinit( register ZModem *info ){	u_char	dbuf[4] ;#ifdef	COMMENT	if( info->timeoutCount >= 5 )	  /* TODO: switch to Ymodem */#endif	/* COMMENT */	zmodemlog("SendRinit[%s]: send ZRINIT\n", sname(info)) ;	info->timeout = ResponseTime ;	dbuf[0] = info->bufsize&0xff ;	dbuf[1] = (info->bufsize>>8)&0xff ;	dbuf[2] = 0 ;	dbuf[3] = info->zrinitflags ;	return ZXmitHdrHex(ZRINIT, dbuf, info) ;}	/* received a ZSINIT header in response to ZRINIT */static	intGotSinit( register ZModem *info ){	zmodemlog("GotSinit[%s]: call dataSetup\n", sname(info)) ;	info->zsinitflags = info->hdrData[4] ;	info->escCtrl = info->zsinitflags & TESCCTL ;	info->escHibit = info->zsinitflags & TESC8 ;	ZFlowControl(1, info) ;	return dataSetup(info) ;}	/* received rest of ZSINIT packet */intGotSinitData( register ZModem *info, int crcGood ){	info->InputState = Idle ;	info->chrCount=0 ;	info->state = RStart ;	zmodemlog("GotSinitData[%s]: crcGood=%d\n", sname(info), crcGood) ;	if( !crcGood )	  return ZXmitHdrHex(ZNAK, zeros, info) ;	if( info->attn != NULL )	  free(info->attn) ;	info->attn = NULL ;	if( info->buffer[0] != '\0' )	  info->attn = strdup((char *)info->buffer) ;	return ZXmitHdrHex(ZACK, ZEnc4(SerialNo), info) ;}	/* got ZFILE.  Cache flags and set up to receive filename */static	intGotFile( register ZModem *info ){	zmodemlog("GotFile[%s]: call dataSetup\n", sname(info)) ;	info->errCount = 0 ;	info->f0 = info->hdrData[4] ;	info->f1 = info->hdrData[3] ;	info->f2 = info->hdrData[2] ;	info->f3 = info->hdrData[1] ;	return dataSetup(info) ;}	/* utility: see if ZOpenFile wants this file, and if	 * so, request it from sender.	 */static	intrequestFile( register ZModem *info, u_long crc ){	info->file = ZOpenFile((char *)info->buffer, crc, info) ;	if( info->file == NULL ) {	  zmodemlog("requestFile[%s]: send ZSKIP\n", sname(info)) ;	  info->state = RStart ;	  ZStatus(FileSkip, 0, info->filename) ;	  return ZXmitHdrHex(ZSKIP, zeros, info) ;	}	else {	  zmodemlog("requestFile[%s]: send ZRPOS(%ld)\n",	    sname(info), info->offset) ;	  info->offset = info->f0 == ZCRESUM ? ftell(info->file) : 0 ;	  info->state = RFile ;	  ZStatus(FileBegin, 0, info->filename) ;	  return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info) ;	}}	/* parse filename info. */static	voidparseFileName( register ZModem *info, char *fileinfo ){	char	*ptr ;	int	serial=0 ;	info->len = info->mode = info->filesRem =		info->bytesRem = info->fileType = 0 ;	ptr = fileinfo + strlen(fileinfo) + 1 ;	if( info->filename != NULL )	  free(info->filename) ;	info->filename = strdup(fileinfo) ;	sscanf(ptr, "%d %lo %o %o %d %d %d", &info->len, &info->date,	    &info->mode, &serial, &info->filesRem, &info->bytesRem,	    &info->fileType) ;}	/* got filename.  Parse arguments from it and execute	 * policy function ZOpenFile(), provided by caller	 */intGotFileName( register ZModem *info, int crcGood ){	info->InputState = Idle ;	info->chrCount=0 ;	if( !crcGood ) {	zmodemlog("GotFileName[%s]: bad crc, send ZNAK\n", sname(info)) ;	  info->state = RStart ;	  return ZXmitHdrHex(ZNAK, zeros, info) ;	}	parseFileName(info, (char *)info->buffer) ;	if( (info->f1 & ZMMASK) == ZMCRC ) {	  info->state = RCrc ;	  return ZXmitHdrHex(ZCRC, zeros, info) ;	}	zmodemlog("GotFileName[%s]: good crc, call requestFile\n",		sname(info)) ;	info->state = RFile ;	return requestFile(info,0) ;}int

⌨️ 快捷键说明

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