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

📄 zmodem.c

📁 Gcomm is a serial communications program similar to seyon, but more modern, and easier to use. Works
💻 C
📖 第 1 页 / 共 2 页
字号:
#define	RDataOps	DoneOps#define	RFinishOps	DoneOps#define	GotFileName	Ignore#define	ResendCrcReq	Ignore#define	GotSinitData	Ignore#define	ResendRpos	Ignore#define	GotFileData	Ignore#define	SendRinit	Ignore#elseextern	StateTable	RStartOps[] ;extern	StateTable	RSinitWaitOps[] ;extern	StateTable	RFileNameOps[] ;extern	StateTable	RCrcOps[] ;extern	StateTable	RFileOps[] ;extern	StateTable	RDataOps[] ;extern	StateTable	RFinishOps[] ;extern	int		GotFileName() ;extern	int		ResendCrcReq() ;extern	int		GotSinitData() ;extern	int		ResendRpos() ;extern	int		GotFileData() ;extern	int		SendRinit() ;#endif#if	RcvOnly#define	TStartOps	DoneOps#define	TInitOps	DoneOps#define	FileWaitOps	DoneOps#define	CrcWaitOps	DoneOps#define	SendingOps	DoneOps#define	SendDoneOps	DoneOps#define	SendWaitOps	DoneOps#define	SendEofOps	DoneOps#define	TFinishOps	DoneOps#define	SendMoreFileData Ignore#elseextern	StateTable	TStartOps[] ;extern	StateTable	TInitOps[] ;extern	StateTable	FileWaitOps[] ;extern	StateTable	CrcWaitOps[] ;extern	StateTable	SendingOps[] ;extern	StateTable	SendDoneOps[] ;extern	StateTable	SendWaitOps[] ;extern	StateTable	SendEofOps[] ;extern	StateTable	TFinishOps[] ;extern	int		SendMoreFileData() ;#endifstatic	StateTable	CommandDataOps[] = {#ifdef	COMMENT	  {ZRQINIT,f,1,1},	  {ZRINIT,f,1,1},	  {ZSINIT,f,1,1},	  {ZACK,f,1,1},	  {ZFILE,f,1,1},	  {ZSKIP,f,1,1},	  {ZNAK,f,1,1},	  {ZABORT,f,1,1,TFinish},	  {ZFIN,f,1,1},	  {ZRPOS,f,1,1},	  {ZDATA,f,1,1},	  {ZEOF,f,1,1},	  {ZFERR,f,1,1,TFinish},	  {ZCRC,f,1,1},	  {ZCHALLENGE,f,1,1},	  {ZCOMPL,f,1,1},	  {ZCAN,f,1,1},	  {ZFREECNT,f,1,1},	  {ZCOMMAND,f,1,1},	  {ZSTDERR,f,1,1},#endif	/* COMMENT */	  {99,ZPF,0,0,CommandData},	} ;static	StateTable	CommandWaitOps[] = {#ifdef	COMMENT	  {ZRQINIT,f,1,1},	  {ZRINIT,f,1,1},	  {ZSINIT,f,1,1},	  {ZACK,f,1,1},	  {ZFILE,f,1,1},	  {ZSKIP,f,1,1},	  {ZNAK,f,1,1},	  {ZABORT,f,1,1,TFinish},	  {ZFIN,f,1,1},	  {ZRPOS,f,1,1},	  {ZDATA,f,1,1},	  {ZEOF,f,1,1},	  {ZFERR,f,1,1,TFinish},	  {ZCRC,f,1,1},	  {ZCHALLENGE,f,1,1},	  {ZCOMPL,f,1,1},	  {ZCAN,f,1,1},	  {ZFREECNT,f,1,1},	  {ZCOMMAND,f,1,1},	  {ZSTDERR,f,1,1},#endif	/* COMMENT */	  {99,ZPF,0,0,CommandWait},	} ;static	StateTable	StderrDataOps[] = {#ifdef	COMMENT	  {ZRQINIT,f,1,1},	  {ZRINIT,f,1,1},	  {ZSINIT,f,1,1},	  {ZACK,f,1,1},	  {ZFILE,f,1,1},	  {ZSKIP,f,1,1},	  {ZNAK,f,1,1},	  {ZABORT,f,1,1,TFinish},	  {ZFIN,f,1,1},	  {ZRPOS,f,1,1},	  {ZDATA,f,1,1},	  {ZEOF,f,1,1},	  {ZFERR,f,1,1,TFinish},	  {ZCRC,f,1,1},	  {ZCHALLENGE,f,1,1},	  {ZCOMPL,f,1,1},	  {ZCAN,f,1,1},	  {ZFREECNT,f,1,1},	  {ZCOMMAND,f,1,1},	  {ZSTDERR,f,1,1},#endif	/* COMMENT */	  {99,ZPF,0,0,StderrData},	} ;static	StateTable	DoneOps[] = {	  {99,ZPF,0,0,Done},	} ;static	StateTable	*tables[] = {	  RStartOps,	  RSinitWaitOps,	  RFileNameOps,	  RCrcOps,	  RFileOps,	  RDataOps,	  RDataOps,	/* RDataErr is the same as RData */	  RFinishOps,	  TStartOps,	  TInitOps,	  FileWaitOps,	  CrcWaitOps,	  SendingOps,	  SendWaitOps,	  SendDoneOps,	  SendEofOps,	  TFinishOps,	  CommandDataOps,	  CommandWaitOps,	  StderrDataOps,	  DoneOps,	} ;	char	*hdrnames[] = {	  "ZRQINIT",	  "ZRINIT",	  "ZSINIT",	  "ZACK",	  "ZFILE",	  "ZSKIP",	  "ZNAK",	  "ZABORT",	  "ZFIN",	  "ZRPOS",	  "ZDATA",	  "ZEOF",	  "ZFERR",	  "ZCRC",	  "ZCHALLENGE",	  "ZCOMPL",	  "ZCAN",	  "ZFREECNT",	  "ZCOMMAND",	  "ZSTDERR",	} ;	/* This function is called (indirectly) by the ZmodemRcv()	 * function when a full header has been received.	 */static	intZProtocol( register ZModem *info ){register StateTable *table ;	zmodemlog("received %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",	    hdrnames[info->hdrData[0]], info->hdrData[1],	    info->hdrData[2], info->hdrData[3], info->hdrData[4],	    ZDec4(info->hdrData+1)) ;	/* Flags are sent in F3 F2 F1 F0 order.  Data is sent in P0 P1 P2 P3 */	info->timeoutCount = 0 ;	info->noiseCount = 0 ;	table = tables[(int)info->state] ;	while( table->type != 99  &&  table->type != info->hdrData[0] )	  ++table ;	zmodemlog("  state %s => %s, iflush=%d, oflush=%d, call %x\n",	    sname(info), sname2(table->newstate), table->IFlush,	    table->OFlush, table->func) ;	info->state = table->newstate ;	if( table->IFlush ) {info->rcvlen = 0 ; ZIFlush(info) ;}	if( table->OFlush ) ZOFlush(info) ;	return table->func(info) ;}static	intZDataReceived( register ZModem *info, int crcGood ){	switch( info->state ) {	  case RSinitWait: return GotSinitData(info, crcGood) ;	  case RFileName: return GotFileName(info, crcGood) ;	  case RData: return GotFileData(info, crcGood) ;	  case CommandData: return GotCommandData(info, crcGood) ;	  case StderrData: return GotStderrData(info, crcGood) ;	  default: return ZPF(info) ;	}}intZmodemTimeout( register ZModem *info ){	/* timed out while waiting for input */	++info->timeoutCount ;	zmodemlog("timeout %d [%s]\n", info->timeoutCount, sname(info) ) ;	switch( info->state ) {	  /* receive */	  case RStart:		/* waiting for INIT frame from other end */	    if( info->timeoutCount > 4 )	      return YmodemRInit(info) ;	  case RSinitWait:	  case RFileName:	    if( info->timeout > 0 )	      ZStatus(SndTimeout, info->timeoutCount, NULL) ;	    if( info->timeoutCount > 4 )	      return ZmErrRcvTo ;	    info->state = RStart ;	    return SendRinit(info) ;	  case RCrc:	  case RFile:	  case RData:	    ZStatus(SndTimeout, info->timeoutCount, NULL) ;	    if( info->timeoutCount > 2 ) {	      info->timeoutCount = 0 ;	      info->state = RStart ;	      return SendRinit(info) ;	    }	    return info->state == RCrc ? ResendCrcReq(info) : ResendRpos(info) ;	  case RFinish:	    ZStatus(SndTimeout, info->timeoutCount, NULL) ;	    return ZmDone ;	  case YRStart:	  case YRDataWait:	  case YRData:	  case YREOF:	    return YrcvTimeout(info) ;	  /* transmit */	  case TStart:		/* waiting for INIT frame from other end */	  case TInit:		/* sent INIT, waiting for ZACK */	  case FileWait:	/* sent file header, waiting for ZRPOS */	  case CrcWait:		/* sent file crc, waiting for ZRPOS */	  case SendWait:	/* waiting for ZACK */	  case SendEof:		/* sent EOF, waiting for ZACK */	  case TFinish:		/* sent ZFIN, waiting for ZFIN */	  case YTStart:	  case YTFile:	  case YTDataWait:	  case YTData:	  case YTEOF:	  case YTFin:	    ZStatus(RcvTimeout,0,NULL) ;	    return ZmErrRcvTo ;	  case Sending:		/* sending data subpackets, ready for int */	    return SendMoreFileData(info) ;	  /* general */	  case CommandData:	/* waiting for command data */	  case StderrData:	/* waiting for stderr data */	    return ZmErrSndTo ;	  case CommandWait:	/* waiting for command to execute */	    return ZmErrCmdTo ;	  case Done:	    return ZmDone ;	  default:	    return 0 ;	}}intZmodemAttention( register ZModem *info ){	/* attention received from remote end */	if( info->state == Sending ) {	  ZOFlush(info) ;	  info->interrupt = 1 ;	}	return 0 ;}intZmodemAbort( register ZModem *info ){static	u_char	canistr[] = {	  CAN,CAN,CAN,CAN,CAN,CAN,CAN,CAN,8,8,8,8,8,8,8,8,8,8	} ;	info->state = Done ;	ZIFlush(info) ;	ZOFlush(info) ;	return ZXmitStr(canistr, sizeof(canistr), info) ;}	/* used to completely ignore headers */intIgnore( ZModem *info ){	return 0 ;}	/* ignore header contents, return ZmDone */intRetDone( ZModem *info ){	return ZmDone ;}	/* ignore header contents, return ZmErrCancel */intGotCancel( ZModem *info ){	return ZmErrCancel ;}	/* utility: set up to receive a data packet */intdataSetup( register ZModem *info ){	info->InputState = Indata ;	info->chrCount = 0 ;	info->crcCount = 0 ;	info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL ;	return 0 ;}	/* called when a remote command received.  For now, we	 * refuse to execute commands.  Send EPERM and ignore.	 */intGotCommand( ZModem *info ){	u_char	rbuf[4] ;	/* TODO: add command capability */	rbuf[0] = EPERM ;	rbuf[1] = rbuf[2] = rbuf[3] = 0 ;	return ZXmitHdrHex(ZCOMPL, rbuf, info) ;}static	intGotCommandData( register ZModem *info ){/* TODO */return 0 ;}	/* called when the remote system wants to put something to	 * stderr	 */intGotStderr( register ZModem *info ){	info->InputState = Indata ;	info->chrCount = 0 ;	return 0 ;}static	intGotStderrData( register ZModem *info ){	info->buffer[info->chrCount] = '\0' ;	ZStatus(RemoteMessage, info->chrCount, (char *)info->buffer) ;	return 0 ;}	/* Protocol failure:  An unexpected packet arrived.  This could	 * be from many sources, such as old pipelined info finally arriving	 * or a serial line with echo enabled.  Report it and ignore it.	 */intZPF( ZModem *info ){	info->waitflag = 1 ;	/* pause any in-progress transmission */	ZStatus(ProtocolErr, info->hdrData[0], NULL) ;	return 0 ;}intAnswerChallenge( register ZModem *info ){	return ZXmitHdrHex(ZACK, info->hdrData+1, info) ;}intGotAbort( register ZModem *info ){	ZStatus(RmtCancel, 0, NULL) ;	return ZXmitHdrHex(ZFIN, zeros, info) ;}

⌨️ 快捷键说明

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